@_mustachio/openauth 0.10.0 → 0.11.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/dist/esm/adapters/memory/session-store.js +22 -0
- package/dist/esm/adapters/memory/token-store.js +13 -0
- package/dist/esm/client.js +9 -2
- package/dist/esm/domain/authorize.js +5 -0
- package/dist/esm/domain/callback.js +3 -0
- package/dist/esm/domain/discovery.js +44 -2
- package/dist/esm/domain/dpop.js +122 -0
- package/dist/esm/domain/id-token.js +94 -0
- package/dist/esm/domain/introspect.js +5 -1
- package/dist/esm/domain/jwt.js +28 -0
- package/dist/esm/domain/logout.js +75 -0
- package/dist/esm/domain/method-route.js +3 -0
- package/dist/esm/domain/par.js +51 -0
- package/dist/esm/domain/refresh.js +12 -1
- package/dist/esm/domain/register.js +74 -0
- package/dist/esm/domain/token-exchange.js +1 -0
- package/dist/esm/domain/token.js +48 -7
- package/dist/esm/domain/userinfo.js +38 -3
- package/dist/esm/http/handlers/authorize.js +90 -3
- package/dist/esm/http/handlers/end-session.js +64 -0
- package/dist/esm/http/handlers/metadata.js +5 -2
- package/dist/esm/http/handlers/par.js +53 -0
- package/dist/esm/http/handlers/register.js +46 -0
- package/dist/esm/http/handlers/token.js +36 -6
- package/dist/esm/http/handlers/userinfo.js +35 -29
- package/dist/esm/http/router.js +10 -0
- package/dist/esm/http/schemas/authorize.js +7 -1
- package/dist/esm/http/schemas/end-session.js +13 -0
- package/dist/esm/http/schemas/par.js +9 -0
- package/dist/esm/http/schemas/register.js +16 -0
- package/dist/esm/index.js +7 -2
- package/dist/esm/types/error.js +5 -0
- package/dist/types/adapters/memory/session-store.d.ts +3 -1
- package/dist/types/adapters/memory/session-store.d.ts.map +1 -1
- package/dist/types/adapters/memory/token-store.d.ts +1 -0
- package/dist/types/adapters/memory/token-store.d.ts.map +1 -1
- package/dist/types/client.d.ts +19 -0
- package/dist/types/client.d.ts.map +1 -1
- package/dist/types/domain/authorize.d.ts.map +1 -1
- package/dist/types/domain/client-credentials.d.ts +2 -0
- package/dist/types/domain/client-credentials.d.ts.map +1 -1
- package/dist/types/domain/discovery.d.ts +37 -0
- package/dist/types/domain/discovery.d.ts.map +1 -1
- package/dist/types/domain/dpop.d.ts +61 -0
- package/dist/types/domain/dpop.d.ts.map +1 -0
- package/dist/types/domain/id-token.d.ts +83 -0
- package/dist/types/domain/id-token.d.ts.map +1 -0
- package/dist/types/domain/introspect.d.ts +8 -0
- package/dist/types/domain/introspect.d.ts.map +1 -1
- package/dist/types/domain/jwt.d.ts +27 -1
- package/dist/types/domain/jwt.d.ts.map +1 -1
- package/dist/types/domain/logout.d.ts +69 -0
- package/dist/types/domain/logout.d.ts.map +1 -0
- package/dist/types/domain/par.d.ts +62 -0
- package/dist/types/domain/par.d.ts.map +1 -0
- package/dist/types/domain/refresh.d.ts +9 -0
- package/dist/types/domain/refresh.d.ts.map +1 -1
- package/dist/types/domain/register.d.ts +33 -0
- package/dist/types/domain/register.d.ts.map +1 -0
- package/dist/types/domain/token-exchange.d.ts +2 -0
- package/dist/types/domain/token-exchange.d.ts.map +1 -1
- package/dist/types/domain/token.d.ts +41 -1
- package/dist/types/domain/token.d.ts.map +1 -1
- package/dist/types/domain/userinfo.d.ts +44 -5
- package/dist/types/domain/userinfo.d.ts.map +1 -1
- package/dist/types/http/context.d.ts +4 -1
- package/dist/types/http/context.d.ts.map +1 -1
- package/dist/types/http/handlers/authorize.d.ts.map +1 -1
- package/dist/types/http/handlers/end-session.d.ts +3 -0
- package/dist/types/http/handlers/end-session.d.ts.map +1 -0
- package/dist/types/http/handlers/metadata.d.ts +1 -1
- package/dist/types/http/handlers/metadata.d.ts.map +1 -1
- package/dist/types/http/handlers/par.d.ts +3 -0
- package/dist/types/http/handlers/par.d.ts.map +1 -0
- package/dist/types/http/handlers/register.d.ts +3 -0
- package/dist/types/http/handlers/register.d.ts.map +1 -0
- package/dist/types/http/handlers/token.d.ts.map +1 -1
- package/dist/types/http/handlers/userinfo.d.ts.map +1 -1
- package/dist/types/http/router.d.ts.map +1 -1
- package/dist/types/http/schemas/authorize.d.ts +40 -0
- package/dist/types/http/schemas/authorize.d.ts.map +1 -1
- package/dist/types/http/schemas/end-session.d.ts +31 -0
- package/dist/types/http/schemas/end-session.d.ts.map +1 -0
- package/dist/types/http/schemas/par.d.ts +20 -0
- package/dist/types/http/schemas/par.d.ts.map +1 -0
- package/dist/types/http/schemas/register.d.ts +42 -0
- package/dist/types/http/schemas/register.d.ts.map +1 -0
- package/dist/types/index.d.ts +3 -3
- package/dist/types/index.d.ts.map +1 -1
- package/dist/types/ports/audit-log.d.ts +27 -0
- package/dist/types/ports/audit-log.d.ts.map +1 -1
- package/dist/types/ports/session-store.d.ts +27 -0
- package/dist/types/ports/session-store.d.ts.map +1 -1
- package/dist/types/ports/token-store.d.ts +12 -0
- package/dist/types/ports/token-store.d.ts.map +1 -1
- package/dist/types/types/authorization.d.ts +23 -0
- package/dist/types/types/authorization.d.ts.map +1 -1
- package/dist/types/types/error.d.ts +9 -0
- package/dist/types/types/error.d.ts.map +1 -1
- package/dist/types/types/flow.d.ts +10 -0
- package/dist/types/types/flow.d.ts.map +1 -1
- package/dist/types/types/idp.d.ts +91 -1
- package/dist/types/types/idp.d.ts.map +1 -1
- package/dist/types/types/tenant.d.ts +37 -0
- package/dist/types/types/tenant.d.ts.map +1 -1
- package/dist/types/types/token.d.ts +128 -0
- package/dist/types/types/token.d.ts.map +1 -1
- package/package.json +1 -1
- package/src/adapters/memory/session-store.ts +44 -1
- package/src/adapters/memory/token-store.ts +16 -0
- package/src/client.ts +32 -0
- package/src/domain/authorize.ts +9 -0
- package/src/domain/callback.ts +5 -0
- package/src/domain/client-credentials.ts +2 -0
- package/src/domain/discovery.ts +80 -2
- package/src/domain/dpop.ts +293 -0
- package/src/domain/id-token.ts +213 -0
- package/src/domain/introspect.ts +10 -0
- package/src/domain/jwt.ts +80 -1
- package/src/domain/logout.ts +180 -0
- package/src/domain/method-route.ts +5 -0
- package/src/domain/par.ts +141 -0
- package/src/domain/refresh.ts +41 -0
- package/src/domain/register.ts +168 -0
- package/src/domain/token-exchange.ts +11 -0
- package/src/domain/token.ts +134 -8
- package/src/domain/userinfo.ts +121 -6
- package/src/http/context.ts +4 -0
- package/src/http/handlers/authorize.ts +144 -3
- package/src/http/handlers/end-session.ts +106 -0
- package/src/http/handlers/metadata.ts +7 -2
- package/src/http/handlers/par.ts +84 -0
- package/src/http/handlers/register.ts +70 -0
- package/src/http/handlers/token.ts +56 -0
- package/src/http/handlers/userinfo.ts +62 -38
- package/src/http/router.ts +19 -0
- package/src/http/schemas/authorize.ts +27 -0
- package/src/http/schemas/end-session.ts +23 -0
- package/src/http/schemas/par.ts +23 -0
- package/src/http/schemas/register.ts +29 -0
- package/src/index.ts +18 -1
- package/src/ports/CONSISTENCY.md +52 -21
- package/src/ports/audit-log.ts +29 -0
- package/src/ports/session-store.ts +33 -0
- package/src/ports/token-store.ts +13 -0
- package/src/types/authorization.ts +25 -0
- package/src/types/error.ts +23 -0
- package/src/types/flow.ts +10 -0
- package/src/types/idp.ts +96 -0
- package/src/types/tenant.ts +37 -0
- package/src/types/token.ts +135 -0
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
import type { ClaimsRequest } from "../types/authorization";
|
|
2
|
+
import type { IdTokenClaims, ScopedProfileClaims } from "../types/token";
|
|
3
|
+
import type { SubjectClaim } from "../types/subject";
|
|
4
|
+
/**
|
|
5
|
+
* Derive `amr` from the originating `methodKind`. Values are RFC 8176
|
|
6
|
+
* registered AMR codes. Returns `undefined` when no clean mapping exists
|
|
7
|
+
* — `amr` is an OPTIONAL id_token claim, so omission is spec-compliant.
|
|
8
|
+
*/
|
|
9
|
+
export declare function deriveAmr(methodKind: string): string[] | undefined;
|
|
10
|
+
/**
|
|
11
|
+
* `at_hash` per OIDC Core §3.1.3.6: left-half of SHA-256(access_token
|
|
12
|
+
* ASCII), base64url. Always 16 bytes → 22 base64url characters for
|
|
13
|
+
* SHA-256 (256-bit → 128-bit half → 16 bytes → 22 chars).
|
|
14
|
+
*/
|
|
15
|
+
export declare function computeAtHash(accessToken: string): Promise<string>;
|
|
16
|
+
/**
|
|
17
|
+
* Filter a `SubjectClaim.properties` record down to claims granted by the
|
|
18
|
+
* requested OIDC scopes, then optionally augment with claim names the RP
|
|
19
|
+
* specifically requested via the OIDC Core §5.5 `claims` parameter.
|
|
20
|
+
* Returns a typed `ScopedProfileClaims` ready to spread into the id_token
|
|
21
|
+
* or `/userinfo` response. Properties not named by any granted scope or
|
|
22
|
+
* explicit claim request are dropped.
|
|
23
|
+
*
|
|
24
|
+
* `extra` is the set of claim names the RP requested via `claims`
|
|
25
|
+
* parameter for THIS surface (id_token vs userinfo). Listing a name in
|
|
26
|
+
* `extra` bypasses scope gating per §5.5 ("works without the requestor
|
|
27
|
+
* having to include the scope value").
|
|
28
|
+
*
|
|
29
|
+
* `customMappings` is a host-supplied scope → claim-names map merged on
|
|
30
|
+
* top of the OIDC Core §5.4 table. Lets the host expose vendor-specific
|
|
31
|
+
* identity fields (e.g. `tenant_id`, `org_role`) via a custom scope
|
|
32
|
+
* (`scope=foo` granting `[tenant_id, …]`). Reserved §5.4 names cannot be
|
|
33
|
+
* shadowed — the standard mapping always wins on collision so an
|
|
34
|
+
* `email` scope can't accidentally start meaning something else.
|
|
35
|
+
*
|
|
36
|
+
* Host-supplied values are trusted to match their declared OIDC types
|
|
37
|
+
* — schemas live on `IdPOptions.subjects`, not here. The narrowing cast
|
|
38
|
+
* is the boundary between "host's responsibility" and "framework's
|
|
39
|
+
* responsibility."
|
|
40
|
+
*/
|
|
41
|
+
export declare function pickScopedClaims(claim: SubjectClaim, scopes: ReadonlyArray<string>, extra?: ReadonlyArray<string>, customMappings?: Record<string, ReadonlyArray<string>>): ScopedProfileClaims;
|
|
42
|
+
export type BuildIdTokenInput = {
|
|
43
|
+
issuerUrl: string;
|
|
44
|
+
/** RP `client_id` — the id_token's `aud`. */
|
|
45
|
+
audience: string;
|
|
46
|
+
/** Stable subject identifier (same value as the access token's `sub`). */
|
|
47
|
+
subjectId: string;
|
|
48
|
+
claim: SubjectClaim;
|
|
49
|
+
scopes: ReadonlyArray<string>;
|
|
50
|
+
/** Seconds-since-epoch the user authenticated. */
|
|
51
|
+
authTime: number;
|
|
52
|
+
/** RP-supplied OIDC nonce, when present. */
|
|
53
|
+
appNonce?: string;
|
|
54
|
+
/** Wall clock (ms). */
|
|
55
|
+
now: number;
|
|
56
|
+
/** id_token TTL (ms). Default 5 minutes. */
|
|
57
|
+
ttlMs?: number;
|
|
58
|
+
/** Method kind for `amr` derivation. */
|
|
59
|
+
methodKind: string;
|
|
60
|
+
/** Pre-signed access token whose `at_hash` is bound into the id_token. */
|
|
61
|
+
accessToken: string;
|
|
62
|
+
/** OIDC Core §5.5 — RP-requested claims (this drives only id_token here). */
|
|
63
|
+
claimsRequest?: ClaimsRequest;
|
|
64
|
+
/**
|
|
65
|
+
* Host-supplied vendor scope → claim-names map. Merged on top of OIDC
|
|
66
|
+
* Core §5.4 at scope-gating time. See `pickScopedClaims`.
|
|
67
|
+
*/
|
|
68
|
+
customScopeClaims?: Record<string, ReadonlyArray<string>>;
|
|
69
|
+
};
|
|
70
|
+
export declare const DEFAULT_ID_TOKEN_TTL_MS: number;
|
|
71
|
+
/**
|
|
72
|
+
* Assemble an `IdTokenClaims` object. Pure — no crypto except `at_hash`.
|
|
73
|
+
* Caller signs the result via `signIdToken`.
|
|
74
|
+
*
|
|
75
|
+
* Composition is via spread so the type stays narrow: the base claim set
|
|
76
|
+
* (REQUIRED OIDC §2 + auth_time + at_hash + optional nonce/amr) is built
|
|
77
|
+
* first; the scope-gated §5.1 profile claims merge over the top via
|
|
78
|
+
* `...pickScopedClaims(...)`. No dynamic index assignment, no cast.
|
|
79
|
+
*/
|
|
80
|
+
export declare function buildIdTokenClaims(input: BuildIdTokenInput): Promise<IdTokenClaims>;
|
|
81
|
+
/** Predicate: does this token request warrant an `id_token` being issued? */
|
|
82
|
+
export declare function shouldIssueIdToken(scopes: ReadonlyArray<string>): boolean;
|
|
83
|
+
//# sourceMappingURL=id-token.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"id-token.d.ts","sourceRoot":"","sources":["../../../src/domain/id-token.ts"],"names":[],"mappings":"AAyBA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,wBAAwB,CAAA;AAC3D,OAAO,KAAK,EAAE,aAAa,EAAE,mBAAmB,EAAE,MAAM,gBAAgB,CAAA;AACxE,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,kBAAkB,CAAA;AA6BpD;;;;GAIG;AACH,wBAAgB,SAAS,CAAC,UAAU,EAAE,MAAM,GAAG,MAAM,EAAE,GAAG,SAAS,CAiBlE;AAED;;;;GAIG;AACH,wBAAsB,aAAa,CAAC,WAAW,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAIxE;AAED;;;;;;;;;;;;;;;;;;;;;;;;GAwBG;AACH,wBAAgB,gBAAgB,CAC9B,KAAK,EAAE,YAAY,EACnB,MAAM,EAAE,aAAa,CAAC,MAAM,CAAC,EAC7B,KAAK,GAAE,aAAa,CAAC,MAAM,CAAM,EACjC,cAAc,GAAE,MAAM,CAAC,MAAM,EAAE,aAAa,CAAC,MAAM,CAAC,CAAM,GACzD,mBAAmB,CAqBrB;AAED,MAAM,MAAM,iBAAiB,GAAG;IAC9B,SAAS,EAAE,MAAM,CAAA;IACjB,6CAA6C;IAC7C,QAAQ,EAAE,MAAM,CAAA;IAChB,0EAA0E;IAC1E,SAAS,EAAE,MAAM,CAAA;IACjB,KAAK,EAAE,YAAY,CAAA;IACnB,MAAM,EAAE,aAAa,CAAC,MAAM,CAAC,CAAA;IAC7B,kDAAkD;IAClD,QAAQ,EAAE,MAAM,CAAA;IAChB,4CAA4C;IAC5C,QAAQ,CAAC,EAAE,MAAM,CAAA;IACjB,uBAAuB;IACvB,GAAG,EAAE,MAAM,CAAA;IACX,4CAA4C;IAC5C,KAAK,CAAC,EAAE,MAAM,CAAA;IACd,wCAAwC;IACxC,UAAU,EAAE,MAAM,CAAA;IAClB,0EAA0E;IAC1E,WAAW,EAAE,MAAM,CAAA;IACnB,6EAA6E;IAC7E,aAAa,CAAC,EAAE,aAAa,CAAA;IAC7B;;;OAGG;IACH,iBAAiB,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,aAAa,CAAC,MAAM,CAAC,CAAC,CAAA;CAC1D,CAAA;AAED,eAAO,MAAM,uBAAuB,QAAgB,CAAA;AAEpD;;;;;;;;GAQG;AACH,wBAAsB,kBAAkB,CACtC,KAAK,EAAE,iBAAiB,GACvB,OAAO,CAAC,aAAa,CAAC,CAqBxB;AAED,6EAA6E;AAC7E,wBAAgB,kBAAkB,CAAC,MAAM,EAAE,aAAa,CAAC,MAAM,CAAC,GAAG,OAAO,CAEzE"}
|
|
@@ -43,9 +43,17 @@ export type IntrospectResponse = {
|
|
|
43
43
|
iat: number;
|
|
44
44
|
scope?: string;
|
|
45
45
|
client_id?: string;
|
|
46
|
+
/** RFC 7662 §2.2 — the token's type indicator. */
|
|
47
|
+
token_type: "Bearer" | "DPoP";
|
|
46
48
|
tid: string;
|
|
47
49
|
mid?: string;
|
|
48
50
|
mkind?: string;
|
|
51
|
+
/** Library-specific — subject schema discriminator (e.g. "user", "admin"). */
|
|
52
|
+
subject_type?: string;
|
|
53
|
+
/** RFC 9449 §6 — present when the access token is DPoP-bound. */
|
|
54
|
+
cnf?: {
|
|
55
|
+
jkt: string;
|
|
56
|
+
};
|
|
49
57
|
};
|
|
50
58
|
export type IntrospectRequest = {
|
|
51
59
|
token: string;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"introspect.d.ts","sourceRoot":"","sources":["../../../src/domain/introspect.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA4BG;AACH,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,uBAAuB,CAAA;AACxD,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,oBAAoB,CAAA;AAClD,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAA;AAE/C,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,iBAAiB,CAAA;AAG7C,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,iBAAiB,CAAA;AAK/C,MAAM,MAAM,kBAAkB,GAC1B;IAAE,MAAM,EAAE,KAAK,CAAA;CAAE,GACjB;IACE,MAAM,EAAE,IAAI,CAAA;IACZ,GAAG,EAAE,MAAM,CAAA;IACX,GAAG,EAAE,MAAM,CAAA;IACX,GAAG,EAAE,MAAM,CAAA;IACX,GAAG,EAAE,MAAM,CAAA;IACX,GAAG,EAAE,MAAM,CAAA;IACX,KAAK,CAAC,EAAE,MAAM,CAAA;IACd,SAAS,CAAC,EAAE,MAAM,CAAA;IAClB,GAAG,EAAE,MAAM,CAAA;IACX,GAAG,CAAC,EAAE,MAAM,CAAA;IACZ,KAAK,CAAC,EAAE,MAAM,CAAA;
|
|
1
|
+
{"version":3,"file":"introspect.d.ts","sourceRoot":"","sources":["../../../src/domain/introspect.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA4BG;AACH,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,uBAAuB,CAAA;AACxD,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,oBAAoB,CAAA;AAClD,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAA;AAE/C,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,iBAAiB,CAAA;AAG7C,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,iBAAiB,CAAA;AAK/C,MAAM,MAAM,kBAAkB,GAC1B;IAAE,MAAM,EAAE,KAAK,CAAA;CAAE,GACjB;IACE,MAAM,EAAE,IAAI,CAAA;IACZ,GAAG,EAAE,MAAM,CAAA;IACX,GAAG,EAAE,MAAM,CAAA;IACX,GAAG,EAAE,MAAM,CAAA;IACX,GAAG,EAAE,MAAM,CAAA;IACX,GAAG,EAAE,MAAM,CAAA;IACX,KAAK,CAAC,EAAE,MAAM,CAAA;IACd,SAAS,CAAC,EAAE,MAAM,CAAA;IAClB,kDAAkD;IAClD,UAAU,EAAE,QAAQ,GAAG,MAAM,CAAA;IAC7B,GAAG,EAAE,MAAM,CAAA;IACX,GAAG,CAAC,EAAE,MAAM,CAAA;IACZ,KAAK,CAAC,EAAE,MAAM,CAAA;IACd,8EAA8E;IAC9E,YAAY,CAAC,EAAE,MAAM,CAAA;IACrB,iEAAiE;IACjE,GAAG,CAAC,EAAE;QAAE,GAAG,EAAE,MAAM,CAAA;KAAE,CAAA;CACtB,CAAA;AAEL,MAAM,MAAM,iBAAiB,GAAG;IAC9B,KAAK,EAAE,MAAM,CAAA;IACb,aAAa,CAAC,EAAE,cAAc,GAAG,eAAe,CAAA;IAChD,gCAAgC;IAChC,QAAQ,EAAE,MAAM,CAAA;IAChB,YAAY,CAAC,EAAE,MAAM,CAAA;IACrB;;;;;OAKG;IACH,iBAAiB,EAAE,QAAQ,CAAA;CAC5B,CAAA;AAED,MAAM,MAAM,cAAc,GAAG;IAC3B,QAAQ,EAAE,QAAQ,CAAA;IAClB,WAAW,EAAE,WAAW,CAAA;IACxB,iDAAiD;IACjD,SAAS,CAAC,EAAE,MAAM,CAAA;CACnB,CAAA;AAED,wBAAsB,UAAU,CAC9B,GAAG,EAAE,iBAAiB,EACtB,IAAI,EAAE,cAAc,GACnB,OAAO,CAAC,MAAM,CAAC,kBAAkB,EAAE,SAAS,CAAC,CAAC,CAkEhD"}
|
|
@@ -7,7 +7,7 @@
|
|
|
7
7
|
* this module.
|
|
8
8
|
*/
|
|
9
9
|
import type { JWK, KeyLike } from "jose";
|
|
10
|
-
import type { AccessTokenClaims } from "../types/token";
|
|
10
|
+
import type { AccessTokenClaims, IdTokenClaims } from "../types/token";
|
|
11
11
|
import type { SigningKey } from "../ports/key-store";
|
|
12
12
|
/**
|
|
13
13
|
* Sign an access-token claim set under the supplied private key. `kid` is
|
|
@@ -15,6 +15,32 @@ import type { SigningKey } from "../ports/key-store";
|
|
|
15
15
|
* key from JWKS.
|
|
16
16
|
*/
|
|
17
17
|
export declare function signAccessToken(claims: AccessTokenClaims, privateKey: KeyLike, alg: string, kid: string): Promise<string>;
|
|
18
|
+
/**
|
|
19
|
+
* Sign an OIDC `id_token` claim set (OIDC Core §2). Header `typ` is
|
|
20
|
+
* `"JWT"` per common practice; OIDC Core does not mandate `"id_token"`.
|
|
21
|
+
* The claims object is verified by the caller to include `iss`, `sub`,
|
|
22
|
+
* `aud`, `exp`, `iat` (REQUIRED per §2).
|
|
23
|
+
*/
|
|
24
|
+
export declare function signIdToken(claims: IdTokenClaims, privateKey: KeyLike, alg: string, kid: string): Promise<string>;
|
|
25
|
+
/**
|
|
26
|
+
* Verify an OIDC `id_token` against the IdP's published signing keys.
|
|
27
|
+
* Used at `/end_session` to validate `id_token_hint` and by adjacent
|
|
28
|
+
* domain code that needs to introspect a previously-issued id_token.
|
|
29
|
+
*
|
|
30
|
+
* Same algorithm-confusion defenses as `verifyAccessToken`: only the
|
|
31
|
+
* asymmetric allow-list (`ES256`, `EdDSA`) accepted; `alg: "none"`
|
|
32
|
+
* rejected explicitly.
|
|
33
|
+
*
|
|
34
|
+
* `acceptExpired` relaxes the `exp` check — required at `/end_session`
|
|
35
|
+
* per OIDC RP-Initiated Logout 1.0 §2, where logout often follows token
|
|
36
|
+
* expiry and the spec permits accepting an expired hint. The signature
|
|
37
|
+
* + issuer + audience checks remain strict.
|
|
38
|
+
*/
|
|
39
|
+
export declare function verifyIdToken(token: string, keys: ReadonlyArray<SigningKey>, options?: {
|
|
40
|
+
issuer?: string;
|
|
41
|
+
audience?: string;
|
|
42
|
+
acceptExpired?: boolean;
|
|
43
|
+
}): Promise<IdTokenClaims>;
|
|
18
44
|
/**
|
|
19
45
|
* Verify a JWT access token using a list of trusted signing keys (from
|
|
20
46
|
* `KeyStore.signingKeys()`). Looks up by `kid` in the JWT header.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"jwt.d.ts","sourceRoot":"","sources":["../../../src/domain/jwt.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AACH,OAAO,KAAK,EAAE,GAAG,EAAE,OAAO,EAAE,MAAM,MAAM,CAAA;AAGxC,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,gBAAgB,CAAA;
|
|
1
|
+
{"version":3,"file":"jwt.d.ts","sourceRoot":"","sources":["../../../src/domain/jwt.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AACH,OAAO,KAAK,EAAE,GAAG,EAAE,OAAO,EAAE,MAAM,MAAM,CAAA;AAGxC,OAAO,KAAK,EAAE,iBAAiB,EAAE,aAAa,EAAE,MAAM,gBAAgB,CAAA;AACtE,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,oBAAoB,CAAA;AAEpD;;;;GAIG;AACH,wBAAsB,eAAe,CACnC,MAAM,EAAE,iBAAiB,EACzB,UAAU,EAAE,OAAO,EACnB,GAAG,EAAE,MAAM,EACX,GAAG,EAAE,MAAM,GACV,OAAO,CAAC,MAAM,CAAC,CAIjB;AAED;;;;;GAKG;AACH,wBAAsB,WAAW,CAC/B,MAAM,EAAE,aAAa,EACrB,UAAU,EAAE,OAAO,EACnB,GAAG,EAAE,MAAM,EACX,GAAG,EAAE,MAAM,GACV,OAAO,CAAC,MAAM,CAAC,CAIjB;AAED;;;;;;;;;;;;;GAaG;AACH,wBAAsB,aAAa,CACjC,KAAK,EAAE,MAAM,EACb,IAAI,EAAE,aAAa,CAAC,UAAU,CAAC,EAC/B,OAAO,GAAE;IACP,MAAM,CAAC,EAAE,MAAM,CAAA;IACf,QAAQ,CAAC,EAAE,MAAM,CAAA;IACjB,aAAa,CAAC,EAAE,OAAO,CAAA;CACnB,GACL,OAAO,CAAC,aAAa,CAAC,CAsCxB;AAKD;;;;;;;;;;;;;;;;GAgBG;AACH,wBAAsB,iBAAiB,CACrC,KAAK,EAAE,MAAM,EACb,IAAI,EAAE,aAAa,CAAC,UAAU,CAAC,EAC/B,OAAO,GAAE;IAAE,MAAM,CAAC,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,EAAE,MAAM,CAAA;CAAO,GACnD,OAAO,CAAC,iBAAiB,CAAC,CAgC5B;AAED;;;;;GAKG;AACH,wBAAgB,iBAAiB,CAAC,IAAI,EAAE,aAAa,CAAC,UAAU,CAAC,GAAG;IAClE,IAAI,EAAE,GAAG,EAAE,CAAA;CACZ,CASA"}
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `/end_session` endpoint logic — OIDC RP-Initiated Logout 1.0.
|
|
3
|
+
*
|
|
4
|
+
* The OP validates the optional `id_token_hint`, validates the optional
|
|
5
|
+
* `post_logout_redirect_uri` against the client's registered list,
|
|
6
|
+
* revokes the subject's refresh tokens (when a subject is identified),
|
|
7
|
+
* and either redirects the user-agent back to the RP with `state` echoed
|
|
8
|
+
* or returns a generic "logged out" acknowledgement.
|
|
9
|
+
*
|
|
10
|
+
* Per §2:
|
|
11
|
+
* - `id_token_hint` (RECOMMENDED): a previously-issued id_token. The
|
|
12
|
+
* OP MUST verify the signature; expiry MAY be tolerated because
|
|
13
|
+
* logout commonly follows token expiry. We accept expired hints but
|
|
14
|
+
* enforce signature + issuer.
|
|
15
|
+
* - `client_id` (OPTIONAL): when both this and `id_token_hint` are
|
|
16
|
+
* present, the OP MUST verify the client_id matches the hint's `aud`.
|
|
17
|
+
* - `post_logout_redirect_uri` (OPTIONAL): MUST be exact-match against
|
|
18
|
+
* the resolved client's `postLogoutRedirectUris`. If the URI is not
|
|
19
|
+
* registered, the OP MUST NOT redirect — surface a non-redirecting
|
|
20
|
+
* error instead, otherwise the endpoint becomes an open redirector.
|
|
21
|
+
* - `state` (OPTIONAL): echoed back in the redirect.
|
|
22
|
+
*
|
|
23
|
+
* Front-channel / back-channel logout (RP notification of OP-initiated
|
|
24
|
+
* logout) is out of scope for this minimal endpoint. Hosts that need it
|
|
25
|
+
* can layer their own notification fan-out on top of `session_logout`
|
|
26
|
+
* audit events.
|
|
27
|
+
*/
|
|
28
|
+
import type { AuditLog } from "../ports/audit-log";
|
|
29
|
+
import type { ConfigStore } from "../ports/config-store";
|
|
30
|
+
import type { KeyStore } from "../ports/key-store";
|
|
31
|
+
import type { TokenStore } from "../ports/token-store";
|
|
32
|
+
import { type AuthError } from "../types/error";
|
|
33
|
+
import type { Result } from "../types/result";
|
|
34
|
+
import type { TenantContext } from "../types/tenant";
|
|
35
|
+
export type EndSessionRequest = {
|
|
36
|
+
idTokenHint?: string;
|
|
37
|
+
clientId?: string;
|
|
38
|
+
postLogoutRedirectUri?: string;
|
|
39
|
+
state?: string;
|
|
40
|
+
};
|
|
41
|
+
export type EndSessionDeps = {
|
|
42
|
+
configStore: ConfigStore;
|
|
43
|
+
tokenStore: TokenStore;
|
|
44
|
+
keyStore: KeyStore;
|
|
45
|
+
auditLog?: AuditLog;
|
|
46
|
+
issuerUrl: string;
|
|
47
|
+
clock: () => number;
|
|
48
|
+
};
|
|
49
|
+
export type EndSessionOutput =
|
|
50
|
+
/** Redirect the user-agent back to the RP. */
|
|
51
|
+
{
|
|
52
|
+
kind: "redirect";
|
|
53
|
+
url: string;
|
|
54
|
+
}
|
|
55
|
+
/**
|
|
56
|
+
* No `post_logout_redirect_uri` was supplied (or it wasn't registered).
|
|
57
|
+
* Caller should render a minimal "logged out" page or return 200.
|
|
58
|
+
*/
|
|
59
|
+
| {
|
|
60
|
+
kind: "ok";
|
|
61
|
+
subjectId?: string;
|
|
62
|
+
};
|
|
63
|
+
/**
|
|
64
|
+
* Process an `/end_session` request and return an outcome the HTTP
|
|
65
|
+
* adapter can translate into a `Response`. Pure domain — no Hono types,
|
|
66
|
+
* no `Response` construction here.
|
|
67
|
+
*/
|
|
68
|
+
export declare function endSession(req: EndSessionRequest, tenant: TenantContext, deps: EndSessionDeps): Promise<Result<EndSessionOutput, AuthError>>;
|
|
69
|
+
//# sourceMappingURL=logout.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"logout.d.ts","sourceRoot":"","sources":["../../../src/domain/logout.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;GA0BG;AACH,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,oBAAoB,CAAA;AAClD,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,uBAAuB,CAAA;AACxD,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,oBAAoB,CAAA;AAClD,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,sBAAsB,CAAA;AACtD,OAAO,EAAa,KAAK,SAAS,EAAE,MAAM,gBAAgB,CAAA;AAC1D,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,iBAAiB,CAAA;AAE7C,OAAO,KAAK,EAAgB,aAAa,EAAE,MAAM,iBAAiB,CAAA;AAMlE,MAAM,MAAM,iBAAiB,GAAG;IAC9B,WAAW,CAAC,EAAE,MAAM,CAAA;IACpB,QAAQ,CAAC,EAAE,MAAM,CAAA;IACjB,qBAAqB,CAAC,EAAE,MAAM,CAAA;IAC9B,KAAK,CAAC,EAAE,MAAM,CAAA;CACf,CAAA;AAED,MAAM,MAAM,cAAc,GAAG;IAC3B,WAAW,EAAE,WAAW,CAAA;IACxB,UAAU,EAAE,UAAU,CAAA;IACtB,QAAQ,EAAE,QAAQ,CAAA;IAClB,QAAQ,CAAC,EAAE,QAAQ,CAAA;IACnB,SAAS,EAAE,MAAM,CAAA;IACjB,KAAK,EAAE,MAAM,MAAM,CAAA;CACpB,CAAA;AAED,MAAM,MAAM,gBAAgB;AAC1B,8CAA8C;AAC5C;IAAE,IAAI,EAAE,UAAU,CAAC;IAAC,GAAG,EAAE,MAAM,CAAA;CAAE;AACnC;;;GAGG;GACD;IAAE,IAAI,EAAE,IAAI,CAAC;IAAC,SAAS,CAAC,EAAE,MAAM,CAAA;CAAE,CAAA;AAEtC;;;;GAIG;AACH,wBAAsB,UAAU,CAC9B,GAAG,EAAE,iBAAiB,EACtB,MAAM,EAAE,aAAa,EACrB,IAAI,EAAE,cAAc,GACnB,OAAO,CAAC,MAAM,CAAC,gBAAgB,EAAE,SAAS,CAAC,CAAC,CAyG9C"}
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Pushed Authorization Requests (RFC 9126).
|
|
3
|
+
*
|
|
4
|
+
* The RP submits the full `/authorize` parameter set to `POST /par` along
|
|
5
|
+
* with its client credentials. The OP authenticates the client, stores
|
|
6
|
+
* the payload under an opaque `request_uri`, and returns it with an
|
|
7
|
+
* `expires_in`. The RP then redirects the user-agent to
|
|
8
|
+
* `GET /authorize?client_id=...&request_uri=...` and the OP rehydrates
|
|
9
|
+
* the original parameter set.
|
|
10
|
+
*
|
|
11
|
+
* Per RFC 9126 §3:
|
|
12
|
+
* - Response is HTTP 201 with `application/json` body
|
|
13
|
+
* `{request_uri, expires_in}`.
|
|
14
|
+
* - `request_uri` MUST be of the form
|
|
15
|
+
* `urn:ietf:params:oauth:request_uri:<opaque>` (§2.2).
|
|
16
|
+
* - Default TTL is 60 seconds — same as auth-code TTL.
|
|
17
|
+
*
|
|
18
|
+
* Per RFC 9126 §4:
|
|
19
|
+
* - At `/authorize`, `request_uri` is one-shot — consumed and discarded
|
|
20
|
+
* on first use.
|
|
21
|
+
* - Parameters in the PAR record take precedence; additional `/authorize`
|
|
22
|
+
* parameters MAY be merged but MUST NOT contradict (we strictly use
|
|
23
|
+
* the PAR'd set and ignore any additional ones except `client_id`).
|
|
24
|
+
*
|
|
25
|
+
* Client authentication (§2):
|
|
26
|
+
* - Public clients: `client_id` only.
|
|
27
|
+
* - Confidential clients: `client_id` + `client_secret` (Basic or form).
|
|
28
|
+
*/
|
|
29
|
+
import type { AuditLog } from "../ports/audit-log";
|
|
30
|
+
import type { ConfigStore } from "../ports/config-store";
|
|
31
|
+
import type { SessionStore } from "../ports/session-store";
|
|
32
|
+
import { type AuthError } from "../types/error";
|
|
33
|
+
import type { Result } from "../types/result";
|
|
34
|
+
import type { TenantContext } from "../types/tenant";
|
|
35
|
+
export declare const PAR_URI_PREFIX = "urn:ietf:params:oauth:request_uri:";
|
|
36
|
+
export declare const DEFAULT_PAR_TTL_MS: number;
|
|
37
|
+
export type ParRequest = {
|
|
38
|
+
clientId: string;
|
|
39
|
+
/** Confidential-client secret. */
|
|
40
|
+
clientSecret?: string;
|
|
41
|
+
/** Raw `/authorize` parameter record, posted by the RP. */
|
|
42
|
+
params: Record<string, string>;
|
|
43
|
+
};
|
|
44
|
+
export type ParResponse = {
|
|
45
|
+
request_uri: string;
|
|
46
|
+
expires_in: number;
|
|
47
|
+
};
|
|
48
|
+
export type ParDeps = {
|
|
49
|
+
configStore: ConfigStore;
|
|
50
|
+
sessionStore: SessionStore;
|
|
51
|
+
auditLog?: AuditLog;
|
|
52
|
+
clock: () => number;
|
|
53
|
+
/** Test override. */
|
|
54
|
+
newRequestUriSuffix?: () => string;
|
|
55
|
+
ttlMs?: number;
|
|
56
|
+
};
|
|
57
|
+
/**
|
|
58
|
+
* Process a `POST /par` request. Authenticates the client, validates the
|
|
59
|
+
* `client_id` consistency, and persists the parameter set.
|
|
60
|
+
*/
|
|
61
|
+
export declare function pushAuthorizationRequest(req: ParRequest, tenant: TenantContext, deps: ParDeps): Promise<Result<ParResponse, AuthError>>;
|
|
62
|
+
//# sourceMappingURL=par.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"par.d.ts","sourceRoot":"","sources":["../../../src/domain/par.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;GA2BG;AACH,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,oBAAoB,CAAA;AAClD,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,uBAAuB,CAAA;AACxD,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,wBAAwB,CAAA;AAC1D,OAAO,EAAa,KAAK,SAAS,EAAE,MAAM,gBAAgB,CAAA;AAC1D,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,iBAAiB,CAAA;AAE7C,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,iBAAiB,CAAA;AAKpD,eAAO,MAAM,cAAc,uCAAuC,CAAA;AAClE,eAAO,MAAM,kBAAkB,QAAY,CAAA;AAE3C,MAAM,MAAM,UAAU,GAAG;IACvB,QAAQ,EAAE,MAAM,CAAA;IAChB,kCAAkC;IAClC,YAAY,CAAC,EAAE,MAAM,CAAA;IACrB,2DAA2D;IAC3D,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAA;CAC/B,CAAA;AAED,MAAM,MAAM,WAAW,GAAG;IACxB,WAAW,EAAE,MAAM,CAAA;IACnB,UAAU,EAAE,MAAM,CAAA;CACnB,CAAA;AAED,MAAM,MAAM,OAAO,GAAG;IACpB,WAAW,EAAE,WAAW,CAAA;IACxB,YAAY,EAAE,YAAY,CAAA;IAC1B,QAAQ,CAAC,EAAE,QAAQ,CAAA;IACnB,KAAK,EAAE,MAAM,MAAM,CAAA;IACnB,qBAAqB;IACrB,mBAAmB,CAAC,EAAE,MAAM,MAAM,CAAA;IAClC,KAAK,CAAC,EAAE,MAAM,CAAA;CACf,CAAA;AAED;;;GAGG;AACH,wBAAsB,wBAAwB,CAC5C,GAAG,EAAE,UAAU,EACf,MAAM,EAAE,aAAa,EACrB,IAAI,EAAE,OAAO,GACZ,OAAO,CAAC,MAAM,CAAC,WAAW,EAAE,SAAS,CAAC,CAAC,CAmEzC"}
|
|
@@ -27,6 +27,13 @@ export type RefreshGrantRequest = {
|
|
|
27
27
|
/** Confidential clients authenticate at /token. */
|
|
28
28
|
clientId?: string;
|
|
29
29
|
clientSecret?: string;
|
|
30
|
+
/**
|
|
31
|
+
* RFC 9449 §6 — JWK thumbprint of the DPoP proof presented on this
|
|
32
|
+
* refresh request. MUST match `RefreshTokenPayload.dpopJkt` when the
|
|
33
|
+
* original grant was DPoP-bound; presence is REQUIRED for bound
|
|
34
|
+
* tokens, OPTIONAL otherwise.
|
|
35
|
+
*/
|
|
36
|
+
dpopJkt?: string;
|
|
30
37
|
};
|
|
31
38
|
export type RefreshTokensDeps = {
|
|
32
39
|
configStore: ConfigStore;
|
|
@@ -38,6 +45,8 @@ export type RefreshTokensDeps = {
|
|
|
38
45
|
/** Reuse-detection window (ms). Default 60 s. */
|
|
39
46
|
reuseWindowMs?: number;
|
|
40
47
|
newRefreshToken?: () => string;
|
|
48
|
+
/** See `IdPOptions.customScopeClaims`. Forwarded to `mintTokens`. */
|
|
49
|
+
customScopeClaims?: Record<string, ReadonlyArray<string>>;
|
|
41
50
|
};
|
|
42
51
|
export declare function refreshTokens(req: RefreshGrantRequest, deps: RefreshTokensDeps): Promise<Result<TokenResponse, AuthError>>;
|
|
43
52
|
//# sourceMappingURL=refresh.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"refresh.d.ts","sourceRoot":"","sources":["../../../src/domain/refresh.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AACH,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,oBAAoB,CAAA;AAClD,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,uBAAuB,CAAA;AACxD,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,oBAAoB,CAAA;AAClD,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,sBAAsB,CAAA;AACtD,OAAO,EAAa,KAAK,SAAS,EAAE,MAAM,gBAAgB,CAAA;AAC1D,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,iBAAiB,CAAA;AAG7C,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,gBAAgB,CAAA;AAMnD,MAAM,MAAM,mBAAmB,GAAG;IAChC,SAAS,EAAE,eAAe,CAAA;IAC1B,YAAY,EAAE,MAAM,CAAA;IACpB,mFAAmF;IACnF,KAAK,CAAC,EAAE,MAAM,CAAA;IACd,mDAAmD;IACnD,QAAQ,CAAC,EAAE,MAAM,CAAA;IACjB,YAAY,CAAC,EAAE,MAAM,CAAA;
|
|
1
|
+
{"version":3,"file":"refresh.d.ts","sourceRoot":"","sources":["../../../src/domain/refresh.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AACH,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,oBAAoB,CAAA;AAClD,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,uBAAuB,CAAA;AACxD,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,oBAAoB,CAAA;AAClD,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,sBAAsB,CAAA;AACtD,OAAO,EAAa,KAAK,SAAS,EAAE,MAAM,gBAAgB,CAAA;AAC1D,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,iBAAiB,CAAA;AAG7C,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,gBAAgB,CAAA;AAMnD,MAAM,MAAM,mBAAmB,GAAG;IAChC,SAAS,EAAE,eAAe,CAAA;IAC1B,YAAY,EAAE,MAAM,CAAA;IACpB,mFAAmF;IACnF,KAAK,CAAC,EAAE,MAAM,CAAA;IACd,mDAAmD;IACnD,QAAQ,CAAC,EAAE,MAAM,CAAA;IACjB,YAAY,CAAC,EAAE,MAAM,CAAA;IACrB;;;;;OAKG;IACH,OAAO,CAAC,EAAE,MAAM,CAAA;CACjB,CAAA;AAED,MAAM,MAAM,iBAAiB,GAAG;IAC9B,WAAW,EAAE,WAAW,CAAA;IACxB,UAAU,EAAE,UAAU,CAAA;IACtB,QAAQ,EAAE,QAAQ,CAAA;IAClB,QAAQ,CAAC,EAAE,QAAQ,CAAA;IACnB,SAAS,EAAE,MAAM,CAAA;IACjB,KAAK,EAAE,MAAM,MAAM,CAAA;IACnB,iDAAiD;IACjD,aAAa,CAAC,EAAE,MAAM,CAAA;IACtB,eAAe,CAAC,EAAE,MAAM,MAAM,CAAA;IAC9B,qEAAqE;IACrE,iBAAiB,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,aAAa,CAAC,MAAM,CAAC,CAAC,CAAA;CAC1D,CAAA;AAED,wBAAsB,aAAa,CACjC,GAAG,EAAE,mBAAmB,EACxB,IAAI,EAAE,iBAAiB,GACtB,OAAO,CAAC,MAAM,CAAC,aAAa,EAAE,SAAS,CAAC,CAAC,CAmJ3C"}
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Dynamic Client Registration (RFC 7591).
|
|
3
|
+
*
|
|
4
|
+
* The host owns persistence — this module validates the wire request,
|
|
5
|
+
* mints a fresh `client_id` (and `client_secret` for confidential
|
|
6
|
+
* clients), invokes the host's `registerClient` hook with a structured
|
|
7
|
+
* `ClientConfig`, and builds the §3.2.1 response.
|
|
8
|
+
*
|
|
9
|
+
* Per RFC 7591:
|
|
10
|
+
* - §2: registration request body is JSON, fields include
|
|
11
|
+
* `client_name`, `redirect_uris`, `grant_types`, `response_types`,
|
|
12
|
+
* `token_endpoint_auth_method`, `scope`, etc.
|
|
13
|
+
* - §3.2.1: response is JSON with `client_id`, optional
|
|
14
|
+
* `client_secret`, `client_id_issued_at`, optional
|
|
15
|
+
* `client_secret_expires_at`, and the registered metadata.
|
|
16
|
+
* - §3.2.2: structural problems → `invalid_client_metadata` /
|
|
17
|
+
* `invalid_redirect_uri`. We collapse to `invalid_request` for
|
|
18
|
+
* consistency with the rest of the library's error mapping.
|
|
19
|
+
*/
|
|
20
|
+
import { type AuthError } from "../types/error";
|
|
21
|
+
import type { RegisterClient, RegisterClientRequest, RegisterClientResponse } from "../types/idp";
|
|
22
|
+
import type { Result } from "../types/result";
|
|
23
|
+
import type { TenantContext } from "../types/tenant";
|
|
24
|
+
export type RegisterDeps = {
|
|
25
|
+
registerClient?: RegisterClient;
|
|
26
|
+
clock: () => number;
|
|
27
|
+
/** Test override for deterministic client_id. */
|
|
28
|
+
newClientId?: () => string;
|
|
29
|
+
/** Test override for deterministic client_secret. */
|
|
30
|
+
newClientSecret?: () => string;
|
|
31
|
+
};
|
|
32
|
+
export declare function registerNewClient(request: RegisterClientRequest, tenant: TenantContext, deps: RegisterDeps): Promise<Result<RegisterClientResponse, AuthError>>;
|
|
33
|
+
//# sourceMappingURL=register.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"register.d.ts","sourceRoot":"","sources":["../../../src/domain/register.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;GAkBG;AACH,OAAO,EAAa,KAAK,SAAS,EAAE,MAAM,gBAAgB,CAAA;AAC1D,OAAO,KAAK,EACV,cAAc,EACd,qBAAqB,EACrB,sBAAsB,EACvB,MAAM,cAAc,CAAA;AACrB,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,iBAAiB,CAAA;AAE7C,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,iBAAiB,CAAA;AAKpD,MAAM,MAAM,YAAY,GAAG;IACzB,cAAc,CAAC,EAAE,cAAc,CAAA;IAC/B,KAAK,EAAE,MAAM,MAAM,CAAA;IACnB,iDAAiD;IACjD,WAAW,CAAC,EAAE,MAAM,MAAM,CAAA;IAC1B,qDAAqD;IACrD,eAAe,CAAC,EAAE,MAAM,MAAM,CAAA;CAC/B,CAAA;AAED,wBAAsB,iBAAiB,CACrC,OAAO,EAAE,qBAAqB,EAC9B,MAAM,EAAE,aAAa,EACrB,IAAI,EAAE,YAAY,GACjB,OAAO,CAAC,MAAM,CAAC,sBAAsB,EAAE,SAAS,CAAC,CAAC,CA0HpD"}
|
|
@@ -62,6 +62,8 @@ export type ExchangeTokenDeps = {
|
|
|
62
62
|
issuerUrl: string;
|
|
63
63
|
clock: () => number;
|
|
64
64
|
newRefreshFamily?: () => string;
|
|
65
|
+
/** See `IdPOptions.customScopeClaims`. Forwarded to `mintTokens`. */
|
|
66
|
+
customScopeClaims?: Record<string, ReadonlyArray<string>>;
|
|
65
67
|
};
|
|
66
68
|
export declare function exchangeToken(req: TokenExchangeRequest, deps: ExchangeTokenDeps): Promise<Result<TokenExchangeResponse, AuthError>>;
|
|
67
69
|
//# sourceMappingURL=token-exchange.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"token-exchange.d.ts","sourceRoot":"","sources":["../../../src/domain/token-exchange.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAgCG;AACH,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,oBAAoB,CAAA;AAClD,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,uBAAuB,CAAA;AACxD,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,oBAAoB,CAAA;AAClD,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,sBAAsB,CAAA;AACtD,OAAO,EAAa,KAAK,SAAS,EAAE,MAAM,gBAAgB,CAAA;AAC1D,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,cAAc,CAAA;AACpD,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,iBAAiB,CAAA;AAI7C,OAAO,KAAK,EAAqB,aAAa,EAAE,MAAM,gBAAgB,CAAA;AAQtE,MAAM,MAAM,oBAAoB,GAAG;IACjC,SAAS,EAAE,iDAAiD,CAAA;IAC5D,YAAY,EAAE,MAAM,CAAA;IACpB,QAAQ,EAAE,MAAM,CAAA;IAChB,qFAAqF;IACrF,QAAQ,CAAC,EAAE,MAAM,CAAA;IACjB,YAAY,CAAC,EAAE,MAAM,CAAA;IACrB,+CAA+C;IAC/C,KAAK,CAAC,EAAE,MAAM,CAAA;CACf,CAAA;AAED,MAAM,MAAM,qBAAqB,GAAG,aAAa,GAAG;IAClD,6DAA6D;IAC7D,iBAAiB,EAAE,+CAA+C,CAAA;CACnE,CAAA;AAED,MAAM,MAAM,iBAAiB,GAAG;IAC9B,WAAW,EAAE,WAAW,CAAA;IACxB,UAAU,EAAE,UAAU,CAAA;IACtB,QAAQ,EAAE,QAAQ,CAAA;IAClB,QAAQ,CAAC,EAAE,QAAQ,CAAA;IACnB,gBAAgB,CAAC,EAAE,gBAAgB,CAAA;IACnC,SAAS,EAAE,MAAM,CAAA;IACjB,KAAK,EAAE,MAAM,MAAM,CAAA;IACnB,gBAAgB,CAAC,EAAE,MAAM,MAAM,CAAA;
|
|
1
|
+
{"version":3,"file":"token-exchange.d.ts","sourceRoot":"","sources":["../../../src/domain/token-exchange.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAgCG;AACH,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,oBAAoB,CAAA;AAClD,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,uBAAuB,CAAA;AACxD,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,oBAAoB,CAAA;AAClD,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,sBAAsB,CAAA;AACtD,OAAO,EAAa,KAAK,SAAS,EAAE,MAAM,gBAAgB,CAAA;AAC1D,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,cAAc,CAAA;AACpD,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,iBAAiB,CAAA;AAI7C,OAAO,KAAK,EAAqB,aAAa,EAAE,MAAM,gBAAgB,CAAA;AAQtE,MAAM,MAAM,oBAAoB,GAAG;IACjC,SAAS,EAAE,iDAAiD,CAAA;IAC5D,YAAY,EAAE,MAAM,CAAA;IACpB,QAAQ,EAAE,MAAM,CAAA;IAChB,qFAAqF;IACrF,QAAQ,CAAC,EAAE,MAAM,CAAA;IACjB,YAAY,CAAC,EAAE,MAAM,CAAA;IACrB,+CAA+C;IAC/C,KAAK,CAAC,EAAE,MAAM,CAAA;CACf,CAAA;AAED,MAAM,MAAM,qBAAqB,GAAG,aAAa,GAAG;IAClD,6DAA6D;IAC7D,iBAAiB,EAAE,+CAA+C,CAAA;CACnE,CAAA;AAED,MAAM,MAAM,iBAAiB,GAAG;IAC9B,WAAW,EAAE,WAAW,CAAA;IACxB,UAAU,EAAE,UAAU,CAAA;IACtB,QAAQ,EAAE,QAAQ,CAAA;IAClB,QAAQ,CAAC,EAAE,QAAQ,CAAA;IACnB,gBAAgB,CAAC,EAAE,gBAAgB,CAAA;IACnC,SAAS,EAAE,MAAM,CAAA;IACjB,KAAK,EAAE,MAAM,MAAM,CAAA;IACnB,gBAAgB,CAAC,EAAE,MAAM,MAAM,CAAA;IAC/B,qEAAqE;IACrE,iBAAiB,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,aAAa,CAAC,MAAM,CAAC,CAAC,CAAA;CAC1D,CAAA;AAED,wBAAsB,aAAa,CACjC,GAAG,EAAE,oBAAoB,EACzB,IAAI,EAAE,iBAAiB,GACtB,OAAO,CAAC,MAAM,CAAC,qBAAqB,EAAE,SAAS,CAAC,CAAC,CA+JnD"}
|
|
@@ -48,6 +48,13 @@ export type TokenAuthCodeRequest = {
|
|
|
48
48
|
clientSecret?: string;
|
|
49
49
|
/** Required if the original `/authorize` request had a `code_challenge`. */
|
|
50
50
|
codeVerifier?: string;
|
|
51
|
+
/**
|
|
52
|
+
* RFC 9449 §6 — the JWK thumbprint of the presented DPoP proof. Set by
|
|
53
|
+
* the HTTP layer after verifying the `DPoP:` header against this
|
|
54
|
+
* request's actual method + URI. The domain binds the issued access
|
|
55
|
+
* token to this thumbprint via `cnf.jkt`.
|
|
56
|
+
*/
|
|
57
|
+
dpopJkt?: string;
|
|
51
58
|
};
|
|
52
59
|
export type ExchangeCodeDeps = {
|
|
53
60
|
configStore: ConfigStore;
|
|
@@ -61,6 +68,11 @@ export type ExchangeCodeDeps = {
|
|
|
61
68
|
newRefreshToken?: () => string;
|
|
62
69
|
/** Test override. */
|
|
63
70
|
newRefreshFamily?: () => string;
|
|
71
|
+
/**
|
|
72
|
+
* Host-supplied vendor scope → claim-names map. Forwarded to `mintTokens`
|
|
73
|
+
* for id_token + /userinfo scope-gating. See `IdPOptions.customScopeClaims`.
|
|
74
|
+
*/
|
|
75
|
+
customScopeClaims?: Record<string, ReadonlyArray<string>>;
|
|
64
76
|
};
|
|
65
77
|
export declare function exchangeCode(req: TokenAuthCodeRequest, deps: ExchangeCodeDeps): Promise<Result<TokenResponse, AuthError>>;
|
|
66
78
|
/**
|
|
@@ -70,7 +82,30 @@ export declare function exchangeCode(req: TokenAuthCodeRequest, deps: ExchangeCo
|
|
|
70
82
|
export declare function mintTokens(args: {
|
|
71
83
|
tenant: TenantContext;
|
|
72
84
|
claim: SubjectClaim;
|
|
73
|
-
payload: Pick<CodePayload, "tenantId" | "clientId" | "methodId" | "methodKind" | "scopes" | "audience"
|
|
85
|
+
payload: Pick<CodePayload, "tenantId" | "clientId" | "methodId" | "methodKind" | "scopes" | "audience"> & {
|
|
86
|
+
/**
|
|
87
|
+
* Present on `authorization_code` and `refresh_token` grants where an
|
|
88
|
+
* end-user actually authenticated. Absent on `client_credentials`
|
|
89
|
+
* (no end-user) — and absent means no `id_token` is emitted even if
|
|
90
|
+
* the requested scopes nominally include `openid`.
|
|
91
|
+
*/
|
|
92
|
+
authTime?: number;
|
|
93
|
+
/** RP's OIDC `nonce` from `/authorize`, when present. */
|
|
94
|
+
appNonce?: string;
|
|
95
|
+
/**
|
|
96
|
+
* DPoP key thumbprint (RFC 9449 §6.1). When present, the access
|
|
97
|
+
* token's `cnf.jkt` claim is set and `token_type` flips to `"DPoP"`;
|
|
98
|
+
* the saved refresh-token payload's `dpopJkt` is set so refresh
|
|
99
|
+
* rotation re-enforces sender constraint.
|
|
100
|
+
*/
|
|
101
|
+
dpopJkt?: string;
|
|
102
|
+
/**
|
|
103
|
+
* OIDC Core §5.5 — RP-requested claims from `/authorize`. Carried
|
|
104
|
+
* into the id_token and forward across refresh rotations (§12) so
|
|
105
|
+
* later /userinfo calls keep returning the requested fields.
|
|
106
|
+
*/
|
|
107
|
+
claimsRequest?: import("../types/authorization").ClaimsRequest;
|
|
108
|
+
};
|
|
74
109
|
family: string;
|
|
75
110
|
/**
|
|
76
111
|
* `client_credentials` grants (RFC 6749 §4.4.3) and other paths where a
|
|
@@ -87,6 +122,11 @@ export declare function mintTokens(args: {
|
|
|
87
122
|
issuerUrl: string;
|
|
88
123
|
clock: () => number;
|
|
89
124
|
newRefreshToken?: () => string;
|
|
125
|
+
/**
|
|
126
|
+
* Host-supplied vendor scope → claim-names map merged into the
|
|
127
|
+
* id_token + /userinfo scope-gating. See `IdPOptions.customScopeClaims`.
|
|
128
|
+
*/
|
|
129
|
+
customScopeClaims?: Record<string, ReadonlyArray<string>>;
|
|
90
130
|
};
|
|
91
131
|
}): Promise<Result<TokenResponse, AuthError>>;
|
|
92
132
|
/**
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"token.d.ts","sourceRoot":"","sources":["../../../src/domain/token.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;GAmBG;AACH,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,oBAAoB,CAAA;AAClD,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,oBAAoB,CAAA;AAClD,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,sBAAsB,CAAA;AACtD,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,uBAAuB,CAAA;AACxD,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAA;AAE/C,OAAO,KAAK,EAAE,qBAAqB,EAAE,eAAe,EAAE,MAAM,cAAc,CAAA;AAC1E,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,iBAAiB,CAAA;AAE7C,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,kBAAkB,CAAA;AACpD,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,iBAAiB,CAAA;AACpD,OAAO,KAAK,EAEV,WAAW,EAEX,aAAa,EACd,MAAM,gBAAgB,CAAA;
|
|
1
|
+
{"version":3,"file":"token.d.ts","sourceRoot":"","sources":["../../../src/domain/token.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,22 +1,61 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* `/userinfo` endpoint logic (OIDC Core §5.3). Verifies the
|
|
3
|
-
* token
|
|
2
|
+
* `/userinfo` endpoint logic (OIDC Core §5.3). Verifies the presented
|
|
3
|
+
* access token, optionally enforces a DPoP proof binding (RFC 9449 §7),
|
|
4
|
+
* and returns the inlined `SubjectClaim` claims, scope-gated per OIDC
|
|
5
|
+
* Core §5.4.
|
|
6
|
+
*
|
|
7
|
+
* Profile / email / phone / address claims appear in the response only
|
|
8
|
+
* when (a) the access token's `scope` includes the granting scope and
|
|
9
|
+
* (b) the value exists on `SubjectClaim.properties`. Other properties
|
|
10
|
+
* (host-specific subject fields like `userId`, `roles`, …) are returned
|
|
11
|
+
* under `properties` and not subject to OIDC scope gating — they're
|
|
12
|
+
* outside §5.4's universe.
|
|
13
|
+
*
|
|
14
|
+
* DPoP at the resource server (RFC 9449 §7):
|
|
15
|
+
* - If the access token has a `cnf.jkt` claim, the request MUST carry a
|
|
16
|
+
* matching `DPoP:` proof whose `ath` equals SHA-256(access_token).
|
|
17
|
+
* - If no `cnf.jkt`, the access token is plain Bearer and any DPoP
|
|
18
|
+
* proof is silently ignored at this layer (host can still enforce).
|
|
4
19
|
*/
|
|
20
|
+
import type { TokenStore } from "../ports/token-store";
|
|
5
21
|
import type { KeyStore } from "../ports/key-store";
|
|
6
22
|
import { type AuthError } from "../types/error";
|
|
7
23
|
import type { Result } from "../types/result";
|
|
8
|
-
|
|
24
|
+
import type { ScopedProfileClaims } from "../types/token";
|
|
25
|
+
export type UserinfoResponse = ScopedProfileClaims & {
|
|
9
26
|
sub: string;
|
|
10
27
|
/** Subject type discriminator (e.g. `"user"` / `"admin"`). */
|
|
11
28
|
subject_type: string;
|
|
12
|
-
/** Inlined claim properties. */
|
|
29
|
+
/** Inlined claim properties, host-specific and not gated by OIDC scope. */
|
|
13
30
|
properties: Record<string, unknown>;
|
|
14
31
|
/** Scope granted to this access token. */
|
|
15
32
|
scope?: string;
|
|
16
33
|
};
|
|
17
34
|
export type UserinfoDeps = {
|
|
18
35
|
keyStore: KeyStore;
|
|
36
|
+
/** Required when DPoP-bound tokens are accepted. */
|
|
37
|
+
tokenStore?: TokenStore;
|
|
19
38
|
issuerUrl?: string;
|
|
39
|
+
/**
|
|
40
|
+
* Host-supplied vendor scope → claim-names map. Merged into the
|
|
41
|
+
* scope-gated /userinfo response just as it is for id_token. See
|
|
42
|
+
* `IdPOptions.customScopeClaims`.
|
|
43
|
+
*/
|
|
44
|
+
customScopeClaims?: Record<string, ReadonlyArray<string>>;
|
|
20
45
|
};
|
|
21
|
-
export
|
|
46
|
+
export type UserinfoInput = {
|
|
47
|
+
/** Access token from `Authorization: Bearer ...` or `Authorization: DPoP ...`. */
|
|
48
|
+
accessToken: string;
|
|
49
|
+
/** `Authorization`-scheme as presented. Defaults to `"Bearer"`. */
|
|
50
|
+
scheme?: "Bearer" | "DPoP";
|
|
51
|
+
/** Raw `DPoP:` header from the request, if any. */
|
|
52
|
+
dpopProof?: string;
|
|
53
|
+
/** Canonical request URI for DPoP `htu` check (scheme + host + path). */
|
|
54
|
+
htu?: string;
|
|
55
|
+
/** Request method for DPoP `htm` check, uppercase. */
|
|
56
|
+
htm?: string;
|
|
57
|
+
/** Wall clock seconds for DPoP `iat` window. */
|
|
58
|
+
nowSec?: number;
|
|
59
|
+
};
|
|
60
|
+
export declare function userinfo(input: UserinfoInput, deps: UserinfoDeps): Promise<Result<UserinfoResponse, AuthError>>;
|
|
22
61
|
//# sourceMappingURL=userinfo.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"userinfo.d.ts","sourceRoot":"","sources":["../../../src/domain/userinfo.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"userinfo.d.ts","sourceRoot":"","sources":["../../../src/domain/userinfo.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;GAkBG;AACH,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,sBAAsB,CAAA;AACtD,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,oBAAoB,CAAA;AAClD,OAAO,EAAa,KAAK,SAAS,EAAE,MAAM,gBAAgB,CAAA;AAC1D,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,iBAAiB,CAAA;AAQ7C,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,gBAAgB,CAAA;AAEzD,MAAM,MAAM,gBAAgB,GAAG,mBAAmB,GAAG;IACnD,GAAG,EAAE,MAAM,CAAA;IACX,8DAA8D;IAC9D,YAAY,EAAE,MAAM,CAAA;IACpB,2EAA2E;IAC3E,UAAU,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;IACnC,0CAA0C;IAC1C,KAAK,CAAC,EAAE,MAAM,CAAA;CACf,CAAA;AAED,MAAM,MAAM,YAAY,GAAG;IACzB,QAAQ,EAAE,QAAQ,CAAA;IAClB,oDAAoD;IACpD,UAAU,CAAC,EAAE,UAAU,CAAA;IACvB,SAAS,CAAC,EAAE,MAAM,CAAA;IAClB;;;;OAIG;IACH,iBAAiB,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,aAAa,CAAC,MAAM,CAAC,CAAC,CAAA;CAC1D,CAAA;AAED,MAAM,MAAM,aAAa,GAAG;IAC1B,kFAAkF;IAClF,WAAW,EAAE,MAAM,CAAA;IACnB,mEAAmE;IACnE,MAAM,CAAC,EAAE,QAAQ,GAAG,MAAM,CAAA;IAC1B,mDAAmD;IACnD,SAAS,CAAC,EAAE,MAAM,CAAA;IAClB,yEAAyE;IACzE,GAAG,CAAC,EAAE,MAAM,CAAA;IACZ,sDAAsD;IACtD,GAAG,CAAC,EAAE,MAAM,CAAA;IACZ,gDAAgD;IAChD,MAAM,CAAC,EAAE,MAAM,CAAA;CAChB,CAAA;AAED,wBAAsB,QAAQ,CAC5B,KAAK,EAAE,aAAa,EACpB,IAAI,EAAE,YAAY,GACjB,OAAO,CAAC,MAAM,CAAC,gBAAgB,EAAE,SAAS,CAAC,CAAC,CAiG9C"}
|
|
@@ -14,7 +14,7 @@ import type { SessionStore } from "../ports/session-store";
|
|
|
14
14
|
import type { TokenStore } from "../ports/token-store";
|
|
15
15
|
import type { MethodCache } from "../domain/method-cache";
|
|
16
16
|
import type { AuthError } from "../types/error";
|
|
17
|
-
import type { ExchangeAudience, PersistUpstreamTokens, RenderPicker, SuccessMapInput } from "../types/idp";
|
|
17
|
+
import type { ExchangeAudience, PersistUpstreamTokens, RegisterClient, RenderPicker, SuccessMapInput } from "../types/idp";
|
|
18
18
|
import type { Result } from "../types/result";
|
|
19
19
|
import type { SubjectClaim } from "../types/subject";
|
|
20
20
|
import type { StateKeyRing, TenantContext, TenantId, TenantRecovery } from "../types/tenant";
|
|
@@ -38,10 +38,13 @@ export type HttpDeps = {
|
|
|
38
38
|
persistUpstreamTokens?: PersistUpstreamTokens;
|
|
39
39
|
exchangeAudience?: ExchangeAudience;
|
|
40
40
|
renderPicker?: RenderPicker;
|
|
41
|
+
registerClient?: RegisterClient;
|
|
41
42
|
/** Builds `TenantContext.request.custom` for every request. See `IdPOptions.buildCustomContext`. */
|
|
42
43
|
buildCustomContext?: (req: Request) => Record<string, unknown> | Promise<Record<string, unknown>>;
|
|
43
44
|
clock: () => number;
|
|
44
45
|
cookieDefaults: CookieDefaults;
|
|
46
|
+
/** See `IdPOptions.customScopeClaims`. */
|
|
47
|
+
customScopeClaims?: Record<string, ReadonlyArray<string>>;
|
|
45
48
|
};
|
|
46
49
|
/** Per-request variables populated by middleware. */
|
|
47
50
|
export type HttpVars = {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"context.d.ts","sourceRoot":"","sources":["../../../src/http/context.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AACH,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,MAAM,CAAA;AAEnC,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,oBAAoB,CAAA;AAClD,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,uBAAuB,CAAA;AACxD,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,oBAAoB,CAAA;AAClD,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,uBAAuB,CAAA;AACxD,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,wBAAwB,CAAA;AAC1D,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,sBAAsB,CAAA;AACtD,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,wBAAwB,CAAA;AACzD,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAA;AAC/C,OAAO,KAAK,EACV,gBAAgB,EAChB,qBAAqB,EACrB,YAAY,EACZ,eAAe,EAChB,MAAM,cAAc,CAAA;AACrB,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,iBAAiB,CAAA;AAC7C,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,kBAAkB,CAAA;AACpD,OAAO,KAAK,EACV,YAAY,EACZ,aAAa,EACb,QAAQ,EACR,cAAc,EACf,MAAM,iBAAiB,CAAA;AAExB,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,WAAW,CAAA;AAE/C,6DAA6D;AAC7D,MAAM,MAAM,QAAQ,GAAG;IACrB,WAAW,EAAE,WAAW,CAAA;IACxB,UAAU,EAAE,UAAU,CAAA;IACtB,YAAY,EAAE,YAAY,CAAA;IAC1B,QAAQ,EAAE,QAAQ,CAAA;IAClB,WAAW,CAAC,EAAE,WAAW,CAAA;IACzB,QAAQ,CAAC,EAAE,QAAQ,CAAA;IACnB,WAAW,EAAE,WAAW,CAAA;IACxB,SAAS,EAAE,YAAY,CAAA;IACvB,gEAAgE;IAChE,aAAa,EAAE,CAAC,GAAG,EAAE,OAAO,KAAK,MAAM,CAAA;IACvC,sDAAsD;IACtD,eAAe,CAAC,EAAE,CAAC,QAAQ,EAAE,QAAQ,KAAK,MAAM,CAAA;IAChD,aAAa,EAAE,CAAC,GAAG,EAAE,OAAO,KAAK,OAAO,CAAC,MAAM,CAAC,QAAQ,EAAE,SAAS,CAAC,CAAC,CAAA;IACrE,OAAO,EAAE,CAAC,KAAK,EAAE,eAAe,KAAK,OAAO,CAAC,YAAY,CAAC,CAAA;IAC1D,qBAAqB,CAAC,EAAE,qBAAqB,CAAA;IAC7C,gBAAgB,CAAC,EAAE,gBAAgB,CAAA;IACnC,YAAY,CAAC,EAAE,YAAY,CAAA;IAC3B,oGAAoG;IACpG,kBAAkB,CAAC,EAAE,CACnB,GAAG,EAAE,OAAO,KACT,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,OAAO,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,CAAA;IAC/D,KAAK,EAAE,MAAM,MAAM,CAAA;IACnB,cAAc,EAAE,cAAc,CAAA;
|
|
1
|
+
{"version":3,"file":"context.d.ts","sourceRoot":"","sources":["../../../src/http/context.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"authorize.d.ts","sourceRoot":"","sources":["../../../../src/http/handlers/authorize.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"authorize.d.ts","sourceRoot":"","sources":["../../../../src/http/handlers/authorize.ts"],"names":[],"mappings":"AA2BA,OAAO,KAAK,EAAE,WAAW,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAA;AAWvD,wBAAgB,oBAAoB,CAAC,IAAI,EAAE,QAAQ,OAChC,WAAW,KAAG,OAAO,CAAC,QAAQ,CAAC,CAkOjD"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"end-session.d.ts","sourceRoot":"","sources":["../../../../src/http/handlers/end-session.ts"],"names":[],"mappings":"AAoBA,OAAO,KAAK,EAAE,WAAW,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAA;AAIvD,wBAAgB,qBAAqB,CAAC,IAAI,EAAE,QAAQ,OACjC,WAAW,KAAG,OAAO,CAAC,QAAQ,CAAC,CAgFjD"}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
1
|
import type { HttpContext, HttpDeps } from "../context";
|
|
2
|
-
export declare function makeDiscoveryHandler(
|
|
2
|
+
export declare function makeDiscoveryHandler(deps: HttpDeps): (c: HttpContext) => Promise<Response>;
|
|
3
3
|
export declare function makeJwksHandler(deps: HttpDeps): (_c: HttpContext) => Promise<Response>;
|
|
4
4
|
//# sourceMappingURL=metadata.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"metadata.d.ts","sourceRoot":"","sources":["../../../../src/http/handlers/metadata.ts"],"names":[],"mappings":"AAeA,OAAO,KAAK,EAAE,WAAW,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAA;AAGvD,wBAAgB,oBAAoB,CAAC,
|
|
1
|
+
{"version":3,"file":"metadata.d.ts","sourceRoot":"","sources":["../../../../src/http/handlers/metadata.ts"],"names":[],"mappings":"AAeA,OAAO,KAAK,EAAE,WAAW,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAA;AAGvD,wBAAgB,oBAAoB,CAAC,IAAI,EAAE,QAAQ,OAChC,WAAW,KAAG,OAAO,CAAC,QAAQ,CAAC,CAejD;AAED,wBAAgB,eAAe,CAAC,IAAI,EAAE,QAAQ,QAC1B,WAAW,KAAG,OAAO,CAAC,QAAQ,CAAC,CAWlD"}
|