javascript-solid-server 0.0.61 → 0.0.62

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/README.md CHANGED
@@ -6,8 +6,9 @@ A minimal, fast, JSON-LD native Solid server.
6
6
 
7
7
  ## Features
8
8
 
9
- ### Implemented (v0.0.60)
9
+ ### Implemented (v0.0.61)
10
10
 
11
+ - **ActivityPub Federation** - Fediverse integration with WebFinger, inbox/outbox, HTTP signatures
11
12
  - **LDP CRUD Operations** - GET, PUT, POST, DELETE, HEAD
12
13
  - **N3 Patch** - Solid's native patch format for RDF updates
13
14
  - **SPARQL Update** - Standard SPARQL UPDATE protocol for PATCH
@@ -126,6 +127,11 @@ jss --help # Show help
126
127
  | `--nostr-max-events <n>` | Max events in relay memory | 1000 |
127
128
  | `--invite-only` | Require invite code for registration | false |
128
129
  | `--default-quota <size>` | Default storage quota per pod (e.g., 50MB) | 50MB |
130
+ | `--activitypub` | Enable ActivityPub federation | false |
131
+ | `--ap-username <name>` | ActivityPub username | me |
132
+ | `--ap-display-name <name>` | ActivityPub display name | (username) |
133
+ | `--ap-summary <text>` | ActivityPub bio/summary | - |
134
+ | `--ap-nostr-pubkey <hex>` | Nostr pubkey for identity linking | - |
129
135
  | `-q, --quiet` | Suppress logs | false |
130
136
 
131
137
  ### Environment Variables
@@ -143,6 +149,8 @@ export JSS_MASHLIB=true
143
149
  export JSS_NOSTR=true
144
150
  export JSS_INVITE_ONLY=true
145
151
  export JSS_DEFAULT_QUOTA=100MB
152
+ export JSS_ACTIVITYPUB=true
153
+ export JSS_AP_USERNAME=alice
146
154
  jss start
147
155
  ```
148
156
 
@@ -409,6 +417,72 @@ git add .acl && git commit -m "Add ACL"
409
417
 
410
418
  See [git-credential-nostr](https://github.com/JavaScriptSolidServer/git-credential-nostr) for more details.
411
419
 
420
+ ## ActivityPub Federation
421
+
422
+ Enable ActivityPub to federate with Mastodon, Pleroma, Misskey, and other Fediverse servers:
423
+
424
+ ```bash
425
+ jss start --activitypub --ap-username alice --ap-display-name "Alice" --ap-summary "Hello from JSS!"
426
+ ```
427
+
428
+ ### Endpoints
429
+
430
+ | Endpoint | Description |
431
+ |----------|-------------|
432
+ | `/.well-known/webfinger` | Actor discovery (Mastodon searches here) |
433
+ | `/.well-known/nodeinfo` | NodeInfo discovery |
434
+ | `/profile/card` | Actor (returns JSON-LD when `Accept: application/activity+json`) |
435
+ | `/inbox` | Shared inbox for receiving activities |
436
+ | `/profile/card/inbox` | Personal inbox |
437
+ | `/profile/card/outbox` | User's activities |
438
+ | `/profile/card/followers` | Followers collection |
439
+ | `/profile/card/following` | Following collection |
440
+
441
+ ### How It Works
442
+
443
+ 1. **Discovery**: Mastodon looks up `@alice@your.server` via WebFinger
444
+ 2. **Actor**: Returns ActivityPub Actor JSON-LD with public key
445
+ 3. **Follow**: Remote servers POST Follow activities to inbox
446
+ 4. **Accept**: JSS auto-accepts follows and sends Accept back
447
+ 5. **Delivery**: Posts are signed with HTTP Signatures and delivered to follower inboxes
448
+
449
+ ### Identity Linking
450
+
451
+ Your WebID (`/profile/card#me`) becomes your ActivityPub Actor. Link to Nostr identity:
452
+
453
+ ```bash
454
+ jss start --activitypub --ap-nostr-pubkey <64-char-hex-pubkey>
455
+ ```
456
+
457
+ This adds `alsoKnownAs: ["did:nostr:<pubkey>"]` to your Actor profile, creating a verifiable link between your Solid, ActivityPub, and Nostr identities (the SAND stack).
458
+
459
+ ### Programmatic Usage
460
+
461
+ ```javascript
462
+ import { createServer } from 'javascript-solid-server';
463
+
464
+ const server = createServer({
465
+ activitypub: true,
466
+ apUsername: 'alice',
467
+ apDisplayName: 'Alice',
468
+ apSummary: 'Building the decentralized web!',
469
+ apNostrPubkey: 'abc123...' // Optional: links to did:nostr
470
+ });
471
+ ```
472
+
473
+ ### Testing Federation
474
+
475
+ ```bash
476
+ # Check WebFinger
477
+ curl "http://localhost:3000/.well-known/webfinger?resource=acct:alice@localhost:3000"
478
+
479
+ # Get Actor (AP format)
480
+ curl -H "Accept: application/activity+json" http://localhost:3000/profile/card
481
+
482
+ # Check NodeInfo
483
+ curl http://localhost:3000/.well-known/nodeinfo/2.1
484
+ ```
485
+
412
486
  ### Linking Nostr to WebID (did:nostr)
413
487
 
414
488
  Bridge your Nostr identity to a Solid WebID for seamless authentication:
@@ -812,6 +886,15 @@ src/
812
886
  │ ├── interactions.js # Login/consent handlers
813
887
  │ ├── views.js # HTML templates
814
888
  │ └── invites.js # Invite code management
889
+ ├── ap/
890
+ │ ├── index.js # ActivityPub plugin
891
+ │ ├── keys.js # RSA keypair management
892
+ │ ├── store.js # SQLite storage (followers, activities)
893
+ │ └── routes/
894
+ │ ├── actor.js # Actor JSON-LD
895
+ │ ├── inbox.js # Receive activities
896
+ │ ├── outbox.js # User's activities
897
+ │ └── collections.js # Followers/following
815
898
  ├── rdf/
816
899
  │ ├── turtle.js # Turtle <-> JSON-LD
817
900
  │ └── conneg.js # Content negotiation
@@ -831,6 +914,8 @@ Minimal dependencies for a fast, secure server:
831
914
  - **n3** - Turtle parsing (only used when conneg enabled)
832
915
  - **oidc-provider** - OpenID Connect Identity Provider (only when IdP enabled)
833
916
  - **bcrypt** - Password hashing (only when IdP enabled)
917
+ - **microfed** - ActivityPub primitives (only when activitypub enabled)
918
+ - **better-sqlite3** - SQLite storage for federation data
834
919
 
835
920
  ## License
836
921
 
package/bin/jss.js CHANGED
@@ -63,6 +63,12 @@ program
63
63
  .option('--no-nostr', 'Disable Nostr relay')
64
64
  .option('--nostr-path <path>', 'Nostr relay WebSocket path (default: /relay)')
65
65
  .option('--nostr-max-events <n>', 'Max events in relay memory (default: 1000)', parseInt)
66
+ .option('--activitypub', 'Enable ActivityPub federation')
67
+ .option('--no-activitypub', 'Disable ActivityPub federation')
68
+ .option('--ap-username <name>', 'ActivityPub username (default: me)')
69
+ .option('--ap-display-name <name>', 'ActivityPub display name')
70
+ .option('--ap-summary <text>', 'ActivityPub bio/summary')
71
+ .option('--ap-nostr-pubkey <hex>', 'Nostr pubkey for identity linking')
66
72
  .option('--invite-only', 'Require invite code for registration')
67
73
  .option('--no-invite-only', 'Allow open registration')
68
74
  .option('-q, --quiet', 'Suppress log output')
@@ -110,6 +116,11 @@ program
110
116
  nostr: config.nostr,
111
117
  nostrPath: config.nostrPath,
112
118
  nostrMaxEvents: config.nostrMaxEvents,
119
+ activitypub: config.activitypub,
120
+ apUsername: config.apUsername,
121
+ apDisplayName: config.apDisplayName,
122
+ apSummary: config.apSummary,
123
+ apNostrPubkey: config.apNostrPubkey,
113
124
  inviteOnly: config.inviteOnly,
114
125
  });
115
126
 
@@ -131,6 +142,7 @@ program
131
142
  }
132
143
  if (config.git) console.log(' Git: enabled (clone/push support)');
133
144
  if (config.nostr) console.log(` Nostr: enabled (${config.nostrPath})`);
145
+ if (config.activitypub) console.log(` ActivityPub: enabled (@${config.apUsername || 'me'})`);
134
146
  if (config.inviteOnly) console.log(' Registration: invite-only');
135
147
  console.log('\n Press Ctrl+C to stop\n');
136
148
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "javascript-solid-server",
3
- "version": "0.0.61",
3
+ "version": "0.0.62",
4
4
  "description": "A minimal, fast Solid server",
5
5
  "main": "src/index.js",
6
6
  "type": "module",
package/src/ap/index.js CHANGED
@@ -110,7 +110,7 @@ export async function activityPubPlugin(fastify, options = {}) {
110
110
  version: '2.1',
111
111
  software: {
112
112
  name: 'jss',
113
- version: '0.0.61',
113
+ version: '0.0.62',
114
114
  repository: 'https://github.com/JavaScriptSolidServer/JavaScriptSolidServer'
115
115
  },
116
116
  protocols: ['activitypub', 'solid'],
package/src/config.js CHANGED
@@ -50,6 +50,13 @@ export const defaults = {
50
50
  nostrPath: '/relay',
51
51
  nostrMaxEvents: 1000,
52
52
 
53
+ // ActivityPub federation
54
+ activitypub: false,
55
+ apUsername: 'me',
56
+ apDisplayName: null,
57
+ apSummary: null,
58
+ apNostrPubkey: null,
59
+
53
60
  // Invite-only registration
54
61
  inviteOnly: false,
55
62
 
@@ -89,6 +96,11 @@ const envMap = {
89
96
  JSS_NOSTR: 'nostr',
90
97
  JSS_NOSTR_PATH: 'nostrPath',
91
98
  JSS_NOSTR_MAX_EVENTS: 'nostrMaxEvents',
99
+ JSS_ACTIVITYPUB: 'activitypub',
100
+ JSS_AP_USERNAME: 'apUsername',
101
+ JSS_AP_DISPLAY_NAME: 'apDisplayName',
102
+ JSS_AP_SUMMARY: 'apSummary',
103
+ JSS_AP_NOSTR_PUBKEY: 'apNostrPubkey',
92
104
  JSS_INVITE_ONLY: 'inviteOnly',
93
105
  JSS_DEFAULT_QUOTA: 'defaultQuota',
94
106
  };