@sentropic/auth-hono 0.4.0 → 0.7.0
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/README.md +34 -0
- package/dist/index.d.ts +2 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1 -0
- package/dist/index.js.map +1 -1
- package/dist/oauth/authorize-handler.d.ts +1 -0
- package/dist/oauth/authorize-handler.d.ts.map +1 -1
- package/dist/oauth/authorize-handler.js +85 -7
- package/dist/oauth/authorize-handler.js.map +1 -1
- package/dist/oauth/consent-decision-handler.d.ts.map +1 -1
- package/dist/oauth/consent-decision-handler.js +7 -18
- package/dist/oauth/consent-decision-handler.js.map +1 -1
- package/dist/oauth/dpop.d.ts +7 -4
- package/dist/oauth/dpop.d.ts.map +1 -1
- package/dist/oauth/dpop.js +23 -44
- package/dist/oauth/dpop.js.map +1 -1
- package/dist/oauth/issue-authorized-code.d.ts +15 -0
- package/dist/oauth/issue-authorized-code.d.ts.map +1 -0
- package/dist/oauth/issue-authorized-code.js +29 -0
- package/dist/oauth/issue-authorized-code.js.map +1 -0
- package/dist/oauth/jwks-service.d.ts.map +1 -1
- package/dist/oauth/jwks-service.js +6 -8
- package/dist/oauth/jwks-service.js.map +1 -1
- package/dist/oauth/service-auth-middleware.d.ts.map +1 -1
- package/dist/oauth/service-auth-middleware.js +46 -64
- package/dist/oauth/service-auth-middleware.js.map +1 -1
- package/dist/oauth/state-codec.d.ts +2 -0
- package/dist/oauth/state-codec.d.ts.map +1 -1
- package/dist/oauth/state-codec.js.map +1 -1
- package/dist/oauth/state-store-types.d.ts +12 -0
- package/dist/oauth/state-store-types.d.ts.map +1 -1
- package/dist/oauth/token-handler.d.ts.map +1 -1
- package/dist/oauth/token-handler.js +38 -1
- package/dist/oauth/token-handler.js.map +1 -1
- package/dist/oauth/wellknown-handler.js +1 -1
- package/dist/oauth/wellknown-handler.js.map +1 -1
- package/dist/ports.d.ts +32 -0
- package/dist/ports.d.ts.map +1 -1
- package/package.json +4 -1
- package/src/index.ts +11 -0
- package/src/oauth/authorize-handler.ts +101 -8
- package/src/oauth/consent-decision-handler.ts +11 -25
- package/src/oauth/dpop.ts +30 -67
- package/src/oauth/issue-authorized-code.ts +50 -0
- package/src/oauth/jwks-service.ts +5 -9
- package/src/oauth/service-auth-middleware.ts +59 -80
- package/src/oauth/state-codec.ts +2 -0
- package/src/oauth/state-store-types.ts +12 -0
- package/src/oauth/token-handler.ts +44 -1
- package/src/oauth/wellknown-handler.ts +1 -1
- package/src/ports.ts +35 -0
package/README.md
CHANGED
|
@@ -154,6 +154,39 @@ interface OauthStateStorePort {
|
|
|
154
154
|
|
|
155
155
|
The package never imports Postgres or any persistence library. Sentropic supplies `api/src/services/auth/oauth-state-adapter.ts` (Drizzle/Postgres). Package tests use the in-memory fixture at `packages/auth-hono/tests/__fixtures__/memory-oauth-state-store.ts`.
|
|
156
156
|
|
|
157
|
+
### Consent persistence — `consentStore` (since 0.7.0)
|
|
158
|
+
|
|
159
|
+
By default the IdP re-shows the consent screen on every `/authorize`. Provide the **optional**
|
|
160
|
+
`AuthHonoPorts.consentStore` port to remember a user's grant and skip consent when it already
|
|
161
|
+
covers the requested scopes:
|
|
162
|
+
|
|
163
|
+
```ts
|
|
164
|
+
interface AuthHonoConsentStorePort {
|
|
165
|
+
getGrant(userId: string, clientId: string): Promise<{ scopes: string[] } | null>;
|
|
166
|
+
saveGrant(userId: string, clientId: string, scopes: string[]): Promise<void>; // upsert + union
|
|
167
|
+
}
|
|
168
|
+
```
|
|
169
|
+
|
|
170
|
+
- **Skip rule** (authorize handler): when `consentStore` is wired, `prompt !== 'consent'`, and a
|
|
171
|
+
stored grant for the exact `(userId, clientId)` is a **superset** of the requested scopes, the
|
|
172
|
+
handler issues the authorization code directly via the same single-use issuance path as the
|
|
173
|
+
consent-approve flow (no consent screen).
|
|
174
|
+
- **Scope-escalation guard** (security invariant): coverage is a strict set-superset check. Any
|
|
175
|
+
requested scope absent from the stored grant re-shows consent. A grant is bound to the exact
|
|
176
|
+
`(userId, clientId)`; another client's grant never satisfies coverage.
|
|
177
|
+
- **`prompt=consent`** always forces the consent screen, even with a fully covering grant.
|
|
178
|
+
- **`prompt=none`**: covered ⇒ silent code; uncovered ⇒ `consent_required` (unchanged).
|
|
179
|
+
- **Persistence**: the consent-approve path calls `saveGrant(userId, clientId, grantedScopes)`
|
|
180
|
+
(deny never persists). The adapter upserts per `(user, client)` and **unions** the scopes with
|
|
181
|
+
any prior grant, so a narrower re-approval never shrinks the grant.
|
|
182
|
+
- **Backward-compatible**: when `consentStore` is **absent**, behavior is unchanged — consent is
|
|
183
|
+
always shown. Existing `0.6.0` implementors keep compiling and behaving identically.
|
|
184
|
+
- **Revocation** (consent revoke endpoint + connected-apps UI) is deferred to a future WP.
|
|
185
|
+
|
|
186
|
+
Like the other ports, the package never persists anything itself. Sentropic supplies
|
|
187
|
+
`api/src/services/auth/consent-store-adapter.ts` (Drizzle/Postgres, `oauth_consents` table).
|
|
188
|
+
Package tests use the in-memory fixture in `packages/auth-hono/tests/__fixtures__/oauth-fixtures.ts`.
|
|
189
|
+
|
|
157
190
|
### DPoP opt-in (RFC 9449)
|
|
158
191
|
|
|
159
192
|
Set `dpop_bound_access_tokens: true` on the OAuth client record. Bound clients must send a `DPoP: <proof-jwt>` header on `/token`, `/userinfo`, and `/revoke`. The IdP verifies `htm`, `htu`, `iat` skew, unique proof `jti`, and `ath` on resource calls. Access and ID tokens include `cnf.jkt`.
|
|
@@ -245,3 +278,4 @@ This branch ships `0.4.0`:
|
|
|
245
278
|
- `0.2.1` patches `extractChallenge` (both WebAuthn handlers) to handle `credential.response === null` defensively (returns 400 `invalid_credential` instead of throwing 500).
|
|
246
279
|
- `0.3.0` adds the OAuth2/OIDC IdP surface: `createOAuthRouter`, `createWellKnownRouter`, `createJwksService`, `OauthStateStorePort`, `JwksPort`, Ed25519 signing, DPoP opt-in, and all six OAuth endpoints. Additive; existing WebAuthn/session handler signatures unchanged.
|
|
247
280
|
- `0.4.0` adds the S2S `client_credentials` grant (stateless service tokens), `createRequireServiceAuth` + `ServiceAuthPorts`, the optional `findServiceClient?` on `OauthStateStorePort`, `ServiceClientRecord`, and RFC 8707 resource indicators. Discovery now advertises `client_credentials` and `client_secret_post`. Additive and non-breaking — existing `0.3.0` implementors keep compiling.
|
|
281
|
+
- `0.7.0` adds **consent persistence**: the optional `AuthHonoConsentStorePort` (`AuthHonoPorts.consentStore?`) and `AuthHonoConsentGrant`, the shared `issueAuthorizedCode` helper (single issuance path for both consent-approve and the authorize skip-path), and the authorize-handler skip logic (covered grant + `prompt !== 'consent'` ⇒ issue code directly; scope-escalation re-consents). Additive and non-breaking — when `consentStore` is absent, consent is always shown exactly as before. (`0.5.0`/`0.6.0` were shipped from earlier branches without a README versioning entry.)
|
package/dist/index.d.ts
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
export type { AccessTokenClaims, ActClaim, IdentityType, TokenKeySource, } from '@sentropic/oauth-verify';
|
|
1
2
|
export * from './contracts.js';
|
|
2
3
|
export * from './credential-route-handlers.js';
|
|
3
4
|
export * from './email-verification.js';
|
|
@@ -9,6 +10,7 @@ export * from './oauth/crypto-utils.js';
|
|
|
9
10
|
export * from './oauth/dpop.js';
|
|
10
11
|
export * from './oauth/http-utils.js';
|
|
11
12
|
export * from './oauth/introspect-handler.js';
|
|
13
|
+
export * from './oauth/issue-authorized-code.js';
|
|
12
14
|
export * from './oauth/jwks-service.js';
|
|
13
15
|
export * from './oauth/router.js';
|
|
14
16
|
export * from './oauth/revoke-handler.js';
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAGA,YAAY,EACV,iBAAiB,EACjB,QAAQ,EACR,YAAY,EACZ,cAAc,GACf,MAAM,yBAAyB,CAAC;AAEjC,cAAc,gBAAgB,CAAC;AAC/B,cAAc,gCAAgC,CAAC;AAC/C,cAAc,yBAAyB,CAAC;AACxC,cAAc,iBAAiB,CAAC;AAChC,cAAc,iBAAiB,CAAC;AAChC,cAAc,8BAA8B,CAAC;AAC7C,cAAc,qCAAqC,CAAC;AACpD,cAAc,yBAAyB,CAAC;AACxC,cAAc,iBAAiB,CAAC;AAChC,cAAc,uBAAuB,CAAC;AACtC,cAAc,+BAA+B,CAAC;AAC9C,cAAc,kCAAkC,CAAC;AACjD,cAAc,yBAAyB,CAAC;AACxC,cAAc,mBAAmB,CAAC;AAClC,cAAc,2BAA2B,CAAC;AAC1C,cAAc,oCAAoC,CAAC;AACnD,cAAc,6BAA6B,CAAC;AAC5C,cAAc,8BAA8B,CAAC;AAC7C,cAAc,wBAAwB,CAAC;AACvC,cAAc,0BAA0B,CAAC;AACzC,cAAc,6BAA6B,CAAC;AAC5C,cAAc,8BAA8B,CAAC;AAC7C,cAAc,YAAY,CAAC;AAC3B,cAAc,qBAAqB,CAAC;AACpC,cAAc,aAAa,CAAC;AAC5B,cAAc,cAAc,CAAC;AAC7B,cAAc,6BAA6B,CAAC;AAC5C,cAAc,8BAA8B,CAAC;AAC7C,cAAc,6CAA6C,CAAC;AAC5D,cAAc,4BAA4B,CAAC;AAC3C,cAAc,2CAA2C,CAAC"}
|
package/dist/index.js
CHANGED
|
@@ -9,6 +9,7 @@ export * from './oauth/crypto-utils.js';
|
|
|
9
9
|
export * from './oauth/dpop.js';
|
|
10
10
|
export * from './oauth/http-utils.js';
|
|
11
11
|
export * from './oauth/introspect-handler.js';
|
|
12
|
+
export * from './oauth/issue-authorized-code.js';
|
|
12
13
|
export * from './oauth/jwks-service.js';
|
|
13
14
|
export * from './oauth/router.js';
|
|
14
15
|
export * from './oauth/revoke-handler.js';
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAUA,cAAc,gBAAgB,CAAC;AAC/B,cAAc,gCAAgC,CAAC;AAC/C,cAAc,yBAAyB,CAAC;AACxC,cAAc,iBAAiB,CAAC;AAChC,cAAc,iBAAiB,CAAC;AAChC,cAAc,8BAA8B,CAAC;AAC7C,cAAc,qCAAqC,CAAC;AACpD,cAAc,yBAAyB,CAAC;AACxC,cAAc,iBAAiB,CAAC;AAChC,cAAc,uBAAuB,CAAC;AACtC,cAAc,+BAA+B,CAAC;AAC9C,cAAc,kCAAkC,CAAC;AACjD,cAAc,yBAAyB,CAAC;AACxC,cAAc,mBAAmB,CAAC;AAClC,cAAc,2BAA2B,CAAC;AAC1C,cAAc,oCAAoC,CAAC;AACnD,cAAc,6BAA6B,CAAC;AAC5C,cAAc,8BAA8B,CAAC;AAC7C,cAAc,wBAAwB,CAAC;AACvC,cAAc,0BAA0B,CAAC;AACzC,cAAc,6BAA6B,CAAC;AAC5C,cAAc,8BAA8B,CAAC;AAC7C,cAAc,YAAY,CAAC;AAC3B,cAAc,qBAAqB,CAAC;AACpC,cAAc,aAAa,CAAC;AAC5B,cAAc,cAAc,CAAC;AAC7B,cAAc,6BAA6B,CAAC;AAC5C,cAAc,8BAA8B,CAAC;AAC7C,cAAc,6CAA6C,CAAC;AAC5D,cAAc,4BAA4B,CAAC;AAC3C,cAAc,2CAA2C,CAAC"}
|
|
@@ -2,6 +2,7 @@ import type { Context } from 'hono';
|
|
|
2
2
|
import type { AuthHonoPorts } from '../ports.js';
|
|
3
3
|
import type { OAuthContinuationCodec } from './state-codec.js';
|
|
4
4
|
export interface OAuthAuthorizeHandlerOptions {
|
|
5
|
+
authorizationCodeTtlSeconds?: number;
|
|
5
6
|
consentUrl: string;
|
|
6
7
|
issuer: string;
|
|
7
8
|
loginUrl: string;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"authorize-handler.d.ts","sourceRoot":"","sources":["../../src/oauth/authorize-handler.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,MAAM,CAAC;AAEpC,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAEjD,OAAO,KAAK,EAAE,sBAAsB,EAA0B,MAAM,kBAAkB,CAAC;
|
|
1
|
+
{"version":3,"file":"authorize-handler.d.ts","sourceRoot":"","sources":["../../src/oauth/authorize-handler.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,MAAM,CAAC;AAEpC,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAEjD,OAAO,KAAK,EAAE,sBAAsB,EAA0B,MAAM,kBAAkB,CAAC;AAKvF,MAAM,WAAW,4BAA4B;IAC3C,2BAA2B,CAAC,EAAE,MAAM,CAAC;IACrC,UAAU,EAAE,MAAM,CAAC;IACnB,MAAM,EAAE,MAAM,CAAC;IACf,QAAQ,EAAE,MAAM,CAAC;IACjB,KAAK,EAAE,aAAa,CAAC;IACrB,UAAU,EAAE,sBAAsB,CAAC;IACnC,eAAe,CAAC,EAAE,MAAM,CAAC;CAC1B;AAaD,eAAO,MAAM,2BAA2B,YAC5B,4BAA4B,SAC5B,OAAO,KAAG,QAAQ,QAAQ,CAkDnC,CAAC"}
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { appendParams, oauthJsonError, redirectWithOAuthError } from './http-utils.js';
|
|
2
|
+
import { issueAuthorizedCode } from './issue-authorized-code.js';
|
|
2
3
|
import { resolveOAuthAcr, resolveOAuthSession } from './session-resolver.js';
|
|
3
4
|
export const createOAuthAuthorizeHandler = (options) => async (c) => {
|
|
4
5
|
const continuation = c.req.query('continue');
|
|
@@ -17,15 +18,47 @@ export const createOAuthAuthorizeHandler = (options) => async (c) => {
|
|
|
17
18
|
const continuation = await sealContinuation(c, options, validation);
|
|
18
19
|
return c.redirect(appendParams(options.loginUrl, { continue: continuation }, c.req.url), 302);
|
|
19
20
|
}
|
|
20
|
-
|
|
21
|
-
return redirectWithOAuthError(validation.redirectUri, 'consent_required', validation.state, c.req.url);
|
|
22
|
-
}
|
|
23
|
-
const sealedState = await sealContinuation(c, options, validation, {
|
|
21
|
+
const consentState = {
|
|
24
22
|
acr: resolveOAuthAcr(session.sessionRecord),
|
|
25
23
|
authTime: session.sessionRecord.createdAt.toISOString(),
|
|
26
24
|
userId: session.user.id,
|
|
27
|
-
}
|
|
28
|
-
|
|
25
|
+
};
|
|
26
|
+
// Consent persistence (optional): skip the consent screen and issue the code directly
|
|
27
|
+
// when a stored grant for the exact (user, client) covers every requested scope.
|
|
28
|
+
// `prompt=consent` ALWAYS forces the screen; coverage is a strict set-superset check,
|
|
29
|
+
// so any requested scope absent from the grant re-shows consent (scope-escalation guard).
|
|
30
|
+
const skipConsent = prompt !== 'consent' &&
|
|
31
|
+
(await hasCoveringGrant(options.ports, session.user.id, validation.client.clientId, validation.scope));
|
|
32
|
+
if (prompt === 'none') {
|
|
33
|
+
if (!skipConsent) {
|
|
34
|
+
return redirectWithOAuthError(validation.redirectUri, 'consent_required', validation.state, c.req.url);
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
else if (!skipConsent) {
|
|
38
|
+
const sealedState = await sealContinuation(c, options, validation, consentState);
|
|
39
|
+
return c.redirect(appendParams(options.consentUrl, { state: sealedState }, c.req.url), 302);
|
|
40
|
+
}
|
|
41
|
+
const sealedState = await sealContinuation(c, options, validation, consentState);
|
|
42
|
+
const payload = await options.stateCodec.unseal(sealedState);
|
|
43
|
+
if (!payload) {
|
|
44
|
+
return oauthJsonError(c, 400, 'invalid_request', 'OAuth continuation is invalid.');
|
|
45
|
+
}
|
|
46
|
+
return issueAuthorizedCode(c, options, payload);
|
|
47
|
+
};
|
|
48
|
+
/**
|
|
49
|
+
* True iff `consentStore` is wired AND a stored grant for `(userId, clientId)` covers every
|
|
50
|
+
* requested scope (stored ⊇ requested). No store ⇒ false (legacy always-consent). The
|
|
51
|
+
* superset check is the scope-escalation invariant: a single uncovered scope forces consent.
|
|
52
|
+
*/
|
|
53
|
+
const hasCoveringGrant = async (ports, userId, clientId, requestedScope) => {
|
|
54
|
+
if (!ports.consentStore)
|
|
55
|
+
return false;
|
|
56
|
+
const grant = await ports.consentStore.getGrant(userId, clientId);
|
|
57
|
+
if (!grant)
|
|
58
|
+
return false;
|
|
59
|
+
const granted = new Set(grant.scopes);
|
|
60
|
+
const requested = requestedScope.split(/\s+/).filter(Boolean);
|
|
61
|
+
return requested.every((scope) => granted.has(scope));
|
|
29
62
|
};
|
|
30
63
|
const resumeLoginContinuation = async (c, options, continuation) => {
|
|
31
64
|
const payload = await options.stateCodec.unseal(continuation);
|
|
@@ -80,12 +113,16 @@ const validateAuthorizeRequest = async (c, ports) => {
|
|
|
80
113
|
const scopeResult = validateScope(c.req.query('scope') ?? '', client, redirectUri, state, c.req.url);
|
|
81
114
|
if (scopeResult instanceof Response)
|
|
82
115
|
return scopeResult;
|
|
116
|
+
const resourceResult = validateResource(c.req.queries('resource'), client, redirectUri, state, c.req.url);
|
|
117
|
+
if (resourceResult instanceof Response)
|
|
118
|
+
return resourceResult;
|
|
83
119
|
return {
|
|
84
120
|
client,
|
|
85
121
|
codeChallenge,
|
|
86
122
|
dpopJkt: c.req.query('dpop_jkt') ?? null,
|
|
87
123
|
nonce: c.req.query('nonce') ?? null,
|
|
88
124
|
redirectUri,
|
|
125
|
+
resource: resourceResult,
|
|
89
126
|
scope: scopeResult,
|
|
90
127
|
state,
|
|
91
128
|
};
|
|
@@ -120,9 +157,49 @@ const validateScope = (scope, client, redirectUri, state, baseUrl) => {
|
|
|
120
157
|
}
|
|
121
158
|
return requestedScopes.join(' ');
|
|
122
159
|
};
|
|
160
|
+
/**
|
|
161
|
+
* RFC 8707 resource indicator validation on the `authorization_code` flow (BR-39l Lot 2).
|
|
162
|
+
* - C1 single-aud: more than one `resource` value ⇒ `invalid_target` (no multi-audience tokens).
|
|
163
|
+
* - C2 default-deny allowlist: a requested `resource` must be in `client.resourceIndicators`,
|
|
164
|
+
* else `invalid_target`. No `resource` ⇒ `null` (default-aud = userinfo, byte-identical to 0.5.0).
|
|
165
|
+
* The validated value is sealed into the continuation and becomes the access-token `aud`.
|
|
166
|
+
*/
|
|
167
|
+
const validateResource = (resources, client, redirectUri, state, baseUrl) => {
|
|
168
|
+
const requested = (resources ?? []).filter((value) => value.length > 0);
|
|
169
|
+
if (requested.length === 0)
|
|
170
|
+
return null;
|
|
171
|
+
if (requested.length > 1) {
|
|
172
|
+
return redirectWithOAuthError(redirectUri, 'invalid_target', state, baseUrl);
|
|
173
|
+
}
|
|
174
|
+
const value = requested[0];
|
|
175
|
+
const allowlist = client.resourceIndicators ?? [];
|
|
176
|
+
if (!allowlist.includes(value)) {
|
|
177
|
+
return redirectWithOAuthError(redirectUri, 'invalid_target', state, baseUrl);
|
|
178
|
+
}
|
|
179
|
+
return value;
|
|
180
|
+
};
|
|
123
181
|
const sealContinuation = async (c, options, request, session) => {
|
|
124
182
|
const now = options.ports.clock.now();
|
|
125
183
|
const expiresAt = options.ports.clock.addSeconds(now, options.stateTtlSeconds ?? 10 * 60);
|
|
184
|
+
// BR-39e: derive the tenant bound to this auth code from the user's VALIDATED membership,
|
|
185
|
+
// never from the raw client/param. Legacy behavior (client tenant) when no tenancy spine is
|
|
186
|
+
// wired. An explicit `?tenant=` selection is honored ONLY if it is an approved membership.
|
|
187
|
+
let tenantId = request.client.tenantId;
|
|
188
|
+
if (options.ports.tenant) {
|
|
189
|
+
tenantId = null;
|
|
190
|
+
if (session?.userId) {
|
|
191
|
+
const approved = await options.ports.tenant.listApprovedTenantIds(session.userId);
|
|
192
|
+
const requested = c.req.query('tenant') ?? null;
|
|
193
|
+
if (requested) {
|
|
194
|
+
tenantId = approved.includes(requested) ? requested : null;
|
|
195
|
+
}
|
|
196
|
+
else if (approved.length === 1) {
|
|
197
|
+
tenantId = approved[0];
|
|
198
|
+
}
|
|
199
|
+
// 0 or >1 approved tenants without a valid explicit selection → no tenant claim
|
|
200
|
+
// (a multi-tenant selection screen is deferred; the RP may re-request with ?tenant=).
|
|
201
|
+
}
|
|
202
|
+
}
|
|
126
203
|
return options.stateCodec.seal({
|
|
127
204
|
acr: session?.acr,
|
|
128
205
|
authTime: session?.authTime,
|
|
@@ -134,9 +211,10 @@ const sealContinuation = async (c, options, request, session) => {
|
|
|
134
211
|
expiresAt: expiresAt.toISOString(),
|
|
135
212
|
nonce: request.nonce,
|
|
136
213
|
redirectUri: request.redirectUri,
|
|
214
|
+
resource: request.resource,
|
|
137
215
|
scope: request.scope,
|
|
138
216
|
state: request.state,
|
|
139
|
-
tenantId
|
|
217
|
+
tenantId,
|
|
140
218
|
userId: session?.userId,
|
|
141
219
|
});
|
|
142
220
|
};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"authorize-handler.js","sourceRoot":"","sources":["../../src/oauth/authorize-handler.ts"],"names":[],"mappings":"AAKA,OAAO,EAAE,YAAY,EAAE,cAAc,EAAE,sBAAsB,EAAE,MAAM,iBAAiB,CAAC;AACvF,OAAO,EAAE,eAAe,EAAE,mBAAmB,EAAE,MAAM,uBAAuB,CAAC;
|
|
1
|
+
{"version":3,"file":"authorize-handler.js","sourceRoot":"","sources":["../../src/oauth/authorize-handler.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"consent-decision-handler.d.ts","sourceRoot":"","sources":["../../src/oauth/consent-decision-handler.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,MAAM,CAAC;AAEpC,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;
|
|
1
|
+
{"version":3,"file":"consent-decision-handler.d.ts","sourceRoot":"","sources":["../../src/oauth/consent-decision-handler.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,MAAM,CAAC;AAEpC,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAGjD,OAAO,KAAK,EAAE,sBAAsB,EAA0B,MAAM,kBAAkB,CAAC;AAGvF,MAAM,WAAW,0BAA0B;IACzC,2BAA2B,CAAC,EAAE,MAAM,CAAC;IACrC,KAAK,EAAE,aAAa,CAAC;IACrB,UAAU,EAAE,sBAAsB,CAAC;CACpC;AAED,eAAO,MAAM,gCAAgC,YACjC,0BAA0B,SAC1B,OAAO,KAAG,QAAQ,QAAQ,CAanC,CAAC;AAEJ,eAAO,MAAM,iCAAiC,YAClC,0BAA0B,SAC1B,OAAO,KAAG,QAAQ,QAAQ,CA2BnC,CAAC"}
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { appendParams, oauthJsonError, redirectOrJson } from './http-utils.js';
|
|
2
|
+
import { issueAuthorizedCode } from './issue-authorized-code.js';
|
|
2
3
|
import { resolveOAuthSession } from './session-resolver.js';
|
|
3
4
|
export const createOAuthConsentDetailsHandler = (options) => async (c) => {
|
|
4
5
|
const state = c.req.query('state') ?? '';
|
|
@@ -25,24 +26,12 @@ export const createOAuthConsentDecisionHandler = (options) => async (c) => {
|
|
|
25
26
|
if (body.decision === 'deny') {
|
|
26
27
|
return redirectOrJson(c, appendParams(payload.redirectUri, { error: 'access_denied', state: payload.state }, c.req.url));
|
|
27
28
|
}
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
codeChallenge: payload.codeChallenge,
|
|
35
|
-
codeChallengeMethod: 'S256',
|
|
36
|
-
createdAt: now,
|
|
37
|
-
dpopJkt: payload.dpopJkt,
|
|
38
|
-
expiresAt: options.ports.clock.addSeconds(now, options.authorizationCodeTtlSeconds ?? 60),
|
|
39
|
-
nonce: payload.nonce,
|
|
40
|
-
redirectUri: payload.redirectUri,
|
|
41
|
-
scope: payload.scope,
|
|
42
|
-
tenantId: payload.tenantId,
|
|
43
|
-
userId: payload.userId ?? '',
|
|
44
|
-
}, options.authorizationCodeTtlSeconds ?? 60);
|
|
45
|
-
return redirectOrJson(c, appendParams(payload.redirectUri, { code, state: payload.state }, c.req.url));
|
|
29
|
+
// Persist the grant so subsequent authorize requests for a covered scope set skip consent.
|
|
30
|
+
// Approve-only: a deny never records a grant. Absent consentStore ⇒ legacy (no persistence).
|
|
31
|
+
if (options.ports.consentStore && payload.userId) {
|
|
32
|
+
await options.ports.consentStore.saveGrant(payload.userId, payload.clientId, payload.scope.split(/\s+/).filter(Boolean));
|
|
33
|
+
}
|
|
34
|
+
return issueAuthorizedCode(c, options, payload);
|
|
46
35
|
};
|
|
47
36
|
const validateConsentState = async (c, options, sealedState) => {
|
|
48
37
|
const payload = await options.stateCodec.unseal(sealedState);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"consent-decision-handler.js","sourceRoot":"","sources":["../../src/oauth/consent-decision-handler.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,YAAY,EAAE,cAAc,EAAE,cAAc,EAAE,MAAM,iBAAiB,CAAC;
|
|
1
|
+
{"version":3,"file":"consent-decision-handler.js","sourceRoot":"","sources":["../../src/oauth/consent-decision-handler.ts"],"names":[],"mappings":"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"}
|
package/dist/oauth/dpop.d.ts
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { type VerifiedDpop } from '@sentropic/oauth-verify';
|
|
1
2
|
import type { AuthHonoPorts } from '../ports.js';
|
|
2
3
|
export interface VerifyDpopProofOptions {
|
|
3
4
|
accessToken?: string;
|
|
@@ -7,12 +8,14 @@ export interface VerifyDpopProofOptions {
|
|
|
7
8
|
ports: AuthHonoPorts;
|
|
8
9
|
proof: string;
|
|
9
10
|
}
|
|
10
|
-
export
|
|
11
|
-
jkt: string;
|
|
12
|
-
jti: string;
|
|
13
|
-
}
|
|
11
|
+
export type VerifiedDpopProof = VerifiedDpop;
|
|
14
12
|
export declare class OAuthDpopProofError extends Error {
|
|
15
13
|
constructor(message: string);
|
|
16
14
|
}
|
|
15
|
+
/**
|
|
16
|
+
* AS-side DPoP proof verification. Thin adapter over `@sentropic/oauth-verify`'s shared
|
|
17
|
+
* `verifyDpopProof`: it binds the IdP's clock + replay store and re-maps verification
|
|
18
|
+
* failures onto `OAuthDpopProofError` for the OAuth handlers (token/userinfo/revoke).
|
|
19
|
+
*/
|
|
17
20
|
export declare const verifyOAuthDpopProof: (options: VerifyDpopProofOptions) => Promise<VerifiedDpopProof>;
|
|
18
21
|
//# sourceMappingURL=dpop.d.ts.map
|
package/dist/oauth/dpop.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"dpop.d.ts","sourceRoot":"","sources":["../../src/oauth/dpop.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"dpop.d.ts","sourceRoot":"","sources":["../../src/oauth/dpop.ts"],"names":[],"mappings":"AAAA,OAAO,EAGL,KAAK,YAAY,EAClB,MAAM,yBAAyB,CAAC;AAEjC,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAEjD,MAAM,WAAW,sBAAsB;IACrC,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,GAAG,EAAE,MAAM,CAAC;IACZ,GAAG,EAAE,MAAM,CAAC;IACZ,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,KAAK,EAAE,aAAa,CAAC;IACrB,KAAK,EAAE,MAAM,CAAC;CACf;AAED,MAAM,MAAM,iBAAiB,GAAG,YAAY,CAAC;AAE7C,qBAAa,mBAAoB,SAAQ,KAAK;gBAChC,OAAO,EAAE,MAAM;CAI5B;AAED;;;;GAIG;AACH,eAAO,MAAM,oBAAoB,YACtB,sBAAsB,KAC9B,QAAQ,iBAAiB,CAsB3B,CAAC"}
|
package/dist/oauth/dpop.js
CHANGED
|
@@ -1,54 +1,33 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import { sha256Base64url } from './crypto-utils.js';
|
|
1
|
+
import { DpopVerifyError, verifyDpopProof, } from '@sentropic/oauth-verify';
|
|
3
2
|
export class OAuthDpopProofError extends Error {
|
|
4
3
|
constructor(message) {
|
|
5
4
|
super(message);
|
|
6
5
|
this.name = 'OAuthDpopProofError';
|
|
7
6
|
}
|
|
8
7
|
}
|
|
8
|
+
/**
|
|
9
|
+
* AS-side DPoP proof verification. Thin adapter over `@sentropic/oauth-verify`'s shared
|
|
10
|
+
* `verifyDpopProof`: it binds the IdP's clock + replay store and re-maps verification
|
|
11
|
+
* failures onto `OAuthDpopProofError` for the OAuth handlers (token/userinfo/revoke).
|
|
12
|
+
*/
|
|
9
13
|
export const verifyOAuthDpopProof = async (options) => {
|
|
10
|
-
const
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
};
|
|
28
|
-
const validateDpopPayload = async (payload, options) => {
|
|
29
|
-
if (payload.htm !== options.htm.toUpperCase()) {
|
|
30
|
-
throw new OAuthDpopProofError('DPoP htm claim does not match the request method.');
|
|
31
|
-
}
|
|
32
|
-
if (payload.htu !== options.htu) {
|
|
33
|
-
throw new OAuthDpopProofError('DPoP htu claim does not match the request URL.');
|
|
34
|
-
}
|
|
35
|
-
if (!payload.jti || typeof payload.jti !== 'string') {
|
|
36
|
-
throw new OAuthDpopProofError('DPoP jti claim is required.');
|
|
37
|
-
}
|
|
38
|
-
if (typeof payload.iat !== 'number') {
|
|
39
|
-
throw new OAuthDpopProofError('DPoP iat claim is required.');
|
|
40
|
-
}
|
|
41
|
-
const nowSeconds = Math.floor(options.ports.clock.now().getTime() / 1000);
|
|
42
|
-
if (Math.abs(payload.iat - nowSeconds) > (options.iatSkewSeconds ?? 60)) {
|
|
43
|
-
throw new OAuthDpopProofError('DPoP iat claim is outside the allowed skew.');
|
|
44
|
-
}
|
|
45
|
-
if (options.accessToken) {
|
|
46
|
-
await validateAth(payload, options.accessToken);
|
|
47
|
-
}
|
|
48
|
-
};
|
|
49
|
-
const validateAth = async (payload, accessToken) => {
|
|
50
|
-
if (payload.ath !== (await sha256Base64url(accessToken))) {
|
|
51
|
-
throw new OAuthDpopProofError('DPoP ath claim does not match the access token.');
|
|
14
|
+
const iatSkewSec = options.iatSkewSeconds ?? 60;
|
|
15
|
+
try {
|
|
16
|
+
return await verifyDpopProof({
|
|
17
|
+
accessToken: options.accessToken,
|
|
18
|
+
htm: options.htm,
|
|
19
|
+
htu: options.htu,
|
|
20
|
+
iatSkewSec,
|
|
21
|
+
now: options.ports.clock.now(),
|
|
22
|
+
proof: options.proof,
|
|
23
|
+
replay: (jti) => options.ports.oauthStateStore.recordDpopJti(jti, options.ports.clock.addSeconds(options.ports.clock.now(), iatSkewSec)),
|
|
24
|
+
});
|
|
25
|
+
}
|
|
26
|
+
catch (error) {
|
|
27
|
+
if (error instanceof DpopVerifyError) {
|
|
28
|
+
throw new OAuthDpopProofError(error.message);
|
|
29
|
+
}
|
|
30
|
+
throw error;
|
|
52
31
|
}
|
|
53
32
|
};
|
|
54
33
|
//# sourceMappingURL=dpop.js.map
|
package/dist/oauth/dpop.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"dpop.js","sourceRoot":"","sources":["../../src/oauth/dpop.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,
|
|
1
|
+
{"version":3,"file":"dpop.js","sourceRoot":"","sources":["../../src/oauth/dpop.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,eAAe,EACf,eAAe,GAEhB,MAAM,yBAAyB,CAAC;AAejC,MAAM,OAAO,mBAAoB,SAAQ,KAAK;IAC5C,YAAY,OAAe;QACzB,KAAK,CAAC,OAAO,CAAC,CAAC;QACf,IAAI,CAAC,IAAI,GAAG,qBAAqB,CAAC;IACpC,CAAC;CACF;AAED;;;;GAIG;AACH,MAAM,CAAC,MAAM,oBAAoB,GAAG,KAAK,EACvC,OAA+B,EACH,EAAE;IAC9B,MAAM,UAAU,GAAG,OAAO,CAAC,cAAc,IAAI,EAAE,CAAC;IAChD,IAAI,CAAC;QACH,OAAO,MAAM,eAAe,CAAC;YAC3B,WAAW,EAAE,OAAO,CAAC,WAAW;YAChC,GAAG,EAAE,OAAO,CAAC,GAAG;YAChB,GAAG,EAAE,OAAO,CAAC,GAAG;YAChB,UAAU;YACV,GAAG,EAAE,OAAO,CAAC,KAAK,CAAC,KAAK,CAAC,GAAG,EAAE;YAC9B,KAAK,EAAE,OAAO,CAAC,KAAK;YACpB,MAAM,EAAE,CAAC,GAAG,EAAE,EAAE,CACd,OAAO,CAAC,KAAK,CAAC,eAAe,CAAC,aAAa,CACzC,GAAG,EACH,OAAO,CAAC,KAAK,CAAC,KAAK,CAAC,UAAU,CAAC,OAAO,CAAC,KAAK,CAAC,KAAK,CAAC,GAAG,EAAE,EAAE,UAAU,CAAC,CACtE;SACJ,CAAC,CAAC;IACL,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,IAAI,KAAK,YAAY,eAAe,EAAE,CAAC;YACrC,MAAM,IAAI,mBAAmB,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC;QAC/C,CAAC;QACD,MAAM,KAAK,CAAC;IACd,CAAC;AACH,CAAC,CAAC"}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import type { Context } from 'hono';
|
|
2
|
+
import type { AuthHonoPorts } from '../ports.js';
|
|
3
|
+
import type { OAuthContinuationState } from './state-codec.js';
|
|
4
|
+
export interface IssueAuthorizedCodeOptions {
|
|
5
|
+
authorizationCodeTtlSeconds?: number;
|
|
6
|
+
ports: AuthHonoPorts;
|
|
7
|
+
}
|
|
8
|
+
/**
|
|
9
|
+
* Single source of truth for issuing an authorization code: mint a single-use code,
|
|
10
|
+
* persist its sealed payload, and redirect (or JSON) back to the RP `redirect_uri` with
|
|
11
|
+
* `code` + `state`. Called by BOTH the consent-approve path and the authorize skip-path
|
|
12
|
+
* (FL-1: never duplicate the seal / single-use-code / redirect logic).
|
|
13
|
+
*/
|
|
14
|
+
export declare const issueAuthorizedCode: (c: Context, options: IssueAuthorizedCodeOptions, payload: OAuthContinuationState) => Promise<Response>;
|
|
15
|
+
//# sourceMappingURL=issue-authorized-code.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"issue-authorized-code.d.ts","sourceRoot":"","sources":["../../src/oauth/issue-authorized-code.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,MAAM,CAAC;AAEpC,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAEjD,OAAO,KAAK,EAAE,sBAAsB,EAAE,MAAM,kBAAkB,CAAC;AAE/D,MAAM,WAAW,0BAA0B;IACzC,2BAA2B,CAAC,EAAE,MAAM,CAAC;IACrC,KAAK,EAAE,aAAa,CAAC;CACtB;AAED;;;;;GAKG;AACH,eAAO,MAAM,mBAAmB,MAC3B,OAAO,WACD,0BAA0B,WAC1B,sBAAsB,KAC9B,QAAQ,QAAQ,CA4BlB,CAAC"}
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import { appendParams, redirectOrJson } from './http-utils.js';
|
|
2
|
+
/**
|
|
3
|
+
* Single source of truth for issuing an authorization code: mint a single-use code,
|
|
4
|
+
* persist its sealed payload, and redirect (or JSON) back to the RP `redirect_uri` with
|
|
5
|
+
* `code` + `state`. Called by BOTH the consent-approve path and the authorize skip-path
|
|
6
|
+
* (FL-1: never duplicate the seal / single-use-code / redirect logic).
|
|
7
|
+
*/
|
|
8
|
+
export const issueAuthorizedCode = async (c, options, payload) => {
|
|
9
|
+
const code = options.ports.random.token(32);
|
|
10
|
+
const now = options.ports.clock.now();
|
|
11
|
+
await options.ports.oauthStateStore.saveAuthCode(code, {
|
|
12
|
+
acr: payload.acr ?? 'urn:sentropic:loa:bearer',
|
|
13
|
+
authTime: new Date(payload.authTime ?? now.toISOString()),
|
|
14
|
+
clientId: payload.clientId,
|
|
15
|
+
codeChallenge: payload.codeChallenge,
|
|
16
|
+
codeChallengeMethod: 'S256',
|
|
17
|
+
createdAt: now,
|
|
18
|
+
dpopJkt: payload.dpopJkt,
|
|
19
|
+
expiresAt: options.ports.clock.addSeconds(now, options.authorizationCodeTtlSeconds ?? 60),
|
|
20
|
+
nonce: payload.nonce,
|
|
21
|
+
redirectUri: payload.redirectUri,
|
|
22
|
+
resource: payload.resource ?? null,
|
|
23
|
+
scope: payload.scope,
|
|
24
|
+
tenantId: payload.tenantId,
|
|
25
|
+
userId: payload.userId ?? '',
|
|
26
|
+
}, options.authorizationCodeTtlSeconds ?? 60);
|
|
27
|
+
return redirectOrJson(c, appendParams(payload.redirectUri, { code, state: payload.state }, c.req.url));
|
|
28
|
+
};
|
|
29
|
+
//# sourceMappingURL=issue-authorized-code.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"issue-authorized-code.js","sourceRoot":"","sources":["../../src/oauth/issue-authorized-code.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,YAAY,EAAE,cAAc,EAAE,MAAM,iBAAiB,CAAC;AAQ/D;;;;;GAKG;AACH,MAAM,CAAC,MAAM,mBAAmB,GAAG,KAAK,EACtC,CAAU,EACV,OAAmC,EACnC,OAA+B,EACZ,EAAE;IACrB,MAAM,IAAI,GAAG,OAAO,CAAC,KAAK,CAAC,MAAM,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC;IAC5C,MAAM,GAAG,GAAG,OAAO,CAAC,KAAK,CAAC,KAAK,CAAC,GAAG,EAAE,CAAC;IACtC,MAAM,OAAO,CAAC,KAAK,CAAC,eAAe,CAAC,YAAY,CAC9C,IAAI,EACJ;QACE,GAAG,EAAE,OAAO,CAAC,GAAG,IAAI,0BAA0B;QAC9C,QAAQ,EAAE,IAAI,IAAI,CAAC,OAAO,CAAC,QAAQ,IAAI,GAAG,CAAC,WAAW,EAAE,CAAC;QACzD,QAAQ,EAAE,OAAO,CAAC,QAAQ;QAC1B,aAAa,EAAE,OAAO,CAAC,aAAa;QACpC,mBAAmB,EAAE,MAAM;QAC3B,SAAS,EAAE,GAAG;QACd,OAAO,EAAE,OAAO,CAAC,OAAO;QACxB,SAAS,EAAE,OAAO,CAAC,KAAK,CAAC,KAAK,CAAC,UAAU,CAAC,GAAG,EAAE,OAAO,CAAC,2BAA2B,IAAI,EAAE,CAAC;QACzF,KAAK,EAAE,OAAO,CAAC,KAAK;QACpB,WAAW,EAAE,OAAO,CAAC,WAAW;QAChC,QAAQ,EAAE,OAAO,CAAC,QAAQ,IAAI,IAAI;QAClC,KAAK,EAAE,OAAO,CAAC,KAAK;QACpB,QAAQ,EAAE,OAAO,CAAC,QAAQ;QAC1B,MAAM,EAAE,OAAO,CAAC,MAAM,IAAI,EAAE;KAC7B,EACD,OAAO,CAAC,2BAA2B,IAAI,EAAE,CAC1C,CAAC;IAEF,OAAO,cAAc,CACnB,CAAC,EACD,YAAY,CAAC,OAAO,CAAC,WAAW,EAAE,EAAE,IAAI,EAAE,KAAK,EAAE,OAAO,CAAC,KAAK,EAAE,EAAE,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAC7E,CAAC;AACJ,CAAC,CAAC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"jwks-service.d.ts","sourceRoot":"","sources":["../../src/oauth/jwks-service.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"jwks-service.d.ts","sourceRoot":"","sources":["../../src/oauth/jwks-service.ts"],"names":[],"mappings":"AACA,OAAO,EAIL,KAAK,gBAAgB,EACrB,KAAK,eAAe,EACpB,KAAK,UAAU,EAChB,MAAM,MAAM,CAAC;AAEd,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,aAAa,CAAC;AACrD,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,wBAAwB,CAAC;AAEvD,MAAM,WAAW,wBAAwB;IACvC,KAAK,EAAE,iBAAiB,CAAC;IACzB,QAAQ,EAAE,QAAQ,CAAC;CACpB;AAED,MAAM,WAAW,eAAe;IAC9B,QAAQ,CAAC,EAAE,MAAM,GAAG,MAAM,EAAE,CAAC;IAC7B,SAAS,CAAC,EAAE,IAAI,CAAC;IACjB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,IAAI,CAAC,EAAE,MAAM,CAAC;CACf;AAED,MAAM,WAAW,UAAU;IACzB,IAAI,EAAE,KAAK,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,CAAC;CACtC;AAED,MAAM,WAAW,WAAW;IAC1B,aAAa,IAAI,OAAO,CAAC,UAAU,CAAC,CAAC;IACrC,OAAO,CAAC,OAAO,EAAE,UAAU,EAAE,OAAO,CAAC,EAAE,eAAe,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC;IACzE,SAAS,CAAC,CAAC,SAAS,UAAU,GAAG,UAAU,EACzC,GAAG,EAAE,MAAM,EACX,OAAO,CAAC,EAAE,gBAAgB,GACzB,OAAO,CAAC,eAAe,CAAC,CAAC,CAAC,CAAC,CAAC;CAChC;AAED,eAAO,MAAM,iBAAiB,wBAAyB,wBAAwB,KAAG,WAwDhF,CAAC"}
|
|
@@ -1,4 +1,5 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { fromJwksPort } from '@sentropic/oauth-verify';
|
|
2
|
+
import { decodeProtectedHeader, jwtVerify, SignJWT, } from 'jose';
|
|
2
3
|
export const createJwksService = ({ clock, jwksPort }) => ({
|
|
3
4
|
async getPublicJwks() {
|
|
4
5
|
const keys = await jwksPort.listPublicKeys();
|
|
@@ -45,15 +46,12 @@ export const createJwksService = ({ clock, jwksPort }) => ({
|
|
|
45
46
|
},
|
|
46
47
|
async verifyJwt(jwt, options = {}) {
|
|
47
48
|
const protectedHeader = decodeProtectedHeader(jwt);
|
|
48
|
-
|
|
49
|
-
if (!kid) {
|
|
49
|
+
if (!protectedHeader.kid) {
|
|
50
50
|
throw new Error('JWT protected header is missing kid.');
|
|
51
51
|
}
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
}
|
|
56
|
-
const publicKey = await importJWK(key.publicJwk, key.alg);
|
|
52
|
+
// Key resolution is shared with @sentropic/oauth-verify (single verify core); the
|
|
53
|
+
// AS-side claim assertions (iss/aud/currentDate) stay here via jose JWTVerifyOptions.
|
|
54
|
+
const publicKey = await fromJwksPort(jwksPort).resolveKey(protectedHeader);
|
|
57
55
|
return jwtVerify(jwt, publicKey, options);
|
|
58
56
|
},
|
|
59
57
|
});
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"jwks-service.js","sourceRoot":"","sources":["../../src/oauth/jwks-service.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,qBAAqB,EACrB,SAAS,EACT,
|
|
1
|
+
{"version":3,"file":"jwks-service.js","sourceRoot":"","sources":["../../src/oauth/jwks-service.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"service-auth-middleware.d.ts","sourceRoot":"","sources":["../../src/oauth/service-auth-middleware.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"service-auth-middleware.d.ts","sourceRoot":"","sources":["../../src/oauth/service-auth-middleware.ts"],"names":[],"mappings":"AAeA,OAAO,KAAK,EAAW,iBAAiB,EAAE,MAAM,MAAM,CAAC;AAEvD,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,aAAa,CAAC;AACrD,OAAO,KAAK,EAAE,QAAQ,EAAE,mBAAmB,EAAE,MAAM,wBAAwB,CAAC;AAE5E;;;;GAIG;AACH,MAAM,WAAW,gBAAgB;IAC/B,KAAK,EAAE,iBAAiB,CAAC;IACzB,IAAI,EAAE,QAAQ,CAAC;IACf,UAAU,CAAC,EAAE,IAAI,CAAC,mBAAmB,EAAE,eAAe,CAAC,CAAC;CACzD;AAED,MAAM,WAAW,kBAAkB;IACjC,QAAQ,EAAE,MAAM,CAAC;IACjB,MAAM,EAAE,MAAM,EAAE,CAAC;IACjB,GAAG,EAAE,MAAM,GAAG,IAAI,CAAC;CACpB;AAED,MAAM,WAAW,+BAA+B;IAC9C,MAAM,EAAE,MAAM,CAAC;IACf,cAAc,CAAC,EAAE,MAAM,EAAE,CAAC;IAC1B,QAAQ,EAAE,MAAM,CAAC;IACjB,KAAK,EAAE,gBAAgB,CAAC;IACxB,gEAAgE;IAChE,kBAAkB,CAAC,EAAE,MAAM,CAAC;IAC5B,iGAAiG;IACjG,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB;AAcD,eAAO,MAAM,wBAAwB,YAC1B,+BAA+B,KACvC,iBA6BF,CAAC"}
|