mirror of
https://github.com/PR0M3TH3AN/SeedPass.git
synced 2025-09-08 07:18:47 +00:00
704 lines
66 KiB
HTML
704 lines
66 KiB
HTML
<!DOCTYPE html>
|
||
<html xmlns="http://www.w3.org/1999/xhtml" lang="" xml:lang="">
|
||
<head>
|
||
<meta charset="utf-8" />
|
||
<meta name="generator" content="pandoc" />
|
||
<meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=yes" />
|
||
<title>json_entries</title>
|
||
<style>
|
||
code{white-space: pre-wrap;}
|
||
span.smallcaps{font-variant: small-caps;}
|
||
div.columns{display: flex; gap: min(4vw, 1.5em);}
|
||
div.column{flex: auto; overflow-x: auto;}
|
||
div.hanging-indent{margin-left: 1.5em; text-indent: -1.5em;}
|
||
/* The extra [class] is a hack that increases specificity enough to
|
||
override a similar rule in reveal.js */
|
||
ul.task-list[class]{list-style: none;}
|
||
ul.task-list li input[type="checkbox"] {
|
||
font-size: inherit;
|
||
width: 0.8em;
|
||
margin: 0 0.8em 0.2em -1.6em;
|
||
vertical-align: middle;
|
||
}
|
||
.display.math{display: block; text-align: center; margin: 0.5rem auto;}
|
||
/* CSS for syntax highlighting */
|
||
pre > code.sourceCode { white-space: pre; position: relative; }
|
||
pre > code.sourceCode > span { line-height: 1.25; }
|
||
pre > code.sourceCode > span:empty { height: 1.2em; }
|
||
.sourceCode { overflow: visible; }
|
||
code.sourceCode > span { color: inherit; text-decoration: inherit; }
|
||
div.sourceCode { margin: 1em 0; }
|
||
pre.sourceCode { margin: 0; }
|
||
@media screen {
|
||
div.sourceCode { overflow: auto; }
|
||
}
|
||
@media print {
|
||
pre > code.sourceCode { white-space: pre-wrap; }
|
||
pre > code.sourceCode > span { text-indent: -5em; padding-left: 5em; }
|
||
}
|
||
pre.numberSource code
|
||
{ counter-reset: source-line 0; }
|
||
pre.numberSource code > span
|
||
{ position: relative; left: -4em; counter-increment: source-line; }
|
||
pre.numberSource code > span > a:first-child::before
|
||
{ content: counter(source-line);
|
||
position: relative; left: -1em; text-align: right; vertical-align: baseline;
|
||
border: none; display: inline-block;
|
||
-webkit-touch-callout: none; -webkit-user-select: none;
|
||
-khtml-user-select: none; -moz-user-select: none;
|
||
-ms-user-select: none; user-select: none;
|
||
padding: 0 4px; width: 4em;
|
||
color: #aaaaaa;
|
||
}
|
||
pre.numberSource { margin-left: 3em; border-left: 1px solid #aaaaaa; padding-left: 4px; }
|
||
div.sourceCode
|
||
{ }
|
||
@media screen {
|
||
pre > code.sourceCode > span > a:first-child::before { text-decoration: underline; }
|
||
}
|
||
code span.al { color: #ff0000; font-weight: bold; } /* Alert */
|
||
code span.an { color: #60a0b0; font-weight: bold; font-style: italic; } /* Annotation */
|
||
code span.at { color: #7d9029; } /* Attribute */
|
||
code span.bn { color: #40a070; } /* BaseN */
|
||
code span.bu { color: #008000; } /* BuiltIn */
|
||
code span.cf { color: #007020; font-weight: bold; } /* ControlFlow */
|
||
code span.ch { color: #4070a0; } /* Char */
|
||
code span.cn { color: #880000; } /* Constant */
|
||
code span.co { color: #60a0b0; font-style: italic; } /* Comment */
|
||
code span.cv { color: #60a0b0; font-weight: bold; font-style: italic; } /* CommentVar */
|
||
code span.do { color: #ba2121; font-style: italic; } /* Documentation */
|
||
code span.dt { color: #902000; } /* DataType */
|
||
code span.dv { color: #40a070; } /* DecVal */
|
||
code span.er { color: #ff0000; font-weight: bold; } /* Error */
|
||
code span.ex { } /* Extension */
|
||
code span.fl { color: #40a070; } /* Float */
|
||
code span.fu { color: #06287e; } /* Function */
|
||
code span.im { color: #008000; font-weight: bold; } /* Import */
|
||
code span.in { color: #60a0b0; font-weight: bold; font-style: italic; } /* Information */
|
||
code span.kw { color: #007020; font-weight: bold; } /* Keyword */
|
||
code span.op { color: #666666; } /* Operator */
|
||
code span.ot { color: #007020; } /* Other */
|
||
code span.pp { color: #bc7a00; } /* Preprocessor */
|
||
code span.sc { color: #4070a0; } /* SpecialChar */
|
||
code span.ss { color: #bb6688; } /* SpecialString */
|
||
code span.st { color: #4070a0; } /* String */
|
||
code span.va { color: #19177c; } /* Variable */
|
||
code span.vs { color: #4070a0; } /* VerbatimString */
|
||
code span.wa { color: #60a0b0; font-weight: bold; font-style: italic; } /* Warning */
|
||
</style>
|
||
<link rel="stylesheet" href="theme.css" />
|
||
</head>
|
||
<body>
|
||
<h1 id="seedpass-json-entry-management-and-extensibility">SeedPass JSON
|
||
Entry Management and Extensibility</h1>
|
||
<h2 id="table-of-contents">Table of Contents</h2>
|
||
<ul>
|
||
<li><a href="#introduction">Introduction</a></li>
|
||
<li><a href="#json-schema-for-individual-entries">JSON Schema for
|
||
Individual Entries</a>
|
||
<ul>
|
||
<li><a href="#general-structure">General Structure</a></li>
|
||
<li><a href="#field-descriptions">Field Descriptions</a></li>
|
||
<li><a href="#example-entries">Example Entries</a></li>
|
||
</ul></li>
|
||
<li><a href="#handling-kind-types-and-extensibility">Handling
|
||
<code>kind</code> Types and Extensibility</a>
|
||
<ul>
|
||
<li><a href="#extensible-json-schema-design">Extensible JSON Schema
|
||
Design</a></li>
|
||
<li><a href="#ensuring-backward-compatibility">Ensuring Backward
|
||
Compatibility</a></li>
|
||
<li><a href="#best-practices-for-adding-new-kinds">Best Practices for
|
||
Adding New Kinds</a></li>
|
||
</ul></li>
|
||
<li><a href="#adding-new-kind-types">Adding New <code>kind</code>
|
||
Types</a>
|
||
<ul>
|
||
<li><a href="#example-adding-cryptocurrency_wallet">Example: Adding
|
||
<code>cryptocurrency_wallet</code></a></li>
|
||
</ul></li>
|
||
<li><a href="#backup-and-rollback-mechanism">Backup and Rollback
|
||
Mechanism</a></li>
|
||
<li><a href="#security-considerations">Security Considerations</a></li>
|
||
<li><a href="#updated-roadmap">Updated Roadmap</a>
|
||
<ul>
|
||
<li><a
|
||
href="#phase-1-core-functionality-and-security-enhancements">Phase 1:
|
||
Core Functionality and Security Enhancements</a></li>
|
||
<li><a href="#phase-2-enhanced-security-and-data-management">Phase 2:
|
||
Enhanced Security and Data Management</a></li>
|
||
<li><a href="#phase-3-advanced-cli-functionalities">Phase 3: Advanced
|
||
CLI Functionalities</a></li>
|
||
<li><a
|
||
href="#phase-4-data-management-enhancements-and-integrations">Phase 4:
|
||
Data Management Enhancements and Integrations</a></li>
|
||
<li><a href="#phase-5-documentation-testing-and-finalization">Phase 5:
|
||
Documentation, Testing, and Finalization</a></li>
|
||
<li><a href="#future-phases-beyond-initial-roadmap">Future Phases
|
||
(Beyond Initial Roadmap)</a></li>
|
||
</ul></li>
|
||
<li><a href="#summary">Summary</a></li>
|
||
<li><a href="#contact">Contact</a></li>
|
||
</ul>
|
||
<hr />
|
||
<h2 id="introduction">Introduction</h2>
|
||
<p><strong>SeedPass</strong> is a secure password generator and manager
|
||
leveraging <strong>Bitcoin’s BIP-85 standard</strong> and integrating
|
||
with the <strong>Nostr network</strong> for decentralized
|
||
synchronization. Instead of pushing one large index file, SeedPass posts
|
||
<strong>snapshot chunks</strong> of the index followed by lightweight
|
||
<strong>delta events</strong> whenever changes occur. This chunked
|
||
approach improves reliability and keeps bandwidth usage minimal. To
|
||
enhance modularity, scalability, and security, SeedPass stores all
|
||
entries in a single encrypted index file named
|
||
<code>seedpass_entries_db.json.enc</code>. This document outlines the
|
||
entry management system, ensuring that new <code>kind</code> types can
|
||
be added seamlessly without disrupting existing functionalities.</p>
|
||
<hr />
|
||
<h2 id="index-file-format">Index File Format</h2>
|
||
<p>All entries belonging to a seed profile are stored in an encrypted
|
||
file named <code>seedpass_entries_db.json.enc</code>. This index uses
|
||
<code>schema_version</code> <code>3</code> and contains an
|
||
<code>entries</code> object keyed by numeric identifiers.</p>
|
||
<div class="sourceCode" id="cb1"><pre
|
||
class="sourceCode json"><code class="sourceCode json"><span id="cb1-1"><a href="#cb1-1" aria-hidden="true" tabindex="-1"></a><span class="fu">{</span></span>
|
||
<span id="cb1-2"><a href="#cb1-2" aria-hidden="true" tabindex="-1"></a> <span class="dt">"schema_version"</span><span class="fu">:</span> <span class="dv">3</span><span class="fu">,</span></span>
|
||
<span id="cb1-3"><a href="#cb1-3" aria-hidden="true" tabindex="-1"></a> <span class="dt">"entries"</span><span class="fu">:</span> <span class="fu">{</span></span>
|
||
<span id="cb1-4"><a href="#cb1-4" aria-hidden="true" tabindex="-1"></a> <span class="dt">"0"</span><span class="fu">:</span> <span class="fu">{</span></span>
|
||
<span id="cb1-5"><a href="#cb1-5" aria-hidden="true" tabindex="-1"></a> <span class="dt">"label"</span><span class="fu">:</span> <span class="st">"example.com"</span><span class="fu">,</span></span>
|
||
<span id="cb1-6"><a href="#cb1-6" aria-hidden="true" tabindex="-1"></a> <span class="dt">"length"</span><span class="fu">:</span> <span class="dv">8</span><span class="fu">,</span></span>
|
||
<span id="cb1-7"><a href="#cb1-7" aria-hidden="true" tabindex="-1"></a> <span class="dt">"username"</span><span class="fu">:</span> <span class="st">"user"</span><span class="fu">,</span></span>
|
||
<span id="cb1-8"><a href="#cb1-8" aria-hidden="true" tabindex="-1"></a> <span class="dt">"url"</span><span class="fu">:</span> <span class="st">"https://example.com"</span><span class="fu">,</span></span>
|
||
<span id="cb1-9"><a href="#cb1-9" aria-hidden="true" tabindex="-1"></a> <span class="dt">"archived"</span><span class="fu">:</span> <span class="kw">false</span><span class="fu">,</span></span>
|
||
<span id="cb1-10"><a href="#cb1-10" aria-hidden="true" tabindex="-1"></a> <span class="dt">"type"</span><span class="fu">:</span> <span class="st">"password"</span><span class="fu">,</span></span>
|
||
<span id="cb1-11"><a href="#cb1-11" aria-hidden="true" tabindex="-1"></a> <span class="dt">"kind"</span><span class="fu">:</span> <span class="st">"password"</span><span class="fu">,</span></span>
|
||
<span id="cb1-12"><a href="#cb1-12" aria-hidden="true" tabindex="-1"></a> <span class="dt">"notes"</span><span class="fu">:</span> <span class="st">""</span><span class="fu">,</span></span>
|
||
<span id="cb1-13"><a href="#cb1-13" aria-hidden="true" tabindex="-1"></a> <span class="dt">"custom_fields"</span><span class="fu">:</span> <span class="ot">[]</span><span class="fu">,</span></span>
|
||
<span id="cb1-14"><a href="#cb1-14" aria-hidden="true" tabindex="-1"></a> <span class="dt">"origin"</span><span class="fu">:</span> <span class="st">""</span></span>
|
||
<span id="cb1-15"><a href="#cb1-15" aria-hidden="true" tabindex="-1"></a> <span class="fu">}</span></span>
|
||
<span id="cb1-16"><a href="#cb1-16" aria-hidden="true" tabindex="-1"></a> <span class="fu">}</span></span>
|
||
<span id="cb1-17"><a href="#cb1-17" aria-hidden="true" tabindex="-1"></a><span class="fu">}</span></span></code></pre></div>
|
||
<hr />
|
||
<h2 id="json-schema-for-individual-entries">JSON Schema for Individual
|
||
Entries</h2>
|
||
<p>Each entry is stored within <code>seedpass_entries_db.json.enc</code>
|
||
under the <code>entries</code> dictionary. The structure supports
|
||
diverse entry types (<code>kind</code>) and allows for future
|
||
expansions.</p>
|
||
<h3 id="general-structure">General Structure</h3>
|
||
<div class="sourceCode" id="cb2"><pre
|
||
class="sourceCode json"><code class="sourceCode json"><span id="cb2-1"><a href="#cb2-1" aria-hidden="true" tabindex="-1"></a><span class="fu">{</span></span>
|
||
<span id="cb2-2"><a href="#cb2-2" aria-hidden="true" tabindex="-1"></a> <span class="dt">"label"</span><span class="fu">:</span> <span class="st">"Example"</span><span class="fu">,</span></span>
|
||
<span id="cb2-3"><a href="#cb2-3" aria-hidden="true" tabindex="-1"></a> <span class="dt">"length"</span><span class="fu">:</span> <span class="dv">8</span><span class="fu">,</span></span>
|
||
<span id="cb2-4"><a href="#cb2-4" aria-hidden="true" tabindex="-1"></a> <span class="dt">"username"</span><span class="fu">:</span> <span class="st">"user@example.com"</span><span class="fu">,</span></span>
|
||
<span id="cb2-5"><a href="#cb2-5" aria-hidden="true" tabindex="-1"></a> <span class="dt">"url"</span><span class="fu">:</span> <span class="st">"https://example.com"</span><span class="fu">,</span></span>
|
||
<span id="cb2-6"><a href="#cb2-6" aria-hidden="true" tabindex="-1"></a> <span class="dt">"archived"</span><span class="fu">:</span> <span class="kw">false</span><span class="fu">,</span></span>
|
||
<span id="cb2-7"><a href="#cb2-7" aria-hidden="true" tabindex="-1"></a> <span class="dt">"type"</span><span class="fu">:</span> <span class="st">"password"</span><span class="fu">,</span></span>
|
||
<span id="cb2-8"><a href="#cb2-8" aria-hidden="true" tabindex="-1"></a> <span class="dt">"kind"</span><span class="fu">:</span> <span class="st">"password"</span><span class="fu">,</span></span>
|
||
<span id="cb2-9"><a href="#cb2-9" aria-hidden="true" tabindex="-1"></a> <span class="dt">"notes"</span><span class="fu">:</span> <span class="st">""</span><span class="fu">,</span></span>
|
||
<span id="cb2-10"><a href="#cb2-10" aria-hidden="true" tabindex="-1"></a> <span class="dt">"custom_fields"</span><span class="fu">:</span> <span class="ot">[]</span><span class="fu">,</span></span>
|
||
<span id="cb2-11"><a href="#cb2-11" aria-hidden="true" tabindex="-1"></a> <span class="dt">"origin"</span><span class="fu">:</span> <span class="st">""</span><span class="fu">,</span></span>
|
||
<span id="cb2-12"><a href="#cb2-12" aria-hidden="true" tabindex="-1"></a> <span class="dt">"tags"</span><span class="fu">:</span> <span class="ot">[]</span><span class="fu">,</span></span>
|
||
<span id="cb2-13"><a href="#cb2-13" aria-hidden="true" tabindex="-1"></a> <span class="dt">"index"</span><span class="fu">:</span> <span class="dv">0</span></span>
|
||
<span id="cb2-14"><a href="#cb2-14" aria-hidden="true" tabindex="-1"></a><span class="fu">}</span></span></code></pre></div>
|
||
<h3 id="field-descriptions">Field Descriptions</h3>
|
||
<ul>
|
||
<li><p><strong>label</strong> (<code>string</code>): Descriptive name
|
||
for the entry (e.g., website or service).</p></li>
|
||
<li><p><strong>length</strong> (<code>integer</code>, optional): Desired
|
||
password length for generated passwords.</p></li>
|
||
<li><p><strong>username</strong> (<code>string</code>, optional):
|
||
Username associated with the entry.</p></li>
|
||
<li><p><strong>url</strong> (<code>string</code>, optional): Website or
|
||
service URL.</p></li>
|
||
<li><p><strong>archived</strong> (<code>boolean</code>): Marks the entry
|
||
as archived when <code>true</code>.</p></li>
|
||
<li><p><strong>type</strong> (<code>string</code>): The entry type
|
||
(<code>password</code>, <code>totp</code>, <code>ssh</code>,
|
||
<code>seed</code>, <code>pgp</code>, <code>nostr</code>,
|
||
<code>note</code>, <code>key_value</code>).</p></li>
|
||
<li><p><strong>kind</strong> (<code>string</code>): Synonym for
|
||
<code>type</code> kept for backward compatibility.</p></li>
|
||
<li><p><strong>notes</strong> (<code>string</code>): Free-form
|
||
notes.</p></li>
|
||
<li><p><strong>custom_fields</strong> (<code>array</code>, optional):
|
||
Additional user-defined fields.</p></li>
|
||
<li><p><strong>origin</strong> (<code>string</code>, optional): Source
|
||
identifier for imported data.</p></li>
|
||
<li><p><strong>value</strong> (<code>string</code>, optional): For
|
||
<code>key_value</code> entries, stores the secret value.</p></li>
|
||
<li><p><strong>index</strong> (<code>integer</code>, optional): BIP-85
|
||
derivation index for entries that derive material from a seed.</p></li>
|
||
<li><p><strong>word_count</strong> (<code>integer</code>,
|
||
managed_account only): Number of words in the child seed. Managed
|
||
accounts always use <code>12</code>.</p></li>
|
||
<li><p><strong>fingerprint</strong> (<code>string</code>,
|
||
managed_account only): Identifier of the child profile, used for its
|
||
directory name.</p></li>
|
||
<li><p><strong>tags</strong> (<code>array</code>, optional): Category
|
||
labels to aid in organization and search. Example:</p>
|
||
<div class="sourceCode" id="cb3"><pre
|
||
class="sourceCode json"><code class="sourceCode json"><span id="cb3-1"><a href="#cb3-1" aria-hidden="true" tabindex="-1"></a><span class="er">"custom_fields":</span> <span class="ot">[</span></span>
|
||
<span id="cb3-2"><a href="#cb3-2" aria-hidden="true" tabindex="-1"></a> <span class="fu">{</span><span class="dt">"name"</span><span class="fu">:</span> <span class="st">"account_id"</span><span class="fu">,</span> <span class="dt">"value"</span><span class="fu">:</span> <span class="st">"123"</span><span class="fu">}</span><span class="ot">,</span></span>
|
||
<span id="cb3-3"><a href="#cb3-3" aria-hidden="true" tabindex="-1"></a> <span class="fu">{</span><span class="dt">"name"</span><span class="fu">:</span> <span class="st">"recovery_hint"</span><span class="fu">,</span> <span class="dt">"value"</span><span class="fu">:</span> <span class="st">"mother's maiden name"</span><span class="fu">}</span></span>
|
||
<span id="cb3-4"><a href="#cb3-4" aria-hidden="true" tabindex="-1"></a><span class="ot">]</span></span></code></pre></div></li>
|
||
</ul>
|
||
<h3 id="example-entries">Example Entries</h3>
|
||
<h4 id="generated-password">1. Generated Password</h4>
|
||
<div class="sourceCode" id="cb4"><pre
|
||
class="sourceCode json"><code class="sourceCode json"><span id="cb4-1"><a href="#cb4-1" aria-hidden="true" tabindex="-1"></a><span class="fu">{</span></span>
|
||
<span id="cb4-2"><a href="#cb4-2" aria-hidden="true" tabindex="-1"></a> <span class="dt">"entry_num"</span><span class="fu">:</span> <span class="dv">0</span><span class="fu">,</span></span>
|
||
<span id="cb4-3"><a href="#cb4-3" aria-hidden="true" tabindex="-1"></a> <span class="dt">"index_num"</span><span class="fu">:</span> <span class="dv">0</span><span class="fu">,</span></span>
|
||
<span id="cb4-4"><a href="#cb4-4" aria-hidden="true" tabindex="-1"></a> <span class="dt">"fingerprint"</span><span class="fu">:</span> <span class="st">"a1b2c3d4"</span><span class="fu">,</span></span>
|
||
<span id="cb4-5"><a href="#cb4-5" aria-hidden="true" tabindex="-1"></a> <span class="dt">"kind"</span><span class="fu">:</span> <span class="st">"generated_password"</span><span class="fu">,</span></span>
|
||
<span id="cb4-6"><a href="#cb4-6" aria-hidden="true" tabindex="-1"></a> <span class="dt">"data"</span><span class="fu">:</span> <span class="fu">{</span></span>
|
||
<span id="cb4-7"><a href="#cb4-7" aria-hidden="true" tabindex="-1"></a> <span class="dt">"title"</span><span class="fu">:</span> <span class="st">"Example Website"</span><span class="fu">,</span></span>
|
||
<span id="cb4-8"><a href="#cb4-8" aria-hidden="true" tabindex="-1"></a> <span class="dt">"username"</span><span class="fu">:</span> <span class="st">"user@example.com"</span><span class="fu">,</span></span>
|
||
<span id="cb4-9"><a href="#cb4-9" aria-hidden="true" tabindex="-1"></a> <span class="dt">"email"</span><span class="fu">:</span> <span class="st">"user@example.com"</span><span class="fu">,</span></span>
|
||
<span id="cb4-10"><a href="#cb4-10" aria-hidden="true" tabindex="-1"></a> <span class="dt">"url"</span><span class="fu">:</span> <span class="st">"https://example.com"</span><span class="fu">,</span></span>
|
||
<span id="cb4-11"><a href="#cb4-11" aria-hidden="true" tabindex="-1"></a> <span class="dt">"password"</span><span class="fu">:</span> <span class="st">"<encrypted_password>"</span></span>
|
||
<span id="cb4-12"><a href="#cb4-12" aria-hidden="true" tabindex="-1"></a> <span class="fu">},</span></span>
|
||
<span id="cb4-13"><a href="#cb4-13" aria-hidden="true" tabindex="-1"></a> <span class="dt">"custom_fields"</span><span class="fu">:</span> <span class="ot">[</span></span>
|
||
<span id="cb4-14"><a href="#cb4-14" aria-hidden="true" tabindex="-1"></a> <span class="fu">{</span><span class="dt">"name"</span><span class="fu">:</span> <span class="st">"department"</span><span class="fu">,</span> <span class="dt">"value"</span><span class="fu">:</span> <span class="st">"finance"</span><span class="fu">}</span></span>
|
||
<span id="cb4-15"><a href="#cb4-15" aria-hidden="true" tabindex="-1"></a> <span class="ot">]</span><span class="fu">,</span></span>
|
||
<span id="cb4-16"><a href="#cb4-16" aria-hidden="true" tabindex="-1"></a> <span class="dt">"tags"</span><span class="fu">:</span> <span class="ot">[</span><span class="st">"work"</span><span class="ot">]</span><span class="fu">,</span></span>
|
||
<span id="cb4-17"><a href="#cb4-17" aria-hidden="true" tabindex="-1"></a> <span class="dt">"timestamp"</span><span class="fu">:</span> <span class="st">"2024-04-27T12:34:56Z"</span><span class="fu">,</span></span>
|
||
<span id="cb4-18"><a href="#cb4-18" aria-hidden="true" tabindex="-1"></a> <span class="dt">"metadata"</span><span class="fu">:</span> <span class="fu">{</span></span>
|
||
<span id="cb4-19"><a href="#cb4-19" aria-hidden="true" tabindex="-1"></a> <span class="dt">"created_at"</span><span class="fu">:</span> <span class="st">"2024-04-27T12:34:56Z"</span><span class="fu">,</span></span>
|
||
<span id="cb4-20"><a href="#cb4-20" aria-hidden="true" tabindex="-1"></a> <span class="dt">"updated_at"</span><span class="fu">:</span> <span class="st">"2024-04-27T12:34:56Z"</span><span class="fu">,</span></span>
|
||
<span id="cb4-21"><a href="#cb4-21" aria-hidden="true" tabindex="-1"></a> <span class="dt">"checksum"</span><span class="fu">:</span> <span class="st">"abc123def456"</span></span>
|
||
<span id="cb4-22"><a href="#cb4-22" aria-hidden="true" tabindex="-1"></a> <span class="fu">}</span></span>
|
||
<span id="cb4-23"><a href="#cb4-23" aria-hidden="true" tabindex="-1"></a><span class="fu">}</span></span></code></pre></div>
|
||
<h4 id="stored-password">2. Stored Password</h4>
|
||
<div class="sourceCode" id="cb5"><pre
|
||
class="sourceCode json"><code class="sourceCode json"><span id="cb5-1"><a href="#cb5-1" aria-hidden="true" tabindex="-1"></a><span class="fu">{</span></span>
|
||
<span id="cb5-2"><a href="#cb5-2" aria-hidden="true" tabindex="-1"></a> <span class="dt">"entry_num"</span><span class="fu">:</span> <span class="dv">1</span><span class="fu">,</span></span>
|
||
<span id="cb5-3"><a href="#cb5-3" aria-hidden="true" tabindex="-1"></a> <span class="dt">"index_num"</span><span class="fu">:</span> <span class="st">"q1wec4d426fs"</span><span class="fu">,</span></span>
|
||
<span id="cb5-4"><a href="#cb5-4" aria-hidden="true" tabindex="-1"></a> <span class="dt">"fingerprint"</span><span class="fu">:</span> <span class="st">"a1b2c3d4"</span><span class="fu">,</span></span>
|
||
<span id="cb5-5"><a href="#cb5-5" aria-hidden="true" tabindex="-1"></a> <span class="dt">"kind"</span><span class="fu">:</span> <span class="st">"stored_password"</span><span class="fu">,</span></span>
|
||
<span id="cb5-6"><a href="#cb5-6" aria-hidden="true" tabindex="-1"></a> <span class="dt">"data"</span><span class="fu">:</span> <span class="fu">{</span></span>
|
||
<span id="cb5-7"><a href="#cb5-7" aria-hidden="true" tabindex="-1"></a> <span class="dt">"title"</span><span class="fu">:</span> <span class="st">"Another Service"</span><span class="fu">,</span></span>
|
||
<span id="cb5-8"><a href="#cb5-8" aria-hidden="true" tabindex="-1"></a> <span class="dt">"username"</span><span class="fu">:</span> <span class="st">"another_user"</span><span class="fu">,</span></span>
|
||
<span id="cb5-9"><a href="#cb5-9" aria-hidden="true" tabindex="-1"></a> <span class="dt">"password"</span><span class="fu">:</span> <span class="st">"<encrypted_password>"</span></span>
|
||
<span id="cb5-10"><a href="#cb5-10" aria-hidden="true" tabindex="-1"></a> <span class="fu">},</span></span>
|
||
<span id="cb5-11"><a href="#cb5-11" aria-hidden="true" tabindex="-1"></a> <span class="dt">"timestamp"</span><span class="fu">:</span> <span class="st">"2024-04-27T12:35:56Z"</span><span class="fu">,</span></span>
|
||
<span id="cb5-12"><a href="#cb5-12" aria-hidden="true" tabindex="-1"></a> <span class="dt">"metadata"</span><span class="fu">:</span> <span class="fu">{</span></span>
|
||
<span id="cb5-13"><a href="#cb5-13" aria-hidden="true" tabindex="-1"></a> <span class="dt">"created_at"</span><span class="fu">:</span> <span class="st">"2024-04-27T12:35:56Z"</span><span class="fu">,</span></span>
|
||
<span id="cb5-14"><a href="#cb5-14" aria-hidden="true" tabindex="-1"></a> <span class="dt">"updated_at"</span><span class="fu">:</span> <span class="st">"2024-04-27T12:35:56Z"</span><span class="fu">,</span></span>
|
||
<span id="cb5-15"><a href="#cb5-15" aria-hidden="true" tabindex="-1"></a> <span class="dt">"checksum"</span><span class="fu">:</span> <span class="st">"def789ghi012"</span></span>
|
||
<span id="cb5-16"><a href="#cb5-16" aria-hidden="true" tabindex="-1"></a> <span class="fu">}</span></span>
|
||
<span id="cb5-17"><a href="#cb5-17" aria-hidden="true" tabindex="-1"></a><span class="fu">}</span></span></code></pre></div>
|
||
<h4 id="managed-user">3. Managed User</h4>
|
||
<div class="sourceCode" id="cb6"><pre
|
||
class="sourceCode json"><code class="sourceCode json"><span id="cb6-1"><a href="#cb6-1" aria-hidden="true" tabindex="-1"></a><span class="fu">{</span></span>
|
||
<span id="cb6-2"><a href="#cb6-2" aria-hidden="true" tabindex="-1"></a> <span class="dt">"entry_num"</span><span class="fu">:</span> <span class="dv">2</span><span class="fu">,</span></span>
|
||
<span id="cb6-3"><a href="#cb6-3" aria-hidden="true" tabindex="-1"></a> <span class="dt">"index_num"</span><span class="fu">:</span> <span class="st">"a1b2c3d4e5f6"</span><span class="fu">,</span></span>
|
||
<span id="cb6-4"><a href="#cb6-4" aria-hidden="true" tabindex="-1"></a> <span class="dt">"fingerprint"</span><span class="fu">:</span> <span class="st">"a1b2c3d4"</span><span class="fu">,</span></span>
|
||
<span id="cb6-5"><a href="#cb6-5" aria-hidden="true" tabindex="-1"></a> <span class="dt">"kind"</span><span class="fu">:</span> <span class="st">"managed_user"</span><span class="fu">,</span></span>
|
||
<span id="cb6-6"><a href="#cb6-6" aria-hidden="true" tabindex="-1"></a> <span class="dt">"data"</span><span class="fu">:</span> <span class="fu">{</span></span>
|
||
<span id="cb6-7"><a href="#cb6-7" aria-hidden="true" tabindex="-1"></a> <span class="dt">"users_password"</span><span class="fu">:</span> <span class="st">"<encrypted_users_password>"</span></span>
|
||
<span id="cb6-8"><a href="#cb6-8" aria-hidden="true" tabindex="-1"></a> <span class="fu">},</span></span>
|
||
<span id="cb6-9"><a href="#cb6-9" aria-hidden="true" tabindex="-1"></a> <span class="dt">"timestamp"</span><span class="fu">:</span> <span class="st">"2024-04-27T12:36:56Z"</span><span class="fu">,</span></span>
|
||
<span id="cb6-10"><a href="#cb6-10" aria-hidden="true" tabindex="-1"></a> <span class="dt">"metadata"</span><span class="fu">:</span> <span class="fu">{</span></span>
|
||
<span id="cb6-11"><a href="#cb6-11" aria-hidden="true" tabindex="-1"></a> <span class="dt">"created_at"</span><span class="fu">:</span> <span class="st">"2024-04-27T12:36:56Z"</span><span class="fu">,</span></span>
|
||
<span id="cb6-12"><a href="#cb6-12" aria-hidden="true" tabindex="-1"></a> <span class="dt">"updated_at"</span><span class="fu">:</span> <span class="st">"2024-04-27T12:36:56Z"</span><span class="fu">,</span></span>
|
||
<span id="cb6-13"><a href="#cb6-13" aria-hidden="true" tabindex="-1"></a> <span class="dt">"checksum"</span><span class="fu">:</span> <span class="st">"ghi345jkl678"</span></span>
|
||
<span id="cb6-14"><a href="#cb6-14" aria-hidden="true" tabindex="-1"></a> <span class="fu">}</span></span>
|
||
<span id="cb6-15"><a href="#cb6-15" aria-hidden="true" tabindex="-1"></a><span class="fu">}</span></span></code></pre></div>
|
||
<h4 id="word-seed">4. 12 Word Seed</h4>
|
||
<div class="sourceCode" id="cb7"><pre
|
||
class="sourceCode json"><code class="sourceCode json"><span id="cb7-1"><a href="#cb7-1" aria-hidden="true" tabindex="-1"></a><span class="fu">{</span></span>
|
||
<span id="cb7-2"><a href="#cb7-2" aria-hidden="true" tabindex="-1"></a> <span class="dt">"entry_num"</span><span class="fu">:</span> <span class="dv">3</span><span class="fu">,</span></span>
|
||
<span id="cb7-3"><a href="#cb7-3" aria-hidden="true" tabindex="-1"></a> <span class="dt">"index_num"</span><span class="fu">:</span> <span class="st">"f7g8h9i0j1k2"</span><span class="fu">,</span></span>
|
||
<span id="cb7-4"><a href="#cb7-4" aria-hidden="true" tabindex="-1"></a> <span class="dt">"fingerprint"</span><span class="fu">:</span> <span class="st">"a1b2c3d4"</span><span class="fu">,</span></span>
|
||
<span id="cb7-5"><a href="#cb7-5" aria-hidden="true" tabindex="-1"></a> <span class="dt">"kind"</span><span class="fu">:</span> <span class="st">"12_word_seed"</span><span class="fu">,</span></span>
|
||
<span id="cb7-6"><a href="#cb7-6" aria-hidden="true" tabindex="-1"></a> <span class="dt">"data"</span><span class="fu">:</span> <span class="fu">{</span></span>
|
||
<span id="cb7-7"><a href="#cb7-7" aria-hidden="true" tabindex="-1"></a> <span class="dt">"seed_phrase"</span><span class="fu">:</span> <span class="st">"<encrypted_seed_phrase>"</span></span>
|
||
<span id="cb7-8"><a href="#cb7-8" aria-hidden="true" tabindex="-1"></a> <span class="fu">},</span></span>
|
||
<span id="cb7-9"><a href="#cb7-9" aria-hidden="true" tabindex="-1"></a> <span class="dt">"timestamp"</span><span class="fu">:</span> <span class="st">"2024-04-27T12:37:56Z"</span><span class="fu">,</span></span>
|
||
<span id="cb7-10"><a href="#cb7-10" aria-hidden="true" tabindex="-1"></a> <span class="dt">"metadata"</span><span class="fu">:</span> <span class="fu">{</span></span>
|
||
<span id="cb7-11"><a href="#cb7-11" aria-hidden="true" tabindex="-1"></a> <span class="dt">"created_at"</span><span class="fu">:</span> <span class="st">"2024-04-27T12:37:56Z"</span><span class="fu">,</span></span>
|
||
<span id="cb7-12"><a href="#cb7-12" aria-hidden="true" tabindex="-1"></a> <span class="dt">"updated_at"</span><span class="fu">:</span> <span class="st">"2024-04-27T12:37:56Z"</span><span class="fu">,</span></span>
|
||
<span id="cb7-13"><a href="#cb7-13" aria-hidden="true" tabindex="-1"></a> <span class="dt">"checksum"</span><span class="fu">:</span> <span class="st">"jkl901mno234"</span></span>
|
||
<span id="cb7-14"><a href="#cb7-14" aria-hidden="true" tabindex="-1"></a> <span class="fu">}</span></span>
|
||
<span id="cb7-15"><a href="#cb7-15" aria-hidden="true" tabindex="-1"></a><span class="fu">}</span></span></code></pre></div>
|
||
<h4 id="nostr-keys">5. Nostr Keys</h4>
|
||
<div class="sourceCode" id="cb8"><pre
|
||
class="sourceCode json"><code class="sourceCode json"><span id="cb8-1"><a href="#cb8-1" aria-hidden="true" tabindex="-1"></a><span class="fu">{</span></span>
|
||
<span id="cb8-2"><a href="#cb8-2" aria-hidden="true" tabindex="-1"></a> <span class="dt">"entry_num"</span><span class="fu">:</span> <span class="dv">4</span><span class="fu">,</span></span>
|
||
<span id="cb8-3"><a href="#cb8-3" aria-hidden="true" tabindex="-1"></a> <span class="dt">"index_num"</span><span class="fu">:</span> <span class="st">"l3m4n5o6p7q8"</span><span class="fu">,</span></span>
|
||
<span id="cb8-4"><a href="#cb8-4" aria-hidden="true" tabindex="-1"></a> <span class="dt">"fingerprint"</span><span class="fu">:</span> <span class="st">"a1b2c3d4"</span><span class="fu">,</span></span>
|
||
<span id="cb8-5"><a href="#cb8-5" aria-hidden="true" tabindex="-1"></a> <span class="dt">"kind"</span><span class="fu">:</span> <span class="st">"nostr_keys"</span><span class="fu">,</span></span>
|
||
<span id="cb8-6"><a href="#cb8-6" aria-hidden="true" tabindex="-1"></a> <span class="dt">"data"</span><span class="fu">:</span> <span class="fu">{</span></span>
|
||
<span id="cb8-7"><a href="#cb8-7" aria-hidden="true" tabindex="-1"></a> <span class="dt">"public_key"</span><span class="fu">:</span> <span class="st">"<public_key>"</span><span class="fu">,</span></span>
|
||
<span id="cb8-8"><a href="#cb8-8" aria-hidden="true" tabindex="-1"></a> <span class="dt">"private_key"</span><span class="fu">:</span> <span class="st">"<encrypted_private_key>"</span></span>
|
||
<span id="cb8-9"><a href="#cb8-9" aria-hidden="true" tabindex="-1"></a> <span class="fu">},</span></span>
|
||
<span id="cb8-10"><a href="#cb8-10" aria-hidden="true" tabindex="-1"></a> <span class="dt">"timestamp"</span><span class="fu">:</span> <span class="st">"2024-04-27T12:38:56Z"</span><span class="fu">,</span></span>
|
||
<span id="cb8-11"><a href="#cb8-11" aria-hidden="true" tabindex="-1"></a> <span class="dt">"metadata"</span><span class="fu">:</span> <span class="fu">{</span></span>
|
||
<span id="cb8-12"><a href="#cb8-12" aria-hidden="true" tabindex="-1"></a> <span class="dt">"created_at"</span><span class="fu">:</span> <span class="st">"2024-04-27T12:38:56Z"</span><span class="fu">,</span></span>
|
||
<span id="cb8-13"><a href="#cb8-13" aria-hidden="true" tabindex="-1"></a> <span class="dt">"updated_at"</span><span class="fu">:</span> <span class="st">"2024-04-27T12:38:56Z"</span><span class="fu">,</span></span>
|
||
<span id="cb8-14"><a href="#cb8-14" aria-hidden="true" tabindex="-1"></a> <span class="dt">"checksum"</span><span class="fu">:</span> <span class="st">"mno567pqr890"</span></span>
|
||
<span id="cb8-15"><a href="#cb8-15" aria-hidden="true" tabindex="-1"></a> <span class="fu">}</span></span>
|
||
<span id="cb8-16"><a href="#cb8-16" aria-hidden="true" tabindex="-1"></a><span class="fu">}</span></span></code></pre></div>
|
||
<h4 id="note">6. Note</h4>
|
||
<div class="sourceCode" id="cb9"><pre
|
||
class="sourceCode json"><code class="sourceCode json"><span id="cb9-1"><a href="#cb9-1" aria-hidden="true" tabindex="-1"></a><span class="fu">{</span></span>
|
||
<span id="cb9-2"><a href="#cb9-2" aria-hidden="true" tabindex="-1"></a> <span class="dt">"entry_num"</span><span class="fu">:</span> <span class="dv">5</span><span class="fu">,</span></span>
|
||
<span id="cb9-3"><a href="#cb9-3" aria-hidden="true" tabindex="-1"></a> <span class="dt">"index_num"</span><span class="fu">:</span> <span class="st">"r9s0t1u2v3w4"</span><span class="fu">,</span></span>
|
||
<span id="cb9-4"><a href="#cb9-4" aria-hidden="true" tabindex="-1"></a> <span class="dt">"fingerprint"</span><span class="fu">:</span> <span class="st">"a1b2c3d4"</span><span class="fu">,</span></span>
|
||
<span id="cb9-5"><a href="#cb9-5" aria-hidden="true" tabindex="-1"></a> <span class="dt">"kind"</span><span class="fu">:</span> <span class="st">"note"</span><span class="fu">,</span></span>
|
||
<span id="cb9-6"><a href="#cb9-6" aria-hidden="true" tabindex="-1"></a> <span class="dt">"data"</span><span class="fu">:</span> <span class="fu">{</span></span>
|
||
<span id="cb9-7"><a href="#cb9-7" aria-hidden="true" tabindex="-1"></a> <span class="dt">"content"</span><span class="fu">:</span> <span class="st">"This is a secure note."</span><span class="fu">,</span></span>
|
||
<span id="cb9-8"><a href="#cb9-8" aria-hidden="true" tabindex="-1"></a> <span class="dt">"tags"</span><span class="fu">:</span> <span class="ot">[</span><span class="st">"personal"</span><span class="ot">,</span> <span class="st">"secure"</span><span class="ot">]</span></span>
|
||
<span id="cb9-9"><a href="#cb9-9" aria-hidden="true" tabindex="-1"></a> <span class="fu">},</span></span>
|
||
<span id="cb9-10"><a href="#cb9-10" aria-hidden="true" tabindex="-1"></a> <span class="dt">"timestamp"</span><span class="fu">:</span> <span class="st">"2024-04-27T12:39:56Z"</span><span class="fu">,</span></span>
|
||
<span id="cb9-11"><a href="#cb9-11" aria-hidden="true" tabindex="-1"></a> <span class="dt">"metadata"</span><span class="fu">:</span> <span class="fu">{</span></span>
|
||
<span id="cb9-12"><a href="#cb9-12" aria-hidden="true" tabindex="-1"></a> <span class="dt">"created_at"</span><span class="fu">:</span> <span class="st">"2024-04-27T12:39:56Z"</span><span class="fu">,</span></span>
|
||
<span id="cb9-13"><a href="#cb9-13" aria-hidden="true" tabindex="-1"></a> <span class="dt">"updated_at"</span><span class="fu">:</span> <span class="st">"2024-04-27T12:39:56Z"</span><span class="fu">,</span></span>
|
||
<span id="cb9-14"><a href="#cb9-14" aria-hidden="true" tabindex="-1"></a> <span class="dt">"checksum"</span><span class="fu">:</span> <span class="st">"pqr345stu678"</span></span>
|
||
<span id="cb9-15"><a href="#cb9-15" aria-hidden="true" tabindex="-1"></a> <span class="fu">}</span></span>
|
||
<span id="cb9-16"><a href="#cb9-16" aria-hidden="true" tabindex="-1"></a><span class="fu">}</span></span></code></pre></div>
|
||
<h4 id="keyvalue">7. Key/Value</h4>
|
||
<div class="sourceCode" id="cb10"><pre
|
||
class="sourceCode json"><code class="sourceCode json"><span id="cb10-1"><a href="#cb10-1" aria-hidden="true" tabindex="-1"></a><span class="fu">{</span></span>
|
||
<span id="cb10-2"><a href="#cb10-2" aria-hidden="true" tabindex="-1"></a> <span class="dt">"entry_num"</span><span class="fu">:</span> <span class="dv">6</span><span class="fu">,</span></span>
|
||
<span id="cb10-3"><a href="#cb10-3" aria-hidden="true" tabindex="-1"></a> <span class="dt">"fingerprint"</span><span class="fu">:</span> <span class="st">"a1b2c3d4"</span><span class="fu">,</span></span>
|
||
<span id="cb10-4"><a href="#cb10-4" aria-hidden="true" tabindex="-1"></a> <span class="dt">"kind"</span><span class="fu">:</span> <span class="st">"key_value"</span><span class="fu">,</span></span>
|
||
<span id="cb10-5"><a href="#cb10-5" aria-hidden="true" tabindex="-1"></a> <span class="dt">"data"</span><span class="fu">:</span> <span class="fu">{</span></span>
|
||
<span id="cb10-6"><a href="#cb10-6" aria-hidden="true" tabindex="-1"></a> <span class="dt">"key"</span><span class="fu">:</span> <span class="st">"api_key"</span><span class="fu">,</span></span>
|
||
<span id="cb10-7"><a href="#cb10-7" aria-hidden="true" tabindex="-1"></a> <span class="dt">"value"</span><span class="fu">:</span> <span class="st">"<encrypted_value>"</span></span>
|
||
<span id="cb10-8"><a href="#cb10-8" aria-hidden="true" tabindex="-1"></a> <span class="fu">},</span></span>
|
||
<span id="cb10-9"><a href="#cb10-9" aria-hidden="true" tabindex="-1"></a> <span class="dt">"tags"</span><span class="fu">:</span> <span class="ot">[</span><span class="st">"api"</span><span class="ot">]</span><span class="fu">,</span></span>
|
||
<span id="cb10-10"><a href="#cb10-10" aria-hidden="true" tabindex="-1"></a> <span class="dt">"timestamp"</span><span class="fu">:</span> <span class="st">"2024-04-27T12:40:56Z"</span></span>
|
||
<span id="cb10-11"><a href="#cb10-11" aria-hidden="true" tabindex="-1"></a><span class="fu">}</span></span></code></pre></div>
|
||
<h4 id="managed-account">8. Managed Account</h4>
|
||
<div class="sourceCode" id="cb11"><pre
|
||
class="sourceCode json"><code class="sourceCode json"><span id="cb11-1"><a href="#cb11-1" aria-hidden="true" tabindex="-1"></a><span class="fu">{</span></span>
|
||
<span id="cb11-2"><a href="#cb11-2" aria-hidden="true" tabindex="-1"></a> <span class="dt">"entry_num"</span><span class="fu">:</span> <span class="dv">7</span><span class="fu">,</span></span>
|
||
<span id="cb11-3"><a href="#cb11-3" aria-hidden="true" tabindex="-1"></a> <span class="dt">"fingerprint"</span><span class="fu">:</span> <span class="st">"a1b2c3d4"</span><span class="fu">,</span></span>
|
||
<span id="cb11-4"><a href="#cb11-4" aria-hidden="true" tabindex="-1"></a> <span class="dt">"kind"</span><span class="fu">:</span> <span class="st">"managed_account"</span><span class="fu">,</span></span>
|
||
<span id="cb11-5"><a href="#cb11-5" aria-hidden="true" tabindex="-1"></a> <span class="dt">"data"</span><span class="fu">:</span> <span class="fu">{</span></span>
|
||
<span id="cb11-6"><a href="#cb11-6" aria-hidden="true" tabindex="-1"></a> <span class="dt">"account"</span><span class="fu">:</span> <span class="st">"alice@example.com"</span><span class="fu">,</span></span>
|
||
<span id="cb11-7"><a href="#cb11-7" aria-hidden="true" tabindex="-1"></a> <span class="dt">"password"</span><span class="fu">:</span> <span class="st">"<encrypted_password>"</span></span>
|
||
<span id="cb11-8"><a href="#cb11-8" aria-hidden="true" tabindex="-1"></a> <span class="fu">},</span></span>
|
||
<span id="cb11-9"><a href="#cb11-9" aria-hidden="true" tabindex="-1"></a> <span class="dt">"timestamp"</span><span class="fu">:</span> <span class="st">"2024-04-27T12:41:56Z"</span></span>
|
||
<span id="cb11-10"><a href="#cb11-10" aria-hidden="true" tabindex="-1"></a><span class="fu">}</span></span></code></pre></div>
|
||
<p>Managed accounts store a child seed derived from the parent profile.
|
||
The entry is saved under
|
||
<code>.seedpass/<parent_fp>/accounts/<child_fp></code> where
|
||
<code><child_fp></code> is the managed account’s fingerprint. When
|
||
loaded, the CLI displays a breadcrumb like
|
||
<code><parent_fp> > Managed Account > <child_fp></code>.
|
||
Press <strong>Enter</strong> on the main menu to exit back to the parent
|
||
profile.</p>
|
||
<p>The <code>key</code> field is purely descriptive, while
|
||
<code>value</code> holds the sensitive string such as an API token.
|
||
Notes and custom fields may also be included alongside the standard
|
||
metadata.</p>
|
||
<hr />
|
||
<h2 id="handling-kind-types-and-extensibility">Handling
|
||
<code>kind</code> Types and Extensibility</h2>
|
||
<h3 id="extensible-json-schema-design">Extensible JSON Schema
|
||
Design</h3>
|
||
<p>The JSON schema is designed to be <strong>extensible</strong> and
|
||
<strong>forward-compatible</strong>, allowing new <code>kind</code>
|
||
types to be added without impacting existing functionalities.</p>
|
||
<h4 id="a.-core-structure">a. Core Structure</h4>
|
||
<p>Each entry is encapsulated in its own JSON file with a standardized
|
||
structure:</p>
|
||
<div class="sourceCode" id="cb12"><pre
|
||
class="sourceCode json"><code class="sourceCode json"><span id="cb12-1"><a href="#cb12-1" aria-hidden="true" tabindex="-1"></a><span class="fu">{</span></span>
|
||
<span id="cb12-2"><a href="#cb12-2" aria-hidden="true" tabindex="-1"></a> <span class="dt">"entry_num"</span><span class="fu">:</span> <span class="dv">0</span><span class="fu">,</span></span>
|
||
<span id="cb12-3"><a href="#cb12-3" aria-hidden="true" tabindex="-1"></a> <span class="dt">"index_num"</span><span class="fu">:</span> <span class="dv">0</span><span class="fu">,</span></span>
|
||
<span id="cb12-4"><a href="#cb12-4" aria-hidden="true" tabindex="-1"></a> <span class="dt">"fingerprint"</span><span class="fu">:</span> <span class="st">"a1b2c3d4"</span><span class="fu">,</span></span>
|
||
<span id="cb12-5"><a href="#cb12-5" aria-hidden="true" tabindex="-1"></a> <span class="dt">"kind"</span><span class="fu">:</span> <span class="st">"generated_password"</span><span class="fu">,</span></span>
|
||
<span id="cb12-6"><a href="#cb12-6" aria-hidden="true" tabindex="-1"></a> <span class="dt">"data"</span><span class="fu">:</span> <span class="fu">{</span></span>
|
||
<span id="cb12-7"><a href="#cb12-7" aria-hidden="true" tabindex="-1"></a> <span class="er">//</span> <span class="er">Fields</span> <span class="er">specific</span> <span class="er">to</span> <span class="er">the</span> <span class="er">kind</span></span>
|
||
<span id="cb12-8"><a href="#cb12-8" aria-hidden="true" tabindex="-1"></a> <span class="fu">},</span></span>
|
||
<span id="cb12-9"><a href="#cb12-9" aria-hidden="true" tabindex="-1"></a> <span class="dt">"timestamp"</span><span class="fu">:</span> <span class="st">"2024-04-27T12:34:56Z"</span><span class="fu">,</span></span>
|
||
<span id="cb12-10"><a href="#cb12-10" aria-hidden="true" tabindex="-1"></a> <span class="dt">"metadata"</span><span class="fu">:</span> <span class="fu">{</span></span>
|
||
<span id="cb12-11"><a href="#cb12-11" aria-hidden="true" tabindex="-1"></a> <span class="dt">"created_at"</span><span class="fu">:</span> <span class="st">"2024-04-27T12:34:56Z"</span><span class="fu">,</span></span>
|
||
<span id="cb12-12"><a href="#cb12-12" aria-hidden="true" tabindex="-1"></a> <span class="dt">"updated_at"</span><span class="fu">:</span> <span class="st">"2024-04-27T12:34:56Z"</span><span class="fu">,</span></span>
|
||
<span id="cb12-13"><a href="#cb12-13" aria-hidden="true" tabindex="-1"></a> <span class="dt">"checksum"</span><span class="fu">:</span> <span class="st">"<checksum_value>"</span></span>
|
||
<span id="cb12-14"><a href="#cb12-14" aria-hidden="true" tabindex="-1"></a> <span class="fu">}</span></span>
|
||
<span id="cb12-15"><a href="#cb12-15" aria-hidden="true" tabindex="-1"></a><span class="fu">}</span></span></code></pre></div>
|
||
<h4 id="b.-the-kind-field">b. The <code>kind</code> Field</h4>
|
||
<ul>
|
||
<li><strong>Purpose:</strong> Specifies the type of entry.</li>
|
||
<li><strong>Flexibility:</strong> As a simple string identifier, new
|
||
<code>kind</code> values can be introduced without altering the existing
|
||
schema.</li>
|
||
</ul>
|
||
<p><strong>Example:</strong></p>
|
||
<div class="sourceCode" id="cb13"><pre
|
||
class="sourceCode json"><code class="sourceCode json"><span id="cb13-1"><a href="#cb13-1" aria-hidden="true" tabindex="-1"></a><span class="er">"kind":</span> <span class="er">"cryptocurrency_wallet"</span></span></code></pre></div>
|
||
<h4 id="c.-the-data-object">c. The <code>data</code> Object</h4>
|
||
<ul>
|
||
<li><strong>Purpose:</strong> Contains fields specific to the
|
||
<code>kind</code>.</li>
|
||
<li><strong>Extensibility:</strong> Each <code>kind</code> can define
|
||
its unique set of fields without affecting others.</li>
|
||
</ul>
|
||
<p><strong>Example for a New Kind
|
||
(<code>cryptocurrency_wallet</code>):</strong></p>
|
||
<div class="sourceCode" id="cb14"><pre
|
||
class="sourceCode json"><code class="sourceCode json"><span id="cb14-1"><a href="#cb14-1" aria-hidden="true" tabindex="-1"></a><span class="er">"data":</span> <span class="fu">{</span></span>
|
||
<span id="cb14-2"><a href="#cb14-2" aria-hidden="true" tabindex="-1"></a> <span class="dt">"wallet_name"</span><span class="fu">:</span> <span class="st">"My Bitcoin Wallet"</span><span class="fu">,</span></span>
|
||
<span id="cb14-3"><a href="#cb14-3" aria-hidden="true" tabindex="-1"></a> <span class="dt">"address"</span><span class="fu">:</span> <span class="st">"1A1zP1eP5QGefi2DMPTfTL5SLmv7DivfNa"</span><span class="fu">,</span></span>
|
||
<span id="cb14-4"><a href="#cb14-4" aria-hidden="true" tabindex="-1"></a> <span class="dt">"private_key"</span><span class="fu">:</span> <span class="st">"<encrypted_private_key>"</span></span>
|
||
<span id="cb14-5"><a href="#cb14-5" aria-hidden="true" tabindex="-1"></a><span class="fu">}</span></span></code></pre></div>
|
||
<h3 id="ensuring-backward-compatibility">Ensuring Backward
|
||
Compatibility</h3>
|
||
<p>To maintain compatibility as new <code>kind</code> types are
|
||
introduced, implement the following practices:</p>
|
||
<h4 id="a.-graceful-handling-of-unknown-kinds">a. Graceful Handling of
|
||
Unknown Kinds</h4>
|
||
<ul>
|
||
<li><strong>Implementation:</strong> When encountering an unrecognized
|
||
<code>kind</code>, handle it gracefully by ignoring the entry, logging a
|
||
warning, or providing a default handling mechanism.</li>
|
||
<li><strong>Benefit:</strong> Prevents the application from crashing or
|
||
misbehaving due to unrecognized <code>kind</code> types.</li>
|
||
</ul>
|
||
<p><strong>Pseudo-Code Example:</strong></p>
|
||
<div class="sourceCode" id="cb15"><pre
|
||
class="sourceCode python"><code class="sourceCode python"><span id="cb15-1"><a href="#cb15-1" aria-hidden="true" tabindex="-1"></a><span class="kw">def</span> process_entry(entry):</span>
|
||
<span id="cb15-2"><a href="#cb15-2" aria-hidden="true" tabindex="-1"></a> kind <span class="op">=</span> entry.get(<span class="st">"kind"</span>)</span>
|
||
<span id="cb15-3"><a href="#cb15-3" aria-hidden="true" tabindex="-1"></a> data <span class="op">=</span> entry.get(<span class="st">"data"</span>)</span>
|
||
<span id="cb15-4"><a href="#cb15-4" aria-hidden="true" tabindex="-1"></a> fingerprint <span class="op">=</span> entry.get(<span class="st">"fingerprint"</span>)</span>
|
||
<span id="cb15-5"><a href="#cb15-5" aria-hidden="true" tabindex="-1"></a> </span>
|
||
<span id="cb15-6"><a href="#cb15-6" aria-hidden="true" tabindex="-1"></a> <span class="cf">if</span> kind <span class="op">==</span> <span class="st">"generated_password"</span>:</span>
|
||
<span id="cb15-7"><a href="#cb15-7" aria-hidden="true" tabindex="-1"></a> handle_generated_password(data, fingerprint)</span>
|
||
<span id="cb15-8"><a href="#cb15-8" aria-hidden="true" tabindex="-1"></a> <span class="cf">elif</span> kind <span class="op">==</span> <span class="st">"stored_password"</span>:</span>
|
||
<span id="cb15-9"><a href="#cb15-9" aria-hidden="true" tabindex="-1"></a> handle_stored_password(data, fingerprint)</span>
|
||
<span id="cb15-10"><a href="#cb15-10" aria-hidden="true" tabindex="-1"></a> <span class="co"># ... other known kinds ...</span></span>
|
||
<span id="cb15-11"><a href="#cb15-11" aria-hidden="true" tabindex="-1"></a> <span class="cf">else</span>:</span>
|
||
<span id="cb15-12"><a href="#cb15-12" aria-hidden="true" tabindex="-1"></a> log_warning(<span class="ss">f"Unknown kind: </span><span class="sc">{</span>kind<span class="sc">}</span><span class="ss">. Skipping entry."</span>)</span></code></pre></div>
|
||
<h4 id="b.-versioning-the-schema">b. Versioning the Schema</h4>
|
||
<ul>
|
||
<li><strong>Implementation:</strong> Introduce a
|
||
<code>schema_version</code> or <code>seedpass_version</code> field to
|
||
indicate the version of the JSON schema being used.</li>
|
||
<li><strong>Benefit:</strong> Facilitates future updates and migrations
|
||
by clearly identifying the schema version.</li>
|
||
</ul>
|
||
<p><strong>Example:</strong></p>
|
||
<div class="sourceCode" id="cb16"><pre
|
||
class="sourceCode json"><code class="sourceCode json"><span id="cb16-1"><a href="#cb16-1" aria-hidden="true" tabindex="-1"></a><span class="er">"seedpass_version":</span> <span class="er">"1.0.0"</span></span></code></pre></div>
|
||
<h4 id="c.-documentation-and-standards">c. Documentation and
|
||
Standards</h4>
|
||
<ul>
|
||
<li><strong>Maintain Clear Documentation:</strong> Keep comprehensive
|
||
documentation for each <code>kind</code>, detailing required and
|
||
optional fields.</li>
|
||
<li><strong>Adhere to Standards:</strong> Follow consistent naming
|
||
conventions and data types to ensure uniformity across different
|
||
<code>kind</code> types.</li>
|
||
</ul>
|
||
<h3 id="best-practices-for-adding-new-kinds">Best Practices for Adding
|
||
New Kinds</h3>
|
||
<p>To ensure seamless integration of new <code>kind</code> types in the
|
||
future, consider the following best practices:</p>
|
||
<h4 id="a.-consistent-naming-conventions">a. Consistent Naming
|
||
Conventions</h4>
|
||
<ul>
|
||
<li><strong>Use Clear and Descriptive Names:</strong> Aids in
|
||
readability and maintenance.</li>
|
||
<li><strong>Avoid Reserved Keywords:</strong> Ensure <code>kind</code>
|
||
names do not clash with existing or future reserved keywords within the
|
||
application or JSON standards.</li>
|
||
</ul>
|
||
<h4 id="b.-modular-code-architecture">b. Modular Code Architecture</h4>
|
||
<ul>
|
||
<li><strong>Separate Handlers:</strong> Implement separate functions or
|
||
modules for handling each <code>kind</code>. Promotes code modularity
|
||
and easier maintenance.</li>
|
||
</ul>
|
||
<p><strong>Example:</strong></p>
|
||
<div class="sourceCode" id="cb17"><pre
|
||
class="sourceCode python"><code class="sourceCode python"><span id="cb17-1"><a href="#cb17-1" aria-hidden="true" tabindex="-1"></a><span class="co"># handlers.py</span></span>
|
||
<span id="cb17-2"><a href="#cb17-2" aria-hidden="true" tabindex="-1"></a></span>
|
||
<span id="cb17-3"><a href="#cb17-3" aria-hidden="true" tabindex="-1"></a><span class="kw">def</span> handle_generated_password(data, fingerprint):</span>
|
||
<span id="cb17-4"><a href="#cb17-4" aria-hidden="true" tabindex="-1"></a> <span class="co"># Implementation</span></span>
|
||
<span id="cb17-5"><a href="#cb17-5" aria-hidden="true" tabindex="-1"></a></span>
|
||
<span id="cb17-6"><a href="#cb17-6" aria-hidden="true" tabindex="-1"></a><span class="kw">def</span> handle_stored_password(data, fingerprint):</span>
|
||
<span id="cb17-7"><a href="#cb17-7" aria-hidden="true" tabindex="-1"></a> <span class="co"># Implementation</span></span>
|
||
<span id="cb17-8"><a href="#cb17-8" aria-hidden="true" tabindex="-1"></a></span>
|
||
<span id="cb17-9"><a href="#cb17-9" aria-hidden="true" tabindex="-1"></a><span class="kw">def</span> handle_cryptocurrency_wallet(data, fingerprint):</span>
|
||
<span id="cb17-10"><a href="#cb17-10" aria-hidden="true" tabindex="-1"></a> <span class="co"># Implementation</span></span></code></pre></div>
|
||
<h4 id="c.-validation-and-error-handling">c. Validation and Error
|
||
Handling</h4>
|
||
<ul>
|
||
<li><strong>Validate Data Fields:</strong> Ensure each <code>kind</code>
|
||
has the necessary fields before processing.</li>
|
||
<li><strong>Handle Missing or Extra Fields:</strong> Implement logic to
|
||
manage incomplete or unexpected data gracefully.</li>
|
||
</ul>
|
||
<p><strong>Example:</strong></p>
|
||
<div class="sourceCode" id="cb18"><pre
|
||
class="sourceCode python"><code class="sourceCode python"><span id="cb18-1"><a href="#cb18-1" aria-hidden="true" tabindex="-1"></a><span class="kw">def</span> handle_cryptocurrency_wallet(data, fingerprint):</span>
|
||
<span id="cb18-2"><a href="#cb18-2" aria-hidden="true" tabindex="-1"></a> required_fields <span class="op">=</span> [<span class="st">"wallet_name"</span>, <span class="st">"address"</span>, <span class="st">"private_key"</span>]</span>
|
||
<span id="cb18-3"><a href="#cb18-3" aria-hidden="true" tabindex="-1"></a> <span class="cf">for</span> field <span class="kw">in</span> required_fields:</span>
|
||
<span id="cb18-4"><a href="#cb18-4" aria-hidden="true" tabindex="-1"></a> <span class="cf">if</span> field <span class="kw">not</span> <span class="kw">in</span> data:</span>
|
||
<span id="cb18-5"><a href="#cb18-5" aria-hidden="true" tabindex="-1"></a> <span class="cf">raise</span> <span class="pp">ValueError</span>(<span class="ss">f"Missing required field '</span><span class="sc">{</span>field<span class="sc">}</span><span class="ss">' in cryptocurrency_wallet entry."</span>)</span>
|
||
<span id="cb18-6"><a href="#cb18-6" aria-hidden="true" tabindex="-1"></a> <span class="co"># Proceed with processing</span></span></code></pre></div>
|
||
<h4 id="d.-backward-compatibility-testing">d. Backward Compatibility
|
||
Testing</h4>
|
||
<ul>
|
||
<li><strong>Automated Tests:</strong> Develop tests that verify the
|
||
application’s ability to handle both existing and new <code>kind</code>
|
||
types.</li>
|
||
<li><strong>Regression Testing:</strong> Ensure adding new kinds does
|
||
not inadvertently affect existing functionalities.</li>
|
||
</ul>
|
||
<hr />
|
||
<h2 id="adding-new-kind-types">Adding New <code>kind</code> Types</h2>
|
||
<p>Adding new <code>kind</code> types is straightforward due to the
|
||
extensible JSON schema design. Below is a step-by-step guide to adding a
|
||
new <code>kind</code> without affecting existing functionalities.</p>
|
||
<h3 id="example-adding-cryptocurrency_wallet">Example: Adding
|
||
<code>cryptocurrency_wallet</code></h3>
|
||
<h4 id="a.-define-the-new-kind-structure">a. Define the New Kind
|
||
Structure</h4>
|
||
<p>Create a JSON file following the standardized structure with the new
|
||
<code>kind</code> value.</p>
|
||
<div class="sourceCode" id="cb19"><pre
|
||
class="sourceCode json"><code class="sourceCode json"><span id="cb19-1"><a href="#cb19-1" aria-hidden="true" tabindex="-1"></a><span class="fu">{</span></span>
|
||
<span id="cb19-2"><a href="#cb19-2" aria-hidden="true" tabindex="-1"></a> <span class="dt">"entry_num"</span><span class="fu">:</span> <span class="dv">6</span><span class="fu">,</span></span>
|
||
<span id="cb19-3"><a href="#cb19-3" aria-hidden="true" tabindex="-1"></a> <span class="dt">"index_num"</span><span class="fu">:</span> <span class="st">"x1y2z3a4b5c6"</span><span class="fu">,</span></span>
|
||
<span id="cb19-4"><a href="#cb19-4" aria-hidden="true" tabindex="-1"></a> <span class="dt">"fingerprint"</span><span class="fu">:</span> <span class="st">"a1b2c3d4"</span><span class="fu">,</span></span>
|
||
<span id="cb19-5"><a href="#cb19-5" aria-hidden="true" tabindex="-1"></a> <span class="dt">"kind"</span><span class="fu">:</span> <span class="st">"cryptocurrency_wallet"</span><span class="fu">,</span></span>
|
||
<span id="cb19-6"><a href="#cb19-6" aria-hidden="true" tabindex="-1"></a> <span class="dt">"data"</span><span class="fu">:</span> <span class="fu">{</span></span>
|
||
<span id="cb19-7"><a href="#cb19-7" aria-hidden="true" tabindex="-1"></a> <span class="dt">"wallet_name"</span><span class="fu">:</span> <span class="st">"My Bitcoin Wallet"</span><span class="fu">,</span></span>
|
||
<span id="cb19-8"><a href="#cb19-8" aria-hidden="true" tabindex="-1"></a> <span class="dt">"address"</span><span class="fu">:</span> <span class="st">"1A1zP1eP5QGefi2DMPTfTL5SLmv7DivfNa"</span><span class="fu">,</span></span>
|
||
<span id="cb19-9"><a href="#cb19-9" aria-hidden="true" tabindex="-1"></a> <span class="dt">"private_key"</span><span class="fu">:</span> <span class="st">"<encrypted_private_key>"</span></span>
|
||
<span id="cb19-10"><a href="#cb19-10" aria-hidden="true" tabindex="-1"></a> <span class="fu">},</span></span>
|
||
<span id="cb19-11"><a href="#cb19-11" aria-hidden="true" tabindex="-1"></a> <span class="dt">"timestamp"</span><span class="fu">:</span> <span class="st">"2024-04-27T12:40:56Z"</span><span class="fu">,</span></span>
|
||
<span id="cb19-12"><a href="#cb19-12" aria-hidden="true" tabindex="-1"></a> <span class="dt">"metadata"</span><span class="fu">:</span> <span class="fu">{</span></span>
|
||
<span id="cb19-13"><a href="#cb19-13" aria-hidden="true" tabindex="-1"></a> <span class="dt">"created_at"</span><span class="fu">:</span> <span class="st">"2024-04-27T12:40:56Z"</span><span class="fu">,</span></span>
|
||
<span id="cb19-14"><a href="#cb19-14" aria-hidden="true" tabindex="-1"></a> <span class="dt">"updated_at"</span><span class="fu">:</span> <span class="st">"2024-04-27T12:40:56Z"</span><span class="fu">,</span></span>
|
||
<span id="cb19-15"><a href="#cb19-15" aria-hidden="true" tabindex="-1"></a> <span class="dt">"checksum"</span><span class="fu">:</span> <span class="st">"stu901vwx234"</span></span>
|
||
<span id="cb19-16"><a href="#cb19-16" aria-hidden="true" tabindex="-1"></a> <span class="fu">}</span></span>
|
||
<span id="cb19-17"><a href="#cb19-17" aria-hidden="true" tabindex="-1"></a><span class="fu">}</span></span></code></pre></div>
|
||
<h4 id="b.-update-the-application-to-handle-the-new-kind">b. Update the
|
||
Application to Handle the New Kind</h4>
|
||
<p><strong>Implement Handler Function:</strong></p>
|
||
<div class="sourceCode" id="cb20"><pre
|
||
class="sourceCode python"><code class="sourceCode python"><span id="cb20-1"><a href="#cb20-1" aria-hidden="true" tabindex="-1"></a><span class="kw">def</span> handle_cryptocurrency_wallet(data, fingerprint):</span>
|
||
<span id="cb20-2"><a href="#cb20-2" aria-hidden="true" tabindex="-1"></a> wallet_name <span class="op">=</span> data.get(<span class="st">"wallet_name"</span>)</span>
|
||
<span id="cb20-3"><a href="#cb20-3" aria-hidden="true" tabindex="-1"></a> address <span class="op">=</span> data.get(<span class="st">"address"</span>)</span>
|
||
<span id="cb20-4"><a href="#cb20-4" aria-hidden="true" tabindex="-1"></a> private_key <span class="op">=</span> decrypt(data.get(<span class="st">"private_key"</span>))</span>
|
||
<span id="cb20-5"><a href="#cb20-5" aria-hidden="true" tabindex="-1"></a> <span class="co"># Process the cryptocurrency wallet entry</span></span>
|
||
<span id="cb20-6"><a href="#cb20-6" aria-hidden="true" tabindex="-1"></a> <span class="co"># e.g., store in memory, display to user, etc.</span></span></code></pre></div>
|
||
<p><strong>Integrate the Handler:</strong></p>
|
||
<div class="sourceCode" id="cb21"><pre
|
||
class="sourceCode python"><code class="sourceCode python"><span id="cb21-1"><a href="#cb21-1" aria-hidden="true" tabindex="-1"></a><span class="kw">def</span> process_entry(entry):</span>
|
||
<span id="cb21-2"><a href="#cb21-2" aria-hidden="true" tabindex="-1"></a> kind <span class="op">=</span> entry.get(<span class="st">"kind"</span>)</span>
|
||
<span id="cb21-3"><a href="#cb21-3" aria-hidden="true" tabindex="-1"></a> data <span class="op">=</span> entry.get(<span class="st">"data"</span>)</span>
|
||
<span id="cb21-4"><a href="#cb21-4" aria-hidden="true" tabindex="-1"></a> fingerprint <span class="op">=</span> entry.get(<span class="st">"fingerprint"</span>)</span>
|
||
<span id="cb21-5"><a href="#cb21-5" aria-hidden="true" tabindex="-1"></a> </span>
|
||
<span id="cb21-6"><a href="#cb21-6" aria-hidden="true" tabindex="-1"></a> <span class="cf">if</span> kind <span class="op">==</span> <span class="st">"generated_password"</span>:</span>
|
||
<span id="cb21-7"><a href="#cb21-7" aria-hidden="true" tabindex="-1"></a> handle_generated_password(data, fingerprint)</span>
|
||
<span id="cb21-8"><a href="#cb21-8" aria-hidden="true" tabindex="-1"></a> <span class="cf">elif</span> kind <span class="op">==</span> <span class="st">"stored_password"</span>:</span>
|
||
<span id="cb21-9"><a href="#cb21-9" aria-hidden="true" tabindex="-1"></a> handle_stored_password(data, fingerprint)</span>
|
||
<span id="cb21-10"><a href="#cb21-10" aria-hidden="true" tabindex="-1"></a> <span class="cf">elif</span> kind <span class="op">==</span> <span class="st">"cryptocurrency_wallet"</span>:</span>
|
||
<span id="cb21-11"><a href="#cb21-11" aria-hidden="true" tabindex="-1"></a> handle_cryptocurrency_wallet(data, fingerprint)</span>
|
||
<span id="cb21-12"><a href="#cb21-12" aria-hidden="true" tabindex="-1"></a> <span class="co"># ... other known kinds ...</span></span>
|
||
<span id="cb21-13"><a href="#cb21-13" aria-hidden="true" tabindex="-1"></a> <span class="cf">else</span>:</span>
|
||
<span id="cb21-14"><a href="#cb21-14" aria-hidden="true" tabindex="-1"></a> log_warning(<span class="ss">f"Unknown kind: </span><span class="sc">{</span>kind<span class="sc">}</span><span class="ss">. Skipping entry."</span>)</span></code></pre></div>
|
||
<h4 id="c.-no-impact-on-existing-kinds">c. No Impact on Existing
|
||
Kinds</h4>
|
||
<p>Existing kinds such as <code>generated_password</code>,
|
||
<code>stored_password</code>, etc., continue to operate without any
|
||
changes. The introduction of <code>cryptocurrency_wallet</code> is
|
||
additive and does not interfere with the processing of other kinds.</p>
|
||
<hr />
|
||
<h2 id="backup-and-rollback-mechanism">Backup and Rollback
|
||
Mechanism</h2>
|
||
<p>To ensure data integrity and provide recovery options, SeedPass
|
||
implements a robust backup and rollback system within the
|
||
<strong>Fingerprint-Based Backup and Local Storage</strong>
|
||
framework.</p>
|
||
<h3 id="backup-directory-structure">Backup Directory Structure</h3>
|
||
<p>All backups are organized based on fingerprints, ensuring that each
|
||
seed’s data remains isolated and secure.</p>
|
||
<pre><code>~/.seedpass/
|
||
├── a1b2c3d4/
|
||
│ ├── entries/
|
||
│ │ ├── entry_0.json
|
||
│ │ ├── entry_1.json
|
||
│ │ └── ...
|
||
│ ├── backups/
|
||
│ │ ├── entry_0_v1.json
|
||
│ │ ├── entry_0_v2.json
|
||
│ │ ├── entry_1_v1.json
|
||
│ │ └── ...
|
||
│ ├── parent_seed.enc
|
||
│ ├── seedpass_entries_db_checksum.txt
|
||
│ └── seedpass_entries_db.json
|
||
├── b5c6d7e8/
|
||
│ ├── entries/
|
||
│ │ ├── entry_0.json
|
||
│ │ ├── entry_1.json
|
||
│ │ └── ...
|
||
│ ├── backups/
|
||
│ │ ├── entry_0_v1.json
|
||
│ │ ├── entry_0_v2.json
|
||
│ │ ├── entry_1_v1.json
|
||
│ │ └── ...
|
||
│ ├── parent_seed.enc
|
||
│ ├── seedpass_entries_db_checksum.txt
|
||
│ └── seedpass_entries_db.json
|
||
└── ...</code></pre>
|
||
<h3 id="backup-process">Backup Process</h3>
|
||
<ol type="1">
|
||
<li><strong>Upon Modifying an Entry:</strong>
|
||
<ul>
|
||
<li>The current version of the entry is copied to the
|
||
<code>backups/</code> directory within the corresponding fingerprint
|
||
folder with a version suffix (e.g., <code>entry_0_v1.json</code>).</li>
|
||
<li>The modified entry is saved in the <code>entries/</code> directory
|
||
within the same fingerprint folder.</li>
|
||
</ul></li>
|
||
<li><strong>Versioning:</strong>
|
||
<ul>
|
||
<li>Each backup file includes a version number to track changes over
|
||
time.</li>
|
||
</ul></li>
|
||
</ol>
|
||
<h3 id="rollback-functionality">Rollback Functionality</h3>
|
||
<ul>
|
||
<li><strong>Restoring an Entry:</strong>
|
||
<ul>
|
||
<li>Users can select a backup version from the <code>backups/</code>
|
||
directory within the specific fingerprint folder.</li>
|
||
<li>The selected backup file is copied back to the <code>entries/</code>
|
||
directory, replacing the current version.</li>
|
||
</ul></li>
|
||
</ul>
|
||
<p><strong>Example Command:</strong></p>
|
||
<div class="sourceCode" id="cb23"><pre
|
||
class="sourceCode bash"><code class="sourceCode bash"><span id="cb23-1"><a href="#cb23-1" aria-hidden="true" tabindex="-1"></a><span class="ex">seedpass</span> rollback <span class="at">--fingerprint</span> a1b2c3d4 <span class="at">--file</span> entry_0_v1.json</span></code></pre></div>
|
||
<p><strong>Example Directory Structure After Rollback:</strong></p>
|
||
<pre><code>~/.seedpass/
|
||
├── a1b2c3d4/
|
||
│ ├── entries/
|
||
│ │ ├── entry_0.json # Restored from entry_0_v1.json
|
||
│ │ ├── entry_1.json
|
||
│ │ └── ...
|
||
│ ├── backups/
|
||
│ │ ├── entry_0_v1.json
|
||
│ │ ├── entry_0_v2.json
|
||
│ │ ├── entry_1_v1.json
|
||
│ │ └── ...
|
||
│ ├── parent_seed.enc
|
||
│ ├── seedpass_script_checksum.txt
|
||
│ ├── seedpass_entries_db_checksum.txt
|
||
│ └── seedpass_entries_db.json
|
||
├── ...</code></pre>
|
||
<p><em>Note: Restoring a backup overwrites the current entry. Ensure
|
||
that you intend to revert to the selected backup before
|
||
proceeding.</em></p>
|
||
</body>
|
||
</html>
|