diff --git a/src/idp/index.js b/src/idp/index.js index 7a2b7c4..951c127 100644 --- a/src/idp/index.js +++ b/src/idp/index.js @@ -70,6 +70,19 @@ export async function idpPlugin(fastify, options) { const req = request.raw; const res = reply.raw; + // Intercept setHeader to strip 'iss' parameter from Location redirects + // oidc-provider v9+ always includes 'iss' (RFC 9207) but Mashlib's auth doesn't handle it + const originalSetHeader = res.setHeader.bind(res); + res.setHeader = (name, value) => { + if (name.toLowerCase() === 'location' && typeof value === 'string' && value.includes('iss=')) { + // Strip the iss parameter from the redirect URL + const url = new URL(value, 'http://localhost'); + url.searchParams.delete('iss'); + value = url.pathname + url.search + url.hash; + } + return originalSetHeader(name, value); + }; + // oidc-provider is now configured with /idp routes, no stripping needed // Ensure parsed body is accessible to oidc-provider // Fastify parses body into request.body, oidc-provider looks for req.body diff --git a/src/idp/provider.js b/src/idp/provider.js index f1de093..2e83d40 100644 --- a/src/idp/provider.js +++ b/src/idp/provider.js @@ -276,16 +276,10 @@ export async function createProvider(issuer) { // Clock tolerance for token validation clockTolerance: 60, // 60 seconds - // Allow CORS for public clients from any origin + // Allow CORS for all clients from any origin // This is needed for web apps like Mashlib loaded from CDN - clientBasedCORS: (ctx, origin, client) => { - // Allow all origins for public clients (no client_secret) - if (client.tokenEndpointAuthMethod === 'none') { - return true; - } - // For confidential clients, check registered origins - return false; - }, + // Solid servers are public and should accept requests from any web app + clientBasedCORS: () => true, // Render errors renderError: async (ctx, out, error) => { diff --git a/src/ldp/headers.js b/src/ldp/headers.js index 53c4e8b..2243ce0 100644 --- a/src/ldp/headers.js +++ b/src/ldp/headers.js @@ -90,7 +90,7 @@ export function getCorsHeaders(origin) { return { 'Access-Control-Allow-Origin': origin || '*', 'Access-Control-Allow-Methods': 'GET, HEAD, POST, PUT, DELETE, PATCH, OPTIONS', - 'Access-Control-Allow-Headers': 'Accept, Authorization, Content-Type, If-Match, If-None-Match, Link, Slug, Origin', + 'Access-Control-Allow-Headers': 'Accept, Authorization, Content-Type, DPoP, If-Match, If-None-Match, Link, Slug, Origin', 'Access-Control-Expose-Headers': 'Accept-Patch, Accept-Post, Allow, Content-Type, ETag, Link, Location, Updates-Via, WAC-Allow', 'Access-Control-Allow-Credentials': 'true', 'Access-Control-Max-Age': '86400'