javascript-solid-server 0.0.110 → 0.0.112
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.claude/settings.local.json +2 -1
- package/README.md +70 -1358
- package/bin/jss.js +1 -5
- package/docs/activitypub.md +109 -0
- package/docs/architecture.md +165 -0
- package/docs/authentication.md +157 -0
- package/docs/configuration.md +434 -0
- package/docs/invites.md +43 -0
- package/docs/mashlib.md +58 -0
- package/docs/mongodb.md +42 -0
- package/docs/nostr.md +56 -0
- package/docs/notifications.md +50 -0
- package/docs/payments.md +94 -0
- package/docs/quotas.md +36 -0
- package/docs/remotestorage.md +86 -0
- package/docs/security.md +96 -0
- package/docs/webrtc.md +66 -0
- package/package.json +1 -1
- package/src/auth/middleware.js +4 -7
- package/src/config.js +1 -6
- package/src/handlers/resource.js +7 -13
- package/src/server.js +11 -74
|
@@ -0,0 +1,434 @@
|
|
|
1
|
+
## Philosophy: JSON-LD First
|
|
2
|
+
|
|
3
|
+
This is a **JSON-LD native implementation**. Unlike traditional Solid servers that treat Turtle as the primary format and convert to/from it, this server:
|
|
4
|
+
|
|
5
|
+
- **Stores everything as JSON-LD** - No RDF parsing overhead for standard operations
|
|
6
|
+
- **Serves JSON-LD by default** - Modern web applications can consume responses directly
|
|
7
|
+
- **Content negotiation is optional** - Enable Turtle support with `{ conneg: true }` when needed
|
|
8
|
+
- **Fast by design** - Skip the RDF parsing tax when you don't need it
|
|
9
|
+
|
|
10
|
+
### Why JSON-LD First?
|
|
11
|
+
|
|
12
|
+
1. **Performance**: JSON parsing is native to JavaScript - no external RDF libraries needed for basic operations
|
|
13
|
+
2. **Simplicity**: JSON-LD is valid JSON - works with any JSON tooling
|
|
14
|
+
3. **Web-native**: Browsers and web apps understand JSON natively
|
|
15
|
+
4. **Semantic web ready**: JSON-LD is a W3C standard RDF serialization
|
|
16
|
+
|
|
17
|
+
### When to Enable Content Negotiation
|
|
18
|
+
|
|
19
|
+
Enable `conneg: true` when:
|
|
20
|
+
- Interoperating with Turtle-based Solid apps
|
|
21
|
+
- Serving data to legacy Solid clients
|
|
22
|
+
- Running conformance tests that require Turtle support
|
|
23
|
+
|
|
24
|
+
```javascript
|
|
25
|
+
import { createServer } from './src/server.js';
|
|
26
|
+
|
|
27
|
+
// Default: JSON-LD only (fast)
|
|
28
|
+
const server = createServer();
|
|
29
|
+
|
|
30
|
+
// With Turtle support (for interoperability)
|
|
31
|
+
const serverWithConneg = createServer({ conneg: true });
|
|
32
|
+
```
|
|
33
|
+
|
|
34
|
+
|
|
35
|
+
## Configuration
|
|
36
|
+
|
|
37
|
+
```javascript
|
|
38
|
+
createServer({
|
|
39
|
+
logger: true, // Enable Fastify logging (default: true)
|
|
40
|
+
conneg: false, // Enable content negotiation (default: false)
|
|
41
|
+
notifications: false, // Enable WebSocket notifications (default: false)
|
|
42
|
+
subdomains: false, // Enable subdomain-based pods (default: false)
|
|
43
|
+
baseDomain: null, // Base domain for subdomains (e.g., "example.com")
|
|
44
|
+
mashlib: false, // Enable Mashlib data browser - local mode (default: false)
|
|
45
|
+
mashlibCdn: false, // Enable Mashlib data browser - CDN mode (default: false)
|
|
46
|
+
mashlibVersion: '2.0.0', // Mashlib version for CDN mode
|
|
47
|
+
});
|
|
48
|
+
```
|
|
49
|
+
|
|
50
|
+
### Mashlib Data Browser
|
|
51
|
+
|
|
52
|
+
Enable the [SolidOS Mashlib](https://github.com/SolidOS/mashlib) data browser for RDF resources. Two modes are available:
|
|
53
|
+
|
|
54
|
+
**CDN Mode** (recommended for getting started):
|
|
55
|
+
```bash
|
|
56
|
+
jss start --mashlib-cdn --conneg
|
|
57
|
+
```
|
|
58
|
+
Loads mashlib from unpkg.com CDN. Zero footprint - no local files needed.
|
|
59
|
+
|
|
60
|
+
**Local Mode** (for production/offline):
|
|
61
|
+
```bash
|
|
62
|
+
jss start --mashlib --conneg
|
|
63
|
+
```
|
|
64
|
+
Serves mashlib from `src/mashlib-local/dist/`. Requires building mashlib locally:
|
|
65
|
+
```bash
|
|
66
|
+
cd src/mashlib-local
|
|
67
|
+
npm install && npm run build
|
|
68
|
+
```
|
|
69
|
+
|
|
70
|
+
**ES Module Mode** (for custom or next-gen mashlib builds):
|
|
71
|
+
```bash
|
|
72
|
+
jss start --mashlib-module https://example.com/mashlib.js
|
|
73
|
+
```
|
|
74
|
+
Loads an ES module-based data browser from any URL. Uses `<script type="module">` and `<div id="mashlib">` (self-initializing). CSS is auto-derived by replacing `.js` with `.css`. Content negotiation is auto-enabled.
|
|
75
|
+
|
|
76
|
+
**How it works:**
|
|
77
|
+
1. Browser requests `/alice/public/data.ttl` with `Accept: text/html`
|
|
78
|
+
2. Server returns Mashlib HTML wrapper
|
|
79
|
+
3. Mashlib fetches the actual data via content negotiation
|
|
80
|
+
4. Mashlib renders an interactive, editable view
|
|
81
|
+
|
|
82
|
+
**Note:** Mashlib works best with `--conneg` enabled for Turtle support.
|
|
83
|
+
|
|
84
|
+
**Modern UI (SolidOS UI):**
|
|
85
|
+
```bash
|
|
86
|
+
jss start --mashlib --solidos-ui --conneg
|
|
87
|
+
```
|
|
88
|
+
Serves a modern Nextcloud-style UI shell while reusing mashlib's data layer. The `--solidos-ui` flag swaps the classic databrowser interface for a cleaner, mobile-friendly design with:
|
|
89
|
+
- Modern file browser with breadcrumb navigation
|
|
90
|
+
- Profile, Contacts, Sharing, and Settings views
|
|
91
|
+
- Path-based URLs (browser URL reflects current resource)
|
|
92
|
+
- Responsive design for mobile devices
|
|
93
|
+
|
|
94
|
+
Requires solidos-ui dist files in `src/mashlib-local/dist/solidos-ui/`. See [solidos-ui](https://github.com/solidos/solidos/tree/main/workspaces/solidos-ui) for details.
|
|
95
|
+
|
|
96
|
+
### Profile Pages
|
|
97
|
+
|
|
98
|
+
Pod profiles (`/alice/`) use HTML with embedded JSON-LD data islands and are rendered using:
|
|
99
|
+
- [mashlib-jss](https://github.com/JavaScriptSolidServer/mashlib-jss) - A fork of mashlib with `getPod()` fix for path-based pods
|
|
100
|
+
- [solidos-lite](https://github.com/SolidOS/solidos-lite) - Parses JSON-LD data islands into the RDF store
|
|
101
|
+
|
|
102
|
+
This allows profiles to work without server-side content negotiation while still providing full SolidOS editing capabilities.
|
|
103
|
+
|
|
104
|
+
### WebSocket Notifications
|
|
105
|
+
|
|
106
|
+
Enable real-time notifications for resource changes:
|
|
107
|
+
|
|
108
|
+
```javascript
|
|
109
|
+
const server = createServer({ notifications: true });
|
|
110
|
+
```
|
|
111
|
+
|
|
112
|
+
Clients discover the WebSocket URL via the `Updates-Via` header:
|
|
113
|
+
|
|
114
|
+
```bash
|
|
115
|
+
curl -I http://localhost:3000/alice/public/
|
|
116
|
+
# Updates-Via: ws://localhost:3000/.notifications
|
|
117
|
+
```
|
|
118
|
+
|
|
119
|
+
Protocol (solid-0.1, compatible with SolidOS):
|
|
120
|
+
```
|
|
121
|
+
Server: protocol solid-0.1
|
|
122
|
+
Client: sub http://localhost:3000/alice/public/data.json
|
|
123
|
+
Server: ack http://localhost:3000/alice/public/data.json
|
|
124
|
+
Server: pub http://localhost:3000/alice/public/data.json (on change)
|
|
125
|
+
```
|
|
126
|
+
|
|
127
|
+
|
|
128
|
+
## CLI Start Options
|
|
129
|
+
|
|
130
|
+
### Start Options
|
|
131
|
+
|
|
132
|
+
| Option | Description | Default |
|
|
133
|
+
|--------|-------------|---------|
|
|
134
|
+
| `-p, --port <n>` | Port to listen on | 3000 |
|
|
135
|
+
| `-h, --host <addr>` | Host to bind to | 0.0.0.0 |
|
|
136
|
+
| `-r, --root <path>` | Data directory | ./data |
|
|
137
|
+
| `-c, --config <file>` | Config file path | - |
|
|
138
|
+
| `--ssl-key <path>` | SSL private key (PEM) | - |
|
|
139
|
+
| `--ssl-cert <path>` | SSL certificate (PEM) | - |
|
|
140
|
+
| `--conneg` | Enable Turtle support | false |
|
|
141
|
+
| `--notifications` | Enable WebSocket | false |
|
|
142
|
+
| `--idp` | Enable built-in IdP | false |
|
|
143
|
+
| `--idp-issuer <url>` | IdP issuer URL | (auto) |
|
|
144
|
+
| `--subdomains` | Enable subdomain-based pods | false |
|
|
145
|
+
| `--base-domain <domain>` | Base domain for subdomains | - |
|
|
146
|
+
| `--mashlib` | Enable Mashlib (local mode) | false |
|
|
147
|
+
| `--mashlib-cdn` | Enable Mashlib (CDN mode) | false |
|
|
148
|
+
| `--mashlib-module <url>` | Enable ES module data browser from a URL | - |
|
|
149
|
+
| `--mashlib-version <ver>` | Mashlib CDN version | 2.0.0 |
|
|
150
|
+
| `--solidos-ui` | Enable modern SolidOS UI (requires --mashlib) | false |
|
|
151
|
+
| `--git` | Enable Git HTTP backend | false |
|
|
152
|
+
| `--nostr` | Enable Nostr relay | false |
|
|
153
|
+
| `--nostr-path <path>` | Nostr relay WebSocket path | /relay |
|
|
154
|
+
| `--nostr-max-events <n>` | Max events in relay memory | 1000 |
|
|
155
|
+
| `--invite-only` | Require invite code for registration | false |
|
|
156
|
+
| `--webid-tls` | Enable WebID-TLS client certificate auth | false |
|
|
157
|
+
| `--default-quota <size>` | Default storage quota per pod (e.g., 50MB) | 50MB |
|
|
158
|
+
| `--activitypub` | Enable ActivityPub federation | false |
|
|
159
|
+
| `--ap-username <name>` | ActivityPub username | me |
|
|
160
|
+
| `--ap-display-name <name>` | ActivityPub display name | (username) |
|
|
161
|
+
| `--ap-summary <text>` | ActivityPub bio/summary | - |
|
|
162
|
+
| `--ap-nostr-pubkey <hex>` | Nostr pubkey for identity linking | - |
|
|
163
|
+
| `--public` | Allow unauthenticated access (skip WAC) | false |
|
|
164
|
+
| `--read-only` | Disable PUT/DELETE/PATCH methods | false |
|
|
165
|
+
| `--live-reload` | Auto-refresh browser on file changes | false |
|
|
166
|
+
| `--pay` | Enable HTTP 402 paid access for /pay/* | false |
|
|
167
|
+
| `--pay-cost <n>` | Cost per request in satoshis | 1 |
|
|
168
|
+
| `--pay-mempool-url <url>` | Mempool API URL for deposit verification | (testnet4) |
|
|
169
|
+
| `--pay-address <addr>` | Address for receiving deposits | - |
|
|
170
|
+
| `--pay-token <ticker>` | Token to sell (enables primary market + withdrawal) | - |
|
|
171
|
+
| `--pay-rate <n>` | Sats per token for buy/withdraw | 1 |
|
|
172
|
+
| `--pay-chains <ids>` | Multi-chain deposits + AMM (e.g. "tbtc3,tbtc4") | - |
|
|
173
|
+
| `--mongo` | Enable MongoDB-backed /db/ route | false |
|
|
174
|
+
| `--mongo-url <url>` | MongoDB connection URL | mongodb://localhost:27017 |
|
|
175
|
+
| `--mongo-database <name>` | MongoDB database name | solid |
|
|
176
|
+
| `--webrtc` | Enable WebRTC signaling server | false |
|
|
177
|
+
| `--webrtc-path <path>` | WebRTC signaling WebSocket path | /.webrtc |
|
|
178
|
+
| `--tunnel` | Enable tunnel proxy (decentralized ngrok) | false |
|
|
179
|
+
| `--tunnel-path <path>` | Tunnel WebSocket path | /.tunnel |
|
|
180
|
+
| `-q, --quiet` | Suppress logs | false |
|
|
181
|
+
|
|
182
|
+
### Environment Variables
|
|
183
|
+
|
|
184
|
+
All options can be set via environment variables with `JSS_` prefix:
|
|
185
|
+
|
|
186
|
+
```bash
|
|
187
|
+
export JSS_PORT=8443
|
|
188
|
+
export JSS_SSL_KEY=/path/to/key.pem
|
|
189
|
+
export JSS_SSL_CERT=/path/to/cert.pem
|
|
190
|
+
export JSS_CONNEG=true
|
|
191
|
+
export JSS_SUBDOMAINS=true
|
|
192
|
+
export JSS_BASE_DOMAIN=example.com
|
|
193
|
+
export JSS_MASHLIB=true
|
|
194
|
+
export JSS_MASHLIB_MODULE=https://example.com/mashlib.js
|
|
195
|
+
export JSS_NOSTR=true
|
|
196
|
+
export JSS_INVITE_ONLY=true
|
|
197
|
+
export JSS_WEBID_TLS=true
|
|
198
|
+
export JSS_DEFAULT_QUOTA=100MB
|
|
199
|
+
export JSS_ACTIVITYPUB=true
|
|
200
|
+
export JSS_AP_USERNAME=alice
|
|
201
|
+
export JSS_PUBLIC=true
|
|
202
|
+
export JSS_READ_ONLY=true
|
|
203
|
+
export JSS_LIVE_RELOAD=true
|
|
204
|
+
export JSS_SOLIDOS_UI=true
|
|
205
|
+
export JSS_PAY=true
|
|
206
|
+
export JSS_PAY_COST=10
|
|
207
|
+
export JSS_PAY_ADDRESS=your-address
|
|
208
|
+
export JSS_PAY_TOKEN=PODS
|
|
209
|
+
export JSS_PAY_RATE=10
|
|
210
|
+
export JSS_MONGO=true
|
|
211
|
+
export JSS_MONGO_URL=mongodb://localhost:27017
|
|
212
|
+
export JSS_MONGO_DATABASE=solid
|
|
213
|
+
export JSS_WEBRTC=true
|
|
214
|
+
jss start
|
|
215
|
+
```
|
|
216
|
+
|
|
217
|
+
### Config File
|
|
218
|
+
|
|
219
|
+
Create `config.json`:
|
|
220
|
+
|
|
221
|
+
```json
|
|
222
|
+
{
|
|
223
|
+
"port": 8443,
|
|
224
|
+
"root": "./data",
|
|
225
|
+
"sslKey": "./ssl/key.pem",
|
|
226
|
+
"sslCert": "./ssl/cert.pem",
|
|
227
|
+
"conneg": true,
|
|
228
|
+
"notifications": true
|
|
229
|
+
}
|
|
230
|
+
```
|
|
231
|
+
|
|
232
|
+
Then: `jss start --config config.json`
|
|
233
|
+
|
|
234
|
+
### Creating a Pod
|
|
235
|
+
|
|
236
|
+
```bash
|
|
237
|
+
curl -X POST http://localhost:3000/.pods \
|
|
238
|
+
-H "Content-Type: application/json" \
|
|
239
|
+
-d '{"name": "alice"}'
|
|
240
|
+
```
|
|
241
|
+
|
|
242
|
+
Response:
|
|
243
|
+
```json
|
|
244
|
+
{
|
|
245
|
+
"name": "alice",
|
|
246
|
+
"webId": "http://localhost:3000/alice/#me",
|
|
247
|
+
"podUri": "http://localhost:3000/alice/",
|
|
248
|
+
"token": "eyJ..."
|
|
249
|
+
}
|
|
250
|
+
```
|
|
251
|
+
|
|
252
|
+
### Single-User Mode
|
|
253
|
+
|
|
254
|
+
For personal pod servers where only one user needs access:
|
|
255
|
+
|
|
256
|
+
```bash
|
|
257
|
+
# Basic single-user mode (creates pod at /me/)
|
|
258
|
+
jss start --single-user --idp
|
|
259
|
+
|
|
260
|
+
# Custom username
|
|
261
|
+
jss start --single-user --single-user-name alice --idp
|
|
262
|
+
|
|
263
|
+
# Root-level pod (pod at /, WebID at /profile/card#me)
|
|
264
|
+
jss start --single-user --single-user-name '' --idp
|
|
265
|
+
|
|
266
|
+
# Via environment
|
|
267
|
+
JSS_SINGLE_USER=true jss start --idp
|
|
268
|
+
```
|
|
269
|
+
|
|
270
|
+
**Features:**
|
|
271
|
+
- Pod auto-created on first startup with full structure (inbox, public, private, profile)
|
|
272
|
+
- Registration endpoint disabled (returns 403)
|
|
273
|
+
- Login still works for the single user
|
|
274
|
+
- Proper ACLs generated automatically
|
|
275
|
+
|
|
276
|
+
|
|
277
|
+
## Invite-Only Registration
|
|
278
|
+
|
|
279
|
+
Control who can create accounts by requiring invite codes:
|
|
280
|
+
|
|
281
|
+
```bash
|
|
282
|
+
jss start --idp --invite-only
|
|
283
|
+
```
|
|
284
|
+
|
|
285
|
+
### Managing Invite Codes
|
|
286
|
+
|
|
287
|
+
```bash
|
|
288
|
+
# Create a single-use invite
|
|
289
|
+
jss invite create
|
|
290
|
+
# Created invite code: ABCD1234
|
|
291
|
+
|
|
292
|
+
# Create multi-use invite with note
|
|
293
|
+
jss invite create -u 5 -n "For team members"
|
|
294
|
+
|
|
295
|
+
# List all active invites
|
|
296
|
+
jss invite list
|
|
297
|
+
# CODE USES CREATED NOTE
|
|
298
|
+
# -------------------------------------------------------
|
|
299
|
+
# ABCD1234 0/1 2026-01-03
|
|
300
|
+
# EFGH5678 2/5 2026-01-03 For team members
|
|
301
|
+
|
|
302
|
+
# Revoke an invite
|
|
303
|
+
jss invite revoke ABCD1234
|
|
304
|
+
```
|
|
305
|
+
|
|
306
|
+
### How It Works
|
|
307
|
+
|
|
308
|
+
| Mode | Registration | Pod Creation |
|
|
309
|
+
|------|--------------|--------------|
|
|
310
|
+
| Open (default) | Anyone can register | Anyone can create pods |
|
|
311
|
+
| Invite-only | Requires valid invite code | Via registration only |
|
|
312
|
+
|
|
313
|
+
When `--invite-only` is enabled:
|
|
314
|
+
- The registration page shows an "Invite Code" field
|
|
315
|
+
- Invalid or expired codes are rejected with an error
|
|
316
|
+
- Each use decrements the invite's remaining uses
|
|
317
|
+
- Depleted invites are automatically removed
|
|
318
|
+
|
|
319
|
+
Invite codes are stored in `.server/invites.json` in your data directory.
|
|
320
|
+
|
|
321
|
+
## Storage Quotas
|
|
322
|
+
|
|
323
|
+
Limit storage per pod to prevent abuse and manage resources:
|
|
324
|
+
|
|
325
|
+
```bash
|
|
326
|
+
jss start --default-quota 50MB
|
|
327
|
+
```
|
|
328
|
+
|
|
329
|
+
### Managing Quotas
|
|
330
|
+
|
|
331
|
+
```bash
|
|
332
|
+
# Set quota for a user (overrides default)
|
|
333
|
+
jss quota set alice 100MB
|
|
334
|
+
|
|
335
|
+
# Show quota info
|
|
336
|
+
jss quota show alice
|
|
337
|
+
# alice:
|
|
338
|
+
# Used: 12.5 MB
|
|
339
|
+
# Limit: 100 MB
|
|
340
|
+
# Free: 87.5 MB
|
|
341
|
+
# Usage: 12%
|
|
342
|
+
|
|
343
|
+
# Recalculate from actual disk usage
|
|
344
|
+
jss quota reconcile alice
|
|
345
|
+
```
|
|
346
|
+
|
|
347
|
+
### How It Works
|
|
348
|
+
|
|
349
|
+
- Quotas are tracked incrementally on PUT, POST, and DELETE operations
|
|
350
|
+
- When quota is exceeded, the server returns HTTP 507 Insufficient Storage
|
|
351
|
+
- Each pod stores its quota in `/{pod}/.quota.json`
|
|
352
|
+
- Use `reconcile` to fix quota drift from manual file changes
|
|
353
|
+
|
|
354
|
+
### Size Formats
|
|
355
|
+
|
|
356
|
+
Supported formats: `50MB`, `1GB`, `500KB`, `1TB`
|
|
357
|
+
|
|
358
|
+
### Mashlib Data Browser
|
|
359
|
+
|
|
360
|
+
Enable the [SolidOS Mashlib](https://github.com/SolidOS/mashlib) data browser for RDF resources. Two modes are available:
|
|
361
|
+
|
|
362
|
+
**CDN Mode** (recommended for getting started):
|
|
363
|
+
```bash
|
|
364
|
+
jss start --mashlib-cdn --conneg
|
|
365
|
+
```
|
|
366
|
+
Loads mashlib from unpkg.com CDN. Zero footprint - no local files needed.
|
|
367
|
+
|
|
368
|
+
**Local Mode** (for production/offline):
|
|
369
|
+
```bash
|
|
370
|
+
jss start --mashlib --conneg
|
|
371
|
+
```
|
|
372
|
+
Serves mashlib from `src/mashlib-local/dist/`. Requires building mashlib locally:
|
|
373
|
+
```bash
|
|
374
|
+
cd src/mashlib-local
|
|
375
|
+
npm install && npm run build
|
|
376
|
+
```
|
|
377
|
+
|
|
378
|
+
**ES Module Mode** (for custom or next-gen mashlib builds):
|
|
379
|
+
```bash
|
|
380
|
+
jss start --mashlib-module https://example.com/mashlib.js
|
|
381
|
+
```
|
|
382
|
+
Loads an ES module-based data browser from any URL. Uses `<script type="module">` and `<div id="mashlib">` (self-initializing). CSS is auto-derived by replacing `.js` with `.css`. Content negotiation is auto-enabled.
|
|
383
|
+
|
|
384
|
+
**How it works:**
|
|
385
|
+
1. Browser requests `/alice/public/data.ttl` with `Accept: text/html`
|
|
386
|
+
2. Server returns Mashlib HTML wrapper
|
|
387
|
+
3. Mashlib fetches the actual data via content negotiation
|
|
388
|
+
4. Mashlib renders an interactive, editable view
|
|
389
|
+
|
|
390
|
+
**Note:** Mashlib works best with `--conneg` enabled for Turtle support.
|
|
391
|
+
|
|
392
|
+
**Modern UI (SolidOS UI):**
|
|
393
|
+
```bash
|
|
394
|
+
jss start --mashlib --solidos-ui --conneg
|
|
395
|
+
```
|
|
396
|
+
Serves a modern Nextcloud-style UI shell while reusing mashlib's data layer. The `--solidos-ui` flag swaps the classic databrowser interface for a cleaner, mobile-friendly design with:
|
|
397
|
+
- Modern file browser with breadcrumb navigation
|
|
398
|
+
- Profile, Contacts, Sharing, and Settings views
|
|
399
|
+
- Path-based URLs (browser URL reflects current resource)
|
|
400
|
+
- Responsive design for mobile devices
|
|
401
|
+
|
|
402
|
+
Requires solidos-ui dist files in `src/mashlib-local/dist/solidos-ui/`. See [solidos-ui](https://github.com/solidos/solidos/tree/main/workspaces/solidos-ui) for details.
|
|
403
|
+
|
|
404
|
+
### Profile Pages
|
|
405
|
+
|
|
406
|
+
Pod profiles (`/alice/`) use HTML with embedded JSON-LD data islands and are rendered using:
|
|
407
|
+
- [mashlib-jss](https://github.com/JavaScriptSolidServer/mashlib-jss) - A fork of mashlib with `getPod()` fix for path-based pods
|
|
408
|
+
- [solidos-lite](https://github.com/SolidOS/solidos-lite) - Parses JSON-LD data islands into the RDF store
|
|
409
|
+
|
|
410
|
+
This allows profiles to work without server-side content negotiation while still providing full SolidOS editing capabilities.
|
|
411
|
+
|
|
412
|
+
### WebSocket Notifications
|
|
413
|
+
|
|
414
|
+
Enable real-time notifications for resource changes:
|
|
415
|
+
|
|
416
|
+
```javascript
|
|
417
|
+
const server = createServer({ notifications: true });
|
|
418
|
+
```
|
|
419
|
+
|
|
420
|
+
Clients discover the WebSocket URL via the `Updates-Via` header:
|
|
421
|
+
|
|
422
|
+
```bash
|
|
423
|
+
curl -I http://localhost:3000/alice/public/
|
|
424
|
+
# Updates-Via: ws://localhost:3000/.notifications
|
|
425
|
+
```
|
|
426
|
+
|
|
427
|
+
Protocol (solid-0.1, compatible with SolidOS):
|
|
428
|
+
```
|
|
429
|
+
Server: protocol solid-0.1
|
|
430
|
+
Client: sub http://localhost:3000/alice/public/data.json
|
|
431
|
+
Server: ack http://localhost:3000/alice/public/data.json
|
|
432
|
+
Server: pub http://localhost:3000/alice/public/data.json (on change)
|
|
433
|
+
```
|
|
434
|
+
|
package/docs/invites.md
ADDED
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
# Invite-Only Registration
|
|
2
|
+
|
|
3
|
+
Control who can create accounts by requiring invite codes.
|
|
4
|
+
|
|
5
|
+
```bash
|
|
6
|
+
jss start --idp --invite-only
|
|
7
|
+
```
|
|
8
|
+
|
|
9
|
+
## Managing Invite Codes
|
|
10
|
+
|
|
11
|
+
```bash
|
|
12
|
+
# Create a single-use invite
|
|
13
|
+
jss invite create
|
|
14
|
+
# Created invite code: ABCD1234
|
|
15
|
+
|
|
16
|
+
# Create multi-use invite with note
|
|
17
|
+
jss invite create -u 5 -n "For team members"
|
|
18
|
+
|
|
19
|
+
# List all active invites
|
|
20
|
+
jss invite list
|
|
21
|
+
# CODE USES CREATED NOTE
|
|
22
|
+
# -------------------------------------------------------
|
|
23
|
+
# ABCD1234 0/1 2026-01-03
|
|
24
|
+
# EFGH5678 2/5 2026-01-03 For team members
|
|
25
|
+
|
|
26
|
+
# Revoke an invite
|
|
27
|
+
jss invite revoke ABCD1234
|
|
28
|
+
```
|
|
29
|
+
|
|
30
|
+
## How It Works
|
|
31
|
+
|
|
32
|
+
| Mode | Registration | Pod Creation |
|
|
33
|
+
|------|--------------|--------------|
|
|
34
|
+
| Open (default) | Anyone can register | Anyone can create pods |
|
|
35
|
+
| Invite-only | Requires valid invite code | Via registration only |
|
|
36
|
+
|
|
37
|
+
When `--invite-only` is enabled:
|
|
38
|
+
- The registration page shows an "Invite Code" field
|
|
39
|
+
- Invalid or expired codes are rejected with an error
|
|
40
|
+
- Each use decrements the invite's remaining uses
|
|
41
|
+
- Depleted invites are automatically removed
|
|
42
|
+
|
|
43
|
+
Invite codes are stored in `.server/invites.json` in your data directory.
|
package/docs/mashlib.md
ADDED
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
# Mashlib Data Browser
|
|
2
|
+
|
|
3
|
+
Enable the [SolidOS Mashlib](https://github.com/SolidOS/mashlib) data browser for RDF resources.
|
|
4
|
+
|
|
5
|
+
## Modes
|
|
6
|
+
|
|
7
|
+
**CDN Mode** (recommended for getting started):
|
|
8
|
+
```bash
|
|
9
|
+
jss start --mashlib-cdn --conneg
|
|
10
|
+
```
|
|
11
|
+
Loads mashlib from unpkg.com CDN. Zero footprint — no local files needed.
|
|
12
|
+
|
|
13
|
+
**Local Mode** (for production/offline):
|
|
14
|
+
```bash
|
|
15
|
+
jss start --mashlib --conneg
|
|
16
|
+
```
|
|
17
|
+
Serves mashlib from `src/mashlib-local/dist/`. Requires building mashlib locally:
|
|
18
|
+
```bash
|
|
19
|
+
cd src/mashlib-local
|
|
20
|
+
npm install && npm run build
|
|
21
|
+
```
|
|
22
|
+
|
|
23
|
+
**ES Module Mode** (for custom or next-gen mashlib builds):
|
|
24
|
+
```bash
|
|
25
|
+
jss start --mashlib-module https://example.com/mashlib.js
|
|
26
|
+
```
|
|
27
|
+
Loads an ES module-based data browser from any URL. Uses `<script type="module">` and `<div id="mashlib">` (self-initializing). CSS is auto-derived by replacing `.js` with `.css`. Content negotiation is auto-enabled.
|
|
28
|
+
|
|
29
|
+
## How It Works
|
|
30
|
+
|
|
31
|
+
1. Browser requests `/alice/public/data.ttl` with `Accept: text/html`
|
|
32
|
+
2. Server returns Mashlib HTML wrapper
|
|
33
|
+
3. Mashlib fetches the actual data via content negotiation
|
|
34
|
+
4. Mashlib renders an interactive, editable view
|
|
35
|
+
|
|
36
|
+
**Note:** Mashlib works best with `--conneg` enabled for Turtle support.
|
|
37
|
+
|
|
38
|
+
## Modern UI (SolidOS UI)
|
|
39
|
+
|
|
40
|
+
```bash
|
|
41
|
+
jss start --mashlib --solidos-ui --conneg
|
|
42
|
+
```
|
|
43
|
+
|
|
44
|
+
Serves a modern Nextcloud-style UI shell while reusing mashlib's data layer:
|
|
45
|
+
- Modern file browser with breadcrumb navigation
|
|
46
|
+
- Profile, Contacts, Sharing, and Settings views
|
|
47
|
+
- Path-based URLs (browser URL reflects current resource)
|
|
48
|
+
- Responsive design for mobile devices
|
|
49
|
+
|
|
50
|
+
Requires solidos-ui dist files in `src/mashlib-local/dist/solidos-ui/`. See [solidos-ui](https://github.com/solidos/solidos/tree/main/workspaces/solidos-ui) for details.
|
|
51
|
+
|
|
52
|
+
## Profile Pages
|
|
53
|
+
|
|
54
|
+
Pod profiles (`/alice/`) use HTML with embedded JSON-LD data islands and are rendered using:
|
|
55
|
+
- [mashlib-jss](https://github.com/JavaScriptSolidServer/mashlib-jss) — A fork of mashlib with `getPod()` fix for path-based pods
|
|
56
|
+
- [solidos-lite](https://github.com/SolidOS/solidos-lite) — Parses JSON-LD data islands into the RDF store
|
|
57
|
+
|
|
58
|
+
This allows profiles to work without server-side content negotiation while still providing full SolidOS editing capabilities.
|
package/docs/mongodb.md
ADDED
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
## MongoDB Storage (`/db/` Route)
|
|
2
|
+
|
|
3
|
+
Optional MongoDB-backed route for JSON-LD documents that need scale (social feeds, posts, follows). All other routes continue using the filesystem unchanged.
|
|
4
|
+
|
|
5
|
+
```bash
|
|
6
|
+
# Install the optional MongoDB driver
|
|
7
|
+
npm install mongodb
|
|
8
|
+
|
|
9
|
+
# Start with MongoDB enabled
|
|
10
|
+
jss start --mongo --mongo-url mongodb://localhost:27017 --mongo-database solid
|
|
11
|
+
```
|
|
12
|
+
|
|
13
|
+
### Operations
|
|
14
|
+
|
|
15
|
+
```bash
|
|
16
|
+
# Store a document
|
|
17
|
+
curl -X PUT http://localhost:3000/db/alice/notes/1 \
|
|
18
|
+
-H "Content-Type: application/ld+json" \
|
|
19
|
+
-H "Authorization: Bearer <token>" \
|
|
20
|
+
-d '{"@context": "https://schema.org/", "@type": "Note", "text": "Hello"}'
|
|
21
|
+
|
|
22
|
+
# Read it back
|
|
23
|
+
curl http://localhost:3000/db/alice/notes/1
|
|
24
|
+
|
|
25
|
+
# List container (derived from URI prefixes)
|
|
26
|
+
curl http://localhost:3000/db/alice/
|
|
27
|
+
|
|
28
|
+
# Delete
|
|
29
|
+
curl -X DELETE http://localhost:3000/db/alice/notes/1 \
|
|
30
|
+
-H "Authorization: Bearer <token>"
|
|
31
|
+
```
|
|
32
|
+
|
|
33
|
+
### How It Works
|
|
34
|
+
|
|
35
|
+
- `GET /db/:path` — retrieve a document by URI, or list a virtual container
|
|
36
|
+
- `PUT /db/:path` — create or update (upsert) a JSON-LD document
|
|
37
|
+
- `DELETE /db/:path` — remove a document
|
|
38
|
+
- Returns standard LDP headers (Link, ETag, WAC-Allow, CORS)
|
|
39
|
+
- Supports conditional requests (If-Match, If-None-Match)
|
|
40
|
+
- Container listings are computed from URI prefix queries — no directory management needed
|
|
41
|
+
- Auth: pod owner can write (`/db/{podName}/...`), reads are public
|
|
42
|
+
- MongoDB is an optional dependency — the server runs without it
|
package/docs/nostr.md
ADDED
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
# Nostr Relay
|
|
2
|
+
|
|
3
|
+
Integrated NIP-01/NIP-11/NIP-16 Nostr relay running on the same port as the Solid server.
|
|
4
|
+
|
|
5
|
+
```bash
|
|
6
|
+
jss start --nostr
|
|
7
|
+
```
|
|
8
|
+
|
|
9
|
+
## Endpoint
|
|
10
|
+
|
|
11
|
+
`wss://your.pod/relay` (configurable via `--nostr-path`)
|
|
12
|
+
|
|
13
|
+
## Supported NIPs
|
|
14
|
+
|
|
15
|
+
- **NIP-01** — Basic protocol flow (EVENT, REQ, CLOSE)
|
|
16
|
+
- **NIP-11** — Relay information document (`GET /relay` with `Accept: application/nostr+json`)
|
|
17
|
+
- **NIP-16** — Event treatment (regular, replaceable, ephemeral)
|
|
18
|
+
|
|
19
|
+
## Options
|
|
20
|
+
|
|
21
|
+
| Option | Description | Default |
|
|
22
|
+
|--------|-------------|---------|
|
|
23
|
+
| `--nostr` | Enable Nostr relay | false |
|
|
24
|
+
| `--nostr-path <path>` | WebSocket path | /relay |
|
|
25
|
+
| `--nostr-max-events <n>` | Max events in memory | 1000 |
|
|
26
|
+
|
|
27
|
+
## How It Works
|
|
28
|
+
|
|
29
|
+
- Events are stored in memory (up to `--nostr-max-events`)
|
|
30
|
+
- Replaceable events (kinds 0, 3, 10000-19999) replace previous events by the same pubkey
|
|
31
|
+
- Ephemeral events (kinds 20000-29999) are broadcast but not stored
|
|
32
|
+
- Parameterized replaceable events (kinds 30000-39999) use the `d` tag for deduplication
|
|
33
|
+
- Rate limiting: 60 events per socket per minute
|
|
34
|
+
|
|
35
|
+
## Client Usage
|
|
36
|
+
|
|
37
|
+
```javascript
|
|
38
|
+
import { Relay } from 'nostr-tools';
|
|
39
|
+
|
|
40
|
+
const relay = await Relay.connect('wss://your.pod/relay');
|
|
41
|
+
|
|
42
|
+
// Subscribe
|
|
43
|
+
const sub = relay.subscribe([{ kinds: [1], limit: 10 }], {
|
|
44
|
+
onevent(event) { console.log(event); }
|
|
45
|
+
});
|
|
46
|
+
|
|
47
|
+
// Publish
|
|
48
|
+
await relay.publish(signedEvent);
|
|
49
|
+
```
|
|
50
|
+
|
|
51
|
+
## Nostr Authentication (NIP-98)
|
|
52
|
+
|
|
53
|
+
JSS also supports NIP-98 HTTP Auth for Solid operations. See [docs/authentication.md](authentication.md) for details on:
|
|
54
|
+
- NIP-98 Schnorr signature authentication
|
|
55
|
+
- `did:nostr` → WebID resolution
|
|
56
|
+
- Linking Nostr identity to your WebID profile
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
# WebSocket Notifications
|
|
2
|
+
|
|
3
|
+
Real-time notifications for resource changes using the solid-0.1 protocol (SolidOS compatible).
|
|
4
|
+
|
|
5
|
+
```bash
|
|
6
|
+
jss start --notifications
|
|
7
|
+
```
|
|
8
|
+
|
|
9
|
+
## Discovery
|
|
10
|
+
|
|
11
|
+
Clients discover the WebSocket URL via the `Updates-Via` header:
|
|
12
|
+
|
|
13
|
+
```bash
|
|
14
|
+
curl -I http://localhost:3000/alice/public/
|
|
15
|
+
# Updates-Via: ws://localhost:3000/.notifications
|
|
16
|
+
```
|
|
17
|
+
|
|
18
|
+
## Protocol
|
|
19
|
+
|
|
20
|
+
```
|
|
21
|
+
Server: protocol solid-0.1
|
|
22
|
+
Client: sub http://localhost:3000/alice/public/data.json
|
|
23
|
+
Server: ack http://localhost:3000/alice/public/data.json
|
|
24
|
+
Server: pub http://localhost:3000/alice/public/data.json (on change)
|
|
25
|
+
```
|
|
26
|
+
|
|
27
|
+
## How It Works
|
|
28
|
+
|
|
29
|
+
1. Client connects to the WebSocket URL from `Updates-Via`
|
|
30
|
+
2. Server sends `protocol solid-0.1` greeting
|
|
31
|
+
3. Client subscribes: `sub <resource-url>`
|
|
32
|
+
4. Server acknowledges: `ack <resource-url>`
|
|
33
|
+
5. On any change (PUT, PATCH, DELETE), server broadcasts: `pub <resource-url>`
|
|
34
|
+
6. Container subscriptions also fire when child resources change
|
|
35
|
+
|
|
36
|
+
## ACL Enforcement
|
|
37
|
+
|
|
38
|
+
- Anonymous clients can subscribe to public resources
|
|
39
|
+
- Private resource subscriptions require authentication
|
|
40
|
+
- Cross-origin subscriptions are rejected
|
|
41
|
+
|
|
42
|
+
## Live Reload
|
|
43
|
+
|
|
44
|
+
For development, `--live-reload` injects a script that auto-refreshes the browser when files change on disk:
|
|
45
|
+
|
|
46
|
+
```bash
|
|
47
|
+
jss start --live-reload --notifications
|
|
48
|
+
```
|
|
49
|
+
|
|
50
|
+
File system changes (editing files directly) also trigger WebSocket notifications.
|