javascript-solid-server 0.0.18 → 0.0.20

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.
Files changed (41) hide show
  1. package/.claude/settings.local.json +7 -1
  2. package/bin/jss.js +3 -0
  3. package/package.json +1 -1
  4. package/src/handlers/resource.js +48 -27
  5. package/src/ldp/headers.js +30 -0
  6. package/test/patch.test.js +8 -3
  7. package/test/sparql-update.test.js +8 -3
  8. package/test-data-idp-accounts/.idp/accounts/00f5d7c4-1da9-4e68-92c9-2b931f7c5750.json +9 -0
  9. package/test-data-idp-accounts/.idp/accounts/_email_index.json +1 -1
  10. package/test-data-idp-accounts/.idp/accounts/_webid_index.json +1 -1
  11. package/test-data-idp-accounts/.idp/keys/jwks.json +8 -8
  12. package/data/.idp/accounts/_email_index.json +0 -3
  13. package/data/.idp/accounts/_webid_index.json +0 -3
  14. package/data/.idp/accounts/be4cfcd3-f6dd-41de-b2f5-7e4045d3e78c.json +0 -9
  15. package/data/.idp/authorization_code/6MiwPzYssbmBMdZ0_yp9RUmeGKJpmChhcPNAT-xkwE1.json +0 -18
  16. package/data/.idp/authorization_code/eC1ZBx2mpNsr0OjKMKdkKK69E4EfKV1SwU8p0dWFQTj.json +0 -18
  17. package/data/.idp/authorization_code/puWy-HQtx9ONFDhm_Bv-sRcBfm3OQPppRalQ956hLR4.json +0 -18
  18. package/data/.idp/client/client_mjocmpsj_vdrkczw9.json +0 -25
  19. package/data/.idp/client/client_mjocnc8k_3sd1aoa6.json +0 -25
  20. package/data/.idp/client/client_mjocnlbf_dkm0ltze.json +0 -25
  21. package/data/.idp/grant/ImpM7BIsyKuhvme7UOctBmRUicTsZweHOrHk95wza0s.json +0 -16
  22. package/data/.idp/grant/R2aOui_2A-m6E_aeq_03IyMd6N5OrFJ-lT67cCTuzOL.json +0 -16
  23. package/data/.idp/grant/YFxdDUi4neEPXjx_riL4_Tyg_VXuyhax_qm9yFEvrWG.json +0 -16
  24. package/data/.idp/grant/k5rDpXSPbMMzYLaWILONhIojmzNP6f1hkWxajC_weW3.json +0 -16
  25. package/data/.idp/grant/luO7y4I33a7yWi1BnfgOtoNcr1-5vH8l3t-aIqG8IgI.json +0 -16
  26. package/data/.idp/grant/nkXTstzTTyrUEN5H0f8Q-YR5jMqk0WdDc6H6H1XD6lJ.json +0 -16
  27. package/data/.idp/registration_access_token/CPhAs33MGp8s-gCRvdnbqjdDDdi0g9vNwacfuLGhX6L.json +0 -7
  28. package/data/.idp/registration_access_token/dbOnxWLEW5O2_pYEfCFQJYbvpdqJJ_t35gr1dd7jC_6.json +0 -7
  29. package/data/.idp/registration_access_token/lAFc6diCNs1g9KLYHRD75O-cH5uv4dRX09HPIelMZbE.json +0 -7
  30. package/data/.idp/session/VXgvz6cHkuwDGG3Hp7CYWzck4AlTDH9qCOnCxVVAGOb.json +0 -28
  31. package/data/demo/.acl +0 -47
  32. package/data/demo/inbox/.acl +0 -50
  33. package/data/demo/index.html +0 -80
  34. package/data/demo/private/.acl +0 -32
  35. package/data/demo/public/.acl +0 -50
  36. package/data/demo/public/card.ttl +0 -8
  37. package/data/demo/settings/.acl +0 -32
  38. package/data/demo/settings/prefs +0 -17
  39. package/data/demo/settings/privateTypeIndex +0 -7
  40. package/data/demo/settings/publicTypeIndex +0 -7
  41. package/test-data-idp-accounts/.idp/accounts/b49949d9-6d61-45a1-bcee-07295aa07579.json +0 -9
@@ -59,7 +59,13 @@
59
59
  "Bash(pm2 list:*)",
60
60
  "Bash(pm2 logs:*)",
61
61
  "Bash(pm2 restart:*)",
62
- "Bash(timeout 60 npm test:*)"
62
+ "Bash(timeout 60 npm test:*)",
63
+ "Bash(pm2 stop:*)",
64
+ "Bash(pm2 delete:*)",
65
+ "Bash(pm2 start:*)",
66
+ "Bash(DATA_ROOT=/home/melvin/jss/data pm2 start:*)",
67
+ "Bash(pm2 save:*)",
68
+ "Bash(gh issue create:*)"
63
69
  ]
64
70
  }
65
71
  }
package/bin/jss.js CHANGED
@@ -59,6 +59,9 @@ program
59
59
  try {
60
60
  const config = await loadConfig(options, options.config);
61
61
 
62
+ // Set DATA_ROOT env var so all modules use the same data directory
63
+ process.env.DATA_ROOT = path.resolve(config.root);
64
+
62
65
  if (options.printConfig) {
63
66
  printConfig(config);
64
67
  process.exit(0);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "javascript-solid-server",
3
- "version": "0.0.18",
3
+ "version": "0.0.20",
4
4
  "description": "A minimal, fast Solid server",
5
5
  "main": "src/index.js",
6
6
  "type": "module",
@@ -1,5 +1,5 @@
1
1
  import * as storage from '../storage/filesystem.js';
2
- import { getAllHeaders } from '../ldp/headers.js';
2
+ import { getAllHeaders, getNotFoundHeaders } from '../ldp/headers.js';
3
3
  import { generateContainerJsonLd, serializeJsonLd } from '../ldp/container.js';
4
4
  import { isContainer, getContentType, isRdfContentType, getEffectiveUrlPath } from '../utils/url.js';
5
5
  import { parseN3Patch, applyN3Patch, validatePatch } from '../patch/n3-patch.js';
@@ -37,6 +37,10 @@ export async function handleGet(request, reply) {
37
37
  const stats = await storage.stat(storagePath);
38
38
 
39
39
  if (!stats) {
40
+ const origin = request.headers.origin;
41
+ const connegEnabled = request.connegEnabled || false;
42
+ const headers = getNotFoundHeaders({ resourceUrl, origin, connegEnabled });
43
+ Object.entries(headers).forEach(([k, v]) => reply.header(k, v));
40
44
  return reply.code(404).send({ error: 'Not Found' });
41
45
  }
42
46
 
@@ -219,6 +223,10 @@ export async function handleHead(request, reply) {
219
223
  const stats = await storage.stat(storagePath);
220
224
 
221
225
  if (!stats) {
226
+ const origin = request.headers.origin;
227
+ const connegEnabled = request.connegEnabled || false;
228
+ const headers = getNotFoundHeaders({ resourceUrl, origin, connegEnabled });
229
+ Object.entries(headers).forEach(([k, v]) => reply.header(k, v));
222
230
  return reply.code(404).send();
223
231
  }
224
232
 
@@ -366,6 +374,10 @@ export async function handleDelete(request, reply) {
366
374
  // Check if resource exists and get current ETag
367
375
  const stats = await storage.stat(storagePath);
368
376
  if (!stats) {
377
+ const origin = request.headers.origin;
378
+ const connegEnabled = request.connegEnabled || false;
379
+ const headers = getNotFoundHeaders({ resourceUrl, origin, connegEnabled });
380
+ Object.entries(headers).forEach(([k, v]) => reply.header(k, v));
369
381
  return reply.code(404).send({ error: 'Not Found' });
370
382
  }
371
383
 
@@ -439,36 +451,44 @@ export async function handlePatch(request, reply) {
439
451
  });
440
452
  }
441
453
 
442
- // Check if resource exists
454
+ // Check if resource exists - PATCH can create resources in Solid
443
455
  const stats = await storage.stat(storagePath);
444
- if (!stats) {
445
- return reply.code(404).send({ error: 'Not Found' });
446
- }
447
-
448
- // Check If-Match header (for safe updates)
449
- const ifMatch = request.headers['if-match'];
450
- if (ifMatch) {
451
- const check = checkIfMatch(ifMatch, stats.etag);
452
- if (!check.ok) {
453
- return reply.code(check.status).send({ error: check.error });
456
+ const resourceExists = !!stats;
457
+
458
+ // Check If-Match header (for safe updates) - only if resource exists
459
+ if (resourceExists) {
460
+ const ifMatch = request.headers['if-match'];
461
+ if (ifMatch) {
462
+ const check = checkIfMatch(ifMatch, stats.etag);
463
+ if (!check.ok) {
464
+ return reply.code(check.status).send({ error: check.error });
465
+ }
454
466
  }
455
467
  }
456
468
 
457
- // Read existing content
458
- const existingContent = await storage.read(storagePath);
459
- if (existingContent === null) {
460
- return reply.code(500).send({ error: 'Read error' });
461
- }
462
-
463
- // Parse existing document as JSON-LD
469
+ // Read existing content or start with empty JSON-LD document
464
470
  let document;
465
- try {
466
- document = JSON.parse(existingContent.toString());
467
- } catch (e) {
468
- return reply.code(409).send({
469
- error: 'Conflict',
470
- message: 'Resource is not valid JSON-LD and cannot be patched'
471
- });
471
+ if (resourceExists) {
472
+ const existingContent = await storage.read(storagePath);
473
+ if (existingContent === null) {
474
+ return reply.code(500).send({ error: 'Read error' });
475
+ }
476
+
477
+ // Parse existing document as JSON-LD
478
+ try {
479
+ document = JSON.parse(existingContent.toString());
480
+ } catch (e) {
481
+ return reply.code(409).send({
482
+ error: 'Conflict',
483
+ message: 'Resource is not valid JSON-LD and cannot be patched'
484
+ });
485
+ }
486
+ } else {
487
+ // Create empty JSON-LD document for new resource
488
+ document = {
489
+ '@context': {},
490
+ '@graph': []
491
+ };
472
492
  }
473
493
 
474
494
  // Parse the patch
@@ -537,5 +557,6 @@ export async function handlePatch(request, reply) {
537
557
  emitChange(resourceUrl);
538
558
  }
539
559
 
540
- return reply.code(204).send();
560
+ // Return 201 Created if resource was created, 204 No Content if updated
561
+ return reply.code(resourceExists ? 204 : 201).send();
541
562
  }
@@ -108,3 +108,33 @@ export function getAllHeaders({ isContainer = false, etag = null, contentType =
108
108
  ...getCorsHeaders(origin)
109
109
  };
110
110
  }
111
+
112
+ /**
113
+ * Get headers for 404 responses (non-existent resources)
114
+ * These headers tell clients what methods are supported for creating the resource
115
+ * @param {object} options
116
+ * @returns {object}
117
+ */
118
+ export function getNotFoundHeaders({ resourceUrl = null, origin = null, connegEnabled = false }) {
119
+ // Determine if this would be a container based on URL ending with /
120
+ const isContainer = resourceUrl?.endsWith('/') || false;
121
+ const aclUrl = resourceUrl ? getAclUrl(resourceUrl, isContainer) : null;
122
+
123
+ // Get Accept-* headers
124
+ const acceptHeaders = getAcceptHeaders(connegEnabled, isContainer);
125
+
126
+ const headers = {
127
+ ...getCorsHeaders(origin),
128
+ 'Link': aclUrl ? `<${aclUrl}>; rel="acl"` : '',
129
+ 'Accept-Patch': 'text/n3, application/sparql-update',
130
+ 'Accept-Put': acceptHeaders['Accept-Put'] || 'application/ld+json, */*',
131
+ 'Allow': 'GET, HEAD, PUT, PATCH, OPTIONS' + (isContainer ? ', POST' : ''),
132
+ 'Vary': connegEnabled ? 'Accept, Authorization, Origin' : 'Authorization, Origin'
133
+ };
134
+
135
+ if (isContainer && acceptHeaders['Accept-Post']) {
136
+ headers['Accept-Post'] = acceptHeaders['Accept-Post'];
137
+ }
138
+
139
+ return headers;
140
+ }
@@ -207,21 +207,26 @@ describe('PATCH Operations', () => {
207
207
  assertStatus(res, 415);
208
208
  });
209
209
 
210
- it('should return 404 for non-existent resource', async () => {
210
+ it('should create resource if it does not exist', async () => {
211
211
  const patch = `
212
212
  @prefix solid: <http://www.w3.org/ns/solid/terms#>.
213
213
  _:patch a solid:InsertDeletePatch;
214
214
  solid:inserts { <#me> <http://example.org/p> "test" }.
215
215
  `;
216
216
 
217
- const res = await request('/patchtest/public/nonexistent.json', {
217
+ const res = await request('/patchtest/public/patch-created.json', {
218
218
  method: 'PATCH',
219
219
  headers: { 'Content-Type': 'text/n3' },
220
220
  body: patch,
221
221
  auth: 'patchtest'
222
222
  });
223
223
 
224
- assertStatus(res, 404);
224
+ // PATCH creates resources in Solid
225
+ assertStatus(res, 201);
226
+
227
+ // Verify resource was created with the inserted data
228
+ const getRes = await request('/patchtest/public/patch-created.json');
229
+ assertStatus(getRes, 200);
225
230
  });
226
231
 
227
232
  it('should return 409 when patching non-JSON-LD resource', async () => {
@@ -157,15 +157,20 @@ describe('SPARQL Update', () => {
157
157
  });
158
158
 
159
159
  describe('Error handling', () => {
160
- it('should return 404 for non-existent resource', async () => {
160
+ it('should create resource if it does not exist', async () => {
161
161
  const sparql = `INSERT DATA { <#x> <http://example.org/p> "v" }`;
162
- const res = await request('/sparqltest/public/nonexistent.json', {
162
+ const res = await request('/sparqltest/public/sparql-created.json', {
163
163
  method: 'PATCH',
164
164
  headers: { 'Content-Type': 'application/sparql-update' },
165
165
  body: sparql,
166
166
  auth: 'sparqltest'
167
167
  });
168
- assertStatus(res, 404);
168
+ // PATCH creates resources in Solid
169
+ assertStatus(res, 201);
170
+
171
+ // Verify resource was created
172
+ const getRes = await request('/sparqltest/public/sparql-created.json');
173
+ assertStatus(getRes, 200);
169
174
  });
170
175
 
171
176
  it('should return 415 for unsupported content type', async () => {
@@ -0,0 +1,9 @@
1
+ {
2
+ "id": "00f5d7c4-1da9-4e68-92c9-2b931f7c5750",
3
+ "email": "credtest@example.com",
4
+ "passwordHash": "$2b$10$oH0fl4a/riqSc4oXZ1pmLuSQOP9AlRSSrOMg7OlP5O2m.C39mOTL6",
5
+ "webId": "http://localhost:3101/credtest/#me",
6
+ "podName": "credtest",
7
+ "createdAt": "2025-12-27T14:04:29.630Z",
8
+ "lastLogin": "2025-12-27T14:04:29.865Z"
9
+ }
@@ -1,3 +1,3 @@
1
1
  {
2
- "credtest@example.com": "b49949d9-6d61-45a1-bcee-07295aa07579"
2
+ "credtest@example.com": "00f5d7c4-1da9-4e68-92c9-2b931f7c5750"
3
3
  }
@@ -1,3 +1,3 @@
1
1
  {
2
- "http://localhost:3101/credtest/#me": "b49949d9-6d61-45a1-bcee-07295aa07579"
2
+ "http://localhost:3101/credtest/#me": "00f5d7c4-1da9-4e68-92c9-2b931f7c5750"
3
3
  }
@@ -3,20 +3,20 @@
3
3
  "keys": [
4
4
  {
5
5
  "kty": "EC",
6
- "x": "LAyVHoAoNTkPv1-7GonFPGYWWh2Oo8W1bxWFGdX8fW8",
7
- "y": "bntHv0EpOcvKrzlGujXkBID_7iHmp9wFte4heIrzf3Y",
6
+ "x": "qUZf3Zu9iULTVgQu_ARo02vLb7MedW9t3jzW6EykbAc",
7
+ "y": "f7fkZpYdSy-m_0vhcw1l5wh4nnHmWLtuw9DEfZNqMyI",
8
8
  "crv": "P-256",
9
- "d": "V6umt-paD0-Uk9SA-0NYZHZSOz0h9OZppYwopeZXedo",
10
- "kid": "1c8e0740-f688-4a68-8231-8d2388dcd810",
9
+ "d": "711_8EPt8sDLyzDB174cNsAGvkIdZLMZKPlH-kFZ270",
10
+ "kid": "af8ee1cc-110c-4e6e-bd2a-12fd7690c20c",
11
11
  "use": "sig",
12
12
  "alg": "ES256",
13
- "iat": 1766842823
13
+ "iat": 1766844269
14
14
  }
15
15
  ]
16
16
  },
17
17
  "cookieKeys": [
18
- "pq7a_Nu9u72ZeHdklGCnSocY9z4nyAkk0ZuUBU8YH7U",
19
- "RzXV-DugE1lvl331HZ5Fo04A5UY2GLJn4MjAqcAZ8Ts"
18
+ "vgN9MVzjMn5ehD1LoDQVnDO_kkTdmCmQbOFhjxwJMnE",
19
+ "x8blYyo4zMs0Vm8sXy1XFDeKPIMD34yPw1_LO1vv5z4"
20
20
  ],
21
- "createdAt": "2025-12-27T13:40:23.081Z"
21
+ "createdAt": "2025-12-27T14:04:29.573Z"
22
22
  }
@@ -1,3 +0,0 @@
1
- {
2
- "demo@example.com": "be4cfcd3-f6dd-41de-b2f5-7e4045d3e78c"
3
- }
@@ -1,3 +0,0 @@
1
- {
2
- "http://localhost:4000/demo/#me": "be4cfcd3-f6dd-41de-b2f5-7e4045d3e78c"
3
- }
@@ -1,9 +0,0 @@
1
- {
2
- "id": "be4cfcd3-f6dd-41de-b2f5-7e4045d3e78c",
3
- "email": "demo@example.com",
4
- "passwordHash": "$2b$10$oNs/bKRsayWfBVgQBmjgEeyo0vt65Borrwhru3huSbA6.U9TyBerq",
5
- "webId": "http://localhost:4000/demo/#me",
6
- "podName": "demo",
7
- "createdAt": "2025-12-27T13:40:57.822Z",
8
- "lastLogin": "2025-12-27T13:41:20.530Z"
9
- }
@@ -1,18 +0,0 @@
1
- {
2
- "iat": 1766842885,
3
- "exp": 1766843485,
4
- "accountId": "be4cfcd3-f6dd-41de-b2f5-7e4045d3e78c",
5
- "authTime": 1766842885,
6
- "codeChallenge": "lFETalcnuAuriGuAQvsKeZcYVW-pRv-Hz5MTPXDj7r0",
7
- "codeChallengeMethod": "S256",
8
- "grantId": "ImpM7BIsyKuhvme7UOctBmRUicTsZweHOrHk95wza0s",
9
- "redirectUri": "http://localhost:4000/demo/public/card.ttl",
10
- "resource": "urn:solid",
11
- "scope": "openid offline_access webid",
12
- "sessionUid": "4uEOfXb2Z3tCyhmDQuG53CpYdqkNf2FfaejZWA-xnqf",
13
- "kind": "AuthorizationCode",
14
- "jti": "6MiwPzYssbmBMdZ0_yp9RUmeGKJpmChhcPNAT-xkwE1",
15
- "clientId": "client_mjocmpsj_vdrkczw9",
16
- "_id": "6MiwPzYssbmBMdZ0_yp9RUmeGKJpmChhcPNAT-xkwE1",
17
- "_expiresAt": 1766843485104
18
- }
@@ -1,18 +0,0 @@
1
- {
2
- "iat": 1766842921,
3
- "exp": 1766843521,
4
- "accountId": "be4cfcd3-f6dd-41de-b2f5-7e4045d3e78c",
5
- "authTime": 1766842885,
6
- "codeChallenge": "BqdP4MPCzvEmeNtCuKNperx_wpsUZSd41h31qsKrjHs",
7
- "codeChallengeMethod": "S256",
8
- "grantId": "YFxdDUi4neEPXjx_riL4_Tyg_VXuyhax_qm9yFEvrWG",
9
- "redirectUri": "http://localhost:4000/demo/public/card.ttl",
10
- "resource": "urn:solid",
11
- "scope": "openid offline_access webid",
12
- "sessionUid": "4uEOfXb2Z3tCyhmDQuG53CpYdqkNf2FfaejZWA-xnqf",
13
- "kind": "AuthorizationCode",
14
- "jti": "eC1ZBx2mpNsr0OjKMKdkKK69E4EfKV1SwU8p0dWFQTj",
15
- "clientId": "client_mjocnlbf_dkm0ltze",
16
- "_id": "eC1ZBx2mpNsr0OjKMKdkKK69E4EfKV1SwU8p0dWFQTj",
17
- "_expiresAt": 1766843521653
18
- }
@@ -1,18 +0,0 @@
1
- {
2
- "iat": 1766842908,
3
- "exp": 1766843508,
4
- "accountId": "be4cfcd3-f6dd-41de-b2f5-7e4045d3e78c",
5
- "authTime": 1766842885,
6
- "codeChallenge": "8mhdOmnnCBhXBjFUC_tIfIle7O4i-ySSck_ZNnAM-TI",
7
- "codeChallengeMethod": "S256",
8
- "grantId": "R2aOui_2A-m6E_aeq_03IyMd6N5OrFJ-lT67cCTuzOL",
9
- "redirectUri": "http://localhost:4000/demo/public/card.ttl",
10
- "resource": "urn:solid",
11
- "scope": "openid offline_access webid",
12
- "sessionUid": "4uEOfXb2Z3tCyhmDQuG53CpYdqkNf2FfaejZWA-xnqf",
13
- "kind": "AuthorizationCode",
14
- "jti": "puWy-HQtx9ONFDhm_Bv-sRcBfm3OQPppRalQ956hLR4",
15
- "clientId": "client_mjocnc8k_3sd1aoa6",
16
- "_id": "puWy-HQtx9ONFDhm_Bv-sRcBfm3OQPppRalQ956hLR4",
17
- "_expiresAt": 1766843508522
18
- }
@@ -1,25 +0,0 @@
1
- {
2
- "application_type": "web",
3
- "grant_types": [
4
- "authorization_code",
5
- "refresh_token"
6
- ],
7
- "id_token_signed_response_alg": "ES256",
8
- "require_auth_time": false,
9
- "response_types": [
10
- "code"
11
- ],
12
- "subject_type": "public",
13
- "token_endpoint_auth_method": "client_secret_basic",
14
- "post_logout_redirect_uris": [],
15
- "require_pushed_authorization_requests": false,
16
- "dpop_bound_access_tokens": false,
17
- "client_id_issued_at": 1766842877,
18
- "client_id": "client_mjocmpsj_vdrkczw9",
19
- "client_secret_expires_at": 0,
20
- "client_secret": "uab7wwtWjqbYV6wpBcVyIo0pDhU7COlN2WEJ5AOr4EX2lmKmY3gxvGpb_YGs09ysVM9RiHs3pO0EsVIEW98XaQ",
21
- "redirect_uris": [
22
- "http://localhost:4000/demo/public/card.ttl"
23
- ],
24
- "_id": "client_mjocmpsj_vdrkczw9"
25
- }
@@ -1,25 +0,0 @@
1
- {
2
- "application_type": "web",
3
- "grant_types": [
4
- "authorization_code",
5
- "refresh_token"
6
- ],
7
- "id_token_signed_response_alg": "ES256",
8
- "require_auth_time": false,
9
- "response_types": [
10
- "code"
11
- ],
12
- "subject_type": "public",
13
- "token_endpoint_auth_method": "client_secret_basic",
14
- "post_logout_redirect_uris": [],
15
- "require_pushed_authorization_requests": false,
16
- "dpop_bound_access_tokens": false,
17
- "client_id_issued_at": 1766842907,
18
- "client_id": "client_mjocnc8k_3sd1aoa6",
19
- "client_secret_expires_at": 0,
20
- "client_secret": "bDLVLSo0s3P7u93bfPDrLw74PAaq8hguSjVfanz0il6V9cCFLshHECGUuNKA8fhgIpCuzdqOX2aBXv8jHwEL2g",
21
- "redirect_uris": [
22
- "http://localhost:4000/demo/public/card.ttl"
23
- ],
24
- "_id": "client_mjocnc8k_3sd1aoa6"
25
- }
@@ -1,25 +0,0 @@
1
- {
2
- "application_type": "web",
3
- "grant_types": [
4
- "authorization_code",
5
- "refresh_token"
6
- ],
7
- "id_token_signed_response_alg": "ES256",
8
- "require_auth_time": false,
9
- "response_types": [
10
- "code"
11
- ],
12
- "subject_type": "public",
13
- "token_endpoint_auth_method": "client_secret_basic",
14
- "post_logout_redirect_uris": [],
15
- "require_pushed_authorization_requests": false,
16
- "dpop_bound_access_tokens": false,
17
- "client_id_issued_at": 1766842918,
18
- "client_id": "client_mjocnlbf_dkm0ltze",
19
- "client_secret_expires_at": 0,
20
- "client_secret": "ag53idPGzSjObWZSvKjxAmaNTsF7p6o8YSwf-3RRucHfTDe-kTmlGU6DYrjqo4qlmWGbWB1jRuCZY8OByg6rqw",
21
- "redirect_uris": [
22
- "http://localhost:4000/demo/public/card.ttl"
23
- ],
24
- "_id": "client_mjocnlbf_dkm0ltze"
25
- }
@@ -1,16 +0,0 @@
1
- {
2
- "iat": 1766842880,
3
- "exp": 1768052480,
4
- "accountId": "be4cfcd3-f6dd-41de-b2f5-7e4045d3e78c",
5
- "clientId": "client_mjocmpsj_vdrkczw9",
6
- "kind": "Grant",
7
- "jti": "ImpM7BIsyKuhvme7UOctBmRUicTsZweHOrHk95wza0s",
8
- "openid": {
9
- "scope": "openid offline_access webid"
10
- },
11
- "resources": {
12
- "urn:solid": "openid offline_access webid"
13
- },
14
- "_id": "ImpM7BIsyKuhvme7UOctBmRUicTsZweHOrHk95wza0s",
15
- "_expiresAt": 1768052480543
16
- }
@@ -1,16 +0,0 @@
1
- {
2
- "iat": 1766842907,
3
- "exp": 1768052507,
4
- "accountId": "be4cfcd3-f6dd-41de-b2f5-7e4045d3e78c",
5
- "clientId": "client_mjocnc8k_3sd1aoa6",
6
- "kind": "Grant",
7
- "jti": "R2aOui_2A-m6E_aeq_03IyMd6N5OrFJ-lT67cCTuzOL",
8
- "openid": {
9
- "scope": "openid offline_access webid"
10
- },
11
- "resources": {
12
- "urn:solid": "openid offline_access webid"
13
- },
14
- "_id": "R2aOui_2A-m6E_aeq_03IyMd6N5OrFJ-lT67cCTuzOL",
15
- "_expiresAt": 1768052507087
16
- }
@@ -1,16 +0,0 @@
1
- {
2
- "iat": 1766842918,
3
- "exp": 1768052518,
4
- "accountId": "be4cfcd3-f6dd-41de-b2f5-7e4045d3e78c",
5
- "clientId": "client_mjocnlbf_dkm0ltze",
6
- "kind": "Grant",
7
- "jti": "YFxdDUi4neEPXjx_riL4_Tyg_VXuyhax_qm9yFEvrWG",
8
- "openid": {
9
- "scope": "openid offline_access webid"
10
- },
11
- "resources": {
12
- "urn:solid": "openid offline_access webid"
13
- },
14
- "_id": "YFxdDUi4neEPXjx_riL4_Tyg_VXuyhax_qm9yFEvrWG",
15
- "_expiresAt": 1768052518858
16
- }
@@ -1,16 +0,0 @@
1
- {
2
- "iat": 1766842885,
3
- "exp": 1768052485,
4
- "accountId": "be4cfcd3-f6dd-41de-b2f5-7e4045d3e78c",
5
- "clientId": "client_mjocmpsj_vdrkczw9",
6
- "kind": "Grant",
7
- "jti": "k5rDpXSPbMMzYLaWILONhIojmzNP6f1hkWxajC_weW3",
8
- "openid": {
9
- "scope": "openid offline_access webid"
10
- },
11
- "resources": {
12
- "urn:solid": "openid offline_access webid"
13
- },
14
- "_id": "k5rDpXSPbMMzYLaWILONhIojmzNP6f1hkWxajC_weW3",
15
- "_expiresAt": 1768052485093
16
- }
@@ -1,16 +0,0 @@
1
- {
2
- "iat": 1766842921,
3
- "exp": 1768052521,
4
- "accountId": "be4cfcd3-f6dd-41de-b2f5-7e4045d3e78c",
5
- "clientId": "client_mjocnlbf_dkm0ltze",
6
- "kind": "Grant",
7
- "jti": "luO7y4I33a7yWi1BnfgOtoNcr1-5vH8l3t-aIqG8IgI",
8
- "openid": {
9
- "scope": "openid offline_access webid"
10
- },
11
- "resources": {
12
- "urn:solid": "openid offline_access webid"
13
- },
14
- "_id": "luO7y4I33a7yWi1BnfgOtoNcr1-5vH8l3t-aIqG8IgI",
15
- "_expiresAt": 1768052521645
16
- }
@@ -1,16 +0,0 @@
1
- {
2
- "iat": 1766842908,
3
- "exp": 1768052508,
4
- "accountId": "be4cfcd3-f6dd-41de-b2f5-7e4045d3e78c",
5
- "clientId": "client_mjocnc8k_3sd1aoa6",
6
- "kind": "Grant",
7
- "jti": "nkXTstzTTyrUEN5H0f8Q-YR5jMqk0WdDc6H6H1XD6lJ",
8
- "openid": {
9
- "scope": "openid offline_access webid"
10
- },
11
- "resources": {
12
- "urn:solid": "openid offline_access webid"
13
- },
14
- "_id": "nkXTstzTTyrUEN5H0f8Q-YR5jMqk0WdDc6H6H1XD6lJ",
15
- "_expiresAt": 1768052508513
16
- }
@@ -1,7 +0,0 @@
1
- {
2
- "iat": 1766842907,
3
- "clientId": "client_mjocnc8k_3sd1aoa6",
4
- "kind": "RegistrationAccessToken",
5
- "jti": "CPhAs33MGp8s-gCRvdnbqjdDDdi0g9vNwacfuLGhX6L",
6
- "_id": "CPhAs33MGp8s-gCRvdnbqjdDDdi0g9vNwacfuLGhX6L"
7
- }
@@ -1,7 +0,0 @@
1
- {
2
- "iat": 1766842918,
3
- "clientId": "client_mjocnlbf_dkm0ltze",
4
- "kind": "RegistrationAccessToken",
5
- "jti": "dbOnxWLEW5O2_pYEfCFQJYbvpdqJJ_t35gr1dd7jC_6",
6
- "_id": "dbOnxWLEW5O2_pYEfCFQJYbvpdqJJ_t35gr1dd7jC_6"
7
- }
@@ -1,7 +0,0 @@
1
- {
2
- "iat": 1766842877,
3
- "clientId": "client_mjocmpsj_vdrkczw9",
4
- "kind": "RegistrationAccessToken",
5
- "jti": "lAFc6diCNs1g9KLYHRD75O-cH5uv4dRX09HPIelMZbE",
6
- "_id": "lAFc6diCNs1g9KLYHRD75O-cH5uv4dRX09HPIelMZbE"
7
- }
@@ -1,28 +0,0 @@
1
- {
2
- "iat": 1766842880,
3
- "exp": 1768052521,
4
- "uid": "4uEOfXb2Z3tCyhmDQuG53CpYdqkNf2FfaejZWA-xnqf",
5
- "accountId": "be4cfcd3-f6dd-41de-b2f5-7e4045d3e78c",
6
- "loginTs": 1766842885,
7
- "authorizations": {
8
- "client_mjocmpsj_vdrkczw9": {
9
- "sid": "p_xkvzyOVCJq5ZLXM2vmqjV35OIzrYbsqAXzUvpknIc",
10
- "grantId": "ImpM7BIsyKuhvme7UOctBmRUicTsZweHOrHk95wza0s",
11
- "persistsLogout": true
12
- },
13
- "client_mjocnc8k_3sd1aoa6": {
14
- "sid": "1SAM86GitibwBsMx8QL-9VCt9Wws4Yq4VMJn4Swf1OY",
15
- "grantId": "R2aOui_2A-m6E_aeq_03IyMd6N5OrFJ-lT67cCTuzOL",
16
- "persistsLogout": true
17
- },
18
- "client_mjocnlbf_dkm0ltze": {
19
- "sid": "NuauxuaSNFbSm9ksu10YakHKPm7zhCcEqhLgM51b90b",
20
- "grantId": "YFxdDUi4neEPXjx_riL4_Tyg_VXuyhax_qm9yFEvrWG",
21
- "persistsLogout": true
22
- }
23
- },
24
- "kind": "Session",
25
- "jti": "VXgvz6cHkuwDGG3Hp7CYWzck4AlTDH9qCOnCxVVAGOb",
26
- "_id": "VXgvz6cHkuwDGG3Hp7CYWzck4AlTDH9qCOnCxVVAGOb",
27
- "_expiresAt": 1768052521654
28
- }
package/data/demo/.acl DELETED
@@ -1,47 +0,0 @@
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": "#owner",
9
- "@type": "acl:Authorization",
10
- "acl:agent": {
11
- "@id": "http://localhost:4000/demo/#me"
12
- },
13
- "acl:accessTo": {
14
- "@id": "http://localhost:4000/demo/"
15
- },
16
- "acl:mode": [
17
- {
18
- "@id": "acl:Read"
19
- },
20
- {
21
- "@id": "acl:Write"
22
- },
23
- {
24
- "@id": "acl:Control"
25
- }
26
- ],
27
- "acl:default": {
28
- "@id": "http://localhost:4000/demo/"
29
- }
30
- },
31
- {
32
- "@id": "#public",
33
- "@type": "acl:Authorization",
34
- "acl:agentClass": {
35
- "@id": "foaf:Agent"
36
- },
37
- "acl:accessTo": {
38
- "@id": "http://localhost:4000/demo/"
39
- },
40
- "acl:mode": [
41
- {
42
- "@id": "acl:Read"
43
- }
44
- ]
45
- }
46
- ]
47
- }
@@ -1,50 +0,0 @@
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": "#owner",
9
- "@type": "acl:Authorization",
10
- "acl:agent": {
11
- "@id": "http://localhost:4000/demo/#me"
12
- },
13
- "acl:accessTo": {
14
- "@id": "http://localhost:4000/demo/inbox/"
15
- },
16
- "acl:default": {
17
- "@id": "http://localhost:4000/demo/inbox/"
18
- },
19
- "acl:mode": [
20
- {
21
- "@id": "acl:Read"
22
- },
23
- {
24
- "@id": "acl:Write"
25
- },
26
- {
27
- "@id": "acl:Control"
28
- }
29
- ]
30
- },
31
- {
32
- "@id": "#public",
33
- "@type": "acl:Authorization",
34
- "acl:agentClass": {
35
- "@id": "foaf:Agent"
36
- },
37
- "acl:accessTo": {
38
- "@id": "http://localhost:4000/demo/inbox/"
39
- },
40
- "acl:default": {
41
- "@id": "http://localhost:4000/demo/inbox/"
42
- },
43
- "acl:mode": [
44
- {
45
- "@id": "acl:Append"
46
- }
47
- ]
48
- }
49
- ]
50
- }
@@ -1,80 +0,0 @@
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>demo's Profile</title>
7
- <script type="application/ld+json">
8
- {
9
- "@context": {
10
- "foaf": "http://xmlns.com/foaf/0.1/",
11
- "solid": "http://www.w3.org/ns/solid/terms#",
12
- "schema": "http://schema.org/",
13
- "pim": "http://www.w3.org/ns/pim/space#",
14
- "ldp": "http://www.w3.org/ns/ldp#",
15
- "inbox": {
16
- "@id": "ldp:inbox",
17
- "@type": "@id"
18
- },
19
- "storage": {
20
- "@id": "pim:storage",
21
- "@type": "@id"
22
- },
23
- "oidcIssuer": {
24
- "@id": "solid:oidcIssuer",
25
- "@type": "@id"
26
- },
27
- "preferencesFile": {
28
- "@id": "pim:preferencesFile",
29
- "@type": "@id"
30
- }
31
- },
32
- "@graph": [
33
- {
34
- "@id": "http://localhost:4000/demo/",
35
- "@type": "foaf:PersonalProfileDocument",
36
- "foaf:maker": {
37
- "@id": "http://localhost:4000/demo/#me"
38
- },
39
- "foaf:primaryTopic": {
40
- "@id": "http://localhost:4000/demo/#me"
41
- }
42
- },
43
- {
44
- "@id": "http://localhost:4000/demo/#me",
45
- "@type": [
46
- "foaf:Person",
47
- "schema:Person"
48
- ],
49
- "foaf:name": "demo",
50
- "inbox": "http://localhost:4000/demo/inbox/",
51
- "storage": "http://localhost:4000/demo/",
52
- "oidcIssuer": "http://localhost:4000/",
53
- "preferencesFile": "http://localhost:4000/demo/settings/prefs"
54
- }
55
- ]
56
- }
57
- </script>
58
- <style>
59
- body { font-family: system-ui, sans-serif; max-width: 600px; margin: 2rem auto; padding: 0 1rem; }
60
- h1 { color: #333; }
61
- .card { background: #f5f5f5; padding: 1.5rem; border-radius: 8px; }
62
- dt { font-weight: bold; margin-top: 1rem; }
63
- dd { margin-left: 0; color: #666; }
64
- a { color: #7c4dff; }
65
- </style>
66
- </head>
67
- <body>
68
- <div class="card">
69
- <h1>demo</h1>
70
- <dl>
71
- <dt>WebID</dt>
72
- <dd><a href="http://localhost:4000/demo/#me">http://localhost:4000/demo/#me</a></dd>
73
- <dt>Storage</dt>
74
- <dd><a href="http://localhost:4000/demo/">http://localhost:4000/demo/</a></dd>
75
- <dt>Inbox</dt>
76
- <dd><a href="http://localhost:4000/demo/inbox/">http://localhost:4000/demo/inbox/</a></dd>
77
- </dl>
78
- </div>
79
- </body>
80
- </html>
@@ -1,32 +0,0 @@
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": "#owner",
9
- "@type": "acl:Authorization",
10
- "acl:agent": {
11
- "@id": "http://localhost:4000/demo/#me"
12
- },
13
- "acl:accessTo": {
14
- "@id": "http://localhost:4000/demo/private/"
15
- },
16
- "acl:mode": [
17
- {
18
- "@id": "acl:Read"
19
- },
20
- {
21
- "@id": "acl:Write"
22
- },
23
- {
24
- "@id": "acl:Control"
25
- }
26
- ],
27
- "acl:default": {
28
- "@id": "http://localhost:4000/demo/private/"
29
- }
30
- }
31
- ]
32
- }
@@ -1,50 +0,0 @@
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": "#owner",
9
- "@type": "acl:Authorization",
10
- "acl:agent": {
11
- "@id": "http://localhost:4000/demo/#me"
12
- },
13
- "acl:accessTo": {
14
- "@id": "http://localhost:4000/demo/public/"
15
- },
16
- "acl:default": {
17
- "@id": "http://localhost:4000/demo/public/"
18
- },
19
- "acl:mode": [
20
- {
21
- "@id": "acl:Read"
22
- },
23
- {
24
- "@id": "acl:Write"
25
- },
26
- {
27
- "@id": "acl:Control"
28
- }
29
- ]
30
- },
31
- {
32
- "@id": "#public",
33
- "@type": "acl:Authorization",
34
- "acl:agentClass": {
35
- "@id": "foaf:Agent"
36
- },
37
- "acl:accessTo": {
38
- "@id": "http://localhost:4000/demo/public/"
39
- },
40
- "acl:default": {
41
- "@id": "http://localhost:4000/demo/public/"
42
- },
43
- "acl:mode": [
44
- {
45
- "@id": "acl:Read"
46
- }
47
- ]
48
- }
49
- ]
50
- }
@@ -1,8 +0,0 @@
1
- @prefix foaf: <http://xmlns.com/foaf/0.1/> .
2
- @prefix solid: <http://www.w3.org/ns/solid/terms#> .
3
- @prefix schema: <http://schema.org/> .
4
-
5
- <#me> a foaf:Person ;
6
- foaf:name "Demo User" ;
7
- foaf:mbox <mailto:demo@example.com> ;
8
- schema:knows <https://melvincarvalho.com/#me> .
@@ -1,32 +0,0 @@
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": "#owner",
9
- "@type": "acl:Authorization",
10
- "acl:agent": {
11
- "@id": "http://localhost:4000/demo/#me"
12
- },
13
- "acl:accessTo": {
14
- "@id": "http://localhost:4000/demo/settings/"
15
- },
16
- "acl:mode": [
17
- {
18
- "@id": "acl:Read"
19
- },
20
- {
21
- "@id": "acl:Write"
22
- },
23
- {
24
- "@id": "acl:Control"
25
- }
26
- ],
27
- "acl:default": {
28
- "@id": "http://localhost:4000/demo/settings/"
29
- }
30
- }
31
- ]
32
- }
@@ -1,17 +0,0 @@
1
- {
2
- "@context": {
3
- "solid": "http://www.w3.org/ns/solid/terms#",
4
- "pim": "http://www.w3.org/ns/pim/space#",
5
- "publicTypeIndex": {
6
- "@id": "solid:publicTypeIndex",
7
- "@type": "@id"
8
- },
9
- "privateTypeIndex": {
10
- "@id": "solid:privateTypeIndex",
11
- "@type": "@id"
12
- }
13
- },
14
- "@id": "http://localhost:4000/demo/settings/prefs",
15
- "publicTypeIndex": "http://localhost:4000/demo/settings/publicTypeIndex",
16
- "privateTypeIndex": "http://localhost:4000/demo/settings/privateTypeIndex"
17
- }
@@ -1,7 +0,0 @@
1
- {
2
- "@context": {
3
- "solid": "http://www.w3.org/ns/solid/terms#"
4
- },
5
- "@id": "http://localhost:4000/demo/settings/privateTypeIndex",
6
- "@type": "solid:TypeIndex"
7
- }
@@ -1,7 +0,0 @@
1
- {
2
- "@context": {
3
- "solid": "http://www.w3.org/ns/solid/terms#"
4
- },
5
- "@id": "http://localhost:4000/demo/settings/publicTypeIndex",
6
- "@type": "solid:TypeIndex"
7
- }
@@ -1,9 +0,0 @@
1
- {
2
- "id": "b49949d9-6d61-45a1-bcee-07295aa07579",
3
- "email": "credtest@example.com",
4
- "passwordHash": "$2b$10$mVzAvASfYaz/wtb7ENo.D..AKd5CWHnOqAeL3RRPGfH20AbZG.ZEm",
5
- "webId": "http://localhost:3101/credtest/#me",
6
- "podName": "credtest",
7
- "createdAt": "2025-12-27T13:40:23.165Z",
8
- "lastLogin": "2025-12-27T13:40:23.500Z"
9
- }