javascript-solid-server 0.0.12 → 0.0.15

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.
@@ -25,7 +25,33 @@
25
25
  "Bash(timeout 5 node:*)",
26
26
  "Bash(npm view:*)",
27
27
  "Bash(npm ls:*)",
28
- "Bash(timeout 10 node:*)"
28
+ "Bash(timeout 10 node:*)",
29
+ "Bash(npm run test:cth:*)",
30
+ "Bash(__NEW_LINE__ curl -s -X POST http://localhost:4000/.pods )",
31
+ "Bash(lsof:*)",
32
+ "Bash(xargs kill -9)",
33
+ "Bash(docker:*)",
34
+ "Bash(solidproject/conformance-test-harness )",
35
+ "Bash(timeout 30 node:*)",
36
+ "Bash(timeout 20 node:*)",
37
+ "Bash(timeout 25 node:*)",
38
+ "Bash(JSS_PORT=4000 JSS_CONNEG=true timeout 5 node:*)",
39
+ "Bash(pgrep:*)",
40
+ "Bash(python3:*)",
41
+ "Bash(ls:*)",
42
+ "Bash(timeout 15 node:*)",
43
+ "Bash(echo 'No .idp folder' echo find /home/melvin/remote/github.com/JavaScriptSolidServer/JavaScriptSolidServer/data/.idp/ -name *.json)",
44
+ "Bash(echo '=== Interactions ===' ls -la /home/melvin/remote/github.com/JavaScriptSolidServer/JavaScriptSolidServer/data/.idp/interaction/ echo echo '=== Latest interaction ===' cat /home/melvin/remote/github.com/JavaScriptSolidServer/JavaScriptSolidServer/data/.idp/interaction/*.json)",
45
+ "Bash(1 echo \"\" echo \"=== Server errors ===\" grep -E \"(error|Error)\" /tmp/jss.log)",
46
+ "Bash(echo 'Server not ready' curl -s -X POST http://localhost:4000/.pods -H 'Content-Type: application/json' -d {\"\"name\"\":\"\"alice\"\",\"\"email\"\":\"\"alice@example.com\"\",\"\"password\"\":\"\"alicepassword123\"\"})",
47
+ "Bash(head -1 curl -s -X POST http://localhost:4000/.pods -H \"Content-Type: application/json\" -d '{\"\"\"\"name\"\"\"\":\"\"\"\"bob\"\"\"\",\"\"\"\"email\"\"\"\":\"\"\"\"bob@example.com\"\"\"\",\"\"\"\"password\"\"\"\":\"\"\"\"bobpassword123\"\"\"\"}')",
48
+ "Bash(xargs:*)",
49
+ "Bash(fuser:*)",
50
+ "Bash(kill:*)",
51
+ "Bash(ACCESS_TOKEN=\"eyJhbGciOiJFUzI1NiIsImtpZCI6IjQwY2U0YzIzLWY2OWQtNDU4NS05ODg2LTE4MDQzZWIyZjU2ZCJ9.eyJpc3MiOiJodHRwOi8vbG9jYWxob3N0OjQwMDAvIiwic3ViIjoiYjhlZjY5YWUtODc0ZS00MDg5LThiMDktOGQwY2QyM2VlZWY3IiwiYXVkIjoic29saWQiLCJ3ZWJpZCI6Imh0dHA6Ly9sb2NhbGhvc3Q0MDAwL2FsaWNlLyNtZSIsImlhdCI6MTc2NjgyOTQ5MiwiZXhwIjoxNzY2ODMzMDkyLCJqdGkiOiIwMWY4ODVlZS05ZjY2LTQ3M2MtYmZkNC05MWM4ZGU3NGJhZjYiLCJjbGllbnRfaWQiOiJjcmVkZW50aWFsc19jbGllbnQiLCJzY29wZSI6Im9wZW5pZCB3ZWJpZCJ9.DYTlSRkORyDN28XtXk-zbR7xNLViD97KkPqUKb6chV860BaIgwa1suif4TxHQDnK_ejvbvmZ46_n5WwwRnf_Zw\" curl -sI -X PUT http://localhost:4000/alice/cth-test/ -H \"Content-Type: text/turtle\" -H \"Authorization: Bearer $ACCESS_TOKEN\")",
52
+ "Bash(timeout 60 docker run:*)",
53
+ "Bash(rm:*)",
54
+ "Bash(mkdir:*)"
29
55
  ]
30
56
  }
31
57
  }
package/CTH.md ADDED
@@ -0,0 +1,222 @@
1
+ # Running Solid Conformance Test Harness (CTH)
2
+
3
+ Step-by-step instructions for running the Solid Conformance Test Harness against this server.
4
+
5
+ ## Prerequisites
6
+
7
+ - Node.js 18+
8
+ - Docker
9
+ - Port 4000 available
10
+
11
+ ## Quick Start
12
+
13
+ ```bash
14
+ # 1. Kill any existing server on port 4000
15
+ fuser -k 4000/tcp 2>/dev/null || true
16
+
17
+ # 2. Clean data directory
18
+ rm -rf data && mkdir data
19
+
20
+ # 3. Start server with IdP and content negotiation
21
+ JSS_PORT=4000 JSS_CONNEG=true JSS_IDP=true node bin/jss.js start &
22
+
23
+ # 4. Wait for server to be ready
24
+ sleep 3
25
+ curl -s http://localhost:4000/ > /dev/null && echo "Server ready"
26
+
27
+ # 5. Create test users
28
+ curl -s -X POST http://localhost:4000/.pods \
29
+ -H "Content-Type: application/json" \
30
+ -d '{"name": "alice", "email": "alice@example.com", "password": "alicepassword123"}'
31
+
32
+ curl -s -X POST http://localhost:4000/.pods \
33
+ -H "Content-Type: application/json" \
34
+ -d '{"name": "bob", "email": "bob@example.com", "password": "bobpassword123"}'
35
+
36
+ # 6. Create test container (required by CTH)
37
+ mkdir -p data/alice/cth-test
38
+
39
+ # 7. Run authentication tests (assumes test-subjects.ttl and cth.env exist - see Configuration Files below)
40
+ docker run --rm --network=host \
41
+ -v $(pwd)/test-subjects.ttl:/app/test-subjects.ttl \
42
+ --env-file cth.env \
43
+ -e SUBJECTS=/app/test-subjects.ttl \
44
+ solidproject/conformance-test-harness:latest \
45
+ --target="https://github.com/solid/conformance-test-harness/jss" \
46
+ --filter="authentication"
47
+ ```
48
+
49
+ ## Configuration Files
50
+
51
+ ### Test Subjects File (test-subjects.ttl)
52
+
53
+ Create `test-subjects.ttl`:
54
+
55
+ ```turtle
56
+ @base <https://github.com/solid/conformance-test-harness/> .
57
+ @prefix solid-test: <https://github.com/solid/conformance-test-harness/vocab#> .
58
+ @prefix doap: <http://usefulinc.com/ns/doap#> .
59
+ @prefix earl: <http://www.w3.org/ns/earl#> .
60
+ @prefix xsd: <http://www.w3.org/2001/XMLSchema#> .
61
+
62
+ <jss>
63
+ a earl:Software, earl:TestSubject ;
64
+ doap:name "JavaScript Solid Server"@en ;
65
+ doap:release <jss#test-subject-release> ;
66
+ doap:developer <https://github.com/JavaScriptSolidServer> ;
67
+ doap:homepage <https://github.com/JavaScriptSolidServer/JavaScriptSolidServer> ;
68
+ doap:description "A minimal, fast, JSON-LD native Solid server."@en ;
69
+ doap:programming-language "JavaScript"@en ;
70
+ solid-test:skip "acp", "wac", "wac-allow-public" .
71
+
72
+ <jss#test-subject-release>
73
+ doap:revision "0.0.14"@en ;
74
+ doap:created "2025-12-27"^^xsd:date .
75
+ ```
76
+
77
+ ### Environment File (cth.env)
78
+
79
+ Create `cth.env`:
80
+
81
+ ```bash
82
+ SERVER_ROOT=http://localhost:4000
83
+ TEST_CONTAINER=/alice/cth-test/
84
+ RESOURCE_SERVER_ROOT=http://localhost:4000
85
+ LOGIN_ENDPOINT=http://localhost:4000/idp/credentials
86
+ SOLID_IDENTITY_PROVIDER=http://localhost:4000/
87
+ USERS_ALICE_IDP=http://localhost:4000/
88
+ USERS_BOB_IDP=http://localhost:4000/
89
+ USERS_ALICE_WEBID=http://localhost:4000/alice/#me
90
+ USERS_BOB_WEBID=http://localhost:4000/bob/#me
91
+ USERS_ALICE_USERNAME=alice@example.com
92
+ USERS_ALICE_PASSWORD=alicepassword123
93
+ USERS_BOB_USERNAME=bob@example.com
94
+ USERS_BOB_PASSWORD=bobpassword123
95
+ ```
96
+
97
+ ### Environment Variables Reference
98
+
99
+ | Variable | Description | Example |
100
+ |----------|-------------|---------|
101
+ | `SERVER_ROOT` | Server base URL | `http://localhost:4000` |
102
+ | `TEST_CONTAINER` | Path to test container | `/alice/cth-test/` |
103
+ | `SOLID_IDENTITY_PROVIDER` | IdP issuer URL (with trailing slash) | `http://localhost:4000/` |
104
+ | `USERS_ALICE_IDP` | Alice's IdP | `http://localhost:4000/` |
105
+ | `USERS_ALICE_WEBID` | Alice's WebID | `http://localhost:4000/alice/#me` |
106
+ | `USERS_ALICE_USERNAME` | Alice's email | `alice@example.com` |
107
+ | `USERS_ALICE_PASSWORD` | Alice's password | `alicepassword123` |
108
+ | `USERS_BOB_IDP` | Bob's IdP | `http://localhost:4000/` |
109
+ | `USERS_BOB_WEBID` | Bob's WebID | `http://localhost:4000/bob/#me` |
110
+ | `USERS_BOB_USERNAME` | Bob's email | `bob@example.com` |
111
+ | `USERS_BOB_PASSWORD` | Bob's password | `bobpassword123` |
112
+ | `SUBJECTS` | Path to test-subjects.ttl inside container | `/app/test-subjects.ttl` |
113
+
114
+ ## Running Specific Test Suites
115
+
116
+ ### Authentication Tests (6 scenarios)
117
+
118
+ ```bash
119
+ docker run --rm --network=host \
120
+ --env-file cth.env \
121
+ -v $(pwd)/test-subjects.ttl:/app/test-subjects.ttl \
122
+ -e SUBJECTS=/app/test-subjects.ttl \
123
+ solidproject/conformance-test-harness:latest \
124
+ --target="https://github.com/solid/conformance-test-harness/jss" \
125
+ --filter="authentication"
126
+ ```
127
+
128
+ **Expected result:** 6/6 scenarios passing
129
+
130
+ ### All Protocol Tests
131
+
132
+ ```bash
133
+ docker run --rm --network=host \
134
+ --env-file cth.env \
135
+ -v $(pwd)/test-subjects.ttl:/app/test-subjects.ttl \
136
+ -e SUBJECTS=/app/test-subjects.ttl \
137
+ solidproject/conformance-test-harness:latest \
138
+ --target="https://github.com/solid/conformance-test-harness/jss"
139
+ ```
140
+
141
+ ## Interpreting Results
142
+
143
+ ### Success Output
144
+
145
+ ```
146
+ scenarios: 6 | passed: 6 | failed: 0 | time: 0.6349
147
+ MustFeatures passed: 1, failed: 0
148
+ MustScenarios passed: 6, failed: 0
149
+ ```
150
+
151
+ ### Failure Output
152
+
153
+ ```
154
+ scenarios: 6 | passed: 4 | failed: 2 | time: 0.7952
155
+ Then status 401
156
+ status code was: 200, expected: 401, response time in milliseconds: 15
157
+ ```
158
+
159
+ ## Troubleshooting
160
+
161
+ ### "Cannot get ACL url for root test container"
162
+
163
+ The test container doesn't exist. Create it:
164
+
165
+ ```bash
166
+ mkdir -p data/alice/cth-test
167
+ ```
168
+
169
+ ### "Failed to read WebID Document" (401)
170
+
171
+ The WebID profile is not publicly readable. Check that the pod's ACL allows public read on the container itself (but not necessarily on children).
172
+
173
+ ### "NullPointerException" during authentication
174
+
175
+ Usually means the IdP isn't returning proper responses. Check:
176
+ 1. Server is running with `--idp` flag
177
+ 2. Issuer URL has trailing slash
178
+ 3. Users were created with email and password
179
+
180
+ ### "DPoP htu mismatch"
181
+
182
+ URL mismatch in DPoP proof validation. Check that issuer URL doesn't have double slashes.
183
+
184
+ ### Token format errors
185
+
186
+ Ensure the server returns JWT access tokens with:
187
+ - `aud: "solid"` claim
188
+ - 3-part JWT format (header.payload.signature)
189
+ - `webid` claim
190
+
191
+ ## Server Requirements for CTH
192
+
193
+ The server must support:
194
+
195
+ 1. **Solid-OIDC Identity Provider**
196
+ - OIDC discovery at `/.well-known/openid-configuration`
197
+ - JWKS at `/.well-known/jwks.json`
198
+ - Dynamic client registration at `/idp/reg`
199
+ - Credentials endpoint at `/idp/credentials` (for programmatic login)
200
+
201
+ 2. **DPoP Token Binding**
202
+ - RS256 and ES256 algorithms
203
+ - Proper `cnf.jkt` claim in tokens
204
+
205
+ 3. **WWW-Authenticate Header**
206
+ - 401 responses must include `WWW-Authenticate: DPoP realm="..."`
207
+
208
+ 4. **Container Creation via PUT**
209
+ - PUT to path ending with `/` creates container
210
+
211
+ 5. **ACL Inheritance**
212
+ - Children should NOT inherit public read by default
213
+ - Only owner permissions should have `acl:default`
214
+
215
+ ## Current CTH Status (v0.0.14)
216
+
217
+ | Test Suite | Status |
218
+ |------------|--------|
219
+ | Authentication | 6/6 passing |
220
+ | Protocol (other) | Not yet tested |
221
+ | WAC | Skipped |
222
+ | ACP | Skipped |
package/README.md CHANGED
@@ -54,7 +54,7 @@ npm run benchmark
54
54
 
55
55
  ## Features
56
56
 
57
- ### Implemented (v0.0.12)
57
+ ### Implemented (v0.0.15)
58
58
 
59
59
  - **LDP CRUD Operations** - GET, PUT, POST, DELETE, HEAD
60
60
  - **N3 Patch** - Solid's native patch format for RDF updates
@@ -306,6 +306,28 @@ Response:
306
306
 
307
307
  OIDC Discovery: `/.well-known/openid-configuration`
308
308
 
309
+ ### Programmatic Login (CTH Compatible)
310
+
311
+ For automated testing and scripts, use the credentials endpoint:
312
+
313
+ ```bash
314
+ curl -X POST http://localhost:3000/idp/credentials \
315
+ -H "Content-Type: application/json" \
316
+ -d '{"email": "alice@example.com", "password": "secret123"}'
317
+ ```
318
+
319
+ Response:
320
+ ```json
321
+ {
322
+ "access_token": "...",
323
+ "token_type": "Bearer",
324
+ "expires_in": 3600,
325
+ "webid": "http://localhost:3000/alice/#me"
326
+ }
327
+ ```
328
+
329
+ For DPoP-bound tokens (Solid-OIDC compliant), include a DPoP proof header.
330
+
309
331
  ### Solid-OIDC (External IdP)
310
332
 
311
333
  The server also accepts DPoP-bound access tokens from external Solid identity providers:
@@ -355,7 +377,38 @@ Server: pub http://localhost:3000/alice/public/data.json (on change)
355
377
  npm test
356
378
  ```
357
379
 
358
- Currently passing: **174 tests** (including 27 conformance tests)
380
+ Currently passing: **182 tests** (including 27 conformance tests)
381
+
382
+ ### Conformance Test Harness (CTH)
383
+
384
+ This server passes the Solid Conformance Test Harness authentication tests:
385
+
386
+ ```bash
387
+ # Start server with IdP and content negotiation
388
+ JSS_PORT=4000 JSS_CONNEG=true JSS_IDP=true jss start
389
+
390
+ # Create test users
391
+ curl -X POST http://localhost:4000/.pods \
392
+ -H "Content-Type: application/json" \
393
+ -d '{"name": "alice", "email": "alice@example.com", "password": "alicepassword123"}'
394
+
395
+ curl -X POST http://localhost:4000/.pods \
396
+ -H "Content-Type: application/json" \
397
+ -d '{"name": "bob", "email": "bob@example.com", "password": "bobpassword123"}'
398
+
399
+ # Run CTH authentication tests
400
+ docker run --rm --network=host \
401
+ -e SOLID_IDENTITY_PROVIDER="http://localhost:4000/" \
402
+ -e USERS_ALICE_WEBID="http://localhost:4000/alice/#me" \
403
+ -e USERS_ALICE_PASSWORD="alicepassword123" \
404
+ -e USERS_BOB_WEBID="http://localhost:4000/bob/#me" \
405
+ -e USERS_BOB_PASSWORD="bobpassword123" \
406
+ solidproject/conformance-test-harness:latest \
407
+ --filter="authentication"
408
+ ```
409
+
410
+ **CTH Status (v0.0.15):**
411
+ - Authentication tests: 6/6 passing
359
412
 
360
413
  ## Project Structure
361
414
 
package/bin/jss.js CHANGED
@@ -62,7 +62,11 @@ program
62
62
  const protocol = config.ssl ? 'https' : 'http';
63
63
  const serverHost = config.host === '0.0.0.0' ? 'localhost' : config.host;
64
64
  const baseUrl = `${protocol}://${serverHost}:${config.port}`;
65
- const idpIssuer = config.idpIssuer || baseUrl;
65
+ // Ensure issuer has trailing slash for CTH compatibility
66
+ let idpIssuer = config.idpIssuer || baseUrl;
67
+ if (idpIssuer && !idpIssuer.endsWith('/')) {
68
+ idpIssuer = idpIssuer + '/';
69
+ }
66
70
 
67
71
  // Create and start server
68
72
  const server = createServer({
@@ -0,0 +1,2 @@
1
+ subjects: file:/config/test-subjects.ttl
2
+ target: jss
@@ -0,0 +1,6 @@
1
+ @prefix test-harness: <https://github.com/solid-contrib/specification-tests/> .
2
+ @prefix solid-test: <https://github.com/solid-contrib/specification-tests/blob/main/vocab.ttl#> .
3
+
4
+ <jss>
5
+ a solid-test:TestSubject ;
6
+ solid-test:serverRoot <http://localhost:4000/> .
@@ -0,0 +1,14 @@
1
+ @prefix doap: <http://usefulinc.com/ns/doap#> .
2
+ @prefix earl: <http://www.w3.org/ns/earl#> .
3
+ @prefix solid-test: <https://github.com/solid-contrib/specification-tests/blob/main/vocab.ttl#> .
4
+ @prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#> .
5
+ @prefix xsd: <http://www.w3.org/2001/XMLSchema#> .
6
+
7
+ <jss>
8
+ a earl:Software, earl:TestSubject ;
9
+ doap:name "JavaScript Solid Server" ;
10
+ doap:description "A minimal, fast, JSON-LD native Solid server" ;
11
+ doap:programming-language "JavaScript" ;
12
+ solid-test:serverRoot <http://localhost:4000/> ;
13
+ solid-test:skip "acp" ;
14
+ rdfs:comment "Uses WAC for access control" .
package/cth.env ADDED
@@ -0,0 +1,19 @@
1
+ # CTH Environment for JSS
2
+ # Generated by test-cth-compat.js
3
+
4
+ SOLID_IDENTITY_PROVIDER=http://localhost:3456
5
+ RESOURCE_SERVER_ROOT=http://localhost:3456
6
+ TEST_CONTAINER=alice/public/
7
+
8
+ USERS_ALICE_WEBID=http://localhost:3456/alice/#me
9
+ USERS_ALICE_USERNAME=alice@test.local
10
+ USERS_ALICE_PASSWORD=alicepassword123
11
+
12
+ USERS_BOB_WEBID=http://localhost:3456/bob/#me
13
+ USERS_BOB_USERNAME=bob@test.local
14
+ USERS_BOB_PASSWORD=bobpassword123
15
+
16
+ LOGIN_ENDPOINT=http://localhost:3456/idp/credentials
17
+
18
+ # For self-signed certs
19
+ ALLOW_SELF_SIGNED_CERTS=true
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "javascript-solid-server",
3
- "version": "0.0.12",
3
+ "version": "0.0.15",
4
4
  "description": "A minimal, fast Solid server",
5
5
  "main": "src/index.js",
6
6
  "type": "module",
@@ -19,6 +19,7 @@
19
19
  "start": "node bin/jss.js start",
20
20
  "dev": "node --watch bin/jss.js start",
21
21
  "test": "node --test --test-concurrency=1",
22
+ "test:cth": "node scripts/test-cth-compat.js",
22
23
  "benchmark": "node benchmark.js"
23
24
  },
24
25
  "dependencies": {