Skip to content

Commit 151ffd3

Browse files
author
Corey B
committed
feat: did:web identity lifecycle v1.2.0 — identity.js, signFdd/parse/verify API, client trust badge, 3 industry examples
1 parent d531e94 commit 151ffd3

12 files changed

Lines changed: 894 additions & 82 deletions

File tree

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -70,7 +70,7 @@ The success of OpenFDD relies entirely on community pushback against static PDFs
7070

7171
**Share the Standard on Social Media:**
7272
<p align="left">
73-
<a href="https://open-fdd.org">
73+
<a href="https://spuds0588.github.io/open-fdd/site/index.html">
7474
<img src="https://img.shields.io/badge/Read%20The%20Web%20Manifesto-002147?style=for-the-badge&logo=read-the-docs&logoColor=white" alt="Read the Manifesto" />
7575
</a>
7676
<a href="https://twitter.com/intent/tweet?text=Stop%20sending%20dead%20PDFs.%20Documents%20should%20be%20data-first,%20not%20pictures%20of%20data.%20Learn%20why%20%23OpenFDD%20and%20Zero-JS%20interactive%20JSON-LD%20containers%20are%20the%20future%20of%20files!%20%20%0A%0A%F0%9F%93%84%20https://github.com/Spuds0588/open-fdd">

TODO.md

Lines changed: 17 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -2,26 +2,26 @@
22

33
This list outlines the remaining steps to transition the OpenFDD project from a "pioneer specification" into a globally adopted document standard.
44

5-
## 🛡️ Immediate Security & Versioning
6-
- [ ] **Final Release Sync**:
7-
- [ ] Bump version in `lib/node-fdd/package.json` to `1.2.0` (to include the Zero-Trust security patch).
8-
- [ ] Run `npm publish --access=public` inside `lib/node-fdd/`.
9-
- [ ] Create and push git tag `v1.2.0` (`git tag v1.2.0 && git push origin v1.2.0`).
10-
- [ ] **Security Audit**: Verify the Zero-Trust regex against a wider range of obfuscated `<scr+ipt>` payloads to ensure no bypasses exist.
5+
## 🛡️ Security & Versioning
6+
- [x] **Zero-Trust Embed Scrubbing**: `<script>`, `<iframe>`, `<object>` blocked in both parsers.
7+
- [x] **Compiler Security Rejection**: `fdd-pack` fatally rejects templates containing hostile embedding vectors.
8+
- [x] **v1.2.0 did:web Identity**: `identity.js`, `signFdd()`, `parse()`, `verify()`, client `resolveIssuer()` + `verifySignature()`.
9+
- [ ] **Publish v1.2.0**: Run `npm publish --access=public` in `lib/node-fdd/`, then `git tag v1.2.0 && git push origin v1.2.0`.
10+
- [ ] **Security Audit**: Test Zero-Trust regex against obfuscated `<scr+ipt>` payloads.
1111

1212
## 📦 Distribution & Tooling
13-
- [ ] **Chrome Web Store Submission**: Wrap the `extension/` directory and submit it to the Chrome Web Store for easier user installation.
14-
- [ ] **Firefox Add-ons Support**: Test the extension in Firefox and list it on AMO.
15-
- [ ] **Schema Validation**: Add a `fdd-validate` command to the Node CLI that checks `.fdd` files against the W3C Verifiable Credential schema standard.
13+
- [ ] **Chrome Web Store Submission**: Submit the `extension/` directory.
14+
- [ ] **Firefox Add-ons Support**: Test in Firefox and list on AMO.
15+
- [ ] **`fdd-validate` CLI command**: Checks `.fdd` files against the W3C VC schema.
1616

1717
## 📚 Documentation & Examples
18-
- [ ] **Industry Templates**: Create dedicated folder examples for:
19-
- [ ] **Medical**: Patient lab results with interactive charting.
20-
- [ ] **Legal**: Court judgments with verifiable signatures.
21-
- [ ] **Finance**: Bank statements with local-only categorizing logic.
22-
- [ ] **Developer Sandbox**: Host a "Live Builder" on the GitHub Pages site where users can paste HTML and JSON to generate a `.fdd` file in-browser.
18+
- [x] **Medical Example**: `examples/medical_lab_result.fdd` — signed lab results with editable physician notes.
19+
- [x] **Legal Example**: `examples/legal_contract.fdd` — consulting agreement with client signature binding.
20+
- [x] **Finance Example**: `examples/bank_statement_v2.fdd` — bank statement with transaction table.
21+
- [ ] **Developer Sandbox**: Live Builder on GitHub Pages for in-browser `.fdd` generation.
22+
- [ ] **Update SPEC.md**: Document the `did:web` workflow, `signFdd()` API, and trust badge behavior.
2323

2424
## 📣 Community & Growth
25-
- [ ] **Social Launch**: Execute the social sharing block in the README (X, LinkedIn, Reddit).
26-
- [ ] **SaaS Outreach**: Identify 3-5 open-source SaaS products and submit PRs to add ".fdd Export" as an alternative to "Download PDF".
27-
- [ ] **Browser Vendor Advocacy**: Draft a proposal for Chromium/Firefox to treat `.fdd` as a first-class citizen (similar to `.pdf`) for local viewing.
25+
- [ ] **Social Launch**: Execute sharing block in README (X, LinkedIn, Reddit, YouTube).
26+
- [ ] **SaaS Outreach**: Identify 35 open-source SaaS products and submit ".fdd Export" PRs.
27+
- [ ] **Browser Vendor Advocacy**: Draft a Chromium/Firefox proposal for native `.fdd` file handling.

examples/bank_statement_v2.fdd

Lines changed: 133 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,133 @@
1+
<fdd-container extension=".fdd">
2+
<script type="application/vc+json" id="fdd-data">
3+
{
4+
"@context": [
5+
"https://www.w3.org/2018/credentials/v1",
6+
"https://www.w3.org/2018/credentials/examples/v1"
7+
],
8+
"type": ["VerifiableCredential"],
9+
"issuer": "did:web:firstnational.example",
10+
"issuanceDate": "2026-04-11T00:00:00Z",
11+
"credentialSubject": {
12+
"bankName": "First National Bank",
13+
"accountHolder": "Jordan M. Castillo",
14+
"accountNumber": "••••••7821",
15+
"accountType": "Personal Checking",
16+
"statementPeriod": "March 1–31, 2026",
17+
"openingBalance": "4,218.44",
18+
"closingBalance": "3,601.17",
19+
"totalCredits": "5,200.00",
20+
"totalDebits": "5,817.27",
21+
"transactions": [
22+
{ "date": "03/01", "description": "Opening Balance", "amount": "", "balance": "4,218.44", "type": "balance" },
23+
{ "date": "03/03", "description": "Direct Deposit — Acme Corp Payroll", "amount": "+2,600.00", "balance": "6,818.44", "type": "credit" },
24+
{ "date": "03/05", "description": "Rent — AutoPay Clearwater Apartments", "amount": "-1,450.00", "balance": "5,368.44", "type": "debit" },
25+
{ "date": "03/07", "description": "Whole Foods Market", "amount": "-112.34", "balance": "5,256.10", "type": "debit" },
26+
{ "date": "03/10", "description": "Netflix Subscription", "amount": "-15.99", "balance": "5,240.11", "type": "debit" },
27+
{ "date": "03/12", "description": "ATM Withdrawal — 5th Ave Branch", "amount": "-200.00", "balance": "5,040.11", "type": "debit" },
28+
{ "date": "03/17", "description": "Direct Deposit — Acme Corp Payroll", "amount": "+2,600.00", "balance": "7,640.11", "type": "credit" },
29+
{ "date": "03/18", "description": "Chase Credit Card Payment", "amount": "-1,800.00", "balance": "5,840.11", "type": "debit" },
30+
{ "date": "03/22", "description": "Amazon.com", "amount": "-67.94", "balance": "5,772.17", "type": "debit" },
31+
{ "date": "03/25", "description": "Spotify", "amount": "-10.99", "balance": "5,761.18", "type": "debit" },
32+
{ "date": "03/28", "description": "Utility — ComEd Electric", "amount": "-98.01", "balance": "5,663.17", "type": "debit" },
33+
{ "date": "03/29", "description": "Gas Station — Shell", "amount": "-62.00", "balance": "5,601.17", "type": "debit" },
34+
{ "date": "03/31", "description": "Transfer to Savings", "amount": "-2,000.00", "balance": "3,601.17", "type": "debit" },
35+
{ "date": "03/31", "description": "Closing Balance", "amount": "", "balance": "3,601.17", "type": "balance" }
36+
]
37+
},
38+
"proof": {
39+
"type": "Ed25519Signature2020",
40+
"created": "2026-04-01T00:00:00Z",
41+
"proofPurpose": "assertionMethod",
42+
"verificationMethod": "did:web:firstnational.example#key-1",
43+
"signatureValue": "EXAMPLE_SIGNATURE_REPLACE_WITH_REAL_VALUE_AFTER_fdd-sign_pack"
44+
}
45+
}
46+
</script>
47+
48+
<script type="application/json" id="user-notes">
49+
{
50+
"tags": []
51+
}
52+
</script>
53+
54+
<template shadowrootmode="open" bind="#fdd-data, #user-notes">
55+
<style>
56+
* { box-sizing: border-box; margin: 0; padding: 0; }
57+
.stmt { max-width: 820px; margin: 2rem auto; font-family: 'Segoe UI', system-ui, sans-serif; color: #1e293b; }
58+
.header { background: linear-gradient(135deg, #1e3a5f, #0ea5e9); color: white; padding: 2rem; border-radius: 8px 8px 0 0; display: flex; justify-content: space-between; align-items: flex-end; }
59+
.bank-name { font-size: 1.6rem; font-weight: 800; letter-spacing: -0.02em; }
60+
.header-right { text-align: right; font-size: 0.85rem; opacity: 0.9; line-height: 1.6; }
61+
.summary { display: grid; grid-template-columns: repeat(4, 1fr); background: #f8fafc; border: 1px solid #e2e8f0; border-top: none; }
62+
.summary-item { padding: 1rem; border-right: 1px solid #e2e8f0; }
63+
.summary-item:last-child { border-right: none; }
64+
.summary-label { font-size: 0.7rem; text-transform: uppercase; letter-spacing: 0.06em; color: #64748b; margin-bottom: 0.25rem; }
65+
.summary-value { font-size: 1.1rem; font-weight: 700; color: #0f172a; }
66+
.summary-value.green { color: #16a34a; }
67+
.summary-value.red { color: #dc2626; }
68+
table { width: 100%; border-collapse: collapse; font-size: 0.875rem; border: 1px solid #e2e8f0; border-top: none; }
69+
th { background: #1e293b; color: #e2e8f0; padding: 0.6rem 1rem; text-align: left; font-size: 0.75rem; letter-spacing: 0.05em; text-transform: uppercase; }
70+
td { padding: 0.6rem 1rem; border-bottom: 1px solid #f1f5f9; }
71+
tr:hover td { background: #f8fafc; }
72+
tr.type-balance td { background: #f1f5f9; font-weight: 600; color: #334155; }
73+
tr.type-credit td { color: #15803d; }
74+
tr.type-credit .amt { font-weight: 700; }
75+
tr.type-debit .amt { color: #dc2626; }
76+
.balance-col { font-family: monospace; text-align: right; }
77+
.footer { padding: 1rem; background: #f8fafc; border: 1px solid #e2e8f0; border-top: none; border-radius: 0 0 8px 8px; font-size: 0.75rem; color: #94a3b8; display: flex; justify-content: space-between; }
78+
</style>
79+
<div class="stmt">
80+
<div class="header">
81+
<div>
82+
<div class="bank-name">{{bankName}}</div>
83+
<div style="font-size:0.85rem;margin-top:0.25rem;opacity:0.9;">Account Statement</div>
84+
</div>
85+
<div class="header-right">
86+
<div>{{accountHolder}}</div>
87+
<div>{{accountType}} · {{accountNumber}}</div>
88+
<div>Period: {{statementPeriod}}</div>
89+
</div>
90+
</div>
91+
92+
<div class="summary">
93+
<div class="summary-item">
94+
<div class="summary-label">Opening Balance</div>
95+
<div class="summary-value">${{openingBalance}}</div>
96+
</div>
97+
<div class="summary-item">
98+
<div class="summary-label">Total Credits</div>
99+
<div class="summary-value green">+${{totalCredits}}</div>
100+
</div>
101+
<div class="summary-item">
102+
<div class="summary-label">Total Debits</div>
103+
<div class="summary-value red">-${{totalDebits}}</div>
104+
</div>
105+
<div class="summary-item">
106+
<div class="summary-label">Closing Balance</div>
107+
<div class="summary-value">${{closingBalance}}</div>
108+
</div>
109+
</div>
110+
111+
<table>
112+
<thead>
113+
<tr><th>Date</th><th>Description</th><th style="text-align:right">Amount</th><th style="text-align:right">Balance</th></tr>
114+
</thead>
115+
<tbody>
116+
{{#each transactions}}
117+
<tr class="type-{{type}}">
118+
<td>{{date}}</td>
119+
<td>{{description}}</td>
120+
<td class="balance-col amt">{{amount}}</td>
121+
<td class="balance-col">${{balance}}</td>
122+
</tr>
123+
{{/each}}
124+
</tbody>
125+
</table>
126+
127+
<div class="footer">
128+
<span>Issued by {{bankName}} · did:web:firstnational.example · Cryptographically Verified</span>
129+
<span>This statement is a Formatted Data Document (.fdd) — tamper-evident and machine-readable.</span>
130+
</div>
131+
</div>
132+
</template>
133+
</fdd-container>

examples/legal_contract.fdd

Lines changed: 141 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,141 @@
1+
<fdd-container extension=".fdd">
2+
<script type="application/vc+json" id="fdd-data">
3+
{
4+
"@context": [
5+
"https://www.w3.org/2018/credentials/v1",
6+
"https://www.w3.org/2018/credentials/examples/v1"
7+
],
8+
"type": ["VerifiableCredential"],
9+
"issuer": "did:web:hartwell-law.example",
10+
"issuanceDate": "2026-04-11T00:00:00Z",
11+
"credentialSubject": {
12+
"documentTitle": "Consulting Services Agreement",
13+
"documentId": "HSL-2026-0041",
14+
"effectiveDate": "2026-05-01",
15+
"expirationDate": "2027-04-30",
16+
"party1": {
17+
"name": "Hartwell & Sons Legal Group, LLP",
18+
"role": "Service Provider",
19+
"representative": "Margaret Hartwell, Esq.",
20+
"address": "1200 Wacker Drive, Suite 800, Chicago, IL 60601"
21+
},
22+
"party2": {
23+
"name": "Meridian Tech Solutions, Inc.",
24+
"role": "Client",
25+
"representative": "Daniel Park, CEO",
26+
"address": "482 Industrial Blvd, Austin, TX 78758"
27+
},
28+
"scopeOfServices": "Corporate legal advisory, contract review, and regulatory compliance consultation as requested by Client on a month-to-month retainer basis.",
29+
"compensation": "$8,500/month retainer, billed on the 1st of each month. Hourly overage rate: $450/hour.",
30+
"governingLaw": "State of Illinois",
31+
"clauses": [
32+
{ "number": "1", "title": "Term", "text": "This Agreement shall commence on the Effective Date and continue for one (1) year unless terminated earlier." },
33+
{ "number": "2", "title": "Confidentiality", "text": "Both parties agree to maintain the confidentiality of all proprietary information disclosed during the engagement." },
34+
{ "number": "3", "title": "Termination", "text": "Either party may terminate this Agreement with thirty (30) days written notice." },
35+
{ "number": "4", "title": "Governing Law", "text": "This Agreement shall be governed by the laws of the State of Illinois." }
36+
]
37+
},
38+
"proof": {
39+
"type": "Ed25519Signature2020",
40+
"created": "2026-04-11T00:00:00Z",
41+
"proofPurpose": "assertionMethod",
42+
"verificationMethod": "did:web:hartwell-law.example#key-1",
43+
"signatureValue": "EXAMPLE_SIGNATURE_REPLACE_WITH_REAL_VALUE_AFTER_fdd-sign_pack"
44+
}
45+
}
46+
</script>
47+
48+
<script type="application/json" id="user-notes">
49+
{
50+
"clientSignature": "",
51+
"clientSignatureDate": "",
52+
"reviewNotes": ""
53+
}
54+
</script>
55+
56+
<template shadowrootmode="open" bind="#fdd-data, #user-notes">
57+
<style>
58+
* { box-sizing: border-box; margin: 0; padding: 0; }
59+
.doc { max-width: 760px; margin: 2rem auto; padding: 2.5rem; background: #fff; border: 1px solid #d1d5db; font-family: 'Times New Roman', Georgia, serif; color: #1a1a1a; }
60+
.doc-title { text-align: center; font-size: 1.5rem; font-weight: 700; text-transform: uppercase; letter-spacing: 0.05em; margin-bottom: 0.25rem; }
61+
.doc-id { text-align: center; font-size: 0.85rem; color: #6b7280; margin-bottom: 2rem; }
62+
h3 { font-size: 1rem; font-weight: 700; margin: 1.5rem 0 0.5rem; border-bottom: 1px solid #e5e7eb; padding-bottom: 0.25rem; }
63+
.parties-grid { display: grid; grid-template-columns: 1fr 1fr; gap: 1.5rem; margin-bottom: 1rem; }
64+
.party-box { background: #f9fafb; border: 1px solid #e5e7eb; padding: 1rem; border-radius: 4px; font-size: 0.9rem; line-height: 1.6; }
65+
.party-role { font-size: 0.75rem; text-transform: uppercase; letter-spacing: 0.05em; color: #374151; font-weight: 700; margin-bottom: 0.3rem; }
66+
.clause { margin-bottom: 1rem; }
67+
.clause-num { font-weight: 700; }
68+
.scope-box { background: #f9fafb; border-left: 3px solid #374151; padding: 0.75rem 1rem; font-size: 0.9rem; line-height: 1.6; margin-bottom: 0.5rem; }
69+
.sig-section { margin-top: 2rem; border-top: 2px solid #1a1a1a; padding-top: 1.5rem; }
70+
.sig-grid { display: grid; grid-template-columns: 1fr 1fr; gap: 2rem; }
71+
.sig-field { border-bottom: 1px solid #374151; padding-bottom: 4px; margin-bottom: 6px; }
72+
label { font-size: 0.75rem; font-weight: 700; text-transform: uppercase; letter-spacing: 0.04em; color: #6b7280; }
73+
input, textarea { width: 100%; font-family: inherit; font-size: 0.9rem; border: none; outline: none; background: transparent; }
74+
textarea { height: 60px; resize: vertical; }
75+
.footer { margin-top: 2rem; font-size: 0.75rem; color: #9ca3af; border-top: 1px solid #e5e7eb; padding-top: 0.75rem; }
76+
</style>
77+
<div class="doc">
78+
<div class="doc-title">{{documentTitle}}</div>
79+
<div class="doc-id">Document ID: {{documentId}} · Effective: {{effectiveDate}} · Expires: {{expirationDate}}</div>
80+
81+
<h3>Parties</h3>
82+
<div class="parties-grid">
83+
<div class="party-box">
84+
<div class="party-role">{{party1.role}}</div>
85+
<strong>{{party1.name}}</strong><br>
86+
{{party1.representative}}<br>
87+
{{party1.address}}
88+
</div>
89+
<div class="party-box">
90+
<div class="party-role">{{party2.role}}</div>
91+
<strong>{{party2.name}}</strong><br>
92+
{{party2.representative}}<br>
93+
{{party2.address}}
94+
</div>
95+
</div>
96+
97+
<h3>Scope of Services</h3>
98+
<div class="scope-box">{{scopeOfServices}}</div>
99+
100+
<h3>Compensation</h3>
101+
<div class="scope-box">{{compensation}}</div>
102+
103+
<h3>Terms & Conditions</h3>
104+
{{#each clauses}}
105+
<div class="clause">
106+
<span class="clause-num">{{number}}. {{title}}.</span> {{text}}
107+
</div>
108+
{{/each}}
109+
110+
<div class="sig-section">
111+
<div class="sig-grid">
112+
<div>
113+
<div class="sig-field" style="font-style:italic; color:#6b7280; padding:8px 0;">{{party1.representative}}</div>
114+
<label>Issuer Signature (pre-signed)</label>
115+
</div>
116+
<div>
117+
<div class="sig-field">
118+
<input type="text" name="user-notes.clientSignature" autosave value="{{clientSignature}}" placeholder="Type your full name to sign…">
119+
</div>
120+
<label>Client Signature ({{party2.representative}})</label>
121+
<div class="sig-field" style="margin-top:0.75rem;">
122+
<input type="date" name="user-notes.clientSignatureDate" autosave value="{{clientSignatureDate}}">
123+
</div>
124+
<label>Date Signed</label>
125+
</div>
126+
</div>
127+
128+
<div style="margin-top:1.5rem;">
129+
<label>Internal Review Notes (editable)</label>
130+
<div class="sig-field">
131+
<textarea name="user-notes.reviewNotes" autosave placeholder="Add review notes…">{{reviewNotes}}</textarea>
132+
</div>
133+
</div>
134+
</div>
135+
136+
<div class="footer">
137+
Governing Law: {{governingLaw}} · This document is cryptographically signed. Issuer: did:web:hartwell-law.example
138+
</div>
139+
</div>
140+
</template>
141+
</fdd-container>

0 commit comments

Comments
 (0)