Skip to content

Commit cb66dd3

Browse files
feat: ship /docs.html — operator-facing reference (#21)
A single-page docs document covering what jspod ships, where things live, and how to customize. Same overwrite + public-read pattern as the other jspod-owned static pages. Linked from the welcome and account page footers. Sections: - What jspod is (positioning vs JSS) - File layout — annotated tree of pod-data/ with notes on which files are jspod-owned (overwritten every start) vs skip-if-exists (user content survives) vs JSS-seeded - Where .idp lives — accounts/ + keys/, what's in them, sensitivity - Customize the landing page — honest about the overwrite limitation and the three current escape hatches (fork, run JSS direct, track upstream issue #459) - Auth ladder — reference to issue #6 and the JSS_SINGLE_USER_PASSWORD override - Backup & reset — tar -czf for backup, rm -rf pod-data for full reset (since /idp/account/delete is disabled in single-user mode) - Bundled apps — Pilot's location, skip-if-exists semantics, how to pin or upgrade - Links — jspod, JSS, solid-oidc, Solid project & spec Bumps jspod to 0.0.23. Refs #1
1 parent b784c76 commit cb66dd3

6 files changed

Lines changed: 171 additions & 3 deletions

File tree

account.html

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -98,7 +98,7 @@ <h2>Session</h2>
9898

9999
<div class="error" id="error"></div>
100100

101-
<footer>Powered by <a href="https://github.com/JavaScriptSolidServer/jspod">jspod</a> · <a href="https://github.com/JavaScriptSolidServer/solid-oidc">solid-oidc</a></footer>
101+
<footer><a href="./docs.html">Docs</a> · Powered by <a href="https://github.com/JavaScriptSolidServer/jspod">jspod</a> · <a href="https://github.com/JavaScriptSolidServer/solid-oidc">solid-oidc</a></footer>
102102
</div>
103103
<script type="module">
104104
import Session from 'https://cdn.jsdelivr.net/npm/solid-oidc@0.0.8/solid-oidc.js';

docs.html

Lines changed: 134 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,134 @@
1+
<!doctype html>
2+
<html lang="en">
3+
<head>
4+
<meta charset="utf-8">
5+
<meta name="viewport" content="width=device-width,initial-scale=1">
6+
<title>jspod docs</title>
7+
<style>
8+
body{font:14px/1.6 system-ui,-apple-system,sans-serif;color:#222;background:#f3eee5;max-width:780px;margin:2em auto;padding:0 1em}
9+
.card{background:#fff;border-radius:12px;box-shadow:0 2px 12px rgba(0,0,0,.08);padding:1.5em 2em}
10+
h1{margin:0 0 .25em;font-weight:500;font-size:1.8em}
11+
h2{margin:1.5em 0 .25em;font-weight:500;font-size:1.15em;color:#333;border-bottom:1px solid #eee;padding-bottom:.25em}
12+
h3{margin:1em 0 .25em;font-weight:500;font-size:1em;color:#444}
13+
p{margin:.5em 0}
14+
a{color:#0a66c2;text-decoration:none}
15+
a:hover{text-decoration:underline}
16+
code,kbd{font-family:"SFMono-Regular",Consolas,monospace;background:#f3eee5;padding:.1em .35em;border-radius:4px;font-size:.9em}
17+
pre{background:#f3eee5;border-radius:8px;padding:.8em 1em;overflow:auto;font-family:"SFMono-Regular",Consolas,monospace;font-size:.85em;line-height:1.5}
18+
pre code{background:none;padding:0;border-radius:0;font-size:1em}
19+
.tree{white-space:pre;line-height:1.55}
20+
.tree .label{color:#0a66c2}
21+
.tree .note{color:#888;font-family:system-ui,sans-serif}
22+
ul{padding-left:1.2em;margin:.3em 0}
23+
ul li{margin:.2em 0}
24+
.callout{background:#fff7e0;border:1px solid #f4d97a;color:#7a5c00;padding:.7em .9em;border-radius:8px;margin:1em 0;font-size:.95em}
25+
footer{margin-top:1.5em;padding-top:1em;border-top:1px solid #eee;color:#888;font-size:.85em;text-align:center}
26+
nav.toc{background:#f3eee5;border-radius:8px;padding:.6em 1em;margin:1em 0;font-size:.95em}
27+
nav.toc a{margin-right:1em}
28+
</style>
29+
</head>
30+
<body>
31+
<div class="card">
32+
<h1>jspod docs</h1>
33+
<p>What jspod ships, where things live, and how to customize.</p>
34+
35+
<nav class="toc">
36+
<a href="#what-jspod-is">What it is</a>
37+
<a href="#layout">File layout</a>
38+
<a href="#idp">Where .idp lives</a>
39+
<a href="#customize">Customize the landing page</a>
40+
<a href="#auth-ladder">Auth ladder</a>
41+
<a href="#backup">Backup &amp; reset</a>
42+
<a href="#apps">Bundled apps</a>
43+
<a href="#links">Links</a>
44+
</nav>
45+
46+
<h2 id="what-jspod-is">What jspod is</h2>
47+
<p>An opinionated thin wrapper around <a href="https://github.com/JavaScriptSolidServer/JavaScriptSolidServer">JavaScriptSolidServer (JSS)</a> aimed at first-time users. Single-user personal pods, default <code>me</code>/<code>me</code> credentials, localhost-only, batteries included.</p>
48+
<p>The wrapper handles: default flags, port hopping, browser auto-open, seeding a custom landing page and account dashboard, bundling Pilot as a self-hosted Solid app, and shipping a ~200-byte default data browser. JSS is the substrate — everything that's actually a pod, an IDP, an OIDC provider, comes from JSS.</p>
49+
50+
<h2 id="layout">File layout (<code>pod-data/</code>)</h2>
51+
<p>jspod creates <code>pod-data/</code> in the current working directory on first start (or wherever you pass via <code>--root</code>). Everything the pod is, including identities and signing keys, lives under that single tree.</p>
52+
53+
<pre class="tree"><span class="label">pod-data/</span> <span class="note">your pod root</span>
54+
├── <span class="label">index.html</span> <span class="note">welcome page — jspod overwrites every start</span>
55+
├── <span class="label">index.html.acl</span> <span class="note">public-read for the landing page (JSS-managed)</span>
56+
├── <span class="label">signin.html</span> <span class="note">jspod's sign-in app — overwritten every start</span>
57+
├── <span class="label">signin.html.acl</span> <span class="note">public-read</span>
58+
├── <span class="label">account.html</span> <span class="note">post-sign-in dashboard — overwritten every start</span>
59+
├── <span class="label">account.html.acl</span> <span class="note">public-read</span>
60+
├── <span class="label">docs.html</span> <span class="note">this page — overwritten every start</span>
61+
├── <span class="label">docs.html.acl</span> <span class="note">public-read</span>
62+
├── <span class="label">profile/</span>
63+
│ └── <span class="label">card.jsonld</span> <span class="note">your WebID profile (JSS-seeded)</span>
64+
├── <span class="label">public/</span> <span class="note">public-read container</span>
65+
│ ├── <span class="label">links.jsonld</span> <span class="note">starter list of Solid apps (jspod-seeded, skip-if-exists)</span>
66+
│ └── <span class="label">apps/pilot/</span> <span class="note">self-hosted Pilot (jspod-bundled, skip-if-exists)</span>
67+
├── <span class="label">private/</span> <span class="note">owner-only container</span>
68+
├── <span class="label">inbox/</span> <span class="note">LDN inbox</span>
69+
├── <span class="label">settings/</span> <span class="note">prefs + type indexes (JSS-seeded)</span>
70+
├── <span class="label">.acl</span> <span class="note">root container ACL — owner read/write, no public default</span>
71+
├── <span class="label">.idp/</span> <span class="note">JSS internal identity storage (see below)</span>
72+
└── <span class="label">.token-secret</span> <span class="note">JWT signing secret (auto-generated, mode 0600)</span></pre>
73+
74+
<div class="callout">
75+
<strong>Overwrite warning.</strong> <code>index.html</code>, <code>signin.html</code>, <code>account.html</code>, and <code>docs.html</code> are owned by jspod and overwritten on every <em>start</em>. Edits won't survive a restart. To customize, fork jspod or run JSS directly instead. The <code>public/links.jsonld</code> and <code>public/apps/pilot/</code> bundles are <em>skip-if-exists</em>, so user edits there <em>do</em> survive.
76+
</div>
77+
78+
<h2 id="idp">Where the IDP data lives</h2>
79+
<p>Everything identity-related is under <code>pod-data/.idp/</code>:</p>
80+
81+
<pre class="tree"><span class="label">.idp/</span>
82+
├── <span class="label">accounts/</span>
83+
│ ├── <span class="label">&lt;uuid&gt;.json</span> <span class="note">account record — username, WebID, bcrypt(password)</span>
84+
│ ├── <span class="label">_email_index.json</span>
85+
│ ├── <span class="label">_username_index.json</span>
86+
│ └── <span class="label">_webid_index.json</span>
87+
└── <span class="label">keys/</span>
88+
└── <span class="label">jwks.json</span> <span class="note">OIDC signing keys for issued tokens</span></pre>
89+
90+
<p>The account record contains a bcrypt hash of the password — not the plaintext. The signing keys are sensitive (anyone with these can mint valid tokens against your pod). JSS manages file modes on these; jspod doesn't touch them.</p>
91+
92+
<h2 id="customize">Customize the landing page</h2>
93+
<p>The default landing page (<code>pod-data/index.html</code>) is owned by jspod. Edits to it are overwritten on the next start. To genuinely customize, the options are, in increasing order of effort:</p>
94+
<ul>
95+
<li>Fork jspod (clone the repo, edit <code>welcome.html</code>, run <code>./index.js</code> from the fork). All overwrites use <em>your</em> templates.</li>
96+
<li>Run JSS directly with your own <code>pod-data/index.html</code> pre-seeded. JSS does skip-if-exists for its own seed, so your file wins. You lose jspod's account dashboard / signin app / data browser, but you can copy any of them out of the npm package and adapt.</li>
97+
<li>Track <a href="https://github.com/JavaScriptSolidServer/JavaScriptSolidServer/issues/459">JSS#459</a> for a future <code>--landing-page &lt;file&gt;</code> option that would make this cleaner.</li>
98+
</ul>
99+
100+
<h2 id="auth-ladder">Auth ladder</h2>
101+
<p>jspod ships you onto rung 1 (default <code>me</code>/<code>me</code>) and makes climbing visible. The dashboard at <code>/account.html</code> exposes a Change password form (rung 2). Passkey support (rung 3) is on the roadmap. See <a href="https://github.com/JavaScriptSolidServer/jspod/issues/6">jspod#6</a> for the full ladder framing.</p>
102+
<p>To set a custom initial password without going through the UI:</p>
103+
<pre>JSS_SINGLE_USER_PASSWORD='your-password' npx jspod</pre>
104+
105+
<h2 id="backup">Backup &amp; reset</h2>
106+
<p>Your entire pod — content, identity, signing keys — is one directory.</p>
107+
108+
<h3>Backup</h3>
109+
<pre>tar -czf my-pod.tar.gz pod-data/</pre>
110+
<p>Restore by extracting the tarball back into a pod-data directory and pointing <code>npx jspod --root /path/to/pod-data</code> at it.</p>
111+
112+
<h3>Reset / "delete account"</h3>
113+
<p>JSS disables the <code>/idp/account/delete</code> endpoint in single-user mode (the account <em>is</em> the pod). To start completely fresh:</p>
114+
<pre>rm -rf pod-data
115+
npx jspod</pre>
116+
<p>A new <code>me</code>/<code>me</code> account is seeded on next start.</p>
117+
118+
<h2 id="apps">Bundled Solid apps</h2>
119+
<p>jspod bundles <a href="https://github.com/solid-apps/pilot">Pilot</a> at <code>/public/apps/pilot/</code>. It's served from your own pod, so same-origin sign-in works even on strict browsers (Brave with shields up).</p>
120+
<p>The bundle is copied skip-if-exists, so you can pin a specific Pilot version by editing the files locally and they'll survive jspod upgrades. Delete <code>pod-data/public/apps/pilot/</code> and restart to re-seed from the current jspod's bundled copy.</p>
121+
122+
<h2 id="links">Links</h2>
123+
<ul>
124+
<li><a href="https://github.com/JavaScriptSolidServer/jspod">jspod source</a> — issues, PRs, releases</li>
125+
<li><a href="https://github.com/JavaScriptSolidServer/JavaScriptSolidServer">JavaScriptSolidServer (JSS)</a> — the substrate</li>
126+
<li><a href="https://github.com/JavaScriptSolidServer/solid-oidc">solid-oidc</a> — the zero-dep OIDC client jspod's signin/account pages use</li>
127+
<li><a href="https://solidproject.org">Solid project</a></li>
128+
<li><a href="https://solidproject.org/TR/protocol">Solid spec</a></li>
129+
</ul>
130+
131+
<footer>Powered by <a href="https://github.com/JavaScriptSolidServer/jspod">jspod</a> · AGPL-3.0-only</footer>
132+
</div>
133+
</body>
134+
</html>

docs.html.acl

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
{
2+
"@context": {
3+
"acl": "http://www.w3.org/ns/auth/acl#",
4+
"foaf": "http://xmlns.com/foaf/0.1/"
5+
},
6+
"@graph": [
7+
{
8+
"@id": "#public",
9+
"@type": "acl:Authorization",
10+
"acl:agentClass": {
11+
"@id": "foaf:Agent"
12+
},
13+
"acl:accessTo": {
14+
"@id": "./docs.html"
15+
},
16+
"acl:mode": [
17+
{
18+
"@id": "acl:Read"
19+
}
20+
]
21+
}
22+
]
23+
}

index.js

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -495,6 +495,15 @@ ready.then((ok) => {
495495
const acctAclDst = join(options.root, 'account.html.acl');
496496
if (existsSync(acctAclSrc)) copyFileSync(acctAclSrc, acctAclDst);
497497

498+
// docs.html + .acl — operator-facing reference. Same overwrite +
499+
// public-read pattern as the rest of the jspod-owned static pages.
500+
const docsSrc = join(__dirname, 'docs.html');
501+
const docsDst = join(options.root, 'docs.html');
502+
if (existsSync(docsSrc)) copyFileSync(docsSrc, docsDst);
503+
const docsAclSrc = join(__dirname, 'docs.html.acl');
504+
const docsAclDst = join(options.root, 'docs.html.acl');
505+
if (existsSync(docsAclSrc)) copyFileSync(docsAclSrc, docsAclDst);
506+
498507
const linksSrc = join(__dirname, 'links.jsonld');
499508
const linksDst = join(options.root, 'public', 'links.jsonld');
500509
if (existsSync(linksSrc) && !existsSync(linksDst)) {

package.json

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "jspod",
3-
"version": "0.0.22",
3+
"version": "0.0.23",
44
"description": "JavaScript Solid Pod - Just works, batteries included",
55
"type": "module",
66
"main": "index.js",
@@ -16,6 +16,8 @@
1616
"signin.html.acl",
1717
"account.html",
1818
"account.html.acl",
19+
"docs.html",
20+
"docs.html.acl",
1921
"links.jsonld",
2022
"apps/"
2123
],

welcome.html

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -64,7 +64,7 @@ <h2 style="margin:1.5em 0 .25em;font-weight:500;font-size:1.05em;color:#444">App
6464
<li><a href="./public/apps/pilot/">✈️ Pilot — Solid data browser</a></li>
6565
</ul>
6666

67-
<footer>Powered by <a href="https://github.com/JavaScriptSolidServer/jspod">jspod</a></footer>
67+
<footer><a href="./docs.html">Docs</a> · Powered by <a href="https://github.com/JavaScriptSolidServer/jspod">jspod</a></footer>
6868
</div>
6969

7070
<script type="module">

0 commit comments

Comments
 (0)