@owlmeans/server-oidc-provider 0.1.18-rc.1 → 0.1.18-rc.12

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.
@@ -1,8 +1,8 @@
1
1
  {
2
2
  "schemaVersion": 2,
3
3
  "package": "@owlmeans/server-oidc-provider",
4
- "version": "0.1.18-rc.0",
5
- "generatedAt": "2026-08-16T22:20:50.512Z",
4
+ "version": "0.1.18-rc.12",
5
+ "generatedAt": "2026-08-24T21:14:00.133Z",
6
6
  "canonicalRepo": "https://github.com/owlmeans/common",
7
7
  "entries": [
8
8
  {
@@ -8,7 +8,7 @@ user-invocable: false
8
8
  # @owlmeans/server-oidc-provider
9
9
 
10
10
  **Layer:** Server
11
- **Install:** `"@owlmeans/server-oidc-provider": "^0.1.18-rc.0"` in `dependencies`
11
+ **Install:** `"@owlmeans/server-oidc-provider": "^0.1.18-rc.12"` in `dependencies`
12
12
  **Runtime deps:** `oidc-provider@9.8.4` (exact), `jose@6.2.3` (exact)
13
13
 
14
14
  ## Key Exports
@@ -67,6 +67,26 @@ const key = await jose.importPKCS8(pkcs8Pem, 'RS256', { extractable: true })
67
67
  const jwk = await jose.exportJWK(key)
68
68
  ```
69
69
 
70
+ ## Response headers the hardened defaults get wrong
71
+
72
+ `@fastify/helmet` runs with its defaults on every OwlMeans server, and two of them break an
73
+ authorization endpoint. Both are corrected by middleware this package mounts ahead of the provider.
74
+
75
+ - **`Cross-Origin-Opener-Policy: same-origin`** puts the authorization document in a fresh browsing
76
+ context group, severing `window.opener` **permanently** — navigating back to the relying party
77
+ afterwards does not restore it. That kills popup-based login, which is how an app embedded in an
78
+ iframe must authenticate (see the `web-oidc-rp` skill). The provider sends `unsafe-none`.
79
+ - **`form-action 'self'`** blocks the provider's own interaction form posting across origins, so it
80
+ is rewritten to `form-action *`.
81
+
82
+ **Set these as middleware, never as a Fastify `onSend` hook.** `oidc.callback()` is a Koa handler
83
+ mounted through Middie: it ends the response itself, outside Fastify's reply lifecycle, so `onSend`
84
+ never fires for any route the provider answers and anything set there silently never reaches the
85
+ wire — the header looks configured in code and is absent in production. Middleware registered
86
+ before the provider writes to the raw response, where helmet has already put its defaults, so the
87
+ override is what ships. Verify with `curl -D -` against `/<basePath>/.well-known/openid-configuration`
88
+ rather than by reading the code.
89
+
70
90
  ## Depends On
71
91
 
72
92
  - `@owlmeans/oidc`, `@owlmeans/server-api`, `@owlmeans/server-context`
@@ -1 +1 @@
1
- {"version":3,"file":"service.d.ts","sourceRoot":"","sources":["../src/service.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,MAAM,EAAE,OAAO,EAA0C,mBAAmB,EAAE,MAAM,YAAY,CAAA;AAS9G,eAAO,MAAM,yBAAyB,WAAW,MAAM,KAAmB,mBAoGzE,CAAA;AAED,eAAO,MAAM,yBAAyB,GAAI,CAAC,SAAS,MAAM,EAAE,CAAC,SAAS,OAAO,CAAC,CAAC,CAAC,OACzE,CAAC,UAAS,MAAM,KACpB,CAOF,CAAA"}
1
+ {"version":3,"file":"service.d.ts","sourceRoot":"","sources":["../src/service.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,MAAM,EAAE,OAAO,EAA0C,mBAAmB,EAAE,MAAM,YAAY,CAAA;AAS9G,eAAO,MAAM,yBAAyB,WAAW,MAAM,KAAmB,mBAoHzE,CAAA;AAED,eAAO,MAAM,yBAAyB,GAAI,CAAC,SAAS,MAAM,EAAE,CAAC,SAAS,OAAO,CAAC,CAAC,CAAC,OACzE,CAAC,UAAS,MAAM,KACpB,CAOF,CAAA"}
package/build/service.js CHANGED
@@ -44,19 +44,33 @@ export const createOidcProviderService = (alias = DEFAULT_ALIAS) => {
44
44
  });
45
45
  oidc.proxy = cfg.behindProxy ?? unsecure;
46
46
  const base = SEP + (cfg.basePath ?? DEFAULT_PATH);
47
- api.server.use(base, oidc.callback());
48
- // oidc-provider v9: provider.use() middleware no longer runs post-response after a matched
49
- // route. CSP rewrite is handled at the Fastify layer via an onSend hook instead.
50
- api.server.addHook('onSend', async (request, reply, payload) => {
51
- if (!request.url.startsWith(base)) {
52
- return payload;
53
- }
54
- const csp = reply.getHeader('content-security-policy');
47
+ /**
48
+ * Response headers the hardened defaults get wrong for an authorization endpoint.
49
+ *
50
+ * This runs as middleware, ahead of the provider in the same chain, and writes to the raw
51
+ * response — deliberately, not as a Fastify `onSend` hook. `oidc.callback()` is a Koa
52
+ * handler mounted through Middie: it ends the response itself, outside Fastify's reply
53
+ * lifecycle, so `onSend` never fires for any route the provider answers and anything set
54
+ * there silently never reaches the wire. The security defaults are already on the raw
55
+ * response by this point (`@fastify/helmet` applies them in `onRequest`), so overriding
56
+ * them here is what actually takes effect.
57
+ */
58
+ api.server.use(base, (_req, res, next) => {
59
+ // `Cross-Origin-Opener-Policy: same-origin` puts this document in a fresh browsing
60
+ // context group, which severs `window.opener` **permanently** — navigating back to the
61
+ // relying party afterwards does not restore it. Popup-based login is the standard way an
62
+ // embedded application authenticates and the opener is its only channel home, so an
63
+ // authorization endpoint must not be the thing that cuts it.
64
+ res.setHeader('Cross-Origin-Opener-Policy', 'unsafe-none');
65
+ // The provider posts its own interaction forms across origins; `form-action 'self'`
66
+ // would block the submission.
67
+ const csp = res.getHeader('Content-Security-Policy');
55
68
  if (typeof csp === 'string' && csp.includes("form-action 'self'")) {
56
- reply.header('Content-Security-Policy', csp.replace(/form-action 'self'/, 'form-action *'));
69
+ res.setHeader('Content-Security-Policy', csp.replace(/form-action 'self'/, 'form-action *'));
57
70
  }
58
- return payload;
71
+ next();
59
72
  });
73
+ api.server.use(base, oidc.callback());
60
74
  if (context.cfg.debug?.all || context.cfg.debug?.oidc) {
61
75
  oidc.on('grant.error', (_, error) => {
62
76
  console.warn('GRANT ERROR .......: ');
@@ -1 +1 @@
1
- {"version":3,"file":"service.js","sourceRoot":"","sources":["../src/service.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"service.js","sourceRoot":"","sources":["../src/service.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@owlmeans/server-oidc-provider",
3
- "version": "0.1.18-rc.1",
3
+ "version": "0.1.18-rc.12",
4
4
  "license": "MIT",
5
5
  "type": "module",
6
6
  "scripts": {
@@ -23,7 +23,7 @@
23
23
  },
24
24
  "devDependencies": {
25
25
  "@owlmeans/dep-config": "workspace:*",
26
- "@owlmeans/context": "^0.1.18-rc.1",
26
+ "@owlmeans/context": "^0.1.18-rc.6",
27
27
  "@types/bun": "^1.3.14",
28
28
  "@types/node": "^26.1.0",
29
29
  "@types/oidc-provider": "9.5.0",
@@ -35,13 +35,13 @@
35
35
  },
36
36
  "dependencies": {
37
37
  "@noble/hashes": "^1.5.0",
38
- "@owlmeans/config": "^0.1.18-rc.1",
39
- "@owlmeans/context": "^0.1.18-rc.1",
40
- "@owlmeans/entrypoint": "^0.1.18-rc.1",
41
- "@owlmeans/oidc": "^0.1.18-rc.1",
42
- "@owlmeans/route": "^0.1.18-rc.1",
43
- "@owlmeans/server-api": "^0.1.18-rc.1",
44
- "@owlmeans/server-context": "^0.1.18-rc.1",
38
+ "@owlmeans/config": "^0.1.18-rc.7",
39
+ "@owlmeans/context": "^0.1.18-rc.6",
40
+ "@owlmeans/entrypoint": "^0.1.18-rc.7",
41
+ "@owlmeans/oidc": "^0.1.18-rc.7",
42
+ "@owlmeans/route": "^0.1.18-rc.6",
43
+ "@owlmeans/server-api": "^0.1.18-rc.11",
44
+ "@owlmeans/server-context": "^0.1.18-rc.7",
45
45
  "@scure/base": "^2.3.0",
46
46
  "jose": "6.2.5",
47
47
  "oidc-provider": "9.11.1"
package/src/service.ts CHANGED
@@ -1,6 +1,7 @@
1
1
  import { assertContext, createService } from '@owlmeans/context'
2
2
  import { DEFAULT_ALIAS, OIDC_ACCOUNT_SERVICE } from './consts.js'
3
3
  import { DEFAULT_PATH, INTERACTION, INTERACTION_UID } from '@owlmeans/oidc'
4
+ import type { ServerResponse } from 'node:http'
4
5
  import type { Config, Context, OidcAccountService, OidcAdapterService, OidcProviderService } from './types.js'
5
6
  import Provider from 'oidc-provider'
6
7
  import type { BasicRoute } from '@owlmeans/route'
@@ -60,21 +61,37 @@ export const createOidcProviderService = (alias: string = DEFAULT_ALIAS): OidcPr
60
61
  oidc.proxy = cfg.behindProxy ?? unsecure
61
62
  const base = SEP + (cfg.basePath ?? DEFAULT_PATH)
62
63
 
63
- api.server.use(base, oidc.callback())
64
-
65
- // oidc-provider v9: provider.use() middleware no longer runs post-response after a matched
66
- // route. CSP rewrite is handled at the Fastify layer via an onSend hook instead.
67
- api.server.addHook('onSend', async (request, reply, payload) => {
68
- if (!request.url.startsWith(base)) {
69
- return payload
70
- }
71
- const csp = reply.getHeader('content-security-policy')
64
+ /**
65
+ * Response headers the hardened defaults get wrong for an authorization endpoint.
66
+ *
67
+ * This runs as middleware, ahead of the provider in the same chain, and writes to the raw
68
+ * response — deliberately, not as a Fastify `onSend` hook. `oidc.callback()` is a Koa
69
+ * handler mounted through Middie: it ends the response itself, outside Fastify's reply
70
+ * lifecycle, so `onSend` never fires for any route the provider answers and anything set
71
+ * there silently never reaches the wire. The security defaults are already on the raw
72
+ * response by this point (`@fastify/helmet` applies them in `onRequest`), so overriding
73
+ * them here is what actually takes effect.
74
+ */
75
+ api.server.use(base, (_req: unknown, res: ServerResponse, next: () => void) => {
76
+ // `Cross-Origin-Opener-Policy: same-origin` puts this document in a fresh browsing
77
+ // context group, which severs `window.opener` **permanently** — navigating back to the
78
+ // relying party afterwards does not restore it. Popup-based login is the standard way an
79
+ // embedded application authenticates and the opener is its only channel home, so an
80
+ // authorization endpoint must not be the thing that cuts it.
81
+ res.setHeader('Cross-Origin-Opener-Policy', 'unsafe-none')
82
+
83
+ // The provider posts its own interaction forms across origins; `form-action 'self'`
84
+ // would block the submission.
85
+ const csp = res.getHeader('Content-Security-Policy')
72
86
  if (typeof csp === 'string' && csp.includes("form-action 'self'")) {
73
- reply.header('Content-Security-Policy', csp.replace(/form-action 'self'/, 'form-action *'))
87
+ res.setHeader('Content-Security-Policy', csp.replace(/form-action 'self'/, 'form-action *'))
74
88
  }
75
- return payload
89
+
90
+ next()
76
91
  })
77
92
 
93
+ api.server.use(base, oidc.callback())
94
+
78
95
  if (context.cfg.debug?.all || context.cfg.debug?.oidc) {
79
96
 
80
97
  oidc.on('grant.error', (_, error) => {