@schemavaults/auth-common 0.22.5 → 0.22.11
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 +7 -0
- package/dist/audience-schema.js +7 -1
- package/dist/audience-schema.js.map +1 -1
- package/dist/auth_acquire_tokens_grant_types.js +8 -0
- package/dist/auth_acquire_tokens_grant_types.js.map +1 -1
- package/dist/credentials/email_credentials.js +2 -1
- package/dist/credentials/email_credentials.js.map +1 -1
- package/dist/credentials/index.d.ts +1 -0
- package/dist/credentials/index.js +1 -0
- package/dist/credentials/index.js.map +1 -1
- package/dist/credentials/normalize-email.d.ts +15 -0
- package/dist/credentials/normalize-email.js +18 -0
- package/dist/credentials/normalize-email.js.map +1 -0
- package/dist/index.d.ts +1 -0
- package/dist/index.js +1 -0
- package/dist/index.js.map +1 -1
- package/dist/sanitize-next-href.d.ts +15 -0
- package/dist/sanitize-next-href.js +71 -0
- package/dist/sanitize-next-href.js.map +1 -0
- package/package.json +1 -1
|
@@ -17,4 +17,11 @@ export interface AudienceSchemaOverrides {
|
|
|
17
17
|
auth_server_app_id?: string;
|
|
18
18
|
}
|
|
19
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
|
+
/**
|
|
21
|
+
* A list of token audiences. The list may be empty: at the token endpoints
|
|
22
|
+
* an empty audience list means the grant mints no access tokens —
|
|
23
|
+
* authenticate (or rotate the refresh token) only, which is how clients
|
|
24
|
+
* configured with no default token audiences complete a login. Call sites
|
|
25
|
+
* that require at least one audience must enforce non-emptiness themselves.
|
|
26
|
+
*/
|
|
20
27
|
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
|
@@ -15,10 +15,16 @@ export function createAudienceSchema(z, environment = getAppEnvironment(), overr
|
|
|
15
15
|
return z.union([authServerUrlSchema, apiServerIdWithoutAuthServerIdSchema]);
|
|
16
16
|
}
|
|
17
17
|
const MAX_APPS_IN_AUDIENCE_LIST = 10;
|
|
18
|
+
/**
|
|
19
|
+
* A list of token audiences. The list may be empty: at the token endpoints
|
|
20
|
+
* an empty audience list means the grant mints no access tokens —
|
|
21
|
+
* authenticate (or rotate the refresh token) only, which is how clients
|
|
22
|
+
* configured with no default token audiences complete a login. Call sites
|
|
23
|
+
* that require at least one audience must enforce non-emptiness themselves.
|
|
24
|
+
*/
|
|
18
25
|
export function createAudienceListSchema(z, environment = getAppEnvironment(), overrides) {
|
|
19
26
|
return createAudienceSchema(z, environment, overrides)
|
|
20
27
|
.array()
|
|
21
|
-
.min(1, "Audience list may not be empty")
|
|
22
28
|
.max(MAX_APPS_IN_AUDIENCE_LIST, `Audience list may not contain more than ${MAX_APPS_IN_AUDIENCE_LIST} audience references.`);
|
|
23
29
|
}
|
|
24
30
|
//# sourceMappingURL=audience-schema.js.map
|
|
@@ -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;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,
|
|
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;;;;;;GAMG;AACH,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,CACF,yBAAyB,EACzB,2CAA2C,yBAAyB,uBAAuB,CAC5F,CAAC;AACN,CAAC"}
|
|
@@ -7,6 +7,10 @@ export const grant_types = [
|
|
|
7
7
|
];
|
|
8
8
|
function createTokenEndpointBaseSchema(z, environment = getAppEnvironment(), overrides) {
|
|
9
9
|
return z.object({
|
|
10
|
+
// A single audience, or a (possibly empty) audience list. An empty list
|
|
11
|
+
// mints no access tokens — the grant authenticates (or rotates the
|
|
12
|
+
// refresh token) only, which is how clients configured with no default
|
|
13
|
+
// token audiences complete a login.
|
|
10
14
|
audience: z.union([
|
|
11
15
|
createAudienceSchema(z, environment, overrides),
|
|
12
16
|
createAudienceListSchema(z, environment, overrides),
|
|
@@ -44,6 +48,10 @@ export function createRefreshTokenPOSTBodySchema(z, environment = getAppEnvironm
|
|
|
44
48
|
return createTokenEndpointBaseSchema(z, environment, overrides)
|
|
45
49
|
.extend({
|
|
46
50
|
grant_type: z.literal("refresh_token"),
|
|
51
|
+
// Deprecated and ignored: the refresh grant now always rotates the
|
|
52
|
+
// refresh token. Still tolerated (the body schema is strict) so
|
|
53
|
+
// requests from older SDK versions — which unconditionally send the
|
|
54
|
+
// flag — keep parsing.
|
|
47
55
|
replaceRefreshToo: z.boolean().optional(),
|
|
48
56
|
})
|
|
49
57
|
.required({
|
|
@@ -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,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"}
|
|
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,wEAAwE;QACxE,mEAAmE;QACnE,uEAAuE;QACvE,oCAAoC;QACpC,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,mEAAmE;QACnE,gEAAgE;QAChE,oEAAoE;QACpE,uBAAuB;QACvB,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"}
|
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
import { z } from 'zod';
|
|
2
2
|
import { passwordSchema } from './password_requirements';
|
|
3
|
+
import { normalizedEmailSchema } from './normalize-email';
|
|
3
4
|
export const emailCredentialsSchema = z.object({
|
|
4
|
-
email:
|
|
5
|
+
email: normalizedEmailSchema,
|
|
5
6
|
password: passwordSchema
|
|
6
7
|
}).required({
|
|
7
8
|
email: true,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"email_credentials.js","sourceRoot":"","sources":["../../src/credentials/email_credentials.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AACxB,OAAO,EAAE,cAAc,EAAE,MAAM,yBAAyB,CAAC;
|
|
1
|
+
{"version":3,"file":"email_credentials.js","sourceRoot":"","sources":["../../src/credentials/email_credentials.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AACxB,OAAO,EAAE,cAAc,EAAE,MAAM,yBAAyB,CAAC;AACzD,OAAO,EAAE,qBAAqB,EAAE,MAAM,mBAAmB,CAAC;AAE1D,MAAM,CAAC,MAAM,sBAAsB,GAAG,CAAC,CAAC,MAAM,CAAC;IAC7C,KAAK,EAAE,qBAAqB;IAC5B,QAAQ,EAAE,cAAc;CACzB,CAAC,CAAC,QAAQ,CAAC;IACV,KAAK,EAAE,IAAI;IACX,QAAQ,EAAE,IAAI;CACf,CAAC,CAAC,MAAM,EAAE,CAAC"}
|
|
@@ -1,3 +1,4 @@
|
|
|
1
1
|
export { passwordSchema } from './password_requirements';
|
|
2
|
+
export { normalizeEmail, normalizedEmailSchema } from './normalize-email';
|
|
2
3
|
export { emailCredentialsSchema, type EmailCredentials } from './email_credentials';
|
|
3
4
|
export { emailRegistrationCredentialsSchema, type EmailRegistrationCredentials } from './register_credentials';
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
export { passwordSchema } from './password_requirements';
|
|
2
|
+
export { normalizeEmail, normalizedEmailSchema } from './normalize-email';
|
|
2
3
|
export { emailCredentialsSchema } from './email_credentials';
|
|
3
4
|
export { emailRegistrationCredentialsSchema } from './register_credentials';
|
|
4
5
|
//# sourceMappingURL=index.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/credentials/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,MAAM,yBAAyB,CAAC;AACzD,OAAO,EAAE,sBAAsB,EAAyB,MAAM,qBAAqB,CAAC;AACpF,OAAO,EAAE,kCAAkC,EAAqC,MAAM,wBAAwB,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/credentials/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,MAAM,yBAAyB,CAAC;AACzD,OAAO,EAAE,cAAc,EAAE,qBAAqB,EAAE,MAAM,mBAAmB,CAAC;AAC1E,OAAO,EAAE,sBAAsB,EAAyB,MAAM,qBAAqB,CAAC;AACpF,OAAO,EAAE,kCAAkC,EAAqC,MAAM,wBAAwB,CAAC"}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
/**
|
|
3
|
+
* Canonical form of an email address for storage and comparison: trimmed
|
|
4
|
+
* and lowercased. RFC 5321 technically allows a case-sensitive local part,
|
|
5
|
+
* but mainstream mail providers treat addresses case-insensitively, and
|
|
6
|
+
* treating case-variants as distinct accounts would let one mailbox
|
|
7
|
+
* register multiple times (e.g. `user@example.com` vs `User@example.com`).
|
|
8
|
+
*/
|
|
9
|
+
export declare function normalizeEmail(email: string): string;
|
|
10
|
+
/**
|
|
11
|
+
* Email schema that normalizes (trims + lowercases) at parse time, so any
|
|
12
|
+
* payload validated with it carries the canonical form of the address.
|
|
13
|
+
*/
|
|
14
|
+
export declare const normalizedEmailSchema: z.ZodString;
|
|
15
|
+
export default normalizeEmail;
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
/**
|
|
3
|
+
* Canonical form of an email address for storage and comparison: trimmed
|
|
4
|
+
* and lowercased. RFC 5321 technically allows a case-sensitive local part,
|
|
5
|
+
* but mainstream mail providers treat addresses case-insensitively, and
|
|
6
|
+
* treating case-variants as distinct accounts would let one mailbox
|
|
7
|
+
* register multiple times (e.g. `user@example.com` vs `User@example.com`).
|
|
8
|
+
*/
|
|
9
|
+
export function normalizeEmail(email) {
|
|
10
|
+
return email.trim().toLowerCase();
|
|
11
|
+
}
|
|
12
|
+
/**
|
|
13
|
+
* Email schema that normalizes (trims + lowercases) at parse time, so any
|
|
14
|
+
* payload validated with it carries the canonical form of the address.
|
|
15
|
+
*/
|
|
16
|
+
export const normalizedEmailSchema = z.string().trim().toLowerCase().email();
|
|
17
|
+
export default normalizeEmail;
|
|
18
|
+
//# sourceMappingURL=normalize-email.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"normalize-email.js","sourceRoot":"","sources":["../../src/credentials/normalize-email.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAExB;;;;;;GAMG;AACH,MAAM,UAAU,cAAc,CAAC,KAAa;IAC1C,OAAO,KAAK,CAAC,IAAI,EAAE,CAAC,WAAW,EAAE,CAAC;AACpC,CAAC;AAED;;;GAGG;AACH,MAAM,CAAC,MAAM,qBAAqB,GAAG,CAAC,CAAC,MAAM,EAAE,CAAC,IAAI,EAAE,CAAC,WAAW,EAAE,CAAC,KAAK,EAAE,CAAC;AAE7E,eAAe,cAAc,CAAC"}
|
package/dist/index.d.ts
CHANGED
|
@@ -35,6 +35,7 @@ export { authorizeClientApplicationFormType } from "./authorize-client-applicati
|
|
|
35
35
|
export { paginationOptionsSchema, DEFAULT_PAGINATION_PAGE_INDEX, DEFAULT_PAGINATION_PAGE_SIZE, isValidPaginationOptions, } from "./pagination";
|
|
36
36
|
export type { PaginationOptions } from "./pagination";
|
|
37
37
|
export { timingSafeStringEqual } from "./timing-safe-string-equal";
|
|
38
|
+
export { sanitizeNextHref, MAX_NEXT_HREF_LENGTH, } from "./sanitize-next-href";
|
|
38
39
|
export { isOriginInAllowedList } from "./cors";
|
|
39
40
|
export { oauth2StateSchema, OAUTH2_STATE_VSCHAR_REGEX, parseOAuth2State, OAuth2StateValidationError, } from "./oauth2-state-schema";
|
|
40
41
|
export type { OAuth2State } from "./oauth2-state-schema";
|
package/dist/index.js
CHANGED
|
@@ -24,6 +24,7 @@ export { determineRefreshTokenCookieSameSiteValue } from "./determineRefreshToke
|
|
|
24
24
|
export { authorizeClientApplicationFormType } from "./authorize-client-application-form-type";
|
|
25
25
|
export { paginationOptionsSchema, DEFAULT_PAGINATION_PAGE_INDEX, DEFAULT_PAGINATION_PAGE_SIZE, isValidPaginationOptions, } from "./pagination";
|
|
26
26
|
export { timingSafeStringEqual } from "./timing-safe-string-equal";
|
|
27
|
+
export { sanitizeNextHref, MAX_NEXT_HREF_LENGTH, } from "./sanitize-next-href";
|
|
27
28
|
export { isOriginInAllowedList } from "./cors";
|
|
28
29
|
export { oauth2StateSchema, OAUTH2_STATE_VSCHAR_REGEX, parseOAuth2State, OAuth2StateValidationError, } from "./oauth2-state-schema";
|
|
29
30
|
export { createAuthorizationCodePOSTBodySchema, createRefreshTokenPOSTBodySchema, } from "./auth_acquire_tokens_grant_types";
|
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,EACL,mCAAmC,EACnC,qCAAqC,GACtC,MAAM,gCAAgC,CAAC;AAExC,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
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,qBAAqB,EACrB,cAAc,GACf,MAAM,8BAA8B,CAAC;AAGtC,OAAO,EACL,mCAAmC,EACnC,qCAAqC,GACtC,MAAM,gCAAgC,CAAC;AAExC,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,EACL,gBAAgB,EAChB,oBAAoB,GACrB,MAAM,sBAAsB,CAAC;AAE9B,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"}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Maximum accepted `next_href` length. Generous enough for deep paths
|
|
3
|
+
* with query strings while keeping the value log- and cookie-safe.
|
|
4
|
+
*/
|
|
5
|
+
export declare const MAX_NEXT_HREF_LENGTH: 2048;
|
|
6
|
+
/**
|
|
7
|
+
* @name sanitizeNextHref
|
|
8
|
+
* @description Validate a post-login redirect target from an untrusted
|
|
9
|
+
* source (query param, form field). Returns the normalized same-origin
|
|
10
|
+
* path (`pathname + search + hash`) when the value is a safe internal
|
|
11
|
+
* absolute-path reference, or `null` when it is absent or unsafe.
|
|
12
|
+
* Callers should treat `null` as "use the default destination".
|
|
13
|
+
*/
|
|
14
|
+
export declare function sanitizeNextHref(value: unknown): string | null;
|
|
15
|
+
export default sanitizeNextHref;
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
// The `next_href` parameter carries the URL a user was trying to reach
|
|
2
|
+
// when an auth route guard bounced them to the login page, so that the
|
|
3
|
+
// post-login redirect can return them to it. Because the value round-trips
|
|
4
|
+
// through a user-controlled query string, it is an open-redirect vector
|
|
5
|
+
// unless it is strictly confined to a same-origin path.
|
|
6
|
+
//
|
|
7
|
+
// This sanitizer accepts only an absolute-path reference (RFC 3986
|
|
8
|
+
// §4.2: begins with "/" but not "//") and returns the normalized
|
|
9
|
+
// `pathname + search + hash`. Everything else — absolute URLs,
|
|
10
|
+
// protocol-relative URLs ("//evil.example"), backslash variants
|
|
11
|
+
// ("/\evil.example", which browsers treat as "//"), control characters,
|
|
12
|
+
// or values a URL parser resolves off-origin — is rejected with `null`
|
|
13
|
+
// so callers can fall back to their default destination.
|
|
14
|
+
/**
|
|
15
|
+
* Maximum accepted `next_href` length. Generous enough for deep paths
|
|
16
|
+
* with query strings while keeping the value log- and cookie-safe.
|
|
17
|
+
*/
|
|
18
|
+
export const MAX_NEXT_HREF_LENGTH = 2048;
|
|
19
|
+
// Sentinel base origin used to resolve the candidate path. If the
|
|
20
|
+
// parsed result escapes this origin, the value was not a plain path.
|
|
21
|
+
const SANITIZE_BASE_ORIGIN = "https://next-href.invalid";
|
|
22
|
+
// eslint-disable-next-line no-control-regex
|
|
23
|
+
const CONTROL_CHARS_REGEX = /[\u0000-\u001f\u007f]/;
|
|
24
|
+
/**
|
|
25
|
+
* @name sanitizeNextHref
|
|
26
|
+
* @description Validate a post-login redirect target from an untrusted
|
|
27
|
+
* source (query param, form field). Returns the normalized same-origin
|
|
28
|
+
* path (`pathname + search + hash`) when the value is a safe internal
|
|
29
|
+
* absolute-path reference, or `null` when it is absent or unsafe.
|
|
30
|
+
* Callers should treat `null` as "use the default destination".
|
|
31
|
+
*/
|
|
32
|
+
export function sanitizeNextHref(value) {
|
|
33
|
+
if (typeof value !== "string") {
|
|
34
|
+
return null;
|
|
35
|
+
}
|
|
36
|
+
if (value.length === 0 || value.length > MAX_NEXT_HREF_LENGTH) {
|
|
37
|
+
return null;
|
|
38
|
+
}
|
|
39
|
+
// Must be an absolute-path reference: "/..." but never "//..." (a
|
|
40
|
+
// protocol-relative URL) nor "/\..." (browser-normalized to "//").
|
|
41
|
+
if (!value.startsWith("/")) {
|
|
42
|
+
return null;
|
|
43
|
+
}
|
|
44
|
+
if (value.startsWith("//") || value.startsWith("/\\")) {
|
|
45
|
+
return null;
|
|
46
|
+
}
|
|
47
|
+
if (CONTROL_CHARS_REGEX.test(value)) {
|
|
48
|
+
return null;
|
|
49
|
+
}
|
|
50
|
+
let parsed;
|
|
51
|
+
try {
|
|
52
|
+
parsed = new URL(value, SANITIZE_BASE_ORIGIN);
|
|
53
|
+
}
|
|
54
|
+
catch {
|
|
55
|
+
return null;
|
|
56
|
+
}
|
|
57
|
+
// A plain path resolved against the sentinel base must stay on the
|
|
58
|
+
// sentinel origin; anything else smuggled in a scheme or authority.
|
|
59
|
+
if (parsed.origin !== SANITIZE_BASE_ORIGIN) {
|
|
60
|
+
return null;
|
|
61
|
+
}
|
|
62
|
+
// Defense-in-depth: reject if normalization still yields a
|
|
63
|
+
// protocol-relative shape (e.g. via backslash tricks the guards
|
|
64
|
+
// above didn't anticipate).
|
|
65
|
+
if (parsed.pathname.startsWith("//")) {
|
|
66
|
+
return null;
|
|
67
|
+
}
|
|
68
|
+
return `${parsed.pathname}${parsed.search}${parsed.hash}`;
|
|
69
|
+
}
|
|
70
|
+
export default sanitizeNextHref;
|
|
71
|
+
//# sourceMappingURL=sanitize-next-href.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"sanitize-next-href.js","sourceRoot":"","sources":["../src/sanitize-next-href.ts"],"names":[],"mappings":"AAAA,uEAAuE;AACvE,uEAAuE;AACvE,2EAA2E;AAC3E,wEAAwE;AACxE,wDAAwD;AACxD,EAAE;AACF,mEAAmE;AACnE,iEAAiE;AACjE,+DAA+D;AAC/D,gEAAgE;AAChE,wEAAwE;AACxE,uEAAuE;AACvE,yDAAyD;AAEzD;;;GAGG;AACH,MAAM,CAAC,MAAM,oBAAoB,GAAG,IAAa,CAAC;AAElD,kEAAkE;AAClE,qEAAqE;AACrE,MAAM,oBAAoB,GAAG,2BAAoC,CAAC;AAElE,4CAA4C;AAC5C,MAAM,mBAAmB,GAAW,uBAAuB,CAAC;AAE5D;;;;;;;GAOG;AACH,MAAM,UAAU,gBAAgB,CAAC,KAAc;IAC7C,IAAI,OAAO,KAAK,KAAK,QAAQ,EAAE,CAAC;QAC9B,OAAO,IAAI,CAAC;IACd,CAAC;IACD,IAAI,KAAK,CAAC,MAAM,KAAK,CAAC,IAAI,KAAK,CAAC,MAAM,GAAG,oBAAoB,EAAE,CAAC;QAC9D,OAAO,IAAI,CAAC;IACd,CAAC;IACD,kEAAkE;IAClE,mEAAmE;IACnE,IAAI,CAAC,KAAK,CAAC,UAAU,CAAC,GAAG,CAAC,EAAE,CAAC;QAC3B,OAAO,IAAI,CAAC;IACd,CAAC;IACD,IAAI,KAAK,CAAC,UAAU,CAAC,IAAI,CAAC,IAAI,KAAK,CAAC,UAAU,CAAC,KAAK,CAAC,EAAE,CAAC;QACtD,OAAO,IAAI,CAAC;IACd,CAAC;IACD,IAAI,mBAAmB,CAAC,IAAI,CAAC,KAAK,CAAC,EAAE,CAAC;QACpC,OAAO,IAAI,CAAC;IACd,CAAC;IAED,IAAI,MAAW,CAAC;IAChB,IAAI,CAAC;QACH,MAAM,GAAG,IAAI,GAAG,CAAC,KAAK,EAAE,oBAAoB,CAAC,CAAC;IAChD,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,IAAI,CAAC;IACd,CAAC;IAED,mEAAmE;IACnE,oEAAoE;IACpE,IAAI,MAAM,CAAC,MAAM,KAAK,oBAAoB,EAAE,CAAC;QAC3C,OAAO,IAAI,CAAC;IACd,CAAC;IACD,2DAA2D;IAC3D,gEAAgE;IAChE,4BAA4B;IAC5B,IAAI,MAAM,CAAC,QAAQ,CAAC,UAAU,CAAC,IAAI,CAAC,EAAE,CAAC;QACrC,OAAO,IAAI,CAAC;IACd,CAAC;IAED,OAAO,GAAG,MAAM,CAAC,QAAQ,GAAG,MAAM,CAAC,MAAM,GAAG,MAAM,CAAC,IAAI,EAAE,CAAC;AAC5D,CAAC;AAED,eAAe,gBAAgB,CAAC"}
|
package/package.json
CHANGED