@owlmeans/server-oidc-provider 0.1.18-rc.0 → 0.1.18-rc.11
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/agent-meta/manifest.json +2 -2
- package/agent-meta/skills/server-oidc-provider/SKILL.md +21 -1
- package/build/iam.d.ts.map +1 -1
- package/build/middleware.js.map +1 -1
- package/build/service.d.ts.map +1 -1
- package/build/service.js +24 -10
- package/build/service.js.map +1 -1
- package/package.json +9 -9
- package/src/service.ts +28 -11
package/agent-meta/manifest.json
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
{
|
|
2
2
|
"schemaVersion": 2,
|
|
3
3
|
"package": "@owlmeans/server-oidc-provider",
|
|
4
|
-
"version": "0.1.18-rc.
|
|
5
|
-
"generatedAt": "2026-08-
|
|
4
|
+
"version": "0.1.18-rc.10",
|
|
5
|
+
"generatedAt": "2026-08-21T11:29:02.442Z",
|
|
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.
|
|
11
|
+
**Install:** `"@owlmeans/server-oidc-provider": "^0.1.18-rc.10"` 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`
|
package/build/iam.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"iam.d.ts","sourceRoot":"","sources":["../src/iam.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAgB,MAAM,eAAe,CAAA;AAEjE,wEAAwE;AACxE,MAAM,WAAW,oBAAoB;IACnC,QAAQ,EAAE,MAAM,CAAA;IAChB,MAAM,EAAE,MAAM,CAAA;IACd,6EAA6E;IAC7E,QAAQ,CAAC,EAAE,MAAM,CAAA;IACjB,+BAA+B;IAC/B,IAAI,CAAC,EAAE,MAAM,CAAA;IACb,YAAY,CAAC,EAAE,MAAM,EAAE,CAAA;IACvB,UAAU,CAAC,EAAE,MAAM,EAAE,CAAA;IACrB,aAAa,CAAC,EAAE,MAAM,EAAE,CAAA;IACxB,KAAK,CAAC,EAAE,MAAM,CAAA;CACf;AAED,mEAAmE;AACnE,MAAM,MAAM,kBAAkB,GAAG,cAAc,GAAG;IAAE,QAAQ,CAAC,EAAE,MAAM,CAAC;IAAC,WAAW,CAAC,EAAE,MAAM,CAAA;CAAE,CAAA;AAE7F,iFAAiF;AACjF,eAAO,MAAM,gBAAgB,
|
|
1
|
+
{"version":3,"file":"iam.d.ts","sourceRoot":"","sources":["../src/iam.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAgB,MAAM,eAAe,CAAA;AAEjE,wEAAwE;AACxE,MAAM,WAAW,oBAAoB;IACnC,QAAQ,EAAE,MAAM,CAAA;IAChB,MAAM,EAAE,MAAM,CAAA;IACd,6EAA6E;IAC7E,QAAQ,CAAC,EAAE,MAAM,CAAA;IACjB,+BAA+B;IAC/B,IAAI,CAAC,EAAE,MAAM,CAAA;IACb,YAAY,CAAC,EAAE,MAAM,EAAE,CAAA;IACvB,UAAU,CAAC,EAAE,MAAM,EAAE,CAAA;IACrB,aAAa,CAAC,EAAE,MAAM,EAAE,CAAA;IACxB,KAAK,CAAC,EAAE,MAAM,CAAA;CACf;AAED,mEAAmE;AACnE,MAAM,MAAM,kBAAkB,GAAG,cAAc,GAAG;IAAE,QAAQ,CAAC,EAAE,MAAM,CAAC;IAAC,WAAW,CAAC,EAAE,MAAM,CAAA;CAAE,CAAA;AAE7F,iFAAiF;AACjF,eAAO,MAAM,gBAAgB,GAAI,QAAQ,oBAAoB,KAAG,kBAS9D,CAAA;AAEF,qFAAqF;AACrF,MAAM,WAAW,wBAAwB;IACvC,qEAAqE;IACrE,gBAAgB,EAAE,OAAO,gBAAgB,CAAA;IACzC,qCAAqC;IACrC,oBAAoB,EAAE,oBAAoB,CAAA;IAC1C,6BAA6B;IAC7B,kBAAkB,EAAE,kBAAkB,CAAA;CACvC"}
|
package/build/middleware.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"middleware.js","sourceRoot":"","sources":["../src/middleware.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,aAAa,EAAE,eAAe,EAAE,cAAc,EAAE,MAAM,mBAAmB,CAAA;AAClF,OAAO,EAAE,aAAa,IAAI,SAAS,EAAE,MAAM,sBAAsB,CAAA;AAEjE,OAAO,EAAE,aAAa,EAAE,MAAM,aAAa,CAAA;AAG3C,MAAM,CAAC,MAAM,4BAA4B,GAAG,CAAC,
|
|
1
|
+
{"version":3,"file":"middleware.js","sourceRoot":"","sources":["../src/middleware.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,aAAa,EAAE,eAAe,EAAE,cAAc,EAAE,MAAM,mBAAmB,CAAA;AAClF,OAAO,EAAE,aAAa,IAAI,SAAS,EAAE,MAAM,sBAAsB,CAAA;AAEjE,OAAO,EAAE,aAAa,EAAE,MAAM,aAAa,CAAA;AAG3C,MAAM,CAAC,MAAM,4BAA4B,GAAG,CAAC,MAAc,SAAS,EAAE,IAAI,GAAG,aAAa,EAAE,EAAE;IAC5F,MAAM,UAAU,GAAe;QAC7B,IAAI,EAAE,cAAc,CAAC,OAAO;QAC5B,KAAK,EAAE,eAAe,CAAC,OAAO;QAC9B,KAAK,EAAE,KAAK,EAAC,GAAG,EAAC,EAAE;YACjB,MAAM,OAAO,GAAG,aAAa,CAAkB,GAAyB,CAAY,CAAA;YACpF,MAAM,UAAU,GAAG,OAAO,CAAC,OAAO,CAAY,GAAG,CAAC,CAAA;YAClD,MAAM,WAAW,GAAG,OAAO,CAAC,OAAO,CAAsB,IAAI,CAAC,CAAA;YAE9D,MAAM,MAAM,GAAG,sBAAsB,GAAG,IAAI,IAAI,EAAE,CAAA;YAClD,IAAI,CAAC,GAAG,CAAC,GAAG,CAAC,OAAO,EAAE,IAAI,CAAC,MAAM,CAAC,EAAE,CAAC,MAAM,CAAC,EAAE,KAAK,MAAM,CAAC,EAAE,CAAC;gBAC3D,MAAM,WAAW,CAAC,MAAM,CAAC,UAAU,CAAC,CAAA;gBACpC,IAAI,GAAG,CAAC,GAAG,CAAC,OAAO,IAAI,IAAI,EAAE,CAAC;oBAC5B,GAAG,CAAC,GAAG,CAAC,OAAO,GAAG,EAAE,CAAA;gBACtB,CAAC;gBACD,GAAG,CAAC,GAAG,CAAC,OAAO,CAAC,IAAI,CAAC,EAAE,EAAE,EAAE,MAAM,EAAE,CAAC,CAAA;YACtC,CAAC;QACH,CAAC;KACF,CAAA;IAED,OAAO,UAAU,CAAA;AACnB,CAAC,CAAA"}
|
package/build/service.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"service.d.ts","sourceRoot":"","sources":["../src/service.ts"],"names":[],"mappings":"
|
|
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,GAAI,QAAO,MAAsB,KAAG,mBAoHzE,CAAA;AAED,eAAO,MAAM,yBAAyB,GAAI,CAAC,SAAS,MAAM,EAAE,CAAC,SAAS,OAAO,CAAC,CAAC,CAAC,EAC9E,KAAK,CAAC,EAAE,QAAO,MAAsB,KACpC,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
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
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
|
-
|
|
69
|
+
res.setHeader('Content-Security-Policy', csp.replace(/form-action 'self'/, 'form-action *'));
|
|
57
70
|
}
|
|
58
|
-
|
|
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 .......: ');
|
package/build/service.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"service.js","sourceRoot":"","sources":["../src/service.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,aAAa,EAAE,MAAM,mBAAmB,CAAA;AAChE,OAAO,EAAE,aAAa,EAAE,oBAAoB,EAAE,MAAM,aAAa,CAAA;AACjE,OAAO,EAAE,YAAY,EAAE,WAAW,EAAE,eAAe,EAAE,MAAM,gBAAgB,CAAA;
|
|
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.
|
|
3
|
+
"version": "0.1.18-rc.11",
|
|
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.
|
|
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.
|
|
39
|
-
"@owlmeans/context": "^0.1.18-rc.
|
|
40
|
-
"@owlmeans/entrypoint": "^0.1.18-rc.
|
|
41
|
-
"@owlmeans/oidc": "^0.1.18-rc.
|
|
42
|
-
"@owlmeans/route": "^0.1.18-rc.
|
|
43
|
-
"@owlmeans/server-api": "^0.1.18-rc.
|
|
44
|
-
"@owlmeans/server-context": "^0.1.18-rc.
|
|
38
|
+
"@owlmeans/config": "^0.1.18-rc.6",
|
|
39
|
+
"@owlmeans/context": "^0.1.18-rc.6",
|
|
40
|
+
"@owlmeans/entrypoint": "^0.1.18-rc.6",
|
|
41
|
+
"@owlmeans/oidc": "^0.1.18-rc.6",
|
|
42
|
+
"@owlmeans/route": "^0.1.18-rc.6",
|
|
43
|
+
"@owlmeans/server-api": "^0.1.18-rc.10",
|
|
44
|
+
"@owlmeans/server-context": "^0.1.18-rc.6",
|
|
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
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
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
|
-
|
|
87
|
+
res.setHeader('Content-Security-Policy', csp.replace(/form-action 'self'/, 'form-action *'))
|
|
74
88
|
}
|
|
75
|
-
|
|
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) => {
|