@absolutejs/auth 0.56.12 → 0.56.13

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,4 +1,4 @@
1
- type SigningKeyIdentity = {
1
+ export type SigningKeyIdentity = {
2
2
  kid: string;
3
3
  publicJwk: JsonWebKey;
4
4
  };
@@ -12,10 +12,10 @@ export type SigningKey = SigningKeyIdentity & ({
12
12
  privateJwk?: never;
13
13
  sign: (input: Uint8Array) => Promise<Uint8Array>;
14
14
  });
15
- export declare const generateSigningKey: () => Promise<SigningKey>;
16
- export declare const jwkThumbprint: (jwk: JsonWebKey) => Promise<string>;
17
- export declare const signJwt: (payload: Record<string, unknown>, signing: SigningKey, typ?: string) => Promise<string>;
18
- export declare const toPublicJwk: (key: SigningKey) => {
15
+ declare const generateSigningKey: () => Promise<SigningKey>;
16
+ declare const jwkThumbprint: (jwk: JsonWebKey) => Promise<string>;
17
+ declare const signJwt: (payload: Record<string, unknown>, signing: SigningKey, typ?: string) => Promise<string>;
18
+ declare const toPublicJwk: (key: SigningKeyIdentity) => {
19
19
  alg: string;
20
20
  crv: string | undefined;
21
21
  kid: string;
@@ -24,7 +24,7 @@ export declare const toPublicJwk: (key: SigningKey) => {
24
24
  x: string | undefined;
25
25
  y: string | undefined;
26
26
  };
27
- export declare const verifyJwt: (token: string, publicJwk: JsonWebKey) => Promise<{
27
+ declare const verifyJwt: (token: string, publicJwk: JsonWebKey) => Promise<{
28
28
  header: {
29
29
  [k: string]: any;
30
30
  };
@@ -32,4 +32,19 @@ export declare const verifyJwt: (token: string, publicJwk: JsonWebKey) => Promis
32
32
  [k: string]: any;
33
33
  };
34
34
  } | undefined>;
35
- export {};
35
+ /** Resolves the active signing identity followed by still-valid previous
36
+ * public identities. Duplicate key IDs fail closed because a JWT `kid` must
37
+ * identify exactly one verification key during an overlap window. */
38
+ declare const signingVerificationKeys: (active: SigningKeyIdentity, previous?: readonly SigningKeyIdentity[]) => SigningKeyIdentity[];
39
+ /** Verifies an Absolute Auth JWT against the exact public identity named by
40
+ * its protected `kid` header. This keeps already-issued tokens valid while a
41
+ * previous public key remains in the configured overlap window. */
42
+ declare const verifyJwtWithKeys: (token: string, keys: readonly SigningKeyIdentity[]) => Promise<{
43
+ header: {
44
+ [k: string]: any;
45
+ };
46
+ payload: {
47
+ [k: string]: any;
48
+ };
49
+ } | undefined>;
50
+ export { generateSigningKey, jwkThumbprint, signingVerificationKeys, signJwt, toPublicJwk, verifyJwt, verifyJwtWithKeys };
package/dist/server.js CHANGED
@@ -3289,6 +3289,26 @@ var verifyJwt = async (token, publicJwk) => {
3289
3289
  payload
3290
3290
  };
3291
3291
  };
3292
+ var signingVerificationKeys = (active, previous = []) => {
3293
+ const keys = [active, ...previous];
3294
+ const keyIds = new Set(keys.map(({ kid }) => kid));
3295
+ if (keyIds.size !== keys.length)
3296
+ throw new Error("OIDC signing key IDs must be unique");
3297
+ return keys;
3298
+ };
3299
+ var verifyJwtWithKeys = async (token, keys) => {
3300
+ const [headerSegment] = token.split(".");
3301
+ if (!headerSegment)
3302
+ return;
3303
+ const header = decodeSegment(headerSegment);
3304
+ const kid = header?.kid;
3305
+ if (typeof kid !== "string" || kid.length === 0)
3306
+ return;
3307
+ const key = keys.find((candidate) => candidate.kid === kid);
3308
+ if (!key)
3309
+ return;
3310
+ return verifyJwt(token, key.publicJwk);
3311
+ };
3292
3312
 
3293
3313
  // src/agents/registration.ts
3294
3314
  var AGENT_CLAIM_GRANT_TYPE = "urn:workos:agent-auth:grant-type:claim";
@@ -6086,7 +6106,7 @@ var exchangeToken = async ({
6086
6106
  requestedScopes,
6087
6107
  subjectToken
6088
6108
  }) => {
6089
- const verified = await verifyJwt(subjectToken, config.signingKey.publicJwk);
6109
+ const verified = await verifyJwtWithKeys(subjectToken, signingVerificationKeys(config.signingKey, config.previousSigningKeys));
6090
6110
  const payload = verified?.payload;
6091
6111
  if (payload === undefined || typeof payload.sub !== "string" || typeof payload.exp !== "number" || payload.exp <= nowSeconds(now)) {
6092
6112
  return { error: "invalid_grant", ok: false };
@@ -6207,7 +6227,7 @@ var introspectToken = async ({
6207
6227
  token
6208
6228
  }) => {
6209
6229
  if (hint !== "refresh_token") {
6210
- const verified = await verifyJwt(token, config.signingKey.publicJwk);
6230
+ const verified = await verifyJwtWithKeys(token, signingVerificationKeys(config.signingKey, config.previousSigningKeys));
6211
6231
  const payload = verified?.payload;
6212
6232
  if (payload !== undefined && typeof payload.sub === "string" && typeof payload.exp === "number" && payload.exp > nowSeconds(now)) {
6213
6233
  return {
@@ -7123,7 +7143,7 @@ var verifyIdTokenHint = async ({
7123
7143
  config,
7124
7144
  idTokenHint
7125
7145
  }) => {
7126
- const verified = await verifyJwt(idTokenHint, config.signingKey.publicJwk);
7146
+ const verified = await verifyJwtWithKeys(idTokenHint, signingVerificationKeys(config.signingKey, config.previousSigningKeys));
7127
7147
  const payload = verified?.payload;
7128
7148
  if (payload === undefined || typeof payload.sub !== "string" || typeof payload.aud !== "string" || payload.iss !== config.issuer) {
7129
7149
  return;
@@ -7353,7 +7373,7 @@ var fetchUserInfo = async ({
7353
7373
  ok: false
7354
7374
  };
7355
7375
  }
7356
- const verified = await verifyJwt(token, config.signingKey.publicJwk);
7376
+ const verified = await verifyJwtWithKeys(token, signingVerificationKeys(config.signingKey, config.previousSigningKeys));
7357
7377
  if (verified === undefined) {
7358
7378
  return {
7359
7379
  body: { error: "invalid_token" },
@@ -8694,7 +8714,9 @@ var oidcProviderRoutes = (config) => {
8694
8714
  headers: t15.Object({
8695
8715
  authorization: t15.Optional(t15.String())
8696
8716
  })
8697
- }).get(jwksRoute, () => ({ keys: [toPublicJwk(signingKey)] })).get("/.well-known/openid-configuration", () => discovery).get("/.well-known/oauth-authorization-server", () => discovery);
8717
+ }).get(jwksRoute, () => ({
8718
+ keys: signingVerificationKeys(signingKey, config.previousSigningKeys).map(toPublicJwk)
8719
+ })).get("/.well-known/openid-configuration", () => discovery).get("/.well-known/oauth-authorization-server", () => discovery);
8698
8720
  };
8699
8721
 
8700
8722
  // src/organizations/routes.ts
@@ -27033,6 +27055,7 @@ var createOidcAgentCredentialVerifier = ({
27033
27055
  isUsedDpopJti,
27034
27056
  maxDpopAgeMs,
27035
27057
  publicJwk,
27058
+ publicKeys,
27036
27059
  requireDpop = false,
27037
27060
  resource
27038
27061
  }) => {
@@ -27044,13 +27067,14 @@ var createOidcAgentCredentialVerifier = ({
27044
27067
  const token = authorization.slice(authorization.indexOf(" ") + 1).trim();
27045
27068
  if (token.length === 0)
27046
27069
  return;
27047
- const verified = await verifyJwt(token, publicJwk);
27070
+ const verified = publicKeys ? await verifyJwtWithKeys(token, publicKeys) : await verifyJwt(token, publicJwk);
27048
27071
  const payload = verified?.payload;
27049
27072
  if (payload === undefined || payload.iss !== issuer || typeof payload.exp !== "number" || payload.exp <= Math.floor(Date.now() / MS_PER_SECOND7) || !readAudience(payload.aud).includes(resource) || typeof payload.client_id !== "string") {
27050
27073
  return;
27051
27074
  }
27052
27075
  const confirmation = payload.cnf;
27053
- const boundJkt = typeof confirmation === "object" && confirmation !== null && typeof confirmation.jkt === "string" ? confirmation.jkt : undefined;
27076
+ const boundJktValue = typeof confirmation === "object" && confirmation !== null ? Reflect.get(confirmation, "jkt") : undefined;
27077
+ const boundJkt = typeof boundJktValue === "string" ? boundJktValue : undefined;
27054
27078
  if (boundJkt !== undefined || requireDpop) {
27055
27079
  if (!authorization.startsWith("DPoP "))
27056
27080
  return;
@@ -30587,5 +30611,5 @@ export {
30587
30611
  auth2 as auth
30588
30612
  };
30589
30613
 
30590
- //# debugId=DC157A619FC3907564756E2164756E21
30614
+ //# debugId=B037EE5900B85A3664756E2164756E21
30591
30615
  //# sourceMappingURL=server.js.map