@schemavaults/auth-common 0.16.2 → 0.22.4
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/audience-schema.d.ts +18 -2
- package/dist/audience-schema.js +5 -10
- package/dist/audience-schema.js.map +1 -1
- package/dist/auth_acquire_tokens_grant_types.d.ts +3 -2
- package/dist/auth_acquire_tokens_grant_types.js +7 -7
- package/dist/auth_acquire_tokens_grant_types.js.map +1 -1
- package/dist/index.d.ts +4 -0
- package/dist/index.js +2 -0
- package/dist/index.js.map +1 -1
- package/dist/middleware/decode-jwts.d.ts +4 -3
- package/dist/middleware/decode-jwts.js +6 -5
- package/dist/middleware/decode-jwts.js.map +1 -1
- package/dist/middleware/decode-token-type.d.ts +1 -1
- package/dist/oidc/index.d.ts +4 -0
- package/dist/oidc/index.js +3 -0
- package/dist/oidc/index.js.map +1 -0
- package/dist/oidc/nonce.d.ts +27 -0
- package/dist/oidc/nonce.js +59 -0
- package/dist/oidc/nonce.js.map +1 -0
- package/dist/oidc/scope.d.ts +63 -0
- package/dist/oidc/scope.js +84 -0
- package/dist/oidc/scope.js.map +1 -0
- package/dist/pkce/code_challenge.d.ts +1 -1
- package/dist/pkce/code_challenge.js +1 -1
- package/dist/pkce/code_challenge.js.map +1 -1
- package/dist/pkce/pkce.js +20 -18
- package/dist/pkce/pkce.js.map +1 -1
- package/dist/request_tokens_result.d.ts +6 -2
- package/dist/request_tokens_result.js +14 -5
- package/dist/request_tokens_result.js.map +1 -1
- package/dist/sha256_digest/index.d.ts +1 -1
- package/dist/sha256_digest/index.js +1 -1
- package/dist/sha256_digest/index.js.map +1 -1
- package/dist/sha256_digest/sha256_digest.d.ts +8 -2
- package/dist/sha256_digest/sha256_digest.js +19 -4
- package/dist/sha256_digest/sha256_digest.js.map +1 -1
- package/package.json +2 -2
|
@@ -1,4 +1,20 @@
|
|
|
1
1
|
import { type SchemaVaultsAppEnvironment } from "@schemavaults/app-definitions";
|
|
2
2
|
import type { z as zod } from "zod";
|
|
3
|
-
export
|
|
4
|
-
|
|
3
|
+
export interface AudienceSchemaOverrides {
|
|
4
|
+
/**
|
|
5
|
+
* The auth server's public URL. Browser bundles can't read the
|
|
6
|
+
* SCHEMAVAULTS_AUTH_SERVER_URL environment variable (they'd silently
|
|
7
|
+
* resolve the per-environment default), so client-side callers must inject
|
|
8
|
+
* the URL their auth client was configured with. Server-side callers can
|
|
9
|
+
* omit it to resolve from the environment.
|
|
10
|
+
*/
|
|
11
|
+
auth_server_url?: string;
|
|
12
|
+
/**
|
|
13
|
+
* The auth server deployment's own app id. Same story as auth_server_url:
|
|
14
|
+
* client-side callers must inject their configured value in white-label
|
|
15
|
+
* deployments; server-side callers can omit it.
|
|
16
|
+
*/
|
|
17
|
+
auth_server_app_id?: string;
|
|
18
|
+
}
|
|
19
|
+
export declare function createAudienceSchema(z: typeof zod, environment?: SchemaVaultsAppEnvironment, overrides?: AudienceSchemaOverrides): zod.ZodUnion<[zod.ZodEffects<zod.ZodString, string, string>, zod.ZodEffects<zod.ZodEffects<zod.ZodEffects<zod.ZodString, string, string>, string, string>, string, string>]>;
|
|
20
|
+
export declare function createAudienceListSchema(z: typeof zod, environment?: SchemaVaultsAppEnvironment, overrides?: AudienceSchemaOverrides): zod.ZodArray<zod.ZodUnion<[zod.ZodEffects<zod.ZodString, string, string>, zod.ZodEffects<zod.ZodEffects<zod.ZodEffects<zod.ZodString, string, string>, string, string>, string, string>]>, "many">;
|
package/dist/audience-schema.js
CHANGED
|
@@ -1,12 +1,7 @@
|
|
|
1
1
|
import { apiServerIdSchema, getAppEnvironment, getAuthServerAppId, getAuthServerUrl, } from "@schemavaults/app-definitions";
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
// concerns; eager module-scope initialization breaks `next build` in Docker
|
|
6
|
-
// where those env vars are unset.
|
|
7
|
-
export function createAudienceSchema(z, environment = getAppEnvironment()) {
|
|
8
|
-
const auth_server_url = getAuthServerUrl(environment);
|
|
9
|
-
const auth_server_app_id = getAuthServerAppId();
|
|
2
|
+
export function createAudienceSchema(z, environment = getAppEnvironment(), overrides) {
|
|
3
|
+
const auth_server_url = overrides?.auth_server_url ?? getAuthServerUrl(environment);
|
|
4
|
+
const auth_server_app_id = overrides?.auth_server_app_id ?? getAuthServerAppId();
|
|
10
5
|
const authServerUrlSchema = z
|
|
11
6
|
.string()
|
|
12
7
|
.url()
|
|
@@ -20,8 +15,8 @@ export function createAudienceSchema(z, environment = getAppEnvironment()) {
|
|
|
20
15
|
return z.union([authServerUrlSchema, apiServerIdWithoutAuthServerIdSchema]);
|
|
21
16
|
}
|
|
22
17
|
const MAX_APPS_IN_AUDIENCE_LIST = 10;
|
|
23
|
-
export function createAudienceListSchema(z, environment = getAppEnvironment()) {
|
|
24
|
-
return createAudienceSchema(z, environment)
|
|
18
|
+
export function createAudienceListSchema(z, environment = getAppEnvironment(), overrides) {
|
|
19
|
+
return createAudienceSchema(z, environment, overrides)
|
|
25
20
|
.array()
|
|
26
21
|
.min(1, "Audience list may not be empty")
|
|
27
22
|
.max(MAX_APPS_IN_AUDIENCE_LIST, `Audience list may not contain more than ${MAX_APPS_IN_AUDIENCE_LIST} audience references.`);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"audience-schema.js","sourceRoot":"","sources":["../src/audience-schema.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,iBAAiB,EACjB,iBAAiB,EACjB,kBAAkB,EAClB,gBAAgB,GAEjB,MAAM,+BAA+B,CAAC;
|
|
1
|
+
{"version":3,"file":"audience-schema.js","sourceRoot":"","sources":["../src/audience-schema.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,iBAAiB,EACjB,iBAAiB,EACjB,kBAAkB,EAClB,gBAAgB,GAEjB,MAAM,+BAA+B,CAAC;AA0BvC,MAAM,UAAU,oBAAoB,CAClC,CAAa,EACb,cAA0C,iBAAiB,EAAE,EAC7D,SAAmC;IAEnC,MAAM,eAAe,GACnB,SAAS,EAAE,eAAe,IAAI,gBAAgB,CAAC,WAAW,CAAC,CAAC;IAC9D,MAAM,kBAAkB,GACtB,SAAS,EAAE,kBAAkB,IAAI,kBAAkB,EAAE,CAAC;IAExD,MAAM,mBAAmB,GAAG,CAAC;SAC1B,MAAM,EAAE;SACR,GAAG,EAAE;SACL,MAAM,CAAC,CAAC,GAAG,EAAiC,EAAE,CAAC,GAAG,KAAK,eAAe,CAAC;SACvE,QAAQ,CAAC,8DAA8D,CAAC,CAAC;IAE5E,MAAM,oCAAoC,GAAG,iBAAiB;SAC3D,MAAM,CAAC,CAAC,EAAE,EAAE,EAAE;QACb,OAAO,EAAE,KAAK,kBAAkB,CAAC;IACnC,CAAC,EAAE,iBAAiB,kBAAkB,qGAAqG,CAAC;SAC3I,QAAQ,CACP,4CAA4C,kBAAkB,iBAAiB,CAChF,CAAC;IAEJ,OAAO,CAAC,CAAC,KAAK,CAAC,CAAC,mBAAmB,EAAE,oCAAoC,CAAC,CAAC,CAAC;AAC9E,CAAC;AAED,MAAM,yBAAyB,GAAG,EAA4B,CAAC;AAE/D,MAAM,UAAU,wBAAwB,CACtC,CAAa,EACb,cAA0C,iBAAiB,EAAE,EAC7D,SAAmC;IAEnC,OAAO,oBAAoB,CAAC,CAAC,EAAE,WAAW,EAAE,SAAS,CAAC;SACnD,KAAK,EAAE;SACP,GAAG,CAAC,CAAC,EAAE,gCAAgC,CAAC;SACxC,GAAG,CACF,yBAAyB,EACzB,2CAA2C,yBAAyB,uBAAuB,CAC5F,CAAC;AACN,CAAC"}
|
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
import type { z as zod } from "zod";
|
|
2
|
+
import { type AudienceSchemaOverrides } from "./audience-schema";
|
|
2
3
|
import { SchemaVaultsAppEnvironment } from "@schemavaults/app-definitions";
|
|
3
4
|
export declare const grant_types: readonly ["authorization_code", "refresh_token"];
|
|
4
|
-
export declare function createAuthorizationCodePOSTBodySchema(z: typeof zod, environment?: SchemaVaultsAppEnvironment): zod.ZodObject<{
|
|
5
|
+
export declare function createAuthorizationCodePOSTBodySchema(z: typeof zod, environment?: SchemaVaultsAppEnvironment, overrides?: AudienceSchemaOverrides): zod.ZodObject<{
|
|
5
6
|
code: zod.ZodString;
|
|
6
7
|
challenge_time: zod.ZodNumber;
|
|
7
8
|
code_verifier: zod.ZodEffects<zod.ZodString, string, string>;
|
|
@@ -26,7 +27,7 @@ export declare function createAuthorizationCodePOSTBodySchema(z: typeof zod, env
|
|
|
26
27
|
grant_type: "authorization_code";
|
|
27
28
|
redirect_uri?: string | null | undefined;
|
|
28
29
|
}>;
|
|
29
|
-
export declare function createRefreshTokenPOSTBodySchema(z: typeof zod, environment?: SchemaVaultsAppEnvironment): zod.ZodObject<{
|
|
30
|
+
export declare function createRefreshTokenPOSTBodySchema(z: typeof zod, environment?: SchemaVaultsAppEnvironment, overrides?: AudienceSchemaOverrides): zod.ZodObject<{
|
|
30
31
|
audience: zod.ZodUnion<[zod.ZodUnion<[zod.ZodEffects<zod.ZodString, string, string>, zod.ZodEffects<zod.ZodEffects<zod.ZodEffects<zod.ZodString, string, string>, string, string>, string, string>]>, zod.ZodArray<zod.ZodUnion<[zod.ZodEffects<zod.ZodString, string, string>, zod.ZodEffects<zod.ZodEffects<zod.ZodEffects<zod.ZodString, string, string>, string, string>, string, string>]>, "many">]>;
|
|
31
32
|
client_app_id: zod.ZodEffects<zod.ZodEffects<zod.ZodString, string, string>, string, string>;
|
|
32
33
|
grant_type: zod.ZodLiteral<"refresh_token">;
|
|
@@ -5,17 +5,17 @@ export const grant_types = [
|
|
|
5
5
|
"authorization_code",
|
|
6
6
|
"refresh_token",
|
|
7
7
|
];
|
|
8
|
-
function createTokenEndpointBaseSchema(z, environment = getAppEnvironment()) {
|
|
8
|
+
function createTokenEndpointBaseSchema(z, environment = getAppEnvironment(), overrides) {
|
|
9
9
|
return z.object({
|
|
10
10
|
audience: z.union([
|
|
11
|
-
createAudienceSchema(z, environment),
|
|
12
|
-
createAudienceListSchema(z, environment),
|
|
11
|
+
createAudienceSchema(z, environment, overrides),
|
|
12
|
+
createAudienceListSchema(z, environment, overrides),
|
|
13
13
|
]),
|
|
14
14
|
client_app_id: appIdSchema,
|
|
15
15
|
});
|
|
16
16
|
}
|
|
17
|
-
export function createAuthorizationCodePOSTBodySchema(z, environment = getAppEnvironment()) {
|
|
18
|
-
return createTokenEndpointBaseSchema(z, environment)
|
|
17
|
+
export function createAuthorizationCodePOSTBodySchema(z, environment = getAppEnvironment(), overrides) {
|
|
18
|
+
return createTokenEndpointBaseSchema(z, environment, overrides)
|
|
19
19
|
.extend({
|
|
20
20
|
grant_type: z.literal("authorization_code"),
|
|
21
21
|
code: z.string().min(64).max(1024).base64url(),
|
|
@@ -40,8 +40,8 @@ export function createAuthorizationCodePOSTBodySchema(z, environment = getAppEnv
|
|
|
40
40
|
})
|
|
41
41
|
.strict();
|
|
42
42
|
}
|
|
43
|
-
export function createRefreshTokenPOSTBodySchema(z, environment = getAppEnvironment()) {
|
|
44
|
-
return createTokenEndpointBaseSchema(z, environment)
|
|
43
|
+
export function createRefreshTokenPOSTBodySchema(z, environment = getAppEnvironment(), overrides) {
|
|
44
|
+
return createTokenEndpointBaseSchema(z, environment, overrides)
|
|
45
45
|
.extend({
|
|
46
46
|
grant_type: z.literal("refresh_token"),
|
|
47
47
|
replaceRefreshToo: z.boolean().optional(),
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"auth_acquire_tokens_grant_types.js","sourceRoot":"","sources":["../src/auth_acquire_tokens_grant_types.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,oBAAoB,EAAE,MAAM,QAAQ,CAAC;AAE9C,OAAO,
|
|
1
|
+
{"version":3,"file":"auth_acquire_tokens_grant_types.js","sourceRoot":"","sources":["../src/auth_acquire_tokens_grant_types.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,oBAAoB,EAAE,MAAM,QAAQ,CAAC;AAE9C,OAAO,EAEL,wBAAwB,EACxB,oBAAoB,GACrB,MAAM,mBAAmB,CAAC;AAC3B,OAAO,EACL,WAAW,EACX,iBAAiB,GAElB,MAAM,+BAA+B,CAAC;AAEvC,MAAM,CAAC,MAAM,WAAW,GAAG;IACzB,oBAAoB;IACpB,eAAe;CACqB,CAAC;AAEvC,SAAS,6BAA6B,CACpC,CAAa,EACb,cAA0C,iBAAiB,EAAE,EAC7D,SAAmC;IAEnC,OAAO,CAAC,CAAC,MAAM,CAAC;QACd,QAAQ,EAAE,CAAC,CAAC,KAAK,CAAC;YAChB,oBAAoB,CAAC,CAAC,EAAE,WAAW,EAAE,SAAS,CAAC;YAC/C,wBAAwB,CAAC,CAAC,EAAE,WAAW,EAAE,SAAS,CAAC;SACpD,CAAC;QACF,aAAa,EAAE,WAAW;KAC3B,CAAC,CAAC;AACL,CAAC;AAED,MAAM,UAAU,qCAAqC,CACnD,CAAa,EACb,cAA0C,iBAAiB,EAAE,EAC7D,SAAmC;IAEnC,OAAO,6BAA6B,CAAC,CAAC,EAAE,WAAW,EAAE,SAAS,CAAC;SAC5D,MAAM,CAAC;QACN,UAAU,EAAE,CAAC,CAAC,OAAO,CAAC,oBAAoB,CAAC;QAC3C,IAAI,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC,SAAS,EAAE;QAC9C,aAAa,EAAE,oBAAoB,CAAC,mBAAmB;QACvD,cAAc,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,WAAW,EAAE;QACxC,8DAA8D;QAC9D,mEAAmE;QACnE,iEAAiE;QACjE,6DAA6D;QAC7D,+DAA+D;QAC/D,kEAAkE;QAClE,qCAAqC;QACrC,YAAY,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,EAAE,CAAC,QAAQ,EAAE,CAAC,QAAQ,EAAE;KACrD,CAAC;SACD,QAAQ,CAAC;QACR,UAAU,EAAE,IAAI;QAChB,QAAQ,EAAE,IAAI;QACd,aAAa,EAAE,IAAI;QACnB,IAAI,EAAE,IAAI;QACV,aAAa,EAAE,IAAI;QACnB,cAAc,EAAE,IAAI;KACrB,CAAC;SACD,MAAM,EAAE,CAAC;AACd,CAAC;AAED,MAAM,UAAU,gCAAgC,CAC9C,CAAa,EACb,cAA0C,iBAAiB,EAAE,EAC7D,SAAmC;IAEnC,OAAO,6BAA6B,CAAC,CAAC,EAAE,WAAW,EAAE,SAAS,CAAC;SAC5D,MAAM,CAAC;QACN,UAAU,EAAE,CAAC,CAAC,OAAO,CAAC,eAAe,CAAC;QACtC,iBAAiB,EAAE,CAAC,CAAC,OAAO,EAAE,CAAC,QAAQ,EAAE;KAC1C,CAAC;SACD,QAAQ,CAAC;QACR,UAAU,EAAE,IAAI;QAChB,QAAQ,EAAE,IAAI;QACd,aAAa,EAAE,IAAI;KACpB,CAAC;SACD,MAAM,EAAE,CAAC;AACd,CAAC"}
|
package/dist/index.d.ts
CHANGED
|
@@ -10,6 +10,9 @@ export * from "./middleware";
|
|
|
10
10
|
export type * from "./middleware";
|
|
11
11
|
export * from "./pkce";
|
|
12
12
|
export type * from "./pkce";
|
|
13
|
+
export * from "./oidc";
|
|
14
|
+
export type * from "./oidc";
|
|
15
|
+
export { sha256_base64url } from "./sha256_digest";
|
|
13
16
|
export { authenticateResultSchema, authenticatedAuthenticateResultSchema, mfaRequiredAuthenticateResultSchema, authenticateFailureResultSchema, challengeExpiredAuthenticateResultSchema, availableMfaFactorSchema, collapseWebauthnFactors, type AuthenticateResult, type AuthenticatedAuthenticateResult, type MfaRequiredAuthenticateResult, type AuthenticateFailureResult, type ChallengeExpiredAuthenticateResult, type AvailableMfaFactor, } from "./authenticate_result";
|
|
14
17
|
export * from "./mfa";
|
|
15
18
|
export { createRequestTokensResultSchema, type RequestTokensResult, createSuccessfullyGeneratedTokensRecordSchema, type SuccessfullyGeneratedTokensRecord, } from "./request_tokens_result";
|
|
@@ -18,6 +21,7 @@ export type * from "./auth_acquire_tokens_grant_types";
|
|
|
18
21
|
export { getAuthServerUrl } from "@schemavaults/app-definitions";
|
|
19
22
|
export { appIdSchema } from "@schemavaults/app-definitions";
|
|
20
23
|
export { createAudienceSchema, createAudienceListSchema, } from "./audience-schema";
|
|
24
|
+
export type { AudienceSchemaOverrides } from "./audience-schema";
|
|
21
25
|
export { inviteCodeFormatSchema, inviteCodeDefinitionSchema, } from "./invite-code";
|
|
22
26
|
export type { InviteCode, InviteCodeDefinition } from "./invite-code";
|
|
23
27
|
export { organizationIdSchema, isValidOrganizationID, RESERVED_ORGANIZATION_IDS, organizationDefinitionSchema, getHardcodedOrgs, getAuthServerOwnerOrganizationId, DEFAULT_AUTH_SERVER_OWNER_ORGANIZATION_ID, getAuthServerOwnerOrganizationName, DEFAULT_AUTH_SERVER_OWNER_ORGANIZATION_NAME, MAXIMUM_USER_ORGANIZATIONS, MINIMUM_ORGANIZATION_ID_LENGTH, MAXIMUM_ORGANIZATION_ID_LENGTH, inviteMemberInputModes, inviteMemberFormSchema, organizationInvitationStatusTypes, organizationInvitationStatusSchema, organizationInvitationSchema, organizationMembershipRoleTypes, organizationMembershipRoleTypeSchema, isValidOrganizationMembershipRoleType, organizationMembershipRoleDetailsSchema, isValidOrganizationMembershipRoleDetails, } from "./organizations";
|
package/dist/index.js
CHANGED
|
@@ -5,6 +5,8 @@ export * from "./credentials";
|
|
|
5
5
|
export * from "./token-data";
|
|
6
6
|
export * from "./middleware";
|
|
7
7
|
export * from "./pkce";
|
|
8
|
+
export * from "./oidc";
|
|
9
|
+
export { sha256_base64url } from "./sha256_digest";
|
|
8
10
|
export { authenticateResultSchema, authenticatedAuthenticateResultSchema, mfaRequiredAuthenticateResultSchema, authenticateFailureResultSchema, challengeExpiredAuthenticateResultSchema, availableMfaFactorSchema, collapseWebauthnFactors, } from "./authenticate_result";
|
|
9
11
|
export * from "./mfa";
|
|
10
12
|
export { createRequestTokensResultSchema, createSuccessfullyGeneratedTokensRecordSchema, } from "./request_tokens_result";
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,qBAAqB,EACrB,cAAc,GACf,MAAM,8BAA8B,CAAC;AAGtC,OAAO,EAAE,cAAc,EAAiB,MAAM,aAAa,CAAC;AAE5D,cAAc,eAAe,CAAC;AAG9B,mBAAmB;AACnB,cAAc,cAAc,CAAC;AAM7B,cAAc,cAAc,CAAC;AAG7B,cAAc,QAAQ,CAAC;AAGvB,OAAO,EACL,wBAAwB,EACxB,qCAAqC,EACrC,mCAAmC,EACnC,+BAA+B,EAC/B,wCAAwC,EACxC,wBAAwB,EACxB,uBAAuB,GAOxB,MAAM,uBAAuB,CAAC;AAE/B,cAAc,OAAO,CAAC;AACtB,OAAO,EACL,+BAA+B,EAE/B,6CAA6C,GAE9C,MAAM,yBAAyB,CAAC;AAEjC,cAAc,mCAAmC,CAAC;AAGlD,OAAO,EAAE,gBAAgB,EAAE,MAAM,+BAA+B,CAAC;AACjE,OAAO,EAAE,WAAW,EAAE,MAAM,+BAA+B,CAAC;AAE5D,OAAO,EACL,oBAAoB,EACpB,wBAAwB,GACzB,MAAM,mBAAmB,CAAC;
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,qBAAqB,EACrB,cAAc,GACf,MAAM,8BAA8B,CAAC;AAGtC,OAAO,EAAE,cAAc,EAAiB,MAAM,aAAa,CAAC;AAE5D,cAAc,eAAe,CAAC;AAG9B,mBAAmB;AACnB,cAAc,cAAc,CAAC;AAM7B,cAAc,cAAc,CAAC;AAG7B,cAAc,QAAQ,CAAC;AAGvB,cAAc,QAAQ,CAAC;AAGvB,OAAO,EAAE,gBAAgB,EAAE,MAAM,iBAAiB,CAAC;AAEnD,OAAO,EACL,wBAAwB,EACxB,qCAAqC,EACrC,mCAAmC,EACnC,+BAA+B,EAC/B,wCAAwC,EACxC,wBAAwB,EACxB,uBAAuB,GAOxB,MAAM,uBAAuB,CAAC;AAE/B,cAAc,OAAO,CAAC;AACtB,OAAO,EACL,+BAA+B,EAE/B,6CAA6C,GAE9C,MAAM,yBAAyB,CAAC;AAEjC,cAAc,mCAAmC,CAAC;AAGlD,OAAO,EAAE,gBAAgB,EAAE,MAAM,+BAA+B,CAAC;AACjE,OAAO,EAAE,WAAW,EAAE,MAAM,+BAA+B,CAAC;AAE5D,OAAO,EACL,oBAAoB,EACpB,wBAAwB,GACzB,MAAM,mBAAmB,CAAC;AAG3B,OAAO,EACL,sBAAsB,EACtB,0BAA0B,GAC3B,MAAM,eAAe,CAAC;AAGvB,OAAO,EACL,oBAAoB,EACpB,qBAAqB,EACrB,yBAAyB,EACzB,4BAA4B,EAC5B,gBAAgB,EAChB,gCAAgC,EAChC,yCAAyC,EACzC,kCAAkC,EAClC,2CAA2C,EAC3C,0BAA0B,EAC1B,8BAA8B,EAC9B,8BAA8B,EAC9B,sBAAsB,EACtB,sBAAsB,EACtB,iCAAiC,EACjC,kCAAkC,EAClC,4BAA4B,EAC5B,+BAA+B,EAC/B,oCAAoC,EACpC,qCAAqC,EACrC,uCAAuC,EACvC,wCAAwC,GACzC,MAAM,iBAAiB,CAAC;AAezB,OAAO,EAAE,wBAAwB,EAAE,MAAM,4BAA4B,CAAC;AAEtE,OAAO,EACL,sBAAsB,EACtB,4BAA4B,GAC7B,MAAM,2BAA2B,CAAC;AAEnC,OAAO,EACL,qBAAqB,EACrB,2BAA2B,GAC5B,MAAM,0BAA0B,CAAC;AAElC,OAAO,EAAE,wCAAwC,EAAE,MAAM,4CAA4C,CAAC;AAEtG,OAAO,EAAE,kCAAkC,EAAE,MAAM,0CAA0C,CAAC;AAE9F,OAAO,EACL,uBAAuB,EACvB,6BAA6B,EAC7B,4BAA4B,EAC5B,wBAAwB,GACzB,MAAM,cAAc,CAAC;AAGtB,OAAO,EAAE,qBAAqB,EAAE,MAAM,4BAA4B,CAAC;AAEnE,OAAO,EAAE,qBAAqB,EAAE,MAAM,QAAQ,CAAC;AAE/C,OAAO,EACL,iBAAiB,EACjB,yBAAyB,EACzB,gBAAgB,EAChB,0BAA0B,GAC3B,MAAM,uBAAuB,CAAC;AAG/B,OAAO,EACL,qCAAqC,EACrC,gCAAgC,GACjC,MAAM,mCAAmC,CAAC"}
|
|
@@ -1,10 +1,11 @@
|
|
|
1
1
|
import type { PotentiallyValidTokenSource } from "./token-source";
|
|
2
2
|
import type { DecodeTokenFn } from "./decode-token-type";
|
|
3
3
|
import type { UserData } from "../user_data";
|
|
4
|
-
export interface IDecodeSeveralJwtsInputOptions {
|
|
4
|
+
export interface IDecodeSeveralJwtsInputOptions<TDecoded = UserData> {
|
|
5
5
|
token_sources: readonly PotentiallyValidTokenSource[];
|
|
6
|
-
decodeJWT: DecodeTokenFn
|
|
6
|
+
decodeJWT: DecodeTokenFn<TDecoded>;
|
|
7
7
|
jwt_audience: string;
|
|
8
|
+
getUserData?: (decoded: TDecoded) => UserData;
|
|
8
9
|
}
|
|
9
|
-
export declare function decodeJWTs({ token_sources, decodeJWT, jwt_audience }: IDecodeSeveralJwtsInputOptions
|
|
10
|
+
export declare function decodeJWTs<TDecoded = UserData>({ token_sources, decodeJWT, jwt_audience, getUserData, }: IDecodeSeveralJwtsInputOptions<TDecoded>, debug?: boolean): Promise<TDecoded>;
|
|
10
11
|
export default decodeJWTs;
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
export async function decodeJWTs({ token_sources, decodeJWT, jwt_audience }, debug = false) {
|
|
1
|
+
export async function decodeJWTs({ token_sources, decodeJWT, jwt_audience, getUserData = (decoded) => decoded, }, debug = false) {
|
|
2
2
|
const n_token_sources = token_sources.length;
|
|
3
3
|
if (!Array.isArray(token_sources) || n_token_sources === 0) {
|
|
4
4
|
throw new Error("Did not receive a list of tokens to decode");
|
|
@@ -67,12 +67,13 @@ export async function decodeJWTs({ token_sources, decodeJWT, jwt_audience }, deb
|
|
|
67
67
|
const subs_set = new Set();
|
|
68
68
|
const emails_set = new Set();
|
|
69
69
|
for (const decoded of successfulDecodeResults) {
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
70
|
+
const user = getUserData(decoded);
|
|
71
|
+
uids_set.add(user.uid);
|
|
72
|
+
subs_set.add(user.sub);
|
|
73
|
+
if (user.uid !== user.sub) {
|
|
73
74
|
throw new Error("uid not equal to sub");
|
|
74
75
|
}
|
|
75
|
-
emails_set.add(
|
|
76
|
+
emails_set.add(user.email);
|
|
76
77
|
}
|
|
77
78
|
if (uids_set.size !== 1 || subs_set.size !== 1) {
|
|
78
79
|
throw new Error("Token decoding produced different user IDs!");
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"decode-jwts.js","sourceRoot":"","sources":["../../src/middleware/decode-jwts.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"decode-jwts.js","sourceRoot":"","sources":["../../src/middleware/decode-jwts.ts"],"names":[],"mappings":"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"}
|
|
@@ -3,4 +3,4 @@ import type { PotentiallyValidTokenSource } from "./token-source";
|
|
|
3
3
|
export interface DecodeTokenFnInputOptions extends PotentiallyValidTokenSource {
|
|
4
4
|
jwt_audience: string;
|
|
5
5
|
}
|
|
6
|
-
export type DecodeTokenFn = (opts: DecodeTokenFnInputOptions) => Promise<
|
|
6
|
+
export type DecodeTokenFn<TDecoded = UserData> = (opts: DecodeTokenFnInputOptions) => Promise<TDecoded>;
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
export { OIDC_OPENID_SCOPE, OIDC_SUPPORTED_SCOPES, DEFAULT_AUTH_SCOPE, OIDC_SCOPE_REGEX, oidcScopeSchema, parseAndGrantScopes, serializeOidcScopes, } from "./scope";
|
|
2
|
+
export type { OidcSupportedScope, OidcScope, ParsedOidcScopes, } from "./scope";
|
|
3
|
+
export { oidcNonceSchema, OIDC_NONCE_VSCHAR_REGEX, parseOidcNonce, OidcNonceValidationError, } from "./nonce";
|
|
4
|
+
export type { OidcNonce } from "./nonce";
|
|
@@ -0,0 +1,3 @@
|
|
|
1
|
+
export { OIDC_OPENID_SCOPE, OIDC_SUPPORTED_SCOPES, DEFAULT_AUTH_SCOPE, OIDC_SCOPE_REGEX, oidcScopeSchema, parseAndGrantScopes, serializeOidcScopes, } from "./scope";
|
|
2
|
+
export { oidcNonceSchema, OIDC_NONCE_VSCHAR_REGEX, parseOidcNonce, OidcNonceValidationError, } from "./nonce";
|
|
3
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/oidc/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,iBAAiB,EACjB,qBAAqB,EACrB,kBAAkB,EAClB,gBAAgB,EAChB,eAAe,EACf,mBAAmB,EACnB,mBAAmB,GACpB,MAAM,SAAS,CAAC;AAOjB,OAAO,EACL,eAAe,EACf,uBAAuB,EACvB,cAAc,EACd,wBAAwB,GACzB,MAAM,SAAS,CAAC"}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
export declare const OIDC_NONCE_VSCHAR_REGEX: RegExp;
|
|
3
|
+
export declare const oidcNonceSchema: z.ZodString;
|
|
4
|
+
export type OidcNonce = z.infer<typeof oidcNonceSchema>;
|
|
5
|
+
/**
|
|
6
|
+
* Thrown by `parseOidcNonce` when the caller supplied a `nonce` value
|
|
7
|
+
* that is present but fails schema validation. Server-side entry points
|
|
8
|
+
* should turn this into a 400 / `invalid_request` response.
|
|
9
|
+
*/
|
|
10
|
+
export declare class OidcNonceValidationError extends Error {
|
|
11
|
+
readonly reasons: readonly string[];
|
|
12
|
+
constructor(reasons: readonly string[]);
|
|
13
|
+
}
|
|
14
|
+
/**
|
|
15
|
+
* Validates an OIDC `nonce` at a server boundary.
|
|
16
|
+
*
|
|
17
|
+
* - Absent / null / undefined → returns `null` (nonce is optional in
|
|
18
|
+
* the authorization-code flow).
|
|
19
|
+
* - Present + well-formed → returns the validated string.
|
|
20
|
+
* - Present + malformed → throws `OidcNonceValidationError` so the
|
|
21
|
+
* caller can respond 400 / `invalid_request`.
|
|
22
|
+
*
|
|
23
|
+
* Empty strings are treated as malformed (not absent) so an RP that
|
|
24
|
+
* accidentally serializes `?nonce=` gets a loud signal instead of a
|
|
25
|
+
* silent downgrade.
|
|
26
|
+
*/
|
|
27
|
+
export declare function parseOidcNonce(raw: unknown): string | null;
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
// OIDC Core §3.1.2.1 defines `nonce` as an opaque, case-sensitive string
|
|
3
|
+
// the RP binds to its session and verifies when it appears in the
|
|
4
|
+
// id_token. Like the OAuth2 `state` parameter (oauth2-state-schema.ts),
|
|
5
|
+
// the auth server never interprets the value — it only stores it on the
|
|
6
|
+
// authorization-code row and echoes it as an id_token claim — so the
|
|
7
|
+
// validator enforces the same protocol-boundary properties: non-empty,
|
|
8
|
+
// bounded length, printable ASCII only (no control chars / CR-LF that
|
|
9
|
+
// could pollute logs or smuggle terminal escapes through the echo).
|
|
10
|
+
const MAX_OIDC_NONCE_LENGTH = 512;
|
|
11
|
+
export const OIDC_NONCE_VSCHAR_REGEX = /^[\x20-\x7E]+$/;
|
|
12
|
+
export const oidcNonceSchema = z
|
|
13
|
+
.string()
|
|
14
|
+
.min(1)
|
|
15
|
+
.max(MAX_OIDC_NONCE_LENGTH)
|
|
16
|
+
.regex(OIDC_NONCE_VSCHAR_REGEX, {
|
|
17
|
+
message: "OIDC 'nonce' must contain only printable ASCII characters",
|
|
18
|
+
});
|
|
19
|
+
/**
|
|
20
|
+
* Thrown by `parseOidcNonce` when the caller supplied a `nonce` value
|
|
21
|
+
* that is present but fails schema validation. Server-side entry points
|
|
22
|
+
* should turn this into a 400 / `invalid_request` response.
|
|
23
|
+
*/
|
|
24
|
+
export class OidcNonceValidationError extends Error {
|
|
25
|
+
reasons;
|
|
26
|
+
constructor(reasons) {
|
|
27
|
+
super(`Invalid OIDC 'nonce' parameter: ${reasons.join("; ")}`);
|
|
28
|
+
this.name = "OidcNonceValidationError";
|
|
29
|
+
this.reasons = reasons;
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
/**
|
|
33
|
+
* Validates an OIDC `nonce` at a server boundary.
|
|
34
|
+
*
|
|
35
|
+
* - Absent / null / undefined → returns `null` (nonce is optional in
|
|
36
|
+
* the authorization-code flow).
|
|
37
|
+
* - Present + well-formed → returns the validated string.
|
|
38
|
+
* - Present + malformed → throws `OidcNonceValidationError` so the
|
|
39
|
+
* caller can respond 400 / `invalid_request`.
|
|
40
|
+
*
|
|
41
|
+
* Empty strings are treated as malformed (not absent) so an RP that
|
|
42
|
+
* accidentally serializes `?nonce=` gets a loud signal instead of a
|
|
43
|
+
* silent downgrade.
|
|
44
|
+
*/
|
|
45
|
+
export function parseOidcNonce(raw) {
|
|
46
|
+
if (raw === undefined || raw === null)
|
|
47
|
+
return null;
|
|
48
|
+
if (typeof raw !== "string") {
|
|
49
|
+
throw new OidcNonceValidationError([
|
|
50
|
+
`Expected string, got ${Array.isArray(raw) ? "array" : typeof raw}`,
|
|
51
|
+
]);
|
|
52
|
+
}
|
|
53
|
+
const parsed = oidcNonceSchema.safeParse(raw);
|
|
54
|
+
if (!parsed.success) {
|
|
55
|
+
throw new OidcNonceValidationError(parsed.error.issues.map((i) => i.message));
|
|
56
|
+
}
|
|
57
|
+
return parsed.data;
|
|
58
|
+
}
|
|
59
|
+
//# sourceMappingURL=nonce.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"nonce.js","sourceRoot":"","sources":["../../src/oidc/nonce.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAExB,yEAAyE;AACzE,kEAAkE;AAClE,wEAAwE;AACxE,wEAAwE;AACxE,qEAAqE;AACrE,uEAAuE;AACvE,sEAAsE;AACtE,oEAAoE;AAEpE,MAAM,qBAAqB,GAAG,GAAY,CAAC;AAE3C,MAAM,CAAC,MAAM,uBAAuB,GAAW,gBAAgB,CAAC;AAEhE,MAAM,CAAC,MAAM,eAAe,GAAG,CAAC;KAC7B,MAAM,EAAE;KACR,GAAG,CAAC,CAAC,CAAC;KACN,GAAG,CAAC,qBAAqB,CAAC;KAC1B,KAAK,CAAC,uBAAuB,EAAE;IAC9B,OAAO,EAAE,2DAA2D;CACrE,CAAC,CAAC;AAIL;;;;GAIG;AACH,MAAM,OAAO,wBAAyB,SAAQ,KAAK;IACjC,OAAO,CAAoB;IAC3C,YAAmB,OAA0B;QAC3C,KAAK,CAAC,mCAAmC,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;QAC/D,IAAI,CAAC,IAAI,GAAG,0BAA0B,CAAC;QACvC,IAAI,CAAC,OAAO,GAAG,OAAO,CAAC;IACzB,CAAC;CACF;AAED;;;;;;;;;;;;GAYG;AACH,MAAM,UAAU,cAAc,CAAC,GAAY;IACzC,IAAI,GAAG,KAAK,SAAS,IAAI,GAAG,KAAK,IAAI;QAAE,OAAO,IAAI,CAAC;IACnD,IAAI,OAAO,GAAG,KAAK,QAAQ,EAAE,CAAC;QAC5B,MAAM,IAAI,wBAAwB,CAAC;YACjC,wBAAwB,KAAK,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,OAAO,GAAG,EAAE;SACpE,CAAC,CAAC;IACL,CAAC;IACD,MAAM,MAAM,GAAG,eAAe,CAAC,SAAS,CAAC,GAAG,CAAC,CAAC;IAC9C,IAAI,CAAC,MAAM,CAAC,OAAO,EAAE,CAAC;QACpB,MAAM,IAAI,wBAAwB,CAChC,MAAM,CAAC,KAAK,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,OAAO,CAAC,CAC1C,CAAC;IACJ,CAAC;IACD,OAAO,MAAM,CAAC,IAAI,CAAC;AACrB,CAAC"}
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* OIDC scope handling for the parallel OIDC surface.
|
|
3
|
+
*
|
|
4
|
+
* The platform's own authorization model is audience-based
|
|
5
|
+
* (see audience-schema.ts / APP_TO_API_PERMISSIONS); OAuth2 scopes exist
|
|
6
|
+
* only on the OIDC surface, where `openid` is mandatory (OIDC Core §3.1.2.1)
|
|
7
|
+
* and `email`/`profile` gate which claims the id_token and /userinfo
|
|
8
|
+
* response carry. Unknown scopes are silently dropped per RFC 6749 §3.3
|
|
9
|
+
* (the granted set is echoed back in the token response, so RPs that
|
|
10
|
+
* hardcode e.g. "openid profile email address" still interoperate).
|
|
11
|
+
*/
|
|
12
|
+
import { z } from "zod";
|
|
13
|
+
export declare const OIDC_OPENID_SCOPE: "openid";
|
|
14
|
+
export declare const OIDC_SUPPORTED_SCOPES: readonly ["openid", "email", "profile"];
|
|
15
|
+
/**
|
|
16
|
+
* Scope requested by default when a flow does not name one explicitly:
|
|
17
|
+
* the SDK's `authenticateWithRedirect`/`sendAuthenticateRequest`
|
|
18
|
+
* default, and the AuthForm's fallback for entry URLs without a
|
|
19
|
+
* `scope` parameter (e.g. the auth server's own /account flow).
|
|
20
|
+
*/
|
|
21
|
+
export declare const DEFAULT_AUTH_SCOPE: "openid email profile";
|
|
22
|
+
/**
|
|
23
|
+
* RFC 6749 §3.3 wire format for the `scope` parameter:
|
|
24
|
+
* scope = scope-token *( SP scope-token )
|
|
25
|
+
* scope-token = 1*( %x21 / %x23-5B / %x5D-7E )
|
|
26
|
+
* i.e. one or more scope-tokens joined by a SINGLE space, where a
|
|
27
|
+
* scope-token is printable ASCII excluding SP (the delimiter), `"`
|
|
28
|
+
* (0x22) and `\` (0x5C), and all control chars. This rejects leading /
|
|
29
|
+
* trailing / repeated spaces and any control / CR-LF that could pollute
|
|
30
|
+
* logs or the token-response `scope` echo.
|
|
31
|
+
*/
|
|
32
|
+
export declare const OIDC_SCOPE_REGEX: RegExp;
|
|
33
|
+
/**
|
|
34
|
+
* Validates the FORMAT of a raw `scope` request parameter (RFC 6749
|
|
35
|
+
* §3.3, bounded length). Orthogonal to `parseAndGrantScopes`, which
|
|
36
|
+
* decides which of the (well-formed) tokens the platform grants — a
|
|
37
|
+
* value can be format-valid here yet grant nothing (all tokens
|
|
38
|
+
* unsupported). Auth flows apply this at the request boundary before
|
|
39
|
+
* deriving the granted set.
|
|
40
|
+
*/
|
|
41
|
+
export declare const oidcScopeSchema: z.ZodString;
|
|
42
|
+
export type OidcScope = z.infer<typeof oidcScopeSchema>;
|
|
43
|
+
export type OidcSupportedScope = (typeof OIDC_SUPPORTED_SCOPES)[number];
|
|
44
|
+
export interface ParsedOidcScopes {
|
|
45
|
+
/**
|
|
46
|
+
* The intersection of the requested scopes with
|
|
47
|
+
* OIDC_SUPPORTED_SCOPES, deduplicated, in request order.
|
|
48
|
+
*/
|
|
49
|
+
granted: OidcSupportedScope[];
|
|
50
|
+
/** Whether the request included the mandatory `openid` scope. */
|
|
51
|
+
hasOpenid: boolean;
|
|
52
|
+
}
|
|
53
|
+
/**
|
|
54
|
+
* Parses a raw `scope` request parameter (space-delimited per
|
|
55
|
+
* RFC 6749 §3.3) into the granted subset. Non-string or empty input
|
|
56
|
+
* grants nothing (callers reject missing `openid` via `hasOpenid`).
|
|
57
|
+
*/
|
|
58
|
+
export declare function parseAndGrantScopes(raw: unknown): ParsedOidcScopes;
|
|
59
|
+
/**
|
|
60
|
+
* Serializes granted scopes back to the space-delimited wire format for
|
|
61
|
+
* the token response `scope` field and the AUTHORIZATION_CODES row.
|
|
62
|
+
*/
|
|
63
|
+
export declare function serializeOidcScopes(scopes: readonly string[]): string;
|
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* OIDC scope handling for the parallel OIDC surface.
|
|
3
|
+
*
|
|
4
|
+
* The platform's own authorization model is audience-based
|
|
5
|
+
* (see audience-schema.ts / APP_TO_API_PERMISSIONS); OAuth2 scopes exist
|
|
6
|
+
* only on the OIDC surface, where `openid` is mandatory (OIDC Core §3.1.2.1)
|
|
7
|
+
* and `email`/`profile` gate which claims the id_token and /userinfo
|
|
8
|
+
* response carry. Unknown scopes are silently dropped per RFC 6749 §3.3
|
|
9
|
+
* (the granted set is echoed back in the token response, so RPs that
|
|
10
|
+
* hardcode e.g. "openid profile email address" still interoperate).
|
|
11
|
+
*/
|
|
12
|
+
import { z } from "zod";
|
|
13
|
+
export const OIDC_OPENID_SCOPE = "openid";
|
|
14
|
+
export const OIDC_SUPPORTED_SCOPES = ["openid", "email", "profile"];
|
|
15
|
+
/**
|
|
16
|
+
* Scope requested by default when a flow does not name one explicitly:
|
|
17
|
+
* the SDK's `authenticateWithRedirect`/`sendAuthenticateRequest`
|
|
18
|
+
* default, and the AuthForm's fallback for entry URLs without a
|
|
19
|
+
* `scope` parameter (e.g. the auth server's own /account flow).
|
|
20
|
+
*/
|
|
21
|
+
export const DEFAULT_AUTH_SCOPE = "openid email profile";
|
|
22
|
+
const MAX_OIDC_SCOPE_LENGTH = 256;
|
|
23
|
+
/**
|
|
24
|
+
* RFC 6749 §3.3 wire format for the `scope` parameter:
|
|
25
|
+
* scope = scope-token *( SP scope-token )
|
|
26
|
+
* scope-token = 1*( %x21 / %x23-5B / %x5D-7E )
|
|
27
|
+
* i.e. one or more scope-tokens joined by a SINGLE space, where a
|
|
28
|
+
* scope-token is printable ASCII excluding SP (the delimiter), `"`
|
|
29
|
+
* (0x22) and `\` (0x5C), and all control chars. This rejects leading /
|
|
30
|
+
* trailing / repeated spaces and any control / CR-LF that could pollute
|
|
31
|
+
* logs or the token-response `scope` echo.
|
|
32
|
+
*/
|
|
33
|
+
export const OIDC_SCOPE_REGEX = /^[\x21\x23-\x5B\x5D-\x7E]+(?: [\x21\x23-\x5B\x5D-\x7E]+)*$/;
|
|
34
|
+
/**
|
|
35
|
+
* Validates the FORMAT of a raw `scope` request parameter (RFC 6749
|
|
36
|
+
* §3.3, bounded length). Orthogonal to `parseAndGrantScopes`, which
|
|
37
|
+
* decides which of the (well-formed) tokens the platform grants — a
|
|
38
|
+
* value can be format-valid here yet grant nothing (all tokens
|
|
39
|
+
* unsupported). Auth flows apply this at the request boundary before
|
|
40
|
+
* deriving the granted set.
|
|
41
|
+
*/
|
|
42
|
+
export const oidcScopeSchema = z
|
|
43
|
+
.string()
|
|
44
|
+
.min(1)
|
|
45
|
+
.max(MAX_OIDC_SCOPE_LENGTH)
|
|
46
|
+
.regex(OIDC_SCOPE_REGEX, {
|
|
47
|
+
message: "'scope' must be a space-delimited list of RFC 6749 §3.3 scope tokens",
|
|
48
|
+
});
|
|
49
|
+
function isSupportedOidcScope(scope) {
|
|
50
|
+
if (typeof scope !== "string" || scope.length === 0) {
|
|
51
|
+
throw new TypeError("Expected 'scope' to be a non-empty string!");
|
|
52
|
+
}
|
|
53
|
+
return OIDC_SUPPORTED_SCOPES.includes(scope);
|
|
54
|
+
}
|
|
55
|
+
/**
|
|
56
|
+
* Parses a raw `scope` request parameter (space-delimited per
|
|
57
|
+
* RFC 6749 §3.3) into the granted subset. Non-string or empty input
|
|
58
|
+
* grants nothing (callers reject missing `openid` via `hasOpenid`).
|
|
59
|
+
*/
|
|
60
|
+
export function parseAndGrantScopes(raw) {
|
|
61
|
+
if (typeof raw !== "string") {
|
|
62
|
+
return { granted: [], hasOpenid: false };
|
|
63
|
+
}
|
|
64
|
+
if (!oidcScopeSchema.safeParse(raw).success) {
|
|
65
|
+
return { granted: [], hasOpenid: false };
|
|
66
|
+
}
|
|
67
|
+
const granted = [];
|
|
68
|
+
for (const token of raw.split(" ")) {
|
|
69
|
+
if (!token)
|
|
70
|
+
continue; // collapse repeated separators
|
|
71
|
+
if (isSupportedOidcScope(token) && !granted.includes(token)) {
|
|
72
|
+
granted.push(token);
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
return { granted, hasOpenid: granted.includes(OIDC_OPENID_SCOPE) };
|
|
76
|
+
}
|
|
77
|
+
/**
|
|
78
|
+
* Serializes granted scopes back to the space-delimited wire format for
|
|
79
|
+
* the token response `scope` field and the AUTHORIZATION_CODES row.
|
|
80
|
+
*/
|
|
81
|
+
export function serializeOidcScopes(scopes) {
|
|
82
|
+
return scopes.join(" ");
|
|
83
|
+
}
|
|
84
|
+
//# sourceMappingURL=scope.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"scope.js","sourceRoot":"","sources":["../../src/oidc/scope.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAEH,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAExB,MAAM,CAAC,MAAM,iBAAiB,GAAG,QAAiB,CAAC;AAEnD,MAAM,CAAC,MAAM,qBAAqB,GAAG,CAAC,QAAQ,EAAE,OAAO,EAAE,SAAS,CAAU,CAAC;AAE7E;;;;;GAKG;AACH,MAAM,CAAC,MAAM,kBAAkB,GAAG,sBAA+B,CAAC;AAElE,MAAM,qBAAqB,GAAG,GAAY,CAAC;AAE3C;;;;;;;;;GASG;AACH,MAAM,CAAC,MAAM,gBAAgB,GAC3B,4DAA4D,CAAC;AAE/D;;;;;;;GAOG;AACH,MAAM,CAAC,MAAM,eAAe,GAAG,CAAC;KAC7B,MAAM,EAAE;KACR,GAAG,CAAC,CAAC,CAAC;KACN,GAAG,CAAC,qBAAqB,CAAC;KAC1B,KAAK,CAAC,gBAAgB,EAAE;IACvB,OAAO,EACL,sEAAsE;CACzE,CAAC,CAAC;AAgBL,SAAS,oBAAoB,CAAC,KAAa;IACzC,IAAI,OAAO,KAAK,KAAK,QAAQ,IAAI,KAAK,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QACpD,MAAM,IAAI,SAAS,CAAC,4CAA4C,CAAC,CAAC;IACpE,CAAC;IACD,OAAQ,qBAA2C,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC;AACtE,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,mBAAmB,CAAC,GAAY;IAC9C,IAAI,OAAO,GAAG,KAAK,QAAQ,EAAE,CAAC;QAC5B,OAAO,EAAE,OAAO,EAAE,EAAE,EAAE,SAAS,EAAE,KAAK,EAAE,CAAC;IAC3C,CAAC;IAED,IAAI,CAAC,eAAe,CAAC,SAAS,CAAC,GAAG,CAAC,CAAC,OAAO,EAAE,CAAC;QAC5C,OAAO,EAAE,OAAO,EAAE,EAAE,EAAE,SAAS,EAAE,KAAK,EAAE,CAAC;IAC3C,CAAC;IAED,MAAM,OAAO,GAAyB,EAAE,CAAC;IACzC,KAAK,MAAM,KAAK,IAAI,GAAG,CAAC,KAAK,CAAC,GAAG,CAAC,EAAE,CAAC;QACnC,IAAI,CAAC,KAAK;YAAE,SAAS,CAAC,+BAA+B;QACrD,IAAI,oBAAoB,CAAC,KAAK,CAAC,IAAI,CAAC,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAC,EAAE,CAAC;YAC5D,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;QACtB,CAAC;IACH,CAAC;IAED,OAAO,EAAE,OAAO,EAAE,SAAS,EAAE,OAAO,CAAC,QAAQ,CAAC,iBAAiB,CAAC,EAAE,CAAC;AACrE,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,mBAAmB,CAAC,MAAyB;IAC3D,OAAO,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;AAC1B,CAAC"}
|
|
@@ -6,7 +6,7 @@ export interface CreateCodeChallengeInputOptions {
|
|
|
6
6
|
code_verifier: CodeVerifier;
|
|
7
7
|
challenge_time: number;
|
|
8
8
|
};
|
|
9
|
-
|
|
9
|
+
sha256: (code_verifier: string) => Promise<string>;
|
|
10
10
|
}
|
|
11
11
|
export declare function create_code_challenge(verifier_opts: CreateCodeChallengeInputOptions): Promise<CodeChallengeWithDetails>;
|
|
12
12
|
export declare const codeChallengeSchema: z.ZodEffects<z.ZodString, string, string>;
|
|
@@ -17,7 +17,7 @@ export async function create_code_challenge(verifier_opts) {
|
|
|
17
17
|
if (typeof max_age === 'number' && max_age !== MAX_PKCE_CODE_VERIFIER_AGE) {
|
|
18
18
|
throw new Error("Code verifier has invalid max_age");
|
|
19
19
|
}
|
|
20
|
-
const base64url_encoded_hash = await verifier_opts.
|
|
20
|
+
const base64url_encoded_hash = await verifier_opts.sha256(code_verifier);
|
|
21
21
|
if (typeof challenge_time !== 'number') {
|
|
22
22
|
throw new Error("'challenge_time' is a required field!");
|
|
23
23
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"code_challenge.js","sourceRoot":"","sources":["../../src/pkce/code_challenge.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AACxB,OAAO,EAAgC,0BAA0B,EAAqB,MAAM,iBAAiB,CAAC;AAE9G,MAAM,CAAC,MAAM,qBAAqB,GAAG,MAAe,CAAC;
|
|
1
|
+
{"version":3,"file":"code_challenge.js","sourceRoot":"","sources":["../../src/pkce/code_challenge.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AACxB,OAAO,EAAgC,0BAA0B,EAAqB,MAAM,iBAAiB,CAAC;AAE9G,MAAM,CAAC,MAAM,qBAAqB,GAAG,MAAe,CAAC;AASrD,wCAAwC;AACxC,4DAA4D;AAC5D,MAAM,CAAC,KAAK,UAAU,qBAAqB,CACzC,aAA8C;IAE9C,IAAI,CAAC,aAAa,CAAC,aAAa,EAAE,CAAC;QACjC,MAAM,IAAI,KAAK,CAAC,+CAA+C,CAAC,CAAC;IACnE,CAAC;IAED,MAAM,EAAE,UAAU,EAAE,OAAO,EAAE,aAAa,EAAE,cAAc,EAAE,GAAG,aAAa,CAAC,aAAa,CAAC;IAC3F,aAAoC,CAAC;IACrC,IAAI,OAAO,UAAU,KAAK,QAAQ,EAAE,CAAC;QACnC,IAAI,UAAU,GAAG,IAAI,CAAC,GAAG,EAAE,EAAE,CAAC;YAC5B,MAAM,IAAI,KAAK,CAAC,2BAA2B,CAAC,CAAC;QAC/C,CAAC;IACH,CAAC;IAED,IAAI,OAAO,OAAO,KAAK,QAAQ,IAAK,OAAO,KAAK,0BAA0B,EAAE,CAAC;QAC3E,MAAM,IAAI,KAAK,CAAC,mCAAmC,CAAC,CAAC;IACvD,CAAC;IAED,MAAM,sBAAsB,GAAG,MAAM,aAAa,CAAC,MAAM,CAAC,aAAa,CAAC,CAAC;IAEzE,IAAI,OAAO,cAAc,KAAK,QAAQ,EAAE,CAAC;QACvC,MAAM,IAAI,KAAK,CAAC,uCAAuC,CAAC,CAAC;IAC3D,CAAC;IAED,OAAO;QACL,cAAc,EAAE,sBAAsB;QACtC,qBAAqB;QACrB,cAAc;KACf,CAAC;AACJ,CAAC;AAED,MAAM,yBAAyB,GAAG,EAAW,CAAC;AAC9C,MAAM,yBAAyB,GAAG,IAAa,CAAC;AAEhD,MAAM,CAAC,MAAM,mBAAmB,GAAG,CAAC,CAAC,MAAM,EAAE;KAC1C,GAAG,CAAC,yBAAyB,CAAC;KAC9B,GAAG,CAAC,yBAAyB,CAAC;KAC9B,MAAM,CAAC,KAAK,CAAC,EAAE,CAAC,kBAAkB,CAAC,IAAI,CAAC,KAAK,CAAC,EAAE;IAC/C,OAAO,EAAE,gDAAgD;CAC1D,CAAC,CAAC;AAIL,MAAM,CAAC,MAAM,8BAA8B,GAAG,CAAC,CAAC,MAAM,CAAC;IACrD,cAAc,EAAE,mBAAmB;IACnC,qBAAqB,EAAE,CAAC,CAAC,OAAO,CAAC,qBAAqB,CAAC;IACvD,cAAc,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,WAAW,EAAE;CACzC,CAAC,CAAC,QAAQ,EAAE,CAAC,MAAM,EAAE,CAAA"}
|
package/dist/pkce/pkce.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { create_code_challenge, codeChallengeSchema, code_challenge_method, codeChallengeWithDetailsSchema, } from "./code_challenge";
|
|
2
2
|
import { create_code_verifier, codeVerifierSchema, MAX_PKCE_CODE_VERIFIER_AGE, codeVerifierWithDetailsSchema, } from "./code_verifier";
|
|
3
|
-
import {
|
|
3
|
+
import { sha256_base64url } from "../sha256_digest";
|
|
4
4
|
// Handles the creation of a PKCE code verifier and challenge
|
|
5
5
|
export class PKCE_ProofKeyManager {
|
|
6
6
|
code_verifier;
|
|
@@ -10,7 +10,7 @@ export class PKCE_ProofKeyManager {
|
|
|
10
10
|
static async createCodeChallenge(code_verifier) {
|
|
11
11
|
const createCodeChallengeOptions = {
|
|
12
12
|
code_verifier,
|
|
13
|
-
|
|
13
|
+
sha256: sha256_base64url,
|
|
14
14
|
};
|
|
15
15
|
const code_challenge = await create_code_challenge(createCodeChallengeOptions);
|
|
16
16
|
return code_challenge;
|
|
@@ -57,7 +57,7 @@ export class PKCE_ProofKeyManager {
|
|
|
57
57
|
code_verifier: code_verifier.code_verifier,
|
|
58
58
|
challenge_time: code_verifier.challenge_time,
|
|
59
59
|
},
|
|
60
|
-
|
|
60
|
+
sha256: sha256_base64url,
|
|
61
61
|
};
|
|
62
62
|
return await create_code_challenge(codeChallengeOptions);
|
|
63
63
|
}
|
|
@@ -109,7 +109,10 @@ export class PKCE_ProofKeyManager {
|
|
|
109
109
|
* @returns sha256_hash(input_code_verifier) === saved_code_challenge
|
|
110
110
|
*/
|
|
111
111
|
static async doesVerifierMatchChallenge(opts) {
|
|
112
|
-
|
|
112
|
+
// `challenge_time` is accepted for caller convenience but is not used
|
|
113
|
+
// for matching (it does not feed the hash) — the proof is purely
|
|
114
|
+
// `BASE64URL-ENCODE(SHA256(verifier)) === saved_code_challenge`.
|
|
115
|
+
const { input_code_verifier, saved_code_challenge, timingSafeEqual } = opts;
|
|
113
116
|
if (typeof input_code_verifier !== "string" || !input_code_verifier) {
|
|
114
117
|
throw new Error("Input code verifier is not a string");
|
|
115
118
|
}
|
|
@@ -122,24 +125,23 @@ export class PKCE_ProofKeyManager {
|
|
|
122
125
|
return false;
|
|
123
126
|
}
|
|
124
127
|
try {
|
|
125
|
-
//
|
|
126
|
-
//
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
// Timing-safe byte comparison using the caller-provided function.
|
|
133
|
-
// The caller is responsible for supplying a constant-time comparator;
|
|
134
|
-
// accepting it as an argument keeps this module free of any runtime
|
|
128
|
+
// RFC 7636 §4.6: recompute the S256 challenge from the presented
|
|
129
|
+
// verifier and compare it to the stored one. Both the SchemaVaults
|
|
130
|
+
// SDK and standard OIDC RPs now emit the strict base64url encoding
|
|
131
|
+
// (see sha256_base64url), so a single computation covers every client.
|
|
132
|
+
const expected_challenge = await sha256_base64url(input_code_verifier);
|
|
133
|
+
// Timing-safe comparison using the caller-provided function. Accepting
|
|
134
|
+
// the comparator as an argument keeps this module free of any runtime
|
|
135
135
|
// dependency on node:crypto, so it can be bundled for browsers (for
|
|
136
136
|
// createCodeVerifier/createCodeChallenge) without bundler errors.
|
|
137
|
-
|
|
138
|
-
const
|
|
139
|
-
|
|
137
|
+
// Challenges are compared as raw UTF-8 bytes (length-checked first).
|
|
138
|
+
const encoder = new TextEncoder();
|
|
139
|
+
const savedBytes = encoder.encode(saved_code_challenge);
|
|
140
|
+
const expectedBytes = encoder.encode(expected_challenge);
|
|
141
|
+
if (expectedBytes.length !== savedBytes.length) {
|
|
140
142
|
return false;
|
|
141
143
|
}
|
|
142
|
-
return timingSafeEqual(
|
|
144
|
+
return timingSafeEqual(expectedBytes, savedBytes);
|
|
143
145
|
}
|
|
144
146
|
catch (e) {
|
|
145
147
|
console.error(e);
|
package/dist/pkce/pkce.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"pkce.js","sourceRoot":"","sources":["../../src/pkce/pkce.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,qBAAqB,EACrB,mBAAmB,EACnB,qBAAqB,EAGrB,8BAA8B,GAC/B,MAAM,kBAAkB,CAAC;AAC1B,OAAO,EAEL,oBAAoB,EACpB,kBAAkB,EAClB,0BAA0B,EAE1B,6BAA6B,GAC9B,MAAM,iBAAiB,CAAC;AACzB,OAAO,EAAE,
|
|
1
|
+
{"version":3,"file":"pkce.js","sourceRoot":"","sources":["../../src/pkce/pkce.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import type { z as zod } from "zod";
|
|
2
|
+
import { type AudienceSchemaOverrides } from "./audience-schema";
|
|
2
3
|
import { type SchemaVaultsAppEnvironment } from "@schemavaults/app-definitions";
|
|
3
|
-
export declare function createSuccessfullyGeneratedTokensRecordSchema(z: typeof zod, environment?: SchemaVaultsAppEnvironment): zod.ZodEffects<zod.ZodEffects<zod.ZodObject<{
|
|
4
|
+
export declare function createSuccessfullyGeneratedTokensRecordSchema(z: typeof zod, environment?: SchemaVaultsAppEnvironment, overrides?: AudienceSchemaOverrides): zod.ZodEffects<zod.ZodEffects<zod.ZodObject<{
|
|
4
5
|
access: zod.ZodOptional<zod.ZodRecord<zod.ZodUnion<[zod.ZodEffects<zod.ZodString, string, string>, zod.ZodEffects<zod.ZodEffects<zod.ZodEffects<zod.ZodString, string, string>, string, string>, string, string>]>, zod.ZodUnion<[zod.ZodObject<{
|
|
5
6
|
uid: zod.ZodString;
|
|
6
7
|
iat: zod.ZodNumber;
|
|
@@ -176,7 +177,7 @@ export declare function createSuccessfullyGeneratedTokensRecordSchema(z: typeof
|
|
|
176
177
|
refresh_token_expiry?: number | undefined;
|
|
177
178
|
}>;
|
|
178
179
|
export type SuccessfullyGeneratedTokensRecord = zod.infer<ReturnType<typeof createSuccessfullyGeneratedTokensRecordSchema>>;
|
|
179
|
-
export declare function createRequestTokensResultSchema(z: typeof zod, environment?: SchemaVaultsAppEnvironment): zod.ZodUnion<[zod.ZodObject<{
|
|
180
|
+
export declare function createRequestTokensResultSchema(z: typeof zod, environment?: SchemaVaultsAppEnvironment, overrides?: AudienceSchemaOverrides): zod.ZodUnion<[zod.ZodObject<{
|
|
180
181
|
message: zod.ZodString;
|
|
181
182
|
success: zod.ZodLiteral<false>;
|
|
182
183
|
error: zod.ZodLiteral<true>;
|
|
@@ -425,6 +426,7 @@ export declare function createRequestTokensResultSchema(z: typeof zod, environme
|
|
|
425
426
|
invite_code?: string | undefined;
|
|
426
427
|
}>>;
|
|
427
428
|
userOrgs: zod.ZodOptional<zod.ZodArray<zod.ZodEffects<zod.ZodEffects<zod.ZodString, string, string>, string, string>, "many">>;
|
|
429
|
+
nonce: zod.ZodOptional<zod.ZodString>;
|
|
428
430
|
}, "strict", zod.ZodTypeAny, {
|
|
429
431
|
message: string;
|
|
430
432
|
client_app_id: string;
|
|
@@ -464,6 +466,7 @@ export declare function createRequestTokensResultSchema(z: typeof zod, environme
|
|
|
464
466
|
invite_code?: string | undefined;
|
|
465
467
|
} | undefined;
|
|
466
468
|
userOrgs?: string[] | undefined;
|
|
469
|
+
nonce?: string | undefined;
|
|
467
470
|
}, {
|
|
468
471
|
message: string;
|
|
469
472
|
client_app_id: string;
|
|
@@ -503,5 +506,6 @@ export declare function createRequestTokensResultSchema(z: typeof zod, environme
|
|
|
503
506
|
invite_code?: string | undefined;
|
|
504
507
|
} | undefined;
|
|
505
508
|
userOrgs?: string[] | undefined;
|
|
509
|
+
nonce?: string | undefined;
|
|
506
510
|
}>]>;
|
|
507
511
|
export type RequestTokensResult = zod.infer<ReturnType<typeof createRequestTokensResultSchema>>;
|
|
@@ -1,19 +1,20 @@
|
|
|
1
1
|
import { userDataSchema } from "./user_data";
|
|
2
2
|
import { accessTokenDataSchema, refreshTokenDataSchema } from "./token-data";
|
|
3
|
-
import { createAudienceSchema } from "./audience-schema";
|
|
3
|
+
import { createAudienceSchema, } from "./audience-schema";
|
|
4
4
|
import { organizationIdSchema } from "./organizations";
|
|
5
|
+
import { oidcNonceSchema } from "./oidc/nonce";
|
|
5
6
|
import { appIdSchema, getAppEnvironment, } from "@schemavaults/app-definitions";
|
|
6
7
|
// NOTE: These schemas are exposed as factories (rather than module-scope
|
|
7
8
|
// constants) because the audience schema depends on the app environment and
|
|
8
9
|
// auth-server URL, which must be resolved at call time. Eager module-scope
|
|
9
10
|
// initialization breaks `next build` in Docker where those env vars are unset.
|
|
10
|
-
export function createSuccessfullyGeneratedTokensRecordSchema(z, environment = getAppEnvironment()) {
|
|
11
|
+
export function createSuccessfullyGeneratedTokensRecordSchema(z, environment = getAppEnvironment(), overrides) {
|
|
11
12
|
return z
|
|
12
13
|
.object({
|
|
13
14
|
access: z
|
|
14
15
|
.record(
|
|
15
16
|
// map of audience (app id, fs region, or auth server url) to token for that audience
|
|
16
|
-
createAudienceSchema(z, environment), z.union([accessTokenDataSchema, z.literal("AS_HTTP_ONLY_COOKIE")]))
|
|
17
|
+
createAudienceSchema(z, environment, overrides), z.union([accessTokenDataSchema, z.literal("AS_HTTP_ONLY_COOKIE")]))
|
|
17
18
|
.optional(),
|
|
18
19
|
refresh: z
|
|
19
20
|
.union([refreshTokenDataSchema, z.literal("AS_HTTP_ONLY_COOKIE")])
|
|
@@ -42,16 +43,24 @@ export function createSuccessfullyGeneratedTokensRecordSchema(z, environment = g
|
|
|
42
43
|
return true;
|
|
43
44
|
}, "Passing 'refresh_token_expiry' is redundant when refresh token is passed as an object!");
|
|
44
45
|
}
|
|
45
|
-
export function createRequestTokensResultSchema(z, environment = getAppEnvironment()) {
|
|
46
|
+
export function createRequestTokensResultSchema(z, environment = getAppEnvironment(), overrides) {
|
|
46
47
|
const requestTokensSuccessfulResultSchema = z
|
|
47
48
|
.object({
|
|
48
49
|
success: z.literal(true),
|
|
49
50
|
error: z.literal(false),
|
|
50
51
|
message: z.string(),
|
|
51
52
|
client_app_id: appIdSchema,
|
|
52
|
-
tokens: createSuccessfullyGeneratedTokensRecordSchema(z, environment).optional(),
|
|
53
|
+
tokens: createSuccessfullyGeneratedTokensRecordSchema(z, environment, overrides).optional(),
|
|
53
54
|
userData: userDataSchema.optional(),
|
|
54
55
|
userOrgs: organizationIdSchema.array().optional(),
|
|
56
|
+
// Echo of the login-time replay nonce bound to the redeemed
|
|
57
|
+
// authorization code — the custom surface's analogue of the OIDC
|
|
58
|
+
// id_token `nonce` claim; the SDK verifies it against the value it
|
|
59
|
+
// stored at redirect time. Absent on refresh grants and on codes
|
|
60
|
+
// minted before nonces became first-class. Validated with the shared
|
|
61
|
+
// `oidcNonceSchema` (the same schema that gated it at the login
|
|
62
|
+
// boundary) so the echo round-trip is symmetric.
|
|
63
|
+
nonce: oidcNonceSchema.optional(),
|
|
55
64
|
})
|
|
56
65
|
.required({
|
|
57
66
|
success: true,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"request_tokens_result.js","sourceRoot":"","sources":["../src/request_tokens_result.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AAC7C,OAAO,EAAE,qBAAqB,EAAE,sBAAsB,EAAE,MAAM,cAAc,CAAC;AAC7E,OAAO,
|
|
1
|
+
{"version":3,"file":"request_tokens_result.js","sourceRoot":"","sources":["../src/request_tokens_result.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
export {
|
|
1
|
+
export { sha256_base64url, sha256_base64url as default, } from "./sha256_digest";
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
export {
|
|
1
|
+
export { sha256_base64url, sha256_base64url as default, } from "./sha256_digest";
|
|
2
2
|
//# sourceMappingURL=index.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/sha256_digest/index.ts"],"names":[],"mappings":"AAAA,OAAO,
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/sha256_digest/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,gBAAgB,EAChB,gBAAgB,IAAI,OAAO,GAC5B,MAAM,iBAAiB,CAAC"}
|
|
@@ -1,3 +1,9 @@
|
|
|
1
1
|
export declare const digest_algorithm: "SHA-256";
|
|
2
|
-
|
|
3
|
-
|
|
2
|
+
/**
|
|
3
|
+
* Strict RFC 7636 §4.2 / RFC 4648 §5 base64url (no padding) encoding of
|
|
4
|
+
* the SHA-256 digest — the `code_challenge` encoding used by both the
|
|
5
|
+
* SchemaVaults SDK and standard OAuth2/OIDC clients. Produces a 43-char
|
|
6
|
+
* string.
|
|
7
|
+
*/
|
|
8
|
+
export declare function sha256_base64url(code_verifier: string): Promise<string>;
|
|
9
|
+
export default sha256_base64url;
|
|
@@ -1,6 +1,12 @@
|
|
|
1
1
|
import isCryptoApiAvailable from "../is_crypto_api_available";
|
|
2
2
|
export const digest_algorithm = "SHA-256";
|
|
3
|
-
|
|
3
|
+
/**
|
|
4
|
+
* Computes the SHA-256 digest of the input and returns it as a
|
|
5
|
+
* standard base64 string (RFC 4648 §4, with `+`, `/`, and `=` padding).
|
|
6
|
+
* Picks the WebCrypto implementation in secure contexts and falls back
|
|
7
|
+
* to crypto-js in insecure HTTP contexts (both return standard base64).
|
|
8
|
+
*/
|
|
9
|
+
async function sha256_standard_base64(code_verifier) {
|
|
4
10
|
let sha256;
|
|
5
11
|
try {
|
|
6
12
|
if (isCryptoApiAvailable()) {
|
|
@@ -21,8 +27,17 @@ export async function sha256_digest(code_verifier) {
|
|
|
21
27
|
if (typeof output !== "string") {
|
|
22
28
|
throw new TypeError("Expected output to be a string!");
|
|
23
29
|
}
|
|
24
|
-
|
|
25
|
-
return output.replace(/[^A-Za-z0-9_-]/g, "_");
|
|
30
|
+
return output;
|
|
26
31
|
}
|
|
27
|
-
|
|
32
|
+
/**
|
|
33
|
+
* Strict RFC 7636 §4.2 / RFC 4648 §5 base64url (no padding) encoding of
|
|
34
|
+
* the SHA-256 digest — the `code_challenge` encoding used by both the
|
|
35
|
+
* SchemaVaults SDK and standard OAuth2/OIDC clients. Produces a 43-char
|
|
36
|
+
* string.
|
|
37
|
+
*/
|
|
38
|
+
export async function sha256_base64url(code_verifier) {
|
|
39
|
+
const output = await sha256_standard_base64(code_verifier);
|
|
40
|
+
return output.replace(/\+/g, "-").replace(/\//g, "_").replace(/=+$/, "");
|
|
41
|
+
}
|
|
42
|
+
export default sha256_base64url;
|
|
28
43
|
//# sourceMappingURL=sha256_digest.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"sha256_digest.js","sourceRoot":"","sources":["../../src/sha256_digest/sha256_digest.ts"],"names":[],"mappings":"AAAA,OAAO,oBAAoB,MAAM,2BAA2B,CAAC;AAE7D,MAAM,CAAC,MAAM,gBAAgB,GAAG,SAAkB,CAAC;AAEnD,
|
|
1
|
+
{"version":3,"file":"sha256_digest.js","sourceRoot":"","sources":["../../src/sha256_digest/sha256_digest.ts"],"names":[],"mappings":"AAAA,OAAO,oBAAoB,MAAM,2BAA2B,CAAC;AAE7D,MAAM,CAAC,MAAM,gBAAgB,GAAG,SAAkB,CAAC;AAEnD;;;;;GAKG;AACH,KAAK,UAAU,sBAAsB,CAAC,aAAqB;IACzD,IAAI,MAAkD,CAAC;IACvD,IAAI,CAAC;QACH,IAAI,oBAAoB,EAAE,EAAE,CAAC;YAC3B,MAAM,GAAG,MAAM,MAAM,CAAC,oBAAoB,CAAC,CAAC,IAAI,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC;QACzE,CAAC;aAAM,CAAC;YACN,MAAM,GAAG,MAAM,MAAM,CAAC,uBAAuB,CAAC,CAAC,IAAI,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC;QAC5E,CAAC;IACH,CAAC;IAAC,OAAO,CAAU,EAAE,CAAC;QACpB,OAAO,CAAC,KAAK,CAAC,uCAAuC,EAAE,CAAC,CAAC,CAAC;QAC1D,MAAM,IAAI,KAAK,CAAC,qCAAqC,CAAC,CAAC;IACzD,CAAC;IAED,IAAI,OAAO,MAAM,KAAK,UAAU,IAAI,OAAO,MAAM,KAAK,QAAQ,EAAE,CAAC;QAC/D,MAAM,IAAI,KAAK,CACb,iGAAiG,CAClG,CAAC;IACJ,CAAC;IAED,MAAM,MAAM,GAAW,MAAM,MAAM,CAAC,aAAa,CAAC,CAAC;IAEnD,IAAI,OAAO,MAAM,KAAK,QAAQ,EAAE,CAAC;QAC/B,MAAM,IAAI,SAAS,CAAC,iCAAiC,CAAC,CAAC;IACzD,CAAC;IAED,OAAO,MAAM,CAAC;AAChB,CAAC;AAED;;;;;GAKG;AACH,MAAM,CAAC,KAAK,UAAU,gBAAgB,CAAC,aAAqB;IAC1D,MAAM,MAAM,GAAW,MAAM,sBAAsB,CAAC,aAAa,CAAC,CAAC;IACnE,OAAO,MAAM,CAAC,OAAO,CAAC,KAAK,EAAE,GAAG,CAAC,CAAC,OAAO,CAAC,KAAK,EAAE,GAAG,CAAC,CAAC,OAAO,CAAC,KAAK,EAAE,EAAE,CAAC,CAAC;AAC3E,CAAC;AAED,eAAe,gBAAgB,CAAC"}
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@schemavaults/auth-common",
|
|
3
3
|
"description": "Types and utility functions for authentication and authorization",
|
|
4
|
-
"version": "0.
|
|
4
|
+
"version": "0.22.4",
|
|
5
5
|
"license": "UNLICENSED",
|
|
6
6
|
"private": false,
|
|
7
7
|
"repository": {
|
|
@@ -14,7 +14,7 @@
|
|
|
14
14
|
"types": "dist/index.d.ts",
|
|
15
15
|
"dependencies": {
|
|
16
16
|
"zod": "3.25.8",
|
|
17
|
-
"@schemavaults/app-definitions": "0.
|
|
17
|
+
"@schemavaults/app-definitions": "0.11.4",
|
|
18
18
|
"crypto-js": "4.2.0"
|
|
19
19
|
},
|
|
20
20
|
"scripts": {
|