javascript-solid-server 0.0.25 → 0.0.27

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "javascript-solid-server",
3
- "version": "0.0.25",
3
+ "version": "0.0.27",
4
4
  "description": "A minimal, fast Solid server",
5
5
  "main": "src/index.js",
6
6
  "type": "module",
package/src/idp/index.js CHANGED
@@ -70,6 +70,25 @@ export async function idpPlugin(fastify, options) {
70
70
  const req = request.raw;
71
71
  const res = reply.raw;
72
72
 
73
+ // Set CORS headers on raw response before oidc-provider handles it
74
+ // This is needed because oidc-provider writes directly to the raw response
75
+ const origin = request.headers.origin;
76
+ if (origin) {
77
+ res.setHeader('Access-Control-Allow-Origin', origin);
78
+ res.setHeader('Access-Control-Allow-Credentials', 'true');
79
+ res.setHeader('Access-Control-Allow-Methods', 'GET, HEAD, POST, PUT, DELETE, PATCH, OPTIONS');
80
+ res.setHeader('Access-Control-Allow-Headers', 'Accept, Authorization, Content-Type, DPoP, If-Match, If-None-Match, Link, Slug, Origin');
81
+ res.setHeader('Access-Control-Expose-Headers', 'Accept-Patch, Accept-Post, Allow, Content-Type, ETag, Link, Location, Updates-Via, WAC-Allow');
82
+ res.setHeader('Access-Control-Max-Age', '86400');
83
+ }
84
+
85
+ // Handle OPTIONS preflight requests directly
86
+ if (request.method === 'OPTIONS') {
87
+ res.statusCode = 204;
88
+ res.end();
89
+ return resolve();
90
+ }
91
+
73
92
  // oidc-provider is now configured with /idp routes, no stripping needed
74
93
  // Ensure parsed body is accessible to oidc-provider
75
94
  // Fastify parses body into request.body, oidc-provider looks for req.body
@@ -116,7 +135,7 @@ export async function idpPlugin(fastify, options) {
116
135
 
117
136
  for (const path of oidcPaths) {
118
137
  fastify.route({
119
- method: ['GET', 'POST', 'DELETE'],
138
+ method: ['GET', 'POST', 'DELETE', 'OPTIONS'],
120
139
  url: path,
121
140
  handler: forwardToProvider,
122
141
  });
@@ -149,8 +149,9 @@ export async function createProvider(issuer) {
149
149
  scopes: ['openid', 'webid', 'profile', 'email', 'offline_access'],
150
150
 
151
151
  // Claims configuration
152
+ // Always include webid with openid scope for Solid-OIDC compliance
152
153
  claims: {
153
- openid: ['sub'],
154
+ openid: ['sub', 'webid'],
154
155
  webid: ['webid'],
155
156
  profile: ['name'],
156
157
  email: ['email', 'email_verified'],
@@ -276,14 +277,31 @@ export async function createProvider(issuer) {
276
277
  // Clock tolerance for token validation
277
278
  clockTolerance: 60, // 60 seconds
278
279
 
279
- // Allow CORS for public clients from any origin
280
+ // Allow CORS for browser-based clients
280
281
  // This is needed for web apps like Mashlib loaded from CDN
281
282
  clientBasedCORS: (ctx, origin, client) => {
282
283
  // Allow all origins for public clients (no client_secret)
283
284
  if (client.tokenEndpointAuthMethod === 'none') {
284
285
  return true;
285
286
  }
286
- // For confidential clients, check registered origins
287
+ // For confidential clients, allow if origin matches a registered redirect_uri
288
+ // This is safe because the client was registered with this redirect_uri
289
+ if (client.redirectUris && Array.isArray(client.redirectUris)) {
290
+ for (const uri of client.redirectUris) {
291
+ try {
292
+ const redirectOrigin = new URL(uri).origin;
293
+ if (redirectOrigin === origin) {
294
+ return true;
295
+ }
296
+ } catch (e) {
297
+ // Invalid URL, skip
298
+ }
299
+ }
300
+ }
301
+ // Also allow if application_type is 'web' - browser apps need CORS
302
+ if (client.applicationType === 'web') {
303
+ return true;
304
+ }
287
305
  return false;
288
306
  },
289
307