@seamless-auth/types 0.19.0 → 0.20.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/CHANGELOG.md CHANGED
@@ -1,5 +1,34 @@
1
1
  # @seamless-auth/types
2
2
 
3
+ ## 0.20.0
4
+
5
+ ### Minor Changes
6
+
7
+ - 9541d01: Carry `returnTo` back out of the OAuth callback, and hold it to a scheme that can be a
8
+ link destination.
9
+
10
+ `StartOAuthLoginRequestSchema` has taken a `returnTo` since OAuth landed, and nothing ever
11
+ gave it back. `seamless-auth-api` validated it against the configured origins and signed it
12
+ into the state, and `seamless-auth-react` sent it, but no schema carried it to the end of the
13
+ flow, so a client that asked to be returned somewhere had no way to learn where. It was a
14
+ field that looked supported and did nothing.
15
+
16
+ `OAuthLoginSuccessResponseSchema` now carries an optional `returnTo`. The API reads it back
17
+ out of the signed state rather than from the callback request, so it is the value validated
18
+ at `/start` and not one introduced at the end of the round trip. Absent when the caller asked
19
+ for nothing, so a client falls through to its own default rather than treating absence as an
20
+ error.
21
+
22
+ Both `returnTo` fields move from `z.url()` to `RedirectTargetSchema`. `z.url()` accepts
23
+ `javascript:alert(1)` and `data:text/html,...`, and a client navigates to whatever comes back
24
+ out of this flow, so it is the same sink a magic link destination is. That is what
25
+ `RedirectTargetSchema` was added for in 0.18.0, and the OAuth fields should have used it
26
+ then.
27
+
28
+ Additive for a consumer that ignores the new field. A caller that was somehow sending a
29
+ `javascript:` or `data:` `returnTo` is now refused at the schema rather than later, which is
30
+ the intended change.
31
+
3
32
  ## 0.19.0
4
33
 
5
34
  ### Minor Changes
@@ -49,6 +49,7 @@ export declare const OAuthLoginSuccessResponseSchema: z.ZodObject<{
49
49
  refreshToken: z.ZodOptional<z.ZodString>;
50
50
  organizationId: z.ZodOptional<z.ZodNullable<z.ZodString>>;
51
51
  refreshTtl: z.ZodOptional<z.ZodNumber>;
52
+ returnTo: z.ZodOptional<z.ZodURL>;
52
53
  }, z.core.$strip>;
53
54
  export type OAuthLoginSuccessResponse = z.infer<typeof OAuthLoginSuccessResponseSchema>;
54
55
  export declare const OAUTH_ERROR_CODES: readonly ["oauth_missing_email", "oauth_email_not_verified", "oauth_missing_subject"];
@@ -1 +1 @@
1
- {"version":3,"file":"schema.d.ts","sourceRoot":"","sources":["../../../src/schemas/oauth/schema.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAIxB,eAAO,MAAM,wBAAwB;;iBAEnC,CAAC;AAEH,MAAM,MAAM,kBAAkB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,wBAAwB,CAAC,CAAC;AAE1E,wFAAwF;AACxF,eAAO,MAAM,yBAAyB;;;;iBAIpC,CAAC;AAEH,MAAM,MAAM,mBAAmB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,yBAAyB,CAAC,CAAC;AAE5E,eAAO,MAAM,4BAA4B;;;;;;iBAEvC,CAAC;AAEH,MAAM,MAAM,sBAAsB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,4BAA4B,CAAC,CAAC;AAElF,eAAO,MAAM,4BAA4B;;;iBAGvC,CAAC;AAEH,MAAM,MAAM,sBAAsB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,4BAA4B,CAAC,CAAC;AAElF,eAAO,MAAM,6BAA6B;;;;;;;;iBAIxC,CAAC;AAEH,MAAM,MAAM,uBAAuB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,6BAA6B,CAAC,CAAC;AAEpF,eAAO,MAAM,6BAA6B;;;iBAGxC,CAAC;AAEH,MAAM,MAAM,uBAAuB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,6BAA6B,CAAC,CAAC;AAEpF,eAAO,MAAM,+BAA+B;;;;;;;;;;;iBAE1C,CAAC;AAEH,MAAM,MAAM,yBAAyB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,+BAA+B,CAAC,CAAC;AAExF,eAAO,MAAM,iBAAiB,uFAIpB,CAAC;AAEX,eAAO,MAAM,oBAAoB;;;;EAA4B,CAAC;AAE9D,MAAM,MAAM,cAAc,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,oBAAoB,CAAC,CAAC;AAElE,eAAO,MAAM,6BAA6B;;;;;;;;iBAIxC,CAAC;AAEH,MAAM,MAAM,uBAAuB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,6BAA6B,CAAC,CAAC"}
1
+ {"version":3,"file":"schema.d.ts","sourceRoot":"","sources":["../../../src/schemas/oauth/schema.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAIxB,eAAO,MAAM,wBAAwB;;iBAEnC,CAAC;AAEH,MAAM,MAAM,kBAAkB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,wBAAwB,CAAC,CAAC;AAE1E,wFAAwF;AACxF,eAAO,MAAM,yBAAyB;;;;iBAIpC,CAAC;AAEH,MAAM,MAAM,mBAAmB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,yBAAyB,CAAC,CAAC;AAE5E,eAAO,MAAM,4BAA4B;;;;;;iBAEvC,CAAC;AAEH,MAAM,MAAM,sBAAsB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,4BAA4B,CAAC,CAAC;AAElF,eAAO,MAAM,4BAA4B;;;iBAGvC,CAAC;AAEH,MAAM,MAAM,sBAAsB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,4BAA4B,CAAC,CAAC;AAElF,eAAO,MAAM,6BAA6B;;;;;;;;iBAIxC,CAAC;AAEH,MAAM,MAAM,uBAAuB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,6BAA6B,CAAC,CAAC;AAEpF,eAAO,MAAM,6BAA6B;;;iBAGxC,CAAC;AAEH,MAAM,MAAM,uBAAuB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,6BAA6B,CAAC,CAAC;AAEpF,eAAO,MAAM,+BAA+B;;;;;;;;;;;;iBAa1C,CAAC;AAEH,MAAM,MAAM,yBAAyB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,+BAA+B,CAAC,CAAC;AAExF,eAAO,MAAM,iBAAiB,uFAIpB,CAAC;AAEX,eAAO,MAAM,oBAAoB;;;;EAA4B,CAAC;AAE9D,MAAM,MAAM,cAAc,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,oBAAoB,CAAC,CAAC;AAElE,eAAO,MAAM,6BAA6B;;;;;;;;iBAIxC,CAAC;AAEH,MAAM,MAAM,uBAAuB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,6BAA6B,CAAC,CAAC"}
@@ -1,6 +1,6 @@
1
1
  import { z } from 'zod';
2
2
  import { RefreshSuccessResponseSchema } from '../auth/auth.schema.js';
3
- import { OAuthProviderIdSchema } from '../systemConfig/schema.js';
3
+ import { OAuthProviderIdSchema, RedirectTargetSchema } from '../systemConfig/schema.js';
4
4
  export const OAuthProviderParamSchema = z.object({
5
5
  providerId: OAuthProviderIdSchema,
6
6
  });
@@ -15,7 +15,7 @@ export const OAuthProvidersResponseSchema = z.object({
15
15
  });
16
16
  export const StartOAuthLoginRequestSchema = z.object({
17
17
  redirectUri: z.url().optional(),
18
- returnTo: z.url().optional(),
18
+ returnTo: RedirectTargetSchema.optional(),
19
19
  });
20
20
  export const StartOAuthLoginResponseSchema = z.object({
21
21
  provider: PublicOAuthProviderSchema,
@@ -28,6 +28,17 @@ export const FinishOAuthLoginRequestSchema = z.object({
28
28
  });
29
29
  export const OAuthLoginSuccessResponseSchema = RefreshSuccessResponseSchema.omit({
30
30
  sessionId: true,
31
+ }).extend({
32
+ /**
33
+ * Where the caller asked to be sent once the flow completes.
34
+ *
35
+ * Read back out of the signed state rather than from the callback request, so it is
36
+ * the value the authorization server accepted at `/start` and not one introduced at
37
+ * the end of the round trip. Present only when the caller supplied one and it passed
38
+ * validation there, so a client treats absence as "use my own default" rather than
39
+ * as an error.
40
+ */
41
+ returnTo: RedirectTargetSchema.optional(),
31
42
  });
32
43
  export const OAUTH_ERROR_CODES = [
33
44
  'oauth_missing_email',
@@ -1 +1 @@
1
- {"version":3,"file":"schema.js","sourceRoot":"","sources":["../../../src/schemas/oauth/schema.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AACxB,OAAO,EAAE,4BAA4B,EAAE,MAAM,wBAAwB,CAAC;AACtE,OAAO,EAAE,qBAAqB,EAAE,MAAM,2BAA2B,CAAC;AAElE,MAAM,CAAC,MAAM,wBAAwB,GAAG,CAAC,CAAC,MAAM,CAAC;IAC/C,UAAU,EAAE,qBAAqB;CAClC,CAAC,CAAC;AAIH,wFAAwF;AACxF,MAAM,CAAC,MAAM,yBAAyB,GAAG,CAAC,CAAC,MAAM,CAAC;IAChD,EAAE,EAAE,CAAC,CAAC,MAAM,EAAE;IACd,IAAI,EAAE,CAAC,CAAC,MAAM,EAAE;IAChB,MAAM,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,MAAM,EAAE,CAAC;CAC5B,CAAC,CAAC;AAIH,MAAM,CAAC,MAAM,4BAA4B,GAAG,CAAC,CAAC,MAAM,CAAC;IACnD,SAAS,EAAE,CAAC,CAAC,KAAK,CAAC,yBAAyB,CAAC;CAC9C,CAAC,CAAC;AAIH,MAAM,CAAC,MAAM,4BAA4B,GAAG,CAAC,CAAC,MAAM,CAAC;IACnD,WAAW,EAAE,CAAC,CAAC,GAAG,EAAE,CAAC,QAAQ,EAAE;IAC/B,QAAQ,EAAE,CAAC,CAAC,GAAG,EAAE,CAAC,QAAQ,EAAE;CAC7B,CAAC,CAAC;AAIH,MAAM,CAAC,MAAM,6BAA6B,GAAG,CAAC,CAAC,MAAM,CAAC;IACpD,QAAQ,EAAE,yBAAyB;IACnC,KAAK,EAAE,CAAC,CAAC,MAAM,EAAE;IACjB,gBAAgB,EAAE,CAAC,CAAC,GAAG,EAAE;CAC1B,CAAC,CAAC;AAIH,MAAM,CAAC,MAAM,6BAA6B,GAAG,CAAC,CAAC,MAAM,CAAC;IACpD,IAAI,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,IAAI,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC;IAC9B,KAAK,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,IAAI,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC;CAChC,CAAC,CAAC;AAIH,MAAM,CAAC,MAAM,+BAA+B,GAAG,4BAA4B,CAAC,IAAI,CAAC;IAC/E,SAAS,EAAE,IAAI;CAChB,CAAC,CAAC;AAIH,MAAM,CAAC,MAAM,iBAAiB,GAAG;IAC/B,qBAAqB;IACrB,0BAA0B;IAC1B,uBAAuB;CACf,CAAC;AAEX,MAAM,CAAC,MAAM,oBAAoB,GAAG,CAAC,CAAC,IAAI,CAAC,iBAAiB,CAAC,CAAC;AAI9D,MAAM,CAAC,MAAM,6BAA6B,GAAG,CAAC,CAAC,MAAM,CAAC;IACpD,OAAO,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE;IAC9B,KAAK,EAAE,CAAC,CAAC,MAAM,EAAE;IACjB,IAAI,EAAE,oBAAoB,CAAC,QAAQ,EAAE;CACtC,CAAC,CAAC"}
1
+ {"version":3,"file":"schema.js","sourceRoot":"","sources":["../../../src/schemas/oauth/schema.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AACxB,OAAO,EAAE,4BAA4B,EAAE,MAAM,wBAAwB,CAAC;AACtE,OAAO,EAAE,qBAAqB,EAAE,oBAAoB,EAAE,MAAM,2BAA2B,CAAC;AAExF,MAAM,CAAC,MAAM,wBAAwB,GAAG,CAAC,CAAC,MAAM,CAAC;IAC/C,UAAU,EAAE,qBAAqB;CAClC,CAAC,CAAC;AAIH,wFAAwF;AACxF,MAAM,CAAC,MAAM,yBAAyB,GAAG,CAAC,CAAC,MAAM,CAAC;IAChD,EAAE,EAAE,CAAC,CAAC,MAAM,EAAE;IACd,IAAI,EAAE,CAAC,CAAC,MAAM,EAAE;IAChB,MAAM,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,MAAM,EAAE,CAAC;CAC5B,CAAC,CAAC;AAIH,MAAM,CAAC,MAAM,4BAA4B,GAAG,CAAC,CAAC,MAAM,CAAC;IACnD,SAAS,EAAE,CAAC,CAAC,KAAK,CAAC,yBAAyB,CAAC;CAC9C,CAAC,CAAC;AAIH,MAAM,CAAC,MAAM,4BAA4B,GAAG,CAAC,CAAC,MAAM,CAAC;IACnD,WAAW,EAAE,CAAC,CAAC,GAAG,EAAE,CAAC,QAAQ,EAAE;IAC/B,QAAQ,EAAE,oBAAoB,CAAC,QAAQ,EAAE;CAC1C,CAAC,CAAC;AAIH,MAAM,CAAC,MAAM,6BAA6B,GAAG,CAAC,CAAC,MAAM,CAAC;IACpD,QAAQ,EAAE,yBAAyB;IACnC,KAAK,EAAE,CAAC,CAAC,MAAM,EAAE;IACjB,gBAAgB,EAAE,CAAC,CAAC,GAAG,EAAE;CAC1B,CAAC,CAAC;AAIH,MAAM,CAAC,MAAM,6BAA6B,GAAG,CAAC,CAAC,MAAM,CAAC;IACpD,IAAI,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,IAAI,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC;IAC9B,KAAK,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,IAAI,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC;CAChC,CAAC,CAAC;AAIH,MAAM,CAAC,MAAM,+BAA+B,GAAG,4BAA4B,CAAC,IAAI,CAAC;IAC/E,SAAS,EAAE,IAAI;CAChB,CAAC,CAAC,MAAM,CAAC;IACR;;;;;;;;OAQG;IACH,QAAQ,EAAE,oBAAoB,CAAC,QAAQ,EAAE;CAC1C,CAAC,CAAC;AAIH,MAAM,CAAC,MAAM,iBAAiB,GAAG;IAC/B,qBAAqB;IACrB,0BAA0B;IAC1B,uBAAuB;CACf,CAAC;AAEX,MAAM,CAAC,MAAM,oBAAoB,GAAG,CAAC,CAAC,IAAI,CAAC,iBAAiB,CAAC,CAAC;AAI9D,MAAM,CAAC,MAAM,6BAA6B,GAAG,CAAC,CAAC,MAAM,CAAC;IACpD,OAAO,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE;IAC9B,KAAK,EAAE,CAAC,CAAC,MAAM,EAAE;IACjB,IAAI,EAAE,oBAAoB,CAAC,QAAQ,EAAE;CACtC,CAAC,CAAC"}
@@ -9,8 +9,8 @@ export declare const WebAuthnPrfRequestSchema: z.ZodObject<{
9
9
  }, z.core.$strip>;
10
10
  export type WebAuthnPrfRequest = z.infer<typeof WebAuthnPrfRequestSchema>;
11
11
  export declare const WebAuthnRegisterStartQuerySchema: z.ZodObject<{
12
- requestPrf: z.ZodPreprocess<z.ZodOptional<z.ZodBoolean>>;
13
- requirePrf: z.ZodPreprocess<z.ZodOptional<z.ZodBoolean>>;
12
+ requestPrf: z.ZodPreprocess<z.ZodOptional<z.ZodBoolean>, unknown>;
13
+ requirePrf: z.ZodPreprocess<z.ZodOptional<z.ZodBoolean>, unknown>;
14
14
  }, z.core.$strip>;
15
15
  export type WebAuthnRegisterStartQuery = z.infer<typeof WebAuthnRegisterStartQuerySchema>;
16
16
  export declare const WebAuthnAssertionStartSchema: z.ZodDefault<z.ZodObject<{
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@seamless-auth/types",
3
- "version": "0.19.0",
3
+ "version": "0.20.0",
4
4
  "description": "Shared TypeScript types and Zod schemas for SeamlessAuth.",
5
5
  "author": "Fells Code, LLC",
6
6
  "license": "AGPL-3.0-only",
@@ -78,7 +78,7 @@
78
78
  "zod": "^4.3.6"
79
79
  },
80
80
  "devDependencies": {
81
- "@changesets/cli": "^2.31.1",
81
+ "@changesets/cli": "^3.0.2",
82
82
  "@commitlint/cli": "^21.2.1",
83
83
  "@commitlint/config-conventional": "^21.2.0",
84
84
  "@typescript-eslint/eslint-plugin": "^8.57.2",
@@ -1,6 +1,6 @@
1
1
  import { z } from 'zod';
2
2
  import { RefreshSuccessResponseSchema } from '../auth/auth.schema.js';
3
- import { OAuthProviderIdSchema } from '../systemConfig/schema.js';
3
+ import { OAuthProviderIdSchema, RedirectTargetSchema } from '../systemConfig/schema.js';
4
4
 
5
5
  export const OAuthProviderParamSchema = z.object({
6
6
  providerId: OAuthProviderIdSchema,
@@ -25,7 +25,7 @@ export type OAuthProvidersResponse = z.infer<typeof OAuthProvidersResponseSchema
25
25
 
26
26
  export const StartOAuthLoginRequestSchema = z.object({
27
27
  redirectUri: z.url().optional(),
28
- returnTo: z.url().optional(),
28
+ returnTo: RedirectTargetSchema.optional(),
29
29
  });
30
30
 
31
31
  export type StartOAuthLoginRequest = z.infer<typeof StartOAuthLoginRequestSchema>;
@@ -47,6 +47,17 @@ export type FinishOAuthLoginRequest = z.infer<typeof FinishOAuthLoginRequestSche
47
47
 
48
48
  export const OAuthLoginSuccessResponseSchema = RefreshSuccessResponseSchema.omit({
49
49
  sessionId: true,
50
+ }).extend({
51
+ /**
52
+ * Where the caller asked to be sent once the flow completes.
53
+ *
54
+ * Read back out of the signed state rather than from the callback request, so it is
55
+ * the value the authorization server accepted at `/start` and not one introduced at
56
+ * the end of the round trip. Present only when the caller supplied one and it passed
57
+ * validation there, so a client treats absence as "use my own default" rather than
58
+ * as an error.
59
+ */
60
+ returnTo: RedirectTargetSchema.optional(),
50
61
  });
51
62
 
52
63
  export type OAuthLoginSuccessResponse = z.infer<typeof OAuthLoginSuccessResponseSchema>;