@seamless-auth/types 0.8.0 → 0.9.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,37 @@
1
1
  # @seamless-auth/types
2
2
 
3
+ ## 0.9.0
4
+
5
+ ### Minor Changes
6
+
7
+ - da415ff: Require identity proofing on admin-assisted device replacement.
8
+
9
+ **Breaking for callers of `DeviceReplacementRecoverySchema`.** The schema now
10
+ requires a `proofing` object:
11
+
12
+ ```ts
13
+ proofing: {
14
+ method: 'in_person' | 'remote_exception';
15
+ evidenceRef: string; // a ticket or case number, not the evidence itself
16
+ approver?: string; // required when method is 'remote_exception'
17
+ }
18
+ ```
19
+
20
+ Admin-assisted recovery revokes every session, removes every passkey and
21
+ disables TOTP, so it is the step social engineering aims at. It previously
22
+ carried no record of how the operator established who they were talking to, which
23
+ made a recovery impossible to review after the fact.
24
+
25
+ `in_person` is the default path and needs no approver. `remote_exception` is the
26
+ documented exception and does not validate without a named approver, so taking
27
+ the weaker path is a deliberate act with someone's name attached.
28
+
29
+ `evidenceRef` is a pointer rather than the evidence. It ends up in the audit
30
+ trail, where identifiers are redacted, so personal data does not belong in it.
31
+
32
+ Callers sending `{}` and relying on the clearing defaults will now fail
33
+ validation. Those defaults are unchanged.
34
+
3
35
  ## 0.8.0
4
36
 
5
37
  ### Minor Changes
@@ -3,15 +3,52 @@ export declare const UserIdParamSchema: z.ZodObject<{
3
3
  userId: z.ZodString;
4
4
  }, z.core.$strip>;
5
5
  export type UserIdParam = z.infer<typeof UserIdParamSchema>;
6
+ export declare const RecoveryProofingMethodSchema: z.ZodEnum<{
7
+ in_person: "in_person";
8
+ remote_exception: "remote_exception";
9
+ }>;
10
+ export type RecoveryProofingMethod = z.infer<typeof RecoveryProofingMethodSchema>;
11
+ /**
12
+ * How the operator established that the person asking is who they say they are.
13
+ *
14
+ * Admin-assisted recovery revokes every session, removes every passkey and
15
+ * disables TOTP, so it is the step social engineering aims at. Recording the
16
+ * proofing makes a recovery reviewable after the fact and forces the operator to
17
+ * have done it.
18
+ *
19
+ * `evidenceRef` is a pointer, for example a ticket or case number, not the
20
+ * evidence itself. Do not put personal data here: it is written to the audit
21
+ * trail, where identifiers are redacted.
22
+ */
23
+ export declare const RecoveryProofingSchema: z.ZodObject<{
24
+ method: z.ZodEnum<{
25
+ in_person: "in_person";
26
+ remote_exception: "remote_exception";
27
+ }>;
28
+ evidenceRef: z.ZodString;
29
+ approver: z.ZodOptional<z.ZodString>;
30
+ }, z.core.$strict>;
31
+ export type RecoveryProofing = z.infer<typeof RecoveryProofingSchema>;
6
32
  /**
7
33
  * What an operator clears when a user replaces a lost device. Each step is
8
34
  * opt-out rather than opt-in so a hurried recovery does not leave the old
9
35
  * device's credentials in place.
36
+ *
37
+ * `proofing` is required: this endpoint cannot be called without stating how
38
+ * identity was established.
10
39
  */
11
40
  export declare const DeviceReplacementRecoverySchema: z.ZodObject<{
12
41
  revokeSessions: z.ZodDefault<z.ZodBoolean>;
13
42
  removePasskeys: z.ZodDefault<z.ZodBoolean>;
14
43
  disableTotp: z.ZodDefault<z.ZodBoolean>;
44
+ proofing: z.ZodObject<{
45
+ method: z.ZodEnum<{
46
+ in_person: "in_person";
47
+ remote_exception: "remote_exception";
48
+ }>;
49
+ evidenceRef: z.ZodString;
50
+ approver: z.ZodOptional<z.ZodString>;
51
+ }, z.core.$strict>;
15
52
  }, z.core.$strict>;
16
53
  export type DeviceReplacementRecoveryRequest = z.infer<typeof DeviceReplacementRecoverySchema>;
17
54
  export declare const DeviceReplacementRecoveryResponseSchema: z.ZodObject<{
@@ -1 +1 @@
1
- {"version":3,"file":"schema.d.ts","sourceRoot":"","sources":["../../../src/schemas/admin/schema.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAMxB,eAAO,MAAM,iBAAiB;;iBAE5B,CAAC;AAEH,MAAM,MAAM,WAAW,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,iBAAiB,CAAC,CAAC;AAE5D;;;;GAIG;AACH,eAAO,MAAM,+BAA+B;;;;kBAMjC,CAAC;AAEZ,MAAM,MAAM,gCAAgC,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,+BAA+B,CAAC,CAAC;AAE/F,eAAO,MAAM,uCAAuC;;;;;iBAKlD,CAAC;AAEH,MAAM,MAAM,iCAAiC,GAAG,CAAC,CAAC,KAAK,CACrD,OAAO,uCAAuC,CAC/C,CAAC;AAEF,eAAO,MAAM,6BAA6B;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;iBAKxC,CAAC;AAEH,MAAM,MAAM,uBAAuB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,6BAA6B,CAAC,CAAC;AAEpF,eAAO,MAAM,gCAAgC;;;;;;;;;;;;;iBAI3C,CAAC;AAEH,MAAM,MAAM,0BAA0B,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,gCAAgC,CAAC,CAAC"}
1
+ {"version":3,"file":"schema.d.ts","sourceRoot":"","sources":["../../../src/schemas/admin/schema.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAMxB,eAAO,MAAM,iBAAiB;;iBAE5B,CAAC;AAEH,MAAM,MAAM,WAAW,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,iBAAiB,CAAC,CAAC;AAE5D,eAAO,MAAM,4BAA4B;;;EAA4C,CAAC;AAEtF,MAAM,MAAM,sBAAsB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,4BAA4B,CAAC,CAAC;AAElF;;;;;;;;;;;GAWG;AACH,eAAO,MAAM,sBAAsB;;;;;;;kBAe/B,CAAC;AAEL,MAAM,MAAM,gBAAgB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,sBAAsB,CAAC,CAAC;AAEtE;;;;;;;GAOG;AACH,eAAO,MAAM,+BAA+B;;;;;;;;;;;;kBAOjC,CAAC;AAEZ,MAAM,MAAM,gCAAgC,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,+BAA+B,CAAC,CAAC;AAE/F,eAAO,MAAM,uCAAuC;;;;;iBAKlD,CAAC;AAEH,MAAM,MAAM,iCAAiC,GAAG,CAAC,CAAC,KAAK,CACrD,OAAO,uCAAuC,CAC/C,CAAC;AAEF,eAAO,MAAM,6BAA6B;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;iBAKxC,CAAC;AAEH,MAAM,MAAM,uBAAuB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,6BAA6B,CAAC,CAAC;AAEpF,eAAO,MAAM,gCAAgC;;;;;;;;;;;;;iBAI3C,CAAC;AAEH,MAAM,MAAM,0BAA0B,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,gCAAgC,CAAC,CAAC"}
@@ -6,16 +6,49 @@ import { ApiUserSchema } from '../user/schema.js';
6
6
  export const UserIdParamSchema = z.object({
7
7
  userId: z.string(),
8
8
  });
9
+ export const RecoveryProofingMethodSchema = z.enum(['in_person', 'remote_exception']);
10
+ /**
11
+ * How the operator established that the person asking is who they say they are.
12
+ *
13
+ * Admin-assisted recovery revokes every session, removes every passkey and
14
+ * disables TOTP, so it is the step social engineering aims at. Recording the
15
+ * proofing makes a recovery reviewable after the fact and forces the operator to
16
+ * have done it.
17
+ *
18
+ * `evidenceRef` is a pointer, for example a ticket or case number, not the
19
+ * evidence itself. Do not put personal data here: it is written to the audit
20
+ * trail, where identifiers are redacted.
21
+ */
22
+ export const RecoveryProofingSchema = z
23
+ .object({
24
+ method: RecoveryProofingMethodSchema,
25
+ evidenceRef: z.string().trim().min(1).max(200),
26
+ approver: z.string().trim().min(1).max(200).optional(),
27
+ })
28
+ .strict()
29
+ .superRefine((value, ctx) => {
30
+ if (value.method === 'remote_exception' && !value.approver) {
31
+ ctx.addIssue({
32
+ code: 'custom',
33
+ path: ['approver'],
34
+ message: 'A remote exception requires a named approver',
35
+ });
36
+ }
37
+ });
9
38
  /**
10
39
  * What an operator clears when a user replaces a lost device. Each step is
11
40
  * opt-out rather than opt-in so a hurried recovery does not leave the old
12
41
  * device's credentials in place.
42
+ *
43
+ * `proofing` is required: this endpoint cannot be called without stating how
44
+ * identity was established.
13
45
  */
14
46
  export const DeviceReplacementRecoverySchema = z
15
47
  .object({
16
48
  revokeSessions: z.boolean().default(true),
17
49
  removePasskeys: z.boolean().default(true),
18
50
  disableTotp: z.boolean().default(true),
51
+ proofing: RecoveryProofingSchema,
19
52
  })
20
53
  .strict();
21
54
  export const DeviceReplacementRecoveryResponseSchema = z.object({
@@ -1 +1 @@
1
- {"version":3,"file":"schema.js","sourceRoot":"","sources":["../../../src/schemas/admin/schema.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AACxB,OAAO,EAAE,eAAe,EAAE,MAAM,wBAAwB,CAAC;AACzD,OAAO,EAAE,wBAAwB,EAAE,MAAM,yBAAyB,CAAC;AACnE,OAAO,EAAE,aAAa,EAAE,MAAM,sBAAsB,CAAC;AACrD,OAAO,EAAE,aAAa,EAAE,MAAM,mBAAmB,CAAC;AAElD,MAAM,CAAC,MAAM,iBAAiB,GAAG,CAAC,CAAC,MAAM,CAAC;IACxC,MAAM,EAAE,CAAC,CAAC,MAAM,EAAE;CACnB,CAAC,CAAC;AAIH;;;;GAIG;AACH,MAAM,CAAC,MAAM,+BAA+B,GAAG,CAAC;KAC7C,MAAM,CAAC;IACN,cAAc,EAAE,CAAC,CAAC,OAAO,EAAE,CAAC,OAAO,CAAC,IAAI,CAAC;IACzC,cAAc,EAAE,CAAC,CAAC,OAAO,EAAE,CAAC,OAAO,CAAC,IAAI,CAAC;IACzC,WAAW,EAAE,CAAC,CAAC,OAAO,EAAE,CAAC,OAAO,CAAC,IAAI,CAAC;CACvC,CAAC;KACD,MAAM,EAAE,CAAC;AAIZ,MAAM,CAAC,MAAM,uCAAuC,GAAG,CAAC,CAAC,MAAM,CAAC;IAC9D,MAAM,EAAE,CAAC,CAAC,MAAM,EAAE;IAClB,eAAe,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,EAAE,CAAC,WAAW,EAAE;IAC/C,kBAAkB,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,EAAE,CAAC,WAAW,EAAE;IAClD,uBAAuB,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,EAAE,CAAC,WAAW,EAAE;CACxD,CAAC,CAAC;AAMH,MAAM,CAAC,MAAM,6BAA6B,GAAG,CAAC,CAAC,MAAM,CAAC;IACpD,IAAI,EAAE,aAAa;IACnB,QAAQ,EAAE,CAAC,CAAC,KAAK,CAAC,aAAa,CAAC;IAChC,WAAW,EAAE,CAAC,CAAC,KAAK,CAAC,wBAAwB,CAAC;IAC9C,MAAM,EAAE,CAAC,CAAC,KAAK,CAAC,eAAe,CAAC;CACjC,CAAC,CAAC;AAIH,MAAM,CAAC,MAAM,gCAAgC,GAAG,CAAC,CAAC,MAAM,CAAC;IACvD,gBAAgB,EAAE,CAAC,CAAC,KAAK,CAAC,eAAe,CAAC;IAC1C,UAAU,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,MAAM,EAAE,CAAC;IAC/B,aAAa,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,MAAM,EAAE,CAAC;CACnC,CAAC,CAAC"}
1
+ {"version":3,"file":"schema.js","sourceRoot":"","sources":["../../../src/schemas/admin/schema.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@seamless-auth/types",
3
- "version": "0.8.0",
3
+ "version": "0.9.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",
@@ -10,16 +10,55 @@ export const UserIdParamSchema = z.object({
10
10
 
11
11
  export type UserIdParam = z.infer<typeof UserIdParamSchema>;
12
12
 
13
+ export const RecoveryProofingMethodSchema = z.enum(['in_person', 'remote_exception']);
14
+
15
+ export type RecoveryProofingMethod = z.infer<typeof RecoveryProofingMethodSchema>;
16
+
17
+ /**
18
+ * How the operator established that the person asking is who they say they are.
19
+ *
20
+ * Admin-assisted recovery revokes every session, removes every passkey and
21
+ * disables TOTP, so it is the step social engineering aims at. Recording the
22
+ * proofing makes a recovery reviewable after the fact and forces the operator to
23
+ * have done it.
24
+ *
25
+ * `evidenceRef` is a pointer, for example a ticket or case number, not the
26
+ * evidence itself. Do not put personal data here: it is written to the audit
27
+ * trail, where identifiers are redacted.
28
+ */
29
+ export const RecoveryProofingSchema = z
30
+ .object({
31
+ method: RecoveryProofingMethodSchema,
32
+ evidenceRef: z.string().trim().min(1).max(200),
33
+ approver: z.string().trim().min(1).max(200).optional(),
34
+ })
35
+ .strict()
36
+ .superRefine((value, ctx) => {
37
+ if (value.method === 'remote_exception' && !value.approver) {
38
+ ctx.addIssue({
39
+ code: 'custom',
40
+ path: ['approver'],
41
+ message: 'A remote exception requires a named approver',
42
+ });
43
+ }
44
+ });
45
+
46
+ export type RecoveryProofing = z.infer<typeof RecoveryProofingSchema>;
47
+
13
48
  /**
14
49
  * What an operator clears when a user replaces a lost device. Each step is
15
50
  * opt-out rather than opt-in so a hurried recovery does not leave the old
16
51
  * device's credentials in place.
52
+ *
53
+ * `proofing` is required: this endpoint cannot be called without stating how
54
+ * identity was established.
17
55
  */
18
56
  export const DeviceReplacementRecoverySchema = z
19
57
  .object({
20
58
  revokeSessions: z.boolean().default(true),
21
59
  removePasskeys: z.boolean().default(true),
22
60
  disableTotp: z.boolean().default(true),
61
+ proofing: RecoveryProofingSchema,
23
62
  })
24
63
  .strict();
25
64