@schemavaults/auth-common 0.10.11 → 0.12.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/authenticate_result.d.ts +114 -4
- package/dist/authenticate_result.js +42 -8
- package/dist/authenticate_result.js.map +1 -1
- package/dist/index.d.ts +5 -1
- package/dist/index.js +4 -1
- package/dist/index.js.map +1 -1
- package/dist/mfa/index.d.ts +3 -0
- package/dist/mfa/index.js +4 -0
- package/dist/mfa/index.js.map +1 -0
- package/dist/mfa/mfa-challenge.d.ts +12 -0
- package/dist/mfa/mfa-challenge.js +8 -0
- package/dist/mfa/mfa-challenge.js.map +1 -0
- package/dist/mfa/mfa-factor-type.d.ts +5 -0
- package/dist/mfa/mfa-factor-type.js +7 -0
- package/dist/mfa/mfa-factor-type.js.map +1 -0
- package/dist/mfa/mfa-verify-body.d.ts +117 -0
- package/dist/mfa/mfa-verify-body.js +57 -0
- package/dist/mfa/mfa-verify-body.js.map +1 -0
- package/dist/oauth2-state-schema.d.ts +29 -0
- package/dist/oauth2-state-schema.js +71 -0
- package/dist/oauth2-state-schema.js.map +1 -0
- package/dist/timing-safe-string-equal.d.ts +13 -0
- package/dist/timing-safe-string-equal.js +24 -0
- package/dist/timing-safe-string-equal.js.map +1 -0
- package/package.json +1 -1
|
@@ -1,15 +1,125 @@
|
|
|
1
1
|
import { z } from "zod";
|
|
2
|
-
export declare const
|
|
2
|
+
export declare const authenticatedAuthenticateResultSchema: z.ZodObject<{
|
|
3
|
+
kind: z.ZodLiteral<"authenticated">;
|
|
4
|
+
success: z.ZodBoolean;
|
|
5
|
+
message: z.ZodString;
|
|
6
|
+
authorization_code: z.ZodString;
|
|
7
|
+
}, "strict", z.ZodTypeAny, {
|
|
8
|
+
message: string;
|
|
9
|
+
authorization_code: string;
|
|
10
|
+
kind: "authenticated";
|
|
11
|
+
success: boolean;
|
|
12
|
+
}, {
|
|
13
|
+
message: string;
|
|
14
|
+
authorization_code: string;
|
|
15
|
+
kind: "authenticated";
|
|
16
|
+
success: boolean;
|
|
17
|
+
}>;
|
|
18
|
+
export type AuthenticatedAuthenticateResult = z.infer<typeof authenticatedAuthenticateResultSchema>;
|
|
19
|
+
export declare const mfaRequiredAuthenticateResultSchema: z.ZodObject<{
|
|
20
|
+
kind: z.ZodLiteral<"mfa_required">;
|
|
21
|
+
success: z.ZodBoolean;
|
|
22
|
+
message: z.ZodString;
|
|
23
|
+
challenge_id: z.ZodString;
|
|
24
|
+
expires_at: z.ZodNumber;
|
|
25
|
+
}, "strict", z.ZodTypeAny, {
|
|
26
|
+
message: string;
|
|
27
|
+
expires_at: number;
|
|
28
|
+
kind: "mfa_required";
|
|
29
|
+
success: boolean;
|
|
30
|
+
challenge_id: string;
|
|
31
|
+
}, {
|
|
32
|
+
message: string;
|
|
33
|
+
expires_at: number;
|
|
34
|
+
kind: "mfa_required";
|
|
35
|
+
success: boolean;
|
|
36
|
+
challenge_id: string;
|
|
37
|
+
}>;
|
|
38
|
+
export type MfaRequiredAuthenticateResult = z.infer<typeof mfaRequiredAuthenticateResultSchema>;
|
|
39
|
+
export declare const authenticateFailureResultSchema: z.ZodObject<{
|
|
40
|
+
kind: z.ZodLiteral<"failure">;
|
|
41
|
+
success: z.ZodBoolean;
|
|
3
42
|
message: z.ZodString;
|
|
4
|
-
|
|
43
|
+
}, "strict", z.ZodTypeAny, {
|
|
44
|
+
message: string;
|
|
45
|
+
kind: "failure";
|
|
46
|
+
success: boolean;
|
|
47
|
+
}, {
|
|
48
|
+
message: string;
|
|
49
|
+
kind: "failure";
|
|
50
|
+
success: boolean;
|
|
51
|
+
}>;
|
|
52
|
+
export type AuthenticateFailureResult = z.infer<typeof authenticateFailureResultSchema>;
|
|
53
|
+
export declare const challengeExpiredAuthenticateResultSchema: z.ZodObject<{
|
|
54
|
+
kind: z.ZodLiteral<"challenge_expired">;
|
|
5
55
|
success: z.ZodBoolean;
|
|
56
|
+
message: z.ZodString;
|
|
6
57
|
}, "strict", z.ZodTypeAny, {
|
|
7
58
|
message: string;
|
|
59
|
+
kind: "challenge_expired";
|
|
8
60
|
success: boolean;
|
|
9
|
-
authorization_code?: string | undefined;
|
|
10
61
|
}, {
|
|
11
62
|
message: string;
|
|
63
|
+
kind: "challenge_expired";
|
|
12
64
|
success: boolean;
|
|
13
|
-
authorization_code?: string | undefined;
|
|
14
65
|
}>;
|
|
66
|
+
export type ChallengeExpiredAuthenticateResult = z.infer<typeof challengeExpiredAuthenticateResultSchema>;
|
|
67
|
+
export declare const authenticateResultSchema: z.ZodDiscriminatedUnion<"kind", [z.ZodObject<{
|
|
68
|
+
kind: z.ZodLiteral<"authenticated">;
|
|
69
|
+
success: z.ZodBoolean;
|
|
70
|
+
message: z.ZodString;
|
|
71
|
+
authorization_code: z.ZodString;
|
|
72
|
+
}, "strict", z.ZodTypeAny, {
|
|
73
|
+
message: string;
|
|
74
|
+
authorization_code: string;
|
|
75
|
+
kind: "authenticated";
|
|
76
|
+
success: boolean;
|
|
77
|
+
}, {
|
|
78
|
+
message: string;
|
|
79
|
+
authorization_code: string;
|
|
80
|
+
kind: "authenticated";
|
|
81
|
+
success: boolean;
|
|
82
|
+
}>, z.ZodObject<{
|
|
83
|
+
kind: z.ZodLiteral<"mfa_required">;
|
|
84
|
+
success: z.ZodBoolean;
|
|
85
|
+
message: z.ZodString;
|
|
86
|
+
challenge_id: z.ZodString;
|
|
87
|
+
expires_at: z.ZodNumber;
|
|
88
|
+
}, "strict", z.ZodTypeAny, {
|
|
89
|
+
message: string;
|
|
90
|
+
expires_at: number;
|
|
91
|
+
kind: "mfa_required";
|
|
92
|
+
success: boolean;
|
|
93
|
+
challenge_id: string;
|
|
94
|
+
}, {
|
|
95
|
+
message: string;
|
|
96
|
+
expires_at: number;
|
|
97
|
+
kind: "mfa_required";
|
|
98
|
+
success: boolean;
|
|
99
|
+
challenge_id: string;
|
|
100
|
+
}>, z.ZodObject<{
|
|
101
|
+
kind: z.ZodLiteral<"failure">;
|
|
102
|
+
success: z.ZodBoolean;
|
|
103
|
+
message: z.ZodString;
|
|
104
|
+
}, "strict", z.ZodTypeAny, {
|
|
105
|
+
message: string;
|
|
106
|
+
kind: "failure";
|
|
107
|
+
success: boolean;
|
|
108
|
+
}, {
|
|
109
|
+
message: string;
|
|
110
|
+
kind: "failure";
|
|
111
|
+
success: boolean;
|
|
112
|
+
}>, z.ZodObject<{
|
|
113
|
+
kind: z.ZodLiteral<"challenge_expired">;
|
|
114
|
+
success: z.ZodBoolean;
|
|
115
|
+
message: z.ZodString;
|
|
116
|
+
}, "strict", z.ZodTypeAny, {
|
|
117
|
+
message: string;
|
|
118
|
+
kind: "challenge_expired";
|
|
119
|
+
success: boolean;
|
|
120
|
+
}, {
|
|
121
|
+
message: string;
|
|
122
|
+
kind: "challenge_expired";
|
|
123
|
+
success: boolean;
|
|
124
|
+
}>]>;
|
|
15
125
|
export type AuthenticateResult = z.infer<typeof authenticateResultSchema>;
|
|
@@ -1,12 +1,46 @@
|
|
|
1
1
|
import { z } from "zod";
|
|
2
|
-
export const
|
|
2
|
+
export const authenticatedAuthenticateResultSchema = z
|
|
3
|
+
.object({
|
|
4
|
+
kind: z.literal("authenticated"),
|
|
3
5
|
success: z.boolean(),
|
|
4
6
|
message: z.string(),
|
|
5
|
-
authorization_code: z
|
|
6
|
-
.
|
|
7
|
-
.
|
|
8
|
-
})
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
7
|
+
authorization_code: z
|
|
8
|
+
.string()
|
|
9
|
+
.min(43, "Authorization code must be at least 43 characters long"),
|
|
10
|
+
})
|
|
11
|
+
.strict();
|
|
12
|
+
export const mfaRequiredAuthenticateResultSchema = z
|
|
13
|
+
.object({
|
|
14
|
+
kind: z.literal("mfa_required"),
|
|
15
|
+
success: z.boolean(),
|
|
16
|
+
message: z.string(),
|
|
17
|
+
challenge_id: z.string().uuid(),
|
|
18
|
+
expires_at: z.number().int().positive(),
|
|
19
|
+
})
|
|
20
|
+
.strict();
|
|
21
|
+
export const authenticateFailureResultSchema = z
|
|
22
|
+
.object({
|
|
23
|
+
kind: z.literal("failure"),
|
|
24
|
+
success: z.boolean(),
|
|
25
|
+
message: z.string(),
|
|
26
|
+
})
|
|
27
|
+
.strict();
|
|
28
|
+
// Returned by /api/auth/mfa/verify with HTTP 410 when an in-flight MFA
|
|
29
|
+
// challenge has been invalidated — either by exhausting the per-challenge
|
|
30
|
+
// attempt cap or by expiring (TTL elapsed). Distinct from `failure` so
|
|
31
|
+
// clients can navigate the user back to the login page rather than letting
|
|
32
|
+
// them retry against a key that no longer exists in Redis.
|
|
33
|
+
export const challengeExpiredAuthenticateResultSchema = z
|
|
34
|
+
.object({
|
|
35
|
+
kind: z.literal("challenge_expired"),
|
|
36
|
+
success: z.boolean(),
|
|
37
|
+
message: z.string(),
|
|
38
|
+
})
|
|
39
|
+
.strict();
|
|
40
|
+
export const authenticateResultSchema = z.discriminatedUnion("kind", [
|
|
41
|
+
authenticatedAuthenticateResultSchema,
|
|
42
|
+
mfaRequiredAuthenticateResultSchema,
|
|
43
|
+
authenticateFailureResultSchema,
|
|
44
|
+
challengeExpiredAuthenticateResultSchema,
|
|
45
|
+
]);
|
|
12
46
|
//# sourceMappingURL=authenticate_result.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"authenticate_result.js","sourceRoot":"","sources":["../src/authenticate_result.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAExB,MAAM,CAAC,MAAM,
|
|
1
|
+
{"version":3,"file":"authenticate_result.js","sourceRoot":"","sources":["../src/authenticate_result.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAExB,MAAM,CAAC,MAAM,qCAAqC,GAAG,CAAC;KACnD,MAAM,CAAC;IACN,IAAI,EAAE,CAAC,CAAC,OAAO,CAAC,eAAe,CAAC;IAChC,OAAO,EAAE,CAAC,CAAC,OAAO,EAAE;IACpB,OAAO,EAAE,CAAC,CAAC,MAAM,EAAE;IACnB,kBAAkB,EAAE,CAAC;SAClB,MAAM,EAAE;SACR,GAAG,CAAC,EAAE,EAAE,wDAAwD,CAAC;CACrE,CAAC;KACD,MAAM,EAAE,CAAC;AAMZ,MAAM,CAAC,MAAM,mCAAmC,GAAG,CAAC;KACjD,MAAM,CAAC;IACN,IAAI,EAAE,CAAC,CAAC,OAAO,CAAC,cAAc,CAAC;IAC/B,OAAO,EAAE,CAAC,CAAC,OAAO,EAAE;IACpB,OAAO,EAAE,CAAC,CAAC,MAAM,EAAE;IACnB,YAAY,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,IAAI,EAAE;IAC/B,UAAU,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,EAAE,CAAC,QAAQ,EAAE;CACxC,CAAC;KACD,MAAM,EAAE,CAAC;AAMZ,MAAM,CAAC,MAAM,+BAA+B,GAAG,CAAC;KAC7C,MAAM,CAAC;IACN,IAAI,EAAE,CAAC,CAAC,OAAO,CAAC,SAAS,CAAC;IAC1B,OAAO,EAAE,CAAC,CAAC,OAAO,EAAE;IACpB,OAAO,EAAE,CAAC,CAAC,MAAM,EAAE;CACpB,CAAC;KACD,MAAM,EAAE,CAAC;AAMZ,uEAAuE;AACvE,0EAA0E;AAC1E,uEAAuE;AACvE,2EAA2E;AAC3E,2DAA2D;AAC3D,MAAM,CAAC,MAAM,wCAAwC,GAAG,CAAC;KACtD,MAAM,CAAC;IACN,IAAI,EAAE,CAAC,CAAC,OAAO,CAAC,mBAAmB,CAAC;IACpC,OAAO,EAAE,CAAC,CAAC,OAAO,EAAE;IACpB,OAAO,EAAE,CAAC,CAAC,MAAM,EAAE;CACpB,CAAC;KACD,MAAM,EAAE,CAAC;AAMZ,MAAM,CAAC,MAAM,wBAAwB,GAAG,CAAC,CAAC,kBAAkB,CAAC,MAAM,EAAE;IACnE,qCAAqC;IACrC,mCAAmC;IACnC,+BAA+B;IAC/B,wCAAwC;CACzC,CAAC,CAAC"}
|
package/dist/index.d.ts
CHANGED
|
@@ -10,7 +10,8 @@ export * from "./middleware";
|
|
|
10
10
|
export type * from "./middleware";
|
|
11
11
|
export * from "./pkce";
|
|
12
12
|
export type * from "./pkce";
|
|
13
|
-
export { authenticateResultSchema, type AuthenticateResult, } from "./authenticate_result";
|
|
13
|
+
export { authenticateResultSchema, authenticatedAuthenticateResultSchema, mfaRequiredAuthenticateResultSchema, authenticateFailureResultSchema, challengeExpiredAuthenticateResultSchema, type AuthenticateResult, type AuthenticatedAuthenticateResult, type MfaRequiredAuthenticateResult, type AuthenticateFailureResult, type ChallengeExpiredAuthenticateResult, } from "./authenticate_result";
|
|
14
|
+
export * from "./mfa";
|
|
14
15
|
export { requestTokensResultSchema, type RequestTokensResult, successfullyGeneratedTokensRecordSchema, type SuccessfullyGeneratedTokensRecord, } from "./request_tokens_result";
|
|
15
16
|
export * from "./auth_acquire_tokens_grant_types";
|
|
16
17
|
export type * from "./auth_acquire_tokens_grant_types";
|
|
@@ -28,3 +29,6 @@ export { determineRefreshTokenCookieSameSiteValue } from "./determineRefreshToke
|
|
|
28
29
|
export { authorizeClientApplicationFormType } from "./authorize-client-application-form-type";
|
|
29
30
|
export { paginationOptionsSchema, DEFAULT_PAGINATION_PAGE_INDEX, DEFAULT_PAGINATION_PAGE_SIZE, isValidPaginationOptions, } from "./pagination";
|
|
30
31
|
export type { PaginationOptions } from "./pagination";
|
|
32
|
+
export { timingSafeStringEqual } from "./timing-safe-string-equal";
|
|
33
|
+
export { oauth2StateSchema, OAUTH2_STATE_VSCHAR_REGEX, parseOAuth2State, OAuth2StateValidationError, } from "./oauth2-state-schema";
|
|
34
|
+
export type { OAuth2State } from "./oauth2-state-schema";
|
package/dist/index.js
CHANGED
|
@@ -5,7 +5,8 @@ export * from "./credentials";
|
|
|
5
5
|
export * from "./token-data";
|
|
6
6
|
export * from "./middleware";
|
|
7
7
|
export * from "./pkce";
|
|
8
|
-
export { authenticateResultSchema, } from "./authenticate_result";
|
|
8
|
+
export { authenticateResultSchema, authenticatedAuthenticateResultSchema, mfaRequiredAuthenticateResultSchema, authenticateFailureResultSchema, challengeExpiredAuthenticateResultSchema, } from "./authenticate_result";
|
|
9
|
+
export * from "./mfa";
|
|
9
10
|
export { requestTokensResultSchema, successfullyGeneratedTokensRecordSchema, } from "./request_tokens_result";
|
|
10
11
|
export * from "./auth_acquire_tokens_grant_types";
|
|
11
12
|
export { PRODUCTION_AUTH_SERVER_URL } from "@schemavaults/app-definitions";
|
|
@@ -19,4 +20,6 @@ export { AccessTokenCookieName, AccessTokenExpiryCookieName, } from "./AccessTok
|
|
|
19
20
|
export { determineRefreshTokenCookieSameSiteValue } from "./determineRefreshTokenCookieSameSiteValue";
|
|
20
21
|
export { authorizeClientApplicationFormType } from "./authorize-client-application-form-type";
|
|
21
22
|
export { paginationOptionsSchema, DEFAULT_PAGINATION_PAGE_INDEX, DEFAULT_PAGINATION_PAGE_SIZE, isValidPaginationOptions, } from "./pagination";
|
|
23
|
+
export { timingSafeStringEqual } from "./timing-safe-string-equal";
|
|
24
|
+
export { oauth2StateSchema, OAUTH2_STATE_VSCHAR_REGEX, parseOAuth2State, OAuth2StateValidationError, } from "./oauth2-state-schema";
|
|
22
25
|
//# sourceMappingURL=index.js.map
|
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,
|
|
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,GAMzC,MAAM,uBAAuB,CAAC;AAE/B,cAAc,OAAO,CAAC;AACtB,OAAO,EACL,yBAAyB,EAEzB,uCAAuC,GAExC,MAAM,yBAAyB,CAAC;AAEjC,cAAc,mCAAmC,CAAC;AAGlD,OAAO,EAAE,0BAA0B,EAAE,MAAM,+BAA+B,CAAC;AAC3E,OAAO,EAAE,WAAW,EAAE,MAAM,+BAA+B,CAAC;AAE5D,OAAO,EAAE,cAAc,EAAE,iBAAiB,EAAE,MAAM,mBAAmB,CAAC;AAEtE,OAAO,EACL,sBAAsB,EACtB,0BAA0B,GAC3B,MAAM,eAAe,CAAC;AAGvB,OAAO,EACL,oBAAoB,EACpB,qBAAqB,EACrB,yBAAyB,EACzB,4BAA4B,EAC5B,aAAa,EACb,4BAA4B,EAC5B,0BAA0B,EAC1B,8BAA8B,EAC9B,8BAA8B,EAC9B,sBAAsB,EACtB,sBAAsB,EACtB,iCAAiC,EACjC,kCAAkC,EAClC,4BAA4B,EAC5B,+BAA+B,EAC/B,oCAAoC,EACpC,qCAAqC,GACtC,MAAM,iBAAiB,CAAC;AAczB,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,EACL,iBAAiB,EACjB,yBAAyB,EACzB,gBAAgB,EAChB,0BAA0B,GAC3B,MAAM,uBAAuB,CAAC"}
|
|
@@ -0,0 +1,3 @@
|
|
|
1
|
+
export { mfaFactorTypes, mfaFactorTypeSchema, isValidMfaFactorType, type MfaFactorType, } from "./mfa-factor-type";
|
|
2
|
+
export { mfaChallengeSchema, type MfaChallengeDescriptor, } from "./mfa-challenge";
|
|
3
|
+
export { totpCodeSchema, recoveryCodeSchema, mfaVerifyBodySchema, mfaEnrollResponseSchema, mfaVerifyEnrollmentBodySchema, mfaVerifyEnrollmentResponseSchema, mfaStatusResponseSchema, mfaCodeOnlyBodySchema, type MfaVerifyBody, type MfaEnrollResponse, type MfaVerifyEnrollmentBody, type MfaVerifyEnrollmentResponse, type MfaStatusResponse, type MfaCodeOnlyBody, } from "./mfa-verify-body";
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
export { mfaFactorTypes, mfaFactorTypeSchema, isValidMfaFactorType, } from "./mfa-factor-type";
|
|
2
|
+
export { mfaChallengeSchema, } from "./mfa-challenge";
|
|
3
|
+
export { totpCodeSchema, recoveryCodeSchema, mfaVerifyBodySchema, mfaEnrollResponseSchema, mfaVerifyEnrollmentBodySchema, mfaVerifyEnrollmentResponseSchema, mfaStatusResponseSchema, mfaCodeOnlyBodySchema, } from "./mfa-verify-body";
|
|
4
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/mfa/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,cAAc,EACd,mBAAmB,EACnB,oBAAoB,GAErB,MAAM,mBAAmB,CAAC;AAE3B,OAAO,EACL,kBAAkB,GAEnB,MAAM,iBAAiB,CAAC;AAEzB,OAAO,EACL,cAAc,EACd,kBAAkB,EAClB,mBAAmB,EACnB,uBAAuB,EACvB,6BAA6B,EAC7B,iCAAiC,EACjC,uBAAuB,EACvB,qBAAqB,GAOtB,MAAM,mBAAmB,CAAC"}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
export declare const mfaChallengeSchema: z.ZodObject<{
|
|
3
|
+
challenge_id: z.ZodString;
|
|
4
|
+
expires_at: z.ZodNumber;
|
|
5
|
+
}, "strict", z.ZodTypeAny, {
|
|
6
|
+
expires_at: number;
|
|
7
|
+
challenge_id: string;
|
|
8
|
+
}, {
|
|
9
|
+
expires_at: number;
|
|
10
|
+
challenge_id: string;
|
|
11
|
+
}>;
|
|
12
|
+
export type MfaChallengeDescriptor = z.infer<typeof mfaChallengeSchema>;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"mfa-challenge.js","sourceRoot":"","sources":["../../src/mfa/mfa-challenge.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAExB,MAAM,CAAC,MAAM,kBAAkB,GAAG,CAAC;KAChC,MAAM,CAAC;IACN,YAAY,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,IAAI,EAAE;IAC/B,UAAU,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,EAAE,CAAC,QAAQ,EAAE;CACxC,CAAC;KACD,MAAM,EAAE,CAAC"}
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
export declare const mfaFactorTypes: readonly ["totp"];
|
|
3
|
+
export declare const mfaFactorTypeSchema: z.ZodEnum<["totp"]>;
|
|
4
|
+
export type MfaFactorType = z.infer<typeof mfaFactorTypeSchema>;
|
|
5
|
+
export declare function isValidMfaFactorType(value: unknown): value is MfaFactorType;
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
export const mfaFactorTypes = ["totp"];
|
|
3
|
+
export const mfaFactorTypeSchema = z.enum(mfaFactorTypes);
|
|
4
|
+
export function isValidMfaFactorType(value) {
|
|
5
|
+
return mfaFactorTypeSchema.safeParse(value).success;
|
|
6
|
+
}
|
|
7
|
+
//# sourceMappingURL=mfa-factor-type.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"mfa-factor-type.js","sourceRoot":"","sources":["../../src/mfa/mfa-factor-type.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAExB,MAAM,CAAC,MAAM,cAAc,GAAG,CAAC,MAAM,CAAU,CAAC;AAEhD,MAAM,CAAC,MAAM,mBAAmB,GAAG,CAAC,CAAC,IAAI,CAAC,cAAc,CAAC,CAAC;AAI1D,MAAM,UAAU,oBAAoB,CAAC,KAAc;IACjD,OAAO,mBAAmB,CAAC,SAAS,CAAC,KAAK,CAAC,CAAC,OAAO,CAAC;AACtD,CAAC"}
|
|
@@ -0,0 +1,117 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
export declare const totpCodeSchema: z.ZodString;
|
|
3
|
+
export declare const recoveryCodeSchema: z.ZodString;
|
|
4
|
+
export declare const mfaVerifyBodySchema: z.ZodObject<{
|
|
5
|
+
challenge_id: z.ZodString;
|
|
6
|
+
client_app_id: z.ZodUnion<readonly [z.ZodString, z.ZodEffects<z.ZodString, "schemavaults-auth" | "schemavaults-mail" | "schemavaults-web" | "schemavaults-cli", string>]>;
|
|
7
|
+
proof: z.ZodDiscriminatedUnion<"type", [z.ZodObject<{
|
|
8
|
+
type: z.ZodLiteral<"totp">;
|
|
9
|
+
code: z.ZodString;
|
|
10
|
+
}, "strict", z.ZodTypeAny, {
|
|
11
|
+
code: string;
|
|
12
|
+
type: "totp";
|
|
13
|
+
}, {
|
|
14
|
+
code: string;
|
|
15
|
+
type: "totp";
|
|
16
|
+
}>, z.ZodObject<{
|
|
17
|
+
type: z.ZodLiteral<"recovery_code">;
|
|
18
|
+
recovery_code: z.ZodString;
|
|
19
|
+
}, "strict", z.ZodTypeAny, {
|
|
20
|
+
type: "recovery_code";
|
|
21
|
+
recovery_code: string;
|
|
22
|
+
}, {
|
|
23
|
+
type: "recovery_code";
|
|
24
|
+
recovery_code: string;
|
|
25
|
+
}>]>;
|
|
26
|
+
}, "strict", z.ZodTypeAny, {
|
|
27
|
+
client_app_id: string;
|
|
28
|
+
challenge_id: string;
|
|
29
|
+
proof: {
|
|
30
|
+
code: string;
|
|
31
|
+
type: "totp";
|
|
32
|
+
} | {
|
|
33
|
+
type: "recovery_code";
|
|
34
|
+
recovery_code: string;
|
|
35
|
+
};
|
|
36
|
+
}, {
|
|
37
|
+
client_app_id: string;
|
|
38
|
+
challenge_id: string;
|
|
39
|
+
proof: {
|
|
40
|
+
code: string;
|
|
41
|
+
type: "totp";
|
|
42
|
+
} | {
|
|
43
|
+
type: "recovery_code";
|
|
44
|
+
recovery_code: string;
|
|
45
|
+
};
|
|
46
|
+
}>;
|
|
47
|
+
export type MfaVerifyBody = z.infer<typeof mfaVerifyBodySchema>;
|
|
48
|
+
export declare const mfaEnrollResponseSchema: z.ZodObject<{
|
|
49
|
+
factor_id: z.ZodString;
|
|
50
|
+
factor_type: z.ZodLiteral<"totp">;
|
|
51
|
+
otpauth_url: z.ZodString;
|
|
52
|
+
qr_code_data_url: z.ZodString;
|
|
53
|
+
secret: z.ZodString;
|
|
54
|
+
}, "strict", z.ZodTypeAny, {
|
|
55
|
+
factor_id: string;
|
|
56
|
+
factor_type: "totp";
|
|
57
|
+
otpauth_url: string;
|
|
58
|
+
qr_code_data_url: string;
|
|
59
|
+
secret: string;
|
|
60
|
+
}, {
|
|
61
|
+
factor_id: string;
|
|
62
|
+
factor_type: "totp";
|
|
63
|
+
otpauth_url: string;
|
|
64
|
+
qr_code_data_url: string;
|
|
65
|
+
secret: string;
|
|
66
|
+
}>;
|
|
67
|
+
export type MfaEnrollResponse = z.infer<typeof mfaEnrollResponseSchema>;
|
|
68
|
+
export declare const mfaVerifyEnrollmentBodySchema: z.ZodObject<{
|
|
69
|
+
factor_id: z.ZodString;
|
|
70
|
+
code: z.ZodString;
|
|
71
|
+
}, "strict", z.ZodTypeAny, {
|
|
72
|
+
code: string;
|
|
73
|
+
factor_id: string;
|
|
74
|
+
}, {
|
|
75
|
+
code: string;
|
|
76
|
+
factor_id: string;
|
|
77
|
+
}>;
|
|
78
|
+
export type MfaVerifyEnrollmentBody = z.infer<typeof mfaVerifyEnrollmentBodySchema>;
|
|
79
|
+
export declare const mfaVerifyEnrollmentResponseSchema: z.ZodObject<{
|
|
80
|
+
success: z.ZodLiteral<true>;
|
|
81
|
+
recovery_codes: z.ZodArray<z.ZodString, "many">;
|
|
82
|
+
}, "strict", z.ZodTypeAny, {
|
|
83
|
+
success: true;
|
|
84
|
+
recovery_codes: string[];
|
|
85
|
+
}, {
|
|
86
|
+
success: true;
|
|
87
|
+
recovery_codes: string[];
|
|
88
|
+
}>;
|
|
89
|
+
export type MfaVerifyEnrollmentResponse = z.infer<typeof mfaVerifyEnrollmentResponseSchema>;
|
|
90
|
+
export declare const mfaStatusResponseSchema: z.ZodObject<{
|
|
91
|
+
enabled: z.ZodBoolean;
|
|
92
|
+
factor_id: z.ZodOptional<z.ZodString>;
|
|
93
|
+
factor_type: z.ZodOptional<z.ZodLiteral<"totp">>;
|
|
94
|
+
verified_at: z.ZodOptional<z.ZodNumber>;
|
|
95
|
+
recovery_codes_remaining: z.ZodOptional<z.ZodNumber>;
|
|
96
|
+
}, "strict", z.ZodTypeAny, {
|
|
97
|
+
enabled: boolean;
|
|
98
|
+
factor_id?: string | undefined;
|
|
99
|
+
factor_type?: "totp" | undefined;
|
|
100
|
+
verified_at?: number | undefined;
|
|
101
|
+
recovery_codes_remaining?: number | undefined;
|
|
102
|
+
}, {
|
|
103
|
+
enabled: boolean;
|
|
104
|
+
factor_id?: string | undefined;
|
|
105
|
+
factor_type?: "totp" | undefined;
|
|
106
|
+
verified_at?: number | undefined;
|
|
107
|
+
recovery_codes_remaining?: number | undefined;
|
|
108
|
+
}>;
|
|
109
|
+
export type MfaStatusResponse = z.infer<typeof mfaStatusResponseSchema>;
|
|
110
|
+
export declare const mfaCodeOnlyBodySchema: z.ZodObject<{
|
|
111
|
+
code: z.ZodString;
|
|
112
|
+
}, "strict", z.ZodTypeAny, {
|
|
113
|
+
code: string;
|
|
114
|
+
}, {
|
|
115
|
+
code: string;
|
|
116
|
+
}>;
|
|
117
|
+
export type MfaCodeOnlyBody = z.infer<typeof mfaCodeOnlyBodySchema>;
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
import { appIdSchema } from "@schemavaults/app-definitions";
|
|
3
|
+
export const totpCodeSchema = z
|
|
4
|
+
.string()
|
|
5
|
+
.regex(/^\d{6}$/u, "TOTP code must be exactly 6 digits");
|
|
6
|
+
export const recoveryCodeSchema = z
|
|
7
|
+
.string()
|
|
8
|
+
.min(8)
|
|
9
|
+
.max(64);
|
|
10
|
+
export const mfaVerifyBodySchema = z
|
|
11
|
+
.object({
|
|
12
|
+
challenge_id: z.string().uuid(),
|
|
13
|
+
client_app_id: appIdSchema,
|
|
14
|
+
proof: z.discriminatedUnion("type", [
|
|
15
|
+
z.object({ type: z.literal("totp"), code: totpCodeSchema }).strict(),
|
|
16
|
+
z
|
|
17
|
+
.object({ type: z.literal("recovery_code"), recovery_code: recoveryCodeSchema })
|
|
18
|
+
.strict(),
|
|
19
|
+
]),
|
|
20
|
+
})
|
|
21
|
+
.strict();
|
|
22
|
+
export const mfaEnrollResponseSchema = z
|
|
23
|
+
.object({
|
|
24
|
+
factor_id: z.string().uuid(),
|
|
25
|
+
factor_type: z.literal("totp"),
|
|
26
|
+
otpauth_url: z.string().url(),
|
|
27
|
+
qr_code_data_url: z.string().min(1),
|
|
28
|
+
secret: z.string().min(16),
|
|
29
|
+
})
|
|
30
|
+
.strict();
|
|
31
|
+
export const mfaVerifyEnrollmentBodySchema = z
|
|
32
|
+
.object({
|
|
33
|
+
factor_id: z.string().uuid(),
|
|
34
|
+
code: totpCodeSchema,
|
|
35
|
+
})
|
|
36
|
+
.strict();
|
|
37
|
+
export const mfaVerifyEnrollmentResponseSchema = z
|
|
38
|
+
.object({
|
|
39
|
+
success: z.literal(true),
|
|
40
|
+
recovery_codes: z.array(recoveryCodeSchema).min(1),
|
|
41
|
+
})
|
|
42
|
+
.strict();
|
|
43
|
+
export const mfaStatusResponseSchema = z
|
|
44
|
+
.object({
|
|
45
|
+
enabled: z.boolean(),
|
|
46
|
+
factor_id: z.string().uuid().optional(),
|
|
47
|
+
factor_type: z.literal("totp").optional(),
|
|
48
|
+
verified_at: z.number().int().positive().optional(),
|
|
49
|
+
recovery_codes_remaining: z.number().int().nonnegative().optional(),
|
|
50
|
+
})
|
|
51
|
+
.strict();
|
|
52
|
+
export const mfaCodeOnlyBodySchema = z
|
|
53
|
+
.object({
|
|
54
|
+
code: totpCodeSchema,
|
|
55
|
+
})
|
|
56
|
+
.strict();
|
|
57
|
+
//# sourceMappingURL=mfa-verify-body.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"mfa-verify-body.js","sourceRoot":"","sources":["../../src/mfa/mfa-verify-body.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AACxB,OAAO,EAAE,WAAW,EAAE,MAAM,+BAA+B,CAAC;AAE5D,MAAM,CAAC,MAAM,cAAc,GAAG,CAAC;KAC5B,MAAM,EAAE;KACR,KAAK,CAAC,UAAU,EAAE,oCAAoC,CAAC,CAAC;AAE3D,MAAM,CAAC,MAAM,kBAAkB,GAAG,CAAC;KAChC,MAAM,EAAE;KACR,GAAG,CAAC,CAAC,CAAC;KACN,GAAG,CAAC,EAAE,CAAC,CAAC;AAEX,MAAM,CAAC,MAAM,mBAAmB,GAAG,CAAC;KACjC,MAAM,CAAC;IACN,YAAY,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,IAAI,EAAE;IAC/B,aAAa,EAAE,WAAW;IAC1B,KAAK,EAAE,CAAC,CAAC,kBAAkB,CAAC,MAAM,EAAE;QAClC,CAAC,CAAC,MAAM,CAAC,EAAE,IAAI,EAAE,CAAC,CAAC,OAAO,CAAC,MAAM,CAAC,EAAE,IAAI,EAAE,cAAc,EAAE,CAAC,CAAC,MAAM,EAAE;QACpE,CAAC;aACE,MAAM,CAAC,EAAE,IAAI,EAAE,CAAC,CAAC,OAAO,CAAC,eAAe,CAAC,EAAE,aAAa,EAAE,kBAAkB,EAAE,CAAC;aAC/E,MAAM,EAAE;KACZ,CAAC;CACH,CAAC;KACD,MAAM,EAAE,CAAC;AAIZ,MAAM,CAAC,MAAM,uBAAuB,GAAG,CAAC;KACrC,MAAM,CAAC;IACN,SAAS,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,IAAI,EAAE;IAC5B,WAAW,EAAE,CAAC,CAAC,OAAO,CAAC,MAAM,CAAC;IAC9B,WAAW,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,EAAE;IAC7B,gBAAgB,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC;IACnC,MAAM,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,EAAE,CAAC;CAC3B,CAAC;KACD,MAAM,EAAE,CAAC;AAIZ,MAAM,CAAC,MAAM,6BAA6B,GAAG,CAAC;KAC3C,MAAM,CAAC;IACN,SAAS,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,IAAI,EAAE;IAC5B,IAAI,EAAE,cAAc;CACrB,CAAC;KACD,MAAM,EAAE,CAAC;AAMZ,MAAM,CAAC,MAAM,iCAAiC,GAAG,CAAC;KAC/C,MAAM,CAAC;IACN,OAAO,EAAE,CAAC,CAAC,OAAO,CAAC,IAAI,CAAC;IACxB,cAAc,EAAE,CAAC,CAAC,KAAK,CAAC,kBAAkB,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC;CACnD,CAAC;KACD,MAAM,EAAE,CAAC;AAMZ,MAAM,CAAC,MAAM,uBAAuB,GAAG,CAAC;KACrC,MAAM,CAAC;IACN,OAAO,EAAE,CAAC,CAAC,OAAO,EAAE;IACpB,SAAS,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,IAAI,EAAE,CAAC,QAAQ,EAAE;IACvC,WAAW,EAAE,CAAC,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC,QAAQ,EAAE;IACzC,WAAW,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,EAAE,CAAC,QAAQ,EAAE,CAAC,QAAQ,EAAE;IACnD,wBAAwB,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,EAAE,CAAC,WAAW,EAAE,CAAC,QAAQ,EAAE;CACpE,CAAC;KACD,MAAM,EAAE,CAAC;AAIZ,MAAM,CAAC,MAAM,qBAAqB,GAAG,CAAC;KACnC,MAAM,CAAC;IACN,IAAI,EAAE,cAAc;CACrB,CAAC;KACD,MAAM,EAAE,CAAC"}
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
export declare const OAUTH2_STATE_VSCHAR_REGEX: RegExp;
|
|
3
|
+
export declare const oauth2StateSchema: z.ZodString;
|
|
4
|
+
export type OAuth2State = z.infer<typeof oauth2StateSchema>;
|
|
5
|
+
/**
|
|
6
|
+
* Thrown by `parseOAuth2State` when the caller supplied a `state`
|
|
7
|
+
* value that is present but fails schema validation. Callers at
|
|
8
|
+
* server-side entry points should turn this into a 400 response
|
|
9
|
+
* (e.g. `redirectWithError(400, "bad_request")` for page routes,
|
|
10
|
+
* `NextResponse.json(..., { status: 400 })` for API routes).
|
|
11
|
+
*/
|
|
12
|
+
export declare class OAuth2StateValidationError extends Error {
|
|
13
|
+
readonly reasons: readonly string[];
|
|
14
|
+
constructor(reasons: readonly string[]);
|
|
15
|
+
}
|
|
16
|
+
/**
|
|
17
|
+
* Validates an OAuth2 `state` at a server boundary.
|
|
18
|
+
*
|
|
19
|
+
* - Absent / null / undefined → returns `null` (RFC-legal; `state`
|
|
20
|
+
* is optional).
|
|
21
|
+
* - Present + well-formed → returns the validated string.
|
|
22
|
+
* - Present + malformed (wrong type, empty, too long, non-VSCHAR)
|
|
23
|
+
* → throws `OAuth2StateValidationError` so the caller can 400.
|
|
24
|
+
*
|
|
25
|
+
* Empty strings are treated as malformed (not absent) so a client
|
|
26
|
+
* that accidentally serializes `?state=` gets a loud signal instead
|
|
27
|
+
* of a silent downgrade.
|
|
28
|
+
*/
|
|
29
|
+
export declare function parseOAuth2State(raw: unknown): string | null;
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
// RFC 6749 §10.12 introduces the OAuth2 `state` parameter as a
|
|
3
|
+
// client-side CSRF nonce. RFC 6749 §A.5 defines its on-the-wire form
|
|
4
|
+
// as `*VSCHAR` — zero or more printable ASCII characters %x20-%x7E.
|
|
5
|
+
// The auth server never interprets `state`; it only echoes the value
|
|
6
|
+
// untouched on the callback. The validator below therefore captures
|
|
7
|
+
// only the properties worth enforcing at the protocol boundary:
|
|
8
|
+
//
|
|
9
|
+
// 1. Non-empty (a zero-length state has no CSRF value).
|
|
10
|
+
// 2. Bounded length — 512 chars is comfortably above common shapes
|
|
11
|
+
// (UUID, base64url 32-byte nonce, short signed JWTs) while
|
|
12
|
+
// protecting log pipelines and callback-URL buffers from
|
|
13
|
+
// unbounded echo.
|
|
14
|
+
// 3. Printable ASCII only — prevents log-pollution / terminal-escape
|
|
15
|
+
// smuggling via control chars, NULs, and CR/LF.
|
|
16
|
+
//
|
|
17
|
+
// This schema is deliberately not base64url-specific: that would be
|
|
18
|
+
// SDK-opinionated and would break RFC-legal third-party clients that
|
|
19
|
+
// use UUIDs, signed JWTs, or other formats for their state value.
|
|
20
|
+
const MAX_OAUTH2_STATE_LENGTH = 512;
|
|
21
|
+
export const OAUTH2_STATE_VSCHAR_REGEX = /^[\x20-\x7E]+$/;
|
|
22
|
+
export const oauth2StateSchema = z
|
|
23
|
+
.string()
|
|
24
|
+
.min(1)
|
|
25
|
+
.max(MAX_OAUTH2_STATE_LENGTH)
|
|
26
|
+
.regex(OAUTH2_STATE_VSCHAR_REGEX, {
|
|
27
|
+
message: "OAuth2 'state' must contain only printable ASCII (RFC 6749 §A.5 VSCHAR)",
|
|
28
|
+
});
|
|
29
|
+
/**
|
|
30
|
+
* Thrown by `parseOAuth2State` when the caller supplied a `state`
|
|
31
|
+
* value that is present but fails schema validation. Callers at
|
|
32
|
+
* server-side entry points should turn this into a 400 response
|
|
33
|
+
* (e.g. `redirectWithError(400, "bad_request")` for page routes,
|
|
34
|
+
* `NextResponse.json(..., { status: 400 })` for API routes).
|
|
35
|
+
*/
|
|
36
|
+
export class OAuth2StateValidationError extends Error {
|
|
37
|
+
reasons;
|
|
38
|
+
constructor(reasons) {
|
|
39
|
+
super(`Invalid OAuth2 'state' parameter: ${reasons.join("; ")}`);
|
|
40
|
+
this.name = "OAuth2StateValidationError";
|
|
41
|
+
this.reasons = reasons;
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
/**
|
|
45
|
+
* Validates an OAuth2 `state` at a server boundary.
|
|
46
|
+
*
|
|
47
|
+
* - Absent / null / undefined → returns `null` (RFC-legal; `state`
|
|
48
|
+
* is optional).
|
|
49
|
+
* - Present + well-formed → returns the validated string.
|
|
50
|
+
* - Present + malformed (wrong type, empty, too long, non-VSCHAR)
|
|
51
|
+
* → throws `OAuth2StateValidationError` so the caller can 400.
|
|
52
|
+
*
|
|
53
|
+
* Empty strings are treated as malformed (not absent) so a client
|
|
54
|
+
* that accidentally serializes `?state=` gets a loud signal instead
|
|
55
|
+
* of a silent downgrade.
|
|
56
|
+
*/
|
|
57
|
+
export function parseOAuth2State(raw) {
|
|
58
|
+
if (raw === undefined || raw === null)
|
|
59
|
+
return null;
|
|
60
|
+
if (typeof raw !== "string") {
|
|
61
|
+
throw new OAuth2StateValidationError([
|
|
62
|
+
`Expected string, got ${Array.isArray(raw) ? "array" : typeof raw}`,
|
|
63
|
+
]);
|
|
64
|
+
}
|
|
65
|
+
const parsed = oauth2StateSchema.safeParse(raw);
|
|
66
|
+
if (!parsed.success) {
|
|
67
|
+
throw new OAuth2StateValidationError(parsed.error.issues.map((i) => i.message));
|
|
68
|
+
}
|
|
69
|
+
return parsed.data;
|
|
70
|
+
}
|
|
71
|
+
//# sourceMappingURL=oauth2-state-schema.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"oauth2-state-schema.js","sourceRoot":"","sources":["../src/oauth2-state-schema.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAExB,+DAA+D;AAC/D,qEAAqE;AACrE,oEAAoE;AACpE,qEAAqE;AACrE,oEAAoE;AACpE,gEAAgE;AAChE,EAAE;AACF,0DAA0D;AAC1D,qEAAqE;AACrE,gEAAgE;AAChE,8DAA8D;AAC9D,uBAAuB;AACvB,uEAAuE;AACvE,qDAAqD;AACrD,EAAE;AACF,oEAAoE;AACpE,qEAAqE;AACrE,kEAAkE;AAElE,MAAM,uBAAuB,GAAG,GAAY,CAAC;AAE7C,MAAM,CAAC,MAAM,yBAAyB,GAAW,gBAAgB,CAAC;AAElE,MAAM,CAAC,MAAM,iBAAiB,GAAG,CAAC;KAC/B,MAAM,EAAE;KACR,GAAG,CAAC,CAAC,CAAC;KACN,GAAG,CAAC,uBAAuB,CAAC;KAC5B,KAAK,CAAC,yBAAyB,EAAE;IAChC,OAAO,EACL,yEAAyE;CAC5E,CAAC,CAAC;AAIL;;;;;;GAMG;AACH,MAAM,OAAO,0BAA2B,SAAQ,KAAK;IACnC,OAAO,CAAoB;IAC3C,YAAmB,OAA0B;QAC3C,KAAK,CAAC,qCAAqC,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;QACjE,IAAI,CAAC,IAAI,GAAG,4BAA4B,CAAC;QACzC,IAAI,CAAC,OAAO,GAAG,OAAO,CAAC;IACzB,CAAC;CACF;AAED;;;;;;;;;;;;GAYG;AACH,MAAM,UAAU,gBAAgB,CAAC,GAAY;IAC3C,IAAI,GAAG,KAAK,SAAS,IAAI,GAAG,KAAK,IAAI;QAAE,OAAO,IAAI,CAAC;IACnD,IAAI,OAAO,GAAG,KAAK,QAAQ,EAAE,CAAC;QAC5B,MAAM,IAAI,0BAA0B,CAAC;YACnC,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,iBAAiB,CAAC,SAAS,CAAC,GAAG,CAAC,CAAC;IAChD,IAAI,CAAC,MAAM,CAAC,OAAO,EAAE,CAAC;QACpB,MAAM,IAAI,0BAA0B,CAClC,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,13 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Timing-safe string comparison usable from browser bundles.
|
|
3
|
+
*
|
|
4
|
+
* `node:crypto.timingSafeEqual` is Node-only; this pure-JS variant
|
|
5
|
+
* operates on strings and runs in both browser and server contexts.
|
|
6
|
+
* Not strictly constant-time under every JIT, but avoids early-exit on
|
|
7
|
+
* the first byte of divergence — strictly better than `===` for
|
|
8
|
+
* CSRF-nonce / token comparison.
|
|
9
|
+
*
|
|
10
|
+
* Returns false on any non-string input or length mismatch.
|
|
11
|
+
*/
|
|
12
|
+
export declare function timingSafeStringEqual(a: string, b: string): boolean;
|
|
13
|
+
export default timingSafeStringEqual;
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Timing-safe string comparison usable from browser bundles.
|
|
3
|
+
*
|
|
4
|
+
* `node:crypto.timingSafeEqual` is Node-only; this pure-JS variant
|
|
5
|
+
* operates on strings and runs in both browser and server contexts.
|
|
6
|
+
* Not strictly constant-time under every JIT, but avoids early-exit on
|
|
7
|
+
* the first byte of divergence — strictly better than `===` for
|
|
8
|
+
* CSRF-nonce / token comparison.
|
|
9
|
+
*
|
|
10
|
+
* Returns false on any non-string input or length mismatch.
|
|
11
|
+
*/
|
|
12
|
+
export function timingSafeStringEqual(a, b) {
|
|
13
|
+
if (typeof a !== "string" || typeof b !== "string")
|
|
14
|
+
return false;
|
|
15
|
+
if (a.length !== b.length)
|
|
16
|
+
return false;
|
|
17
|
+
let diff = 0;
|
|
18
|
+
for (let i = 0; i < a.length; i++) {
|
|
19
|
+
diff |= a.charCodeAt(i) ^ b.charCodeAt(i);
|
|
20
|
+
}
|
|
21
|
+
return diff === 0;
|
|
22
|
+
}
|
|
23
|
+
export default timingSafeStringEqual;
|
|
24
|
+
//# sourceMappingURL=timing-safe-string-equal.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"timing-safe-string-equal.js","sourceRoot":"","sources":["../src/timing-safe-string-equal.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AACH,MAAM,UAAU,qBAAqB,CAAC,CAAS,EAAE,CAAS;IACxD,IAAI,OAAO,CAAC,KAAK,QAAQ,IAAI,OAAO,CAAC,KAAK,QAAQ;QAAE,OAAO,KAAK,CAAC;IACjE,IAAI,CAAC,CAAC,MAAM,KAAK,CAAC,CAAC,MAAM;QAAE,OAAO,KAAK,CAAC;IACxC,IAAI,IAAI,GAAG,CAAC,CAAC;IACb,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;QAClC,IAAI,IAAI,CAAC,CAAC,UAAU,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC;IAC5C,CAAC;IACD,OAAO,IAAI,KAAK,CAAC,CAAC;AACpB,CAAC;AAED,eAAe,qBAAqB,CAAC"}
|
package/package.json
CHANGED