@learncard/sss-key-manager 0.2.5 → 0.2.7

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.
@@ -1 +1 @@
1
- {"version":3,"file":"sss-strategy.d.ts","sourceRoot":"","sources":["../src/sss-strategy.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AAEH,OAAO,KAAK,EACR,wBAAwB,EAaxB,uBAAuB,EAI1B,MAAM,SAAS,CAAC;AAoCjB,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,sBAAsB,CAAC;AAyC/D;;;;;;;GAOG;AACH,eAAO,MAAM,kCAAkC,QAAQ,CAAC;AAExD,MAAM,WAAW,mBAAmB;IAChC,gBAAgB,EAAE,CAAC,KAAK,EAAE,MAAM,EAAE,EAAE,CAAC,EAAE,MAAM,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;IAChE,cAAc,EAAE,CAAC,EAAE,CAAC,EAAE,MAAM,KAAK,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CAAC;IACxD,cAAc,EAAE,CAAC,EAAE,CAAC,EAAE,MAAM,KAAK,OAAO,CAAC,OAAO,CAAC,CAAC;IAClD,cAAc,EAAE,CAAC,EAAE,CAAC,EAAE,MAAM,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;IAC/C,iBAAiB,EAAE,CAAC,EAAE,CAAC,EAAE,MAAM,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;IAClD,iBAAiB,EAAE,CAAC,OAAO,EAAE,MAAM,EAAE,EAAE,CAAC,EAAE,MAAM,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;IACnE,eAAe,EAAE,CAAC,EAAE,CAAC,EAAE,MAAM,KAAK,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CAAC;CAC5D;AAED,MAAM,WAAW,iBAAiB;IAC9B,0EAA0E;IAC1E,MAAM,CAAC,EAAE;QAAE,OAAO,EAAE,OAAO,CAAC;QAAC,WAAW,EAAE,uBAAuB,CAAA;KAAE,CAAC;IAEpE,oEAAoE;IACpE,aAAa,CAAC,EAAE,CAAC,GAAG,EAAE,OAAO,KAAK,IAAI,CAAC;IAEvC;;;;;;OAMG;IACH,uBAAuB,CAAC,EAAE,OAAO,CAAC;IAElC;;;;OAIG;IACH,sBAAsB,CAAC,EAAE,CAAC,KAAK,EAAE,yBAAyB,KAAK,IAAI,CAAC;IAEpE,0CAA0C;IAC1C,SAAS,EAAE,MAAM,CAAC;IAElB,uDAAuD;IACvD,OAAO,CAAC,EAAE,mBAAmB,CAAC;IAE9B;;;;;OAKG;IACH,sBAAsB,CAAC,EAAE,OAAO,CAAC;IAEjC,4EAA4E;IAC5E,oBAAoB,CAAC,EAAE,MAAM,CAAC;IAE9B,2EAA2E;IAC3E,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAE1B,8EAA8E;IAC9E,aAAa,CAAC,EAAE,kBAAkB,CAAC;IAEnC;;;;OAIG;IACH,QAAQ,CAAC,EAAE,MAAM,CAAC;CACrB;AA0BD,eAAO,MAAM,yBAAyB,QAAS,CAAC;AAiBhD,2FAA2F;AAC3F,MAAM,WAAW,yBAAyB;IACtC,IAAI,EAAE,yBAAyB,CAAC;IAChC,8DAA8D;IAC9D,YAAY,EAAE,MAAM,CAAC;IACrB,2EAA2E;IAC3E,qBAAqB,EAAE,MAAM,GAAG,IAAI,CAAC;CACxC;AAED,gFAAgF;AAChF,qBAAa,kBAAmB,SAAQ,KAAK;aAErB,MAAM,EAAE,MAAM;aACd,MAAM,CAAC,EAAE,cAAc,GAAG,aAAa,GAAG,YAAY;gBADtD,MAAM,EAAE,MAAM,EACd,MAAM,CAAC,EAAE,cAAc,GAAG,aAAa,GAAG,YAAY,YAAA;CAK7E;AAED,kFAAkF;AAClF,qBAAa,6BAA8B,SAAQ,KAAK;;CAKvD;AAiLD;;;GAGG;AACH,qBAAa,oCAAqC,SAAQ,KAAK;gBAC/C,OAAO,EAAE,MAAM;CAI9B;AA+ED,2EAA2E;AAC3E,eAAO,MAAM,+BAA+B,IAAI,CAAC;AAEjD,eAAO,MAAM,oCAAoC,GAC7C,WAAW,MAAM,EACjB,uBAAgD,KACjD,MAAM,EAoBR,CAAC;AAEF;;;;;;;;GAQG;AACH,eAAO,MAAM,kBAAkB,IAAI,CAAC;AAEpC,eAAO,MAAM,yBAAyB,GAAI,YAAY,MAAM,EAAE,cAAc,MAAM,KAAG,MACT,CAAC;AAE7E;;;;GAIG;AACH,eAAO,MAAM,wBAAwB,GACjC,OAAO,MAAM,KACd;IAAE,KAAK,EAAE,MAAM,CAAC;IAAC,OAAO,EAAE,MAAM,GAAG,SAAS,CAAA;CAY9C,CAAC;AAqDF;;;;GAIG;AACH,eAAO,MAAM,gBAAgB,GAAI,CAAC,EAAE,WAAW,MAAM,OAAO,CAAC,CAAC,CAAC,KAAG,OAAO,CAAC,CAAC,CAI1E,CAAC;AAOF,uFAAuF;AACvF,eAAO,MAAM,uBAAuB,QAAiB,CAAC;AAGtD,MAAM,WAAW,qBAAqB;IAClC,KAAK,EAAE,MAAM,CAAC;IACd,SAAS,EAAE,MAAM,CAAC;CACrB;AAED;;;;;GAKG;AACH,eAAO,MAAM,0BAA0B,GACnC,SAAS,mBAAmB,EAC5B,YAAY,MAAM,KACnB,OAAO,CAAC,qBAAqB,EAAE,CA0BjC,CAAC;AAEF,oFAAoF;AACpF,eAAO,MAAM,2BAA2B,GACpC,SAAS,mBAAmB,EAC5B,YAAY,MAAM,KACnB,OAAO,CAAC,IAAI,CAAsD,CAAC;AAEtE,0FAA0F;AAC1F,eAAO,MAAM,2BAA2B,GACpC,SAAS,mBAAmB,EAC5B,YAAY,qBAAqB,EAAE,EACnC,YAAY,MAAM,KACnB,OAAO,CAAC,IAAI,CAGd,CAAC;AAEF,iFAAiF;AACjF,eAAO,MAAM,wBAAwB,GACjC,SAAS,mBAAmB,EAC5B,WAAW,qBAAqB,EAChC,YAAY,MAAM,KACnB,OAAO,CAAC,IAAI,CAUd,CAAC;AAEF,+FAA+F;AAC/F,eAAO,MAAM,2BAA2B,GACpC,SAAS,mBAAmB,EAC5B,OAAO,MAAM,EACb,YAAY,MAAM,KACnB,OAAO,CAAC,IAAI,CAOd,CAAC;AAEF,UAAU,oBAAoB;IAC1B,cAAc,EAAE,MAAM,GAAG,IAAI,CAAC;IAC9B,SAAS,EAAE,MAAM,GAAG,IAAI,CAAC;CAC5B;AAED;;;;GAIG;AACH,eAAO,MAAM,6BAA6B,GACtC,SAAS,mBAAmB,EAC5B,WAAW,MAAM,GAAG,SAAS,EAC7B,cAAc,MAAM,OAAO,CAAC,oBAAoB,CAAC,EACjD,aAAa,MAAM,EACnB,mBAAmB,CAAC,GAAG,EAAE,MAAM,KAAK,OAAO,CAAC,MAAM,CAAC,EACnD,mBAAkB,MAAM,IAAe,EACvC,aAAa,CAAC,QAAQ,EAAE,oBAAoB,KAAK,IAAI,EACrD,kBAAkB,CAAC,OAAO,EAAE,MAAM,KAAK,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,KAC9D,OAAO,CAAC;IAAE,QAAQ,EAAE,oBAAoB,CAAC;IAAC,UAAU,EAAE,MAAM,GAAG,IAAI,CAAA;CAAE,CAwGvE,CAAC;AAgJF;;;;;;;;;;;;;;;GAeG;AACH,wBAAgB,iBAAiB,CAAC,MAAM,EAAE,iBAAiB,GAAG,wBAAwB,CA4rFrF;AAED,YAAY,EAAE,wBAAwB,EAAE,CAAC"}
1
+ {"version":3,"file":"sss-strategy.d.ts","sourceRoot":"","sources":["../src/sss-strategy.ts"],"names":[],"mappings":"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"}
package/dist/types.d.ts CHANGED
@@ -4,7 +4,7 @@
4
4
  * Re-exports provider-agnostic interfaces from @learncard/types
5
5
  * and defines SSS-specific types (recovery shapes, backup files, etc.).
6
6
  */
7
- export { AuthSessionError, type AuthProviderType, type AuthUser, type AuthProvider, type RecoveryMethodInfo, type RecoveryResult, type IdentityRecoverySession, type ServerKeyStatus, type SssActivationState, type KeyDerivationStrategy, type DidAuthVpSigner, type EscrowEnrollmentOptions, type EscrowEnrollmentState, type EscrowBlobStaleReason, type EscrowPinStatus, } from '@learncard/types';
7
+ export { AuthSessionError, type AuthProviderType, type AuthUser, type AuthProvider, type RecoveryMethodInfo, type RecoveryResult, type RevokeOtherDevicesResult, type IdentityRecoverySession, type ServerKeyStatus, type SssActivationState, type KeyDerivationStrategy, type DidAuthVpSigner, type EscrowEnrollmentOptions, type EscrowEnrollmentState, type EscrowBlobStaleReason, type EscrowPinStatus, } from '@learncard/types';
8
8
  import type { AuthProvider, AuthProviderType, KeyDerivationStrategy, RecoveryMethodInfo, SssActivationState } from '@learncard/types';
9
9
  export type ContactMethodType = 'email' | 'phone';
10
10
  export interface ContactMethod {
@@ -78,6 +78,28 @@ export type EscrowRecoveryStart = EscrowHoldStatus & {
78
78
  export declare class EscrowPinUnavailableError extends Error {
79
79
  constructor();
80
80
  }
81
+ /**
82
+ * What this client saw during one PIN sign-in flow (own-typos rule, E). A flow starts
83
+ * with the first PIN status read before the first attempt and ends when the sign-in
84
+ * completes; a new modal or app start begins a new flow.
85
+ */
86
+ export interface EscrowPinAttemptContext {
87
+ /**
88
+ * Verified wrong entries recorded against the PIN when the flow started, before
89
+ * any attempt here. Undefined when the server could not say (legacy record, failed
90
+ * read): treated as "wrong entries recorded".
91
+ */
92
+ priorWrongAttempts?: number;
93
+ /** Wrong entries this client itself submitted in this flow (mismatch responses). */
94
+ ownWrongAttempts: number;
95
+ /**
96
+ * Salt of the PIN generation the counts belong to (from the flow's first status).
97
+ * A status read during the release that shows another salt (a new PIN, or a
98
+ * same-PIN re-set elsewhere) means the counts describe a different PIN, so they
99
+ * are ignored and the stricter #1905 rule applies.
100
+ */
101
+ pinSalt?: string;
102
+ }
81
103
  /** A failed PIN attempt consumes its hold; another attempt must start a fresh hold. */
82
104
  export declare class EscrowPinMismatchError extends Error {
83
105
  readonly attemptsRemaining: number;
@@ -96,6 +118,14 @@ export declare class EscrowHoldRestartThrottledError extends Error {
96
118
  export declare class EscrowPinLockedError extends Error {
97
119
  constructor();
98
120
  }
121
+ /**
122
+ * A PIN sign-in released the key, but the released share version is no longer on the
123
+ * server (another device secured the account or recovered meanwhile). Nothing was
124
+ * stored; a revoke is never silently undone.
125
+ */
126
+ export declare class PinSignInStaleError extends Error {
127
+ constructor();
128
+ }
99
129
  export interface PasskeyRecoveryMethod {
100
130
  type: 'passkey';
101
131
  credentialId?: string;
@@ -118,6 +148,14 @@ export type RecoveryInput = {
118
148
  method: 'escrow-pin';
119
149
  pin: string;
120
150
  expectedDid?: string;
151
+ /** Verified recovery-email session; set only when no login is bound yet. */
152
+ recoverySessionToken?: string;
153
+ /**
154
+ * Own-typos rule (E): wrong entries this client observed in the current PIN
155
+ * sign-in flow. Omitted by older callers, which keeps the stricter rule (any
156
+ * recorded wrong entry blocks the same-PIN re-set).
157
+ */
158
+ pinAttempts?: EscrowPinAttemptContext;
121
159
  } | {
122
160
  method: 'escrow';
123
161
  holdId: string;
@@ -1 +1 @@
1
- {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAMH,OAAO,EACH,gBAAgB,EAChB,KAAK,gBAAgB,EACrB,KAAK,QAAQ,EACb,KAAK,YAAY,EACjB,KAAK,kBAAkB,EACvB,KAAK,cAAc,EACnB,KAAK,wBAAwB,EAC7B,KAAK,uBAAuB,EAC5B,KAAK,eAAe,EACpB,KAAK,kBAAkB,EACvB,KAAK,qBAAqB,EAC1B,KAAK,eAAe,EACpB,KAAK,uBAAuB,EAC5B,KAAK,qBAAqB,EAC1B,KAAK,qBAAqB,EAC1B,KAAK,eAAe,GACvB,MAAM,kBAAkB,CAAC;AAE1B,OAAO,KAAK,EACR,YAAY,EACZ,gBAAgB,EAChB,qBAAqB,EACrB,kBAAkB,EAClB,kBAAkB,EACrB,MAAM,kBAAkB,CAAC;AAM1B,MAAM,MAAM,iBAAiB,GAAG,OAAO,GAAG,OAAO,CAAC;AAElD,MAAM,WAAW,aAAa;IAC1B,IAAI,EAAE,iBAAiB,CAAC;IACxB,KAAK,EAAE,MAAM,CAAC;CACjB;AAED,MAAM,WAAW,mBAAmB;IAChC,IAAI,EAAE,gBAAgB,CAAC;IACvB,EAAE,EAAE,MAAM,CAAC;CACd;AAMD,MAAM,MAAM,aAAa,GAAG,OAAO,GAAG,UAAU,GAAG,UAAU,CAAC;AAE9D,eAAO,MAAM,cAAc,EAAE,SAAS,aAAa,EAA+C,CAAC;AAMnG;;;GAGG;AACH,MAAM,MAAM,kBAAkB,GAAG,SAAS,GAAG,QAAQ,GAAG,QAAQ,GAAG,OAAO,GAAG,QAAQ,CAAC;AAEtF,oEAAoE;AACpE,MAAM,MAAM,uBAAuB,GAC7B;IAAE,IAAI,EAAE,UAAU,CAAC;IAAC,gBAAgB,EAAE,MAAM,EAAE,CAAA;CAAE,GAChD;IACI,IAAI,EAAE,OAAO,CAAC;IACd,+EAA+E;IAC/E,kBAAkB,EAAE,CACd;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAC;QAAC,WAAW,CAAC,EAAE,MAAM,CAAA;KAAE,GAClE;QAAE,WAAW,EAAE,MAAM,CAAC;QAAC,IAAI,CAAC,EAAE,MAAM,CAAC;QAAC,IAAI,CAAC,EAAE,MAAM,CAAC;QAAC,IAAI,CAAC,EAAE,MAAM,CAAA;KAAE,CACzE,EAAE,CAAC;IACJ,qBAAqB,CAAC,EAAE,MAAM,CAAC;IAC/B,6DAA6D;IAC7D,QAAQ,CAAC,EAAE,MAAM,CAAC;CACrB,CAAC;AAER,0DAA0D;AAC1D,MAAM,WAAW,gBAAgB;IAC7B,MAAM,EAAE,MAAM,CAAC;IACf,aAAa,EAAE,MAAM,GAAG,KAAK,CAAC;IAC9B,MAAM,EAAE,SAAS,GAAG,WAAW,GAAG,WAAW,GAAG,SAAS,CAAC;IAC1D,WAAW,EAAE,MAAM,CAAC;IACpB,YAAY,EAAE,MAAM,CAAC;IACrB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,kGAAkG;IAClG,oBAAoB,CAAC,EAAE,OAAO,CAAC;IAC/B,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB;;wEAEoE;IACpE,UAAU,CAAC,EAAE,OAAO,oBAAoB,EAAE,oBAAoB,CAAC;CAClE;AAED,4FAA4F;AAC5F,MAAM,MAAM,mBAAmB,GAAG,gBAAgB,GAAG;IACjD,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,QAAQ,CAAC,EAAE;QACP,QAAQ,EAAE,OAAO,CAAC;QAClB,KAAK,EAAE,OAAO,0BAA0B,EAAE,qBAAqB,CAAC;KACnE,CAAC;IACF,6FAA6F;IAC7F,YAAY,CAAC,EAAE,OAAO,kBAAkB,EAAE,0BAA0B,CAAC;IACrE,WAAW,EAAE,MAAM,GAAG,IAAI,CAAC;IAC3B,yBAAyB,EAAE,MAAM,CAAC;IAClC,OAAO,CAAC,EAAE,MAAM,CAAC;CACpB,CAAC;AAEF,uDAAuD;AACvD,qBAAa,yBAA0B,SAAQ,KAAK;;CAKnD;AAED;;;;GAIG;AACH,MAAM,WAAW,uBAAuB;IACpC;;;;OAIG;IACH,kBAAkB,CAAC,EAAE,MAAM,CAAC;IAC5B,oFAAoF;IACpF,gBAAgB,EAAE,MAAM,CAAC;IACzB;;;;;OAKG;IACH,OAAO,CAAC,EAAE,MAAM,CAAC;CACpB;AAED,uFAAuF;AACvF,qBAAa,sBAAuB,SAAQ,KAAK;aACjB,iBAAiB,EAAE,MAAM;gBAAzB,iBAAiB,EAAE,MAAM;CAIxD;AAED,yFAAyF;AACzF,qBAAa,uBAAwB,SAAQ,KAAK;;CAKjD;AAED,iEAAiE;AACjE,qBAAa,+BAAgC,SAAQ,KAAK;aAC1B,UAAU,CAAC,EAAE,MAAM;gBAAnB,UAAU,CAAC,EAAE,MAAM,YAAA;CAIlD;AAED,4EAA4E;AAC5E,qBAAa,oBAAqB,SAAQ,KAAK;;CAK9C;AAED;;;;GAIG;AACH,qBAAa,mBAAoB,SAAQ,KAAK;;CAK7C;AAED,MAAM,WAAW,qBAAqB;IAClC,IAAI,EAAE,SAAS,CAAC;IAChB,YAAY,CAAC,EAAE,MAAM,CAAC;CACzB;AAED,MAAM,WAAW,wBAAwB;IACrC,IAAI,EAAE,QAAQ,CAAC;IACf,YAAY,EAAE,MAAM,CAAC;IACrB,QAAQ,EAAE,MAAM,CAAC;CACpB;AAED,MAAM,WAAW,4BAA4B;IACzC,IAAI,EAAE,QAAQ,CAAC;IACf,MAAM,EAAE,MAAM,CAAC;CAClB;AAED,kFAAkF;AAClF,MAAM,MAAM,cAAc,GACtB,qBAAqB,GAAG,wBAAwB,GAAG,4BAA4B,CAAC;AAEpF;;GAEG;AACH,MAAM,MAAM,aAAa,GACnB;IACI,MAAM,EAAE,YAAY,CAAC;IACrB,GAAG,EAAE,MAAM,CAAC;IACZ,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,4EAA4E;IAC5E,oBAAoB,CAAC,EAAE,MAAM,CAAC;IAC9B;;;;OAIG;IACH,WAAW,CAAC,EAAE,uBAAuB,CAAC;CACzC,GACD;IACI,MAAM,EAAE,QAAQ,CAAC;IACjB,MAAM,EAAE,MAAM,CAAC;IACf,WAAW,EAAE,MAAM,CAAC;IACpB,yBAAyB,EAAE,MAAM,CAAC;IAClC,+EAA+E;IAC/E,YAAY,CAAC,EAAE,OAAO,kBAAkB,EAAE,0BAA0B,CAAC;CACxE,GACD;IAAE,MAAM,EAAE,SAAS,CAAC;IAAC,YAAY,EAAE,MAAM,CAAA;CAAE,GAC3C;IAAE,MAAM,EAAE,QAAQ,CAAC;IAAC,MAAM,EAAE,MAAM,CAAA;CAAE,GACpC;IAAE,MAAM,EAAE,QAAQ,CAAC;IAAC,YAAY,EAAE,MAAM,CAAC;IAAC,QAAQ,EAAE,MAAM,CAAA;CAAE,GAC5D;IAAE,MAAM,EAAE,OAAO,CAAC;IAAC,UAAU,EAAE,MAAM,CAAA;CAAE,CAAC;AAE9C;;GAEG;AACH,MAAM,MAAM,kBAAkB,GACxB;IAAE,MAAM,EAAE,QAAQ,CAAC;IAAC,GAAG,CAAC,EAAE,MAAM,CAAA;CAAE,GAClC;IAAE,MAAM,EAAE,SAAS,CAAA;CAAE,GACrB;IAAE,MAAM,EAAE,QAAQ,CAAA;CAAE,GACpB;IAAE,MAAM,EAAE,QAAQ,CAAC;IAAC,QAAQ,EAAE,MAAM,CAAC;IAAC,GAAG,EAAE,MAAM,CAAA;CAAE,GACnD;IAAE,MAAM,EAAE,OAAO,CAAC;IAAC,KAAK,EAAE,MAAM,CAAA;CAAE,CAAC;AAEzC;;GAEG;AACH,MAAM,MAAM,mBAAmB,GACzB;IAAE,MAAM,EAAE,QAAQ,CAAC;IAAC,YAAY,EAAE,MAAM,CAAA;CAAE,GAC1C;IAAE,MAAM,EAAE,SAAS,CAAC;IAAC,YAAY,EAAE,MAAM,CAAA;CAAE,GAC3C;IACI,MAAM,EAAE,QAAQ,CAAC;IACjB,MAAM,EAAE,MAAM,CAAC;IACf,oBAAoB,EAAE,MAAM,EAAE,CAAC;IAC/B,uFAAuF;IACvF,oBAAoB,EAAE,MAAM,EAAE,EAAE,CAAC;CACpC,GACD;IAAE,MAAM,EAAE,QAAQ,CAAC;IAAC,UAAU,EAAE,UAAU,CAAA;CAAE,GAC5C;IAAE,MAAM,EAAE,OAAO,CAAA;CAAE,CAAC;AAE1B,uEAAuE;AACvE,MAAM,MAAM,yBAAyB,GAC/B;IAAE,MAAM,EAAE,QAAQ,CAAC;IAAC,cAAc,EAAE,MAAM,EAAE,CAAA;CAAE,GAC9C;IAAE,MAAM,EAAE,QAAQ,CAAC;IAAC,YAAY,EAAE,MAAM,CAAC;IAAC,QAAQ,EAAE,MAAM,CAAA;CAAE,GAC5D;IAAE,MAAM,EAAE,OAAO,CAAC;IAAC,IAAI,EAAE,MAAM,CAAA;CAAE,CAAC;AAMxC,MAAM,WAAW,cAAc;IAC3B,aAAa,EAAE,MAAM,CAAC;IACtB,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,CAAC,EAAE,MAAM,CAAC;CACjB;AAED,MAAM,WAAW,oBAAoB;IACjC,aAAa,EAAE,MAAM,CAAC;IACtB,YAAY,EAAE,MAAM,CAAC;IACrB,EAAE,EAAE,MAAM,CAAC;CACd;AAMD,MAAM,WAAW,aAAa;IAC1B,aAAa,EAAE,aAAa,CAAC;IAC7B,aAAa,EAAE,mBAAmB,EAAE,CAAC;IACrC,UAAU,EAAE,MAAM,CAAC;IACnB,UAAU,EAAE,MAAM,EAAE,CAAC;IACrB,WAAW,EAAE,UAAU,GAAG,KAAK,CAAC;IAChC,SAAS,CAAC,EAAE,oBAAoB,CAAC;IACjC,aAAa,EAAE,aAAa,CAAC;IAC7B,eAAe,EAAE,kBAAkB,EAAE,CAAC;IACtC,oBAAoB,EAAE,OAAO,CAAC;IAC9B,UAAU,CAAC,EAAE,IAAI,CAAC;IAClB,kBAAkB,CAAC,EAAE,kBAAkB,CAAC;IACxC,oBAAoB,CAAC,EAAE,IAAI,CAAC;IAC5B,SAAS,EAAE,IAAI,CAAC;IAChB,SAAS,EAAE,IAAI,CAAC;CACnB;AAED,MAAM,WAAW,UAAU;IACvB,OAAO,EAAE,CAAC,CAAC;IACX,SAAS,EAAE,MAAM,CAAC;IAClB,UAAU,EAAE,MAAM,CAAC;IACnB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,mFAAmF;IACnF,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,cAAc,EAAE;QACZ,UAAU,EAAE,MAAM,CAAC;QACnB,EAAE,EAAE,MAAM,CAAC;QACX,IAAI,EAAE,MAAM,CAAC;QACb,SAAS,EAAE;YACP,SAAS,EAAE,UAAU,CAAC;YACtB,QAAQ,EAAE,MAAM,CAAC;YACjB,UAAU,EAAE,MAAM,CAAC;YACnB,WAAW,EAAE,MAAM,CAAC;SACvB,CAAC;KACL,CAAC;CACL;AAMD,MAAM,WAAW,mBAAmB;IAChC,SAAS,EAAE,MAAM,CAAC;IAClB,YAAY,EAAE,YAAY,CAAC;IAC3B,gBAAgB,CAAC,EAAE,MAAM,CAAC;CAC7B;AAMD;;;GAGG;AACH,MAAM,MAAM,wBAAwB,GAAG,qBAAqB,CACxD,aAAa,EACb,kBAAkB,EAClB,mBAAmB,EACnB,yBAAyB,CAC5B,GAAG;IACA,4FAA4F;IAC5F,yBAAyB,CAAC,IAAI,OAAO,iBAAiB,EAAE,cAAc,GAAG,IAAI,CAAC;CACjF,CAAC;AAMF,0FAA0F;AAC1F,MAAM,WAAW,qBAAqB;IAClC,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,OAAO,IAAI,OAAO,CAAC,MAAM,CAAC,CAAC;IAC3B,UAAU,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;IAC5B,aAAa,IAAI,OAAO,CAAC;IACzB,WAAW,IAAI,OAAO,CAAC,OAAO,CAAC,CAAC;IAChC,UAAU,CAAC,IAAI,OAAO,CAAC,OAAO,CAAC,CAAC;IAChC,OAAO,CAAC,CAAC,UAAU,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;CAC/C;AAED,0FAA0F;AAC1F,MAAM,WAAW,wBAAyB,SAAQ,qBAAqB;IACnE,iBAAiB,CAAC,MAAM,EAAE,cAAc,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IACzD,kBAAkB,IAAI,OAAO,CAAC,kBAAkB,EAAE,CAAC,CAAC;IACpD,OAAO,CAAC,MAAM,EAAE,cAAc,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC;IACjD,gBAAgB,IAAI,OAAO,CAAC,aAAa,CAAC,CAAC;IAC3C,YAAY,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,UAAU,CAAC,CAAC;CACvD"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@learncard/sss-key-manager",
3
- "version": "0.2.5",
3
+ "version": "0.2.7",
4
4
  "description": "Shamir Secret Sharing key manager for LearnCard - replaces Web3Auth SFA",
5
5
  "main": "./dist/index.js",
6
6
  "module": "./dist/sss-key-manager.esm.js",
@@ -39,7 +39,7 @@
39
39
  "vitest": "4.1.11"
40
40
  },
41
41
  "dependencies": {
42
- "@learncard/types": "5.24.0",
42
+ "@learncard/types": "5.24.2",
43
43
  "@noble/ed25519": "^2.0.0",
44
44
  "@peculiar/x509": "^2.1.0",
45
45
  "@scure/bip39": "^1.2.1",
package/src/index.ts CHANGED
@@ -108,7 +108,12 @@ export type {
108
108
  } from './escrow-authority.types';
109
109
  export { verifyNitroAttestationDocument, NitroAttestationError } from './escrow-nitro-attestation';
110
110
  export type { NitroAttestationReason } from './escrow-nitro-attestation';
111
- export type { EscrowAttestationPolicy, EscrowHoldStatus, EscrowRecoveryStart } from './types';
111
+ export type {
112
+ EscrowAttestationPolicy,
113
+ EscrowHoldStatus,
114
+ EscrowPinAttemptContext,
115
+ EscrowRecoveryStart,
116
+ } from './types';
112
117
  export type {
113
118
  EscrowEnrollmentOptions,
114
119
  EscrowEnrollmentState,
@@ -121,6 +126,7 @@ export {
121
126
  EscrowPinThrottledError,
122
127
  EscrowHoldRestartThrottledError,
123
128
  EscrowPinUnavailableError,
129
+ PinSignInStaleError,
124
130
  } from './types';
125
131
  export {
126
132
  PIN_MIN_LENGTH,
@@ -234,6 +240,7 @@ export type {
234
240
  RecoveryMethodInfo,
235
241
  RecoveryInput,
236
242
  RecoveryResult,
243
+ RevokeOtherDevicesResult,
237
244
  RecoverySetupInput,
238
245
  RecoverySetupResult,
239
246
  RecoveryConfirmationInput,
@@ -20,6 +20,7 @@ import {
20
20
  import type { EscrowEnvelope } from './escrow-crypto';
21
21
  import { encodeEscrowEnrollmentIntent, getEscrowBlobIdentity } from './escrow-enrollment-intent';
22
22
  import { splitPrivateKey } from './sss';
23
+ import { derivePinProof } from './escrow-pin';
23
24
  import type {
24
25
  EscrowAuthorityRecord,
25
26
  EscrowAuthorityState,
@@ -151,6 +152,8 @@ const setup = async (legacyEnrolled = false) => {
151
152
  attemptsUsed: 0,
152
153
  };
153
154
  let version = 1;
155
+ // lca-api's charged PIN budget: like the server, every PIN release is charged.
156
+ let releaseCharges = 0;
154
157
  const recoveryShares = await splitPrivateKey(owner.seedHex);
155
158
  let authShare = recoveryShares.authShare;
156
159
  let pendingHold: EscrowHoldRecordLike | undefined;
@@ -180,6 +183,7 @@ const setup = async (legacyEnrolled = false) => {
180
183
  const calls: string[] = [];
181
184
  const nonces: string[] = [];
182
185
  const intents: SignedEscrowEnrollmentIntent[] = [];
186
+ const enrollments: Array<{ pinSalt?: unknown; clearPin?: unknown; pinVerifier?: string }> = [];
183
187
  const faults: {
184
188
  snapshotNonce?: boolean;
185
189
  returnedEnvelope?: boolean;
@@ -199,6 +203,17 @@ const setup = async (legacyEnrolled = false) => {
199
203
  oldServer?: boolean;
200
204
  /** A compromised lca-api forging post-rebind status for a healthy account. */
201
205
  forgedRebindStatus?: boolean;
206
+ /** lca-api's verified wrong-entry count for the current PIN, when reported. */
207
+ wrongPinAttempts?: number;
208
+ /**
209
+ * lca-api's escrow copy identity on /keys/auth-share: 'authority' reports the
210
+ * authority's current copy; a string is a stale copy (a lost PIN-operation write).
211
+ */
212
+ serverBlobIdentity?: 'authority' | string;
213
+ /** lca-api reports a PIN operation holding its lease (`escrowUpdating`). */
214
+ serverUpdating?: boolean;
215
+ /** lca-api refuses the next PIN change (e.g. a concurrent compare): 409. */
216
+ refusePinChange?: boolean;
202
217
  } = {};
203
218
  const signHold = async (record: EscrowHoldRecordLike): Promise<EscrowHoldRecordLike> => {
204
219
  const h = record.hold;
@@ -265,9 +280,31 @@ const setup = async (legacyEnrolled = false) => {
265
280
  ...(faults.oldServer
266
281
  ? {}
267
282
  : { priorEscrowEnrollment: !enrolled && !!faults.missingPinMetadata }),
283
+ ...(faults.serverBlobIdentity === undefined
284
+ ? {}
285
+ : {
286
+ escrowBlobIdentity:
287
+ faults.serverBlobIdentity === 'authority'
288
+ ? state.envelope &&
289
+ (await getEscrowBlobIdentity(state.envelope))
290
+ : faults.serverBlobIdentity,
291
+ }),
292
+ ...(faults.serverUpdating ? { escrowUpdating: true } : {}),
268
293
  ...(faults.missingPinMetadata
269
294
  ? { escrowPin: { state: 'none', enabled: false, attemptsRemaining: 0 } }
270
- : {}),
295
+ : faults.wrongPinAttempts !== undefined
296
+ ? {
297
+ escrowPin: {
298
+ state: 'enabled',
299
+ enabled: true,
300
+ attemptsRemaining: Math.max(
301
+ 0,
302
+ 10 - state.attemptsUsed - releaseCharges
303
+ ),
304
+ wrongAttempts: faults.wrongPinAttempts,
305
+ },
306
+ }
307
+ : {}),
271
308
  });
272
309
  }
273
310
  if (path === '/keys/escrow/attestation') return response({ attestation: {} });
@@ -297,6 +334,13 @@ const setup = async (legacyEnrolled = false) => {
297
334
  expect(signed.intent.expectedEnrollmentVersion).toBe(state.enrollmentVersion);
298
335
  intents.push(signed);
299
336
  if (faults.failEnrollment) throw new Error('Temporary enrollment outage');
337
+ if (faults.refusePinChange && signed.intent.pinAction === 'change') {
338
+ faults.refusePinChange = false;
339
+ return response(
340
+ { message: 'Automatic recovery changed; please refresh.' },
341
+ 409
342
+ );
343
+ }
300
344
  // Mirror escrow.enroll: rebind removes Mongo metadata, so carry cannot work.
301
345
  if (
302
346
  faults.missingPinMetadata &&
@@ -315,6 +359,11 @@ const setup = async (legacyEnrolled = false) => {
315
359
  parseEscrowEnvelope(body.envelope),
316
360
  keys.privateKey
317
361
  );
362
+ enrollments.push({
363
+ pinSalt: body.pinSalt,
364
+ clearPin: body.clearPin,
365
+ pinVerifier: plaintext.pinVerifier,
366
+ });
318
367
  if (signed.intent.action === 'carry')
319
368
  plaintext.pinVerifier = (
320
369
  await decryptEscrowBlob(state.envelope!, keys.privateKey)
@@ -333,6 +382,7 @@ const setup = async (legacyEnrolled = false) => {
333
382
  pinGeneration: state.pinGeneration + Number(pinChange),
334
383
  attemptsUsed: pinChange ? 0 : state.attemptsUsed,
335
384
  };
385
+ if (pinChange) releaseCharges = 0;
336
386
  enrolled = !!output;
337
387
  const receipt = await sign('commit', {
338
388
  commit: {
@@ -413,6 +463,9 @@ const setup = async (legacyEnrolled = false) => {
413
463
  requestedAt: new Date().toISOString(),
414
464
  releaseAfter: new Date(Date.now() + 604800000).toISOString(),
415
465
  holdRecord,
466
+ ...(body.releasePolicy === 'pin'
467
+ ? { pinSalt: 'AAAAAAAAAAAAAAAAAAAAAA==' }
468
+ : {}),
416
469
  });
417
470
  }
418
471
  if (path === '/keys/escrow/status') {
@@ -494,6 +547,7 @@ const setup = async (legacyEnrolled = false) => {
494
547
  }
495
548
  if (path === '/keys/escrow/complete') {
496
549
  if (!pendingHold) throw new Error('No test hold');
550
+ if (body.pinProof !== undefined) releaseCharges++;
497
551
  return response({
498
552
  sealedShare: await sealEscrowRelease(
499
553
  {
@@ -560,6 +614,7 @@ const setup = async (legacyEnrolled = false) => {
560
614
  calls,
561
615
  nonces,
562
616
  intents,
617
+ enrollments,
563
618
  faults,
564
619
  config,
565
620
  identity,
@@ -616,6 +671,244 @@ describe('Nitro recovery initiating-client bindings and measurement rollover', (
616
671
  expect(f.state()).toMatchObject({ status: 'active', hasPin: false });
617
672
  expect(f.calls.filter(call => call === 'PUT:/keys/auth-share')).toHaveLength(writes);
618
673
  });
674
+ it('keeps the account and re-sets the proven PIN with an owner-signed change after a PIN sign-in', async () => {
675
+ const f = await setup();
676
+ await f.strategy.ensureEscrowEnrollment!({
677
+ ...f.params,
678
+ options: { ...f.params.options, pin: '135790' },
679
+ });
680
+ f.spend();
681
+ // Charged attempts (e.g. earlier successful releases), but no verified wrong entry.
682
+ f.faults.wrongPinAttempts = 0;
683
+ const generation = f.state().pinGeneration;
684
+ const shareVersion = f.intents.at(-1)!.intent.shareVersion;
685
+ const writes = f.calls.filter(call => call === 'PUT:/keys/auth-share').length;
686
+ const recovered = await f.strategy.executeRecovery({
687
+ token: 'token',
688
+ providerType: 'firebase',
689
+ input: { method: 'escrow-pin', pin: '135790', expectedDid: owner.intent.did },
690
+ didFromPrivateKey: async () => owner.intent.did,
691
+ signDidAuthVp: f.params.signDidAuthVp,
692
+ options: f.params.options,
693
+ });
694
+ expect(recovered).toMatchObject({
695
+ escrowEnrolled: true,
696
+ escrowRecovery: true,
697
+ pinSignIn: { mode: 'kept', pinRefreshed: true, newPinRequired: false },
698
+ });
699
+ // Keep mode: no rebind, no re-split; the re-set targets the released version.
700
+ expect(f.calls).not.toContain('POST:/keys/recovery-session/rebind');
701
+ expect(f.calls.filter(call => call === 'PUT:/keys/auth-share')).toHaveLength(writes);
702
+ expect(f.intents.at(-1)?.intent).toMatchObject({
703
+ shareVersion,
704
+ action: 'replace',
705
+ pinAction: 'change',
706
+ recoveryEmail: 'owner@example.com',
707
+ recoveryLanguage: 'en',
708
+ });
709
+ expect(f.state()).toMatchObject({
710
+ status: 'active',
711
+ hasPin: true,
712
+ pinGeneration: generation + 1,
713
+ attemptsUsed: 0,
714
+ });
715
+ const enrollment = f.enrollments.at(-1)!;
716
+ expect(enrollment.clearPin).toBeUndefined();
717
+ expect(typeof enrollment.pinSalt).toBe('string');
718
+ expect(enrollment.pinVerifier).toBe(
719
+ await derivePinProof('135790', String(enrollment.pinSalt))
720
+ );
721
+ // The repair intent is not needed: a current PIN enrollment needs no change.
722
+ const intents = f.intents.length;
723
+ await expect(f.strategy.ensureEscrowEnrollment!(f.params)).resolves.toMatchObject({
724
+ enrolled: true,
725
+ changed: false,
726
+ });
727
+ expect(f.intents).toHaveLength(intents);
728
+ });
729
+ it('signs no PIN change after a PIN sign-in when wrong entries are recorded', async () => {
730
+ const f = await setup();
731
+ await f.strategy.ensureEscrowEnrollment!({
732
+ ...f.params,
733
+ options: { ...f.params.options, pin: '135790' },
734
+ });
735
+ f.spend();
736
+ f.faults.wrongPinAttempts = 2;
737
+ const before = { ...f.state() };
738
+ const intents = f.intents.length;
739
+ await expect(
740
+ f.strategy.executeRecovery({
741
+ token: 'token',
742
+ providerType: 'firebase',
743
+ input: { method: 'escrow-pin', pin: '135790', expectedDid: owner.intent.did },
744
+ didFromPrivateKey: async () => owner.intent.did,
745
+ signDidAuthVp: f.params.signDidAuthVp,
746
+ options: f.params.options,
747
+ })
748
+ ).resolves.toMatchObject({
749
+ escrowEnrolled: true,
750
+ pinSignIn: { mode: 'kept', pinRefreshed: false, newPinRequired: true },
751
+ });
752
+ // No owner-signed change: same PIN generation, the used attempts stand.
753
+ expect(f.intents).toHaveLength(intents);
754
+ expect(f.state()).toMatchObject({
755
+ pinGeneration: before.pinGeneration,
756
+ attemptsUsed: before.attemptsUsed,
757
+ });
758
+ });
759
+ it('reports a refused same-PIN refresh instead of a silent success, and keeps the PIN', async () => {
760
+ const f = await setup();
761
+ await f.strategy.ensureEscrowEnrollment!({
762
+ ...f.params,
763
+ options: { ...f.params.options, pin: '135790' },
764
+ });
765
+ f.spend();
766
+ f.faults.wrongPinAttempts = 0;
767
+ f.faults.refusePinChange = true;
768
+ const before = { ...f.state() };
769
+ const recovered = await f.strategy.executeRecovery({
770
+ token: 'token',
771
+ providerType: 'firebase',
772
+ input: { method: 'escrow-pin', pin: '135790', expectedDid: owner.intent.did },
773
+ didFromPrivateKey: async () => owner.intent.did,
774
+ signDidAuthVp: f.params.signDidAuthVp,
775
+ options: f.params.options,
776
+ });
777
+ expect(recovered).toMatchObject({
778
+ escrowEnrolled: true,
779
+ pinSignIn: {
780
+ mode: 'kept',
781
+ pinRefreshed: false,
782
+ newPinRequired: false,
783
+ pinRefreshFailed: true,
784
+ },
785
+ });
786
+ // Nothing committed: the PIN keeps its generation and reduced budget.
787
+ expect(f.state()).toMatchObject({
788
+ pinGeneration: before.pinGeneration,
789
+ attemptsUsed: before.attemptsUsed,
790
+ });
791
+ });
792
+ it('does not report a refresh failure when none was attempted', async () => {
793
+ const f = await setup();
794
+ await f.strategy.ensureEscrowEnrollment!({
795
+ ...f.params,
796
+ options: { ...f.params.options, pin: '135790' },
797
+ });
798
+ f.spend();
799
+ f.faults.wrongPinAttempts = 2;
800
+ const recovered = await f.strategy.executeRecovery({
801
+ token: 'token',
802
+ providerType: 'firebase',
803
+ input: { method: 'escrow-pin', pin: '135790', expectedDid: owner.intent.did },
804
+ didFromPrivateKey: async () => owner.intent.did,
805
+ signDidAuthVp: f.params.signDidAuthVp,
806
+ options: f.params.options,
807
+ });
808
+ expect(recovered.pinSignIn).not.toHaveProperty('pinRefreshFailed');
809
+ });
810
+ it('treats an enrollment whose lca-api copy differs from the authority as unenrolled', async () => {
811
+ const f = await setup();
812
+ await f.strategy.ensureEscrowEnrollment!(f.params);
813
+ expect(f.state()).toMatchObject({ status: 'active', hasPin: false });
814
+ f.faults.serverBlobIdentity = 'authority';
815
+ const intents = f.intents.length;
816
+ // Matching copies: nothing to repair.
817
+ await expect(f.strategy.ensureEscrowEnrollment!(f.params)).resolves.toMatchObject({
818
+ enrolled: true,
819
+ changed: false,
820
+ });
821
+ expect(f.intents).toHaveLength(intents);
822
+ // lca-api kept an old copy the authority already replaced: re-enroll (no PIN).
823
+ f.faults.serverBlobIdentity = 'ef'.repeat(32);
824
+ await expect(f.strategy.ensureEscrowEnrollment!(f.params)).resolves.toMatchObject({
825
+ enrolled: true,
826
+ changed: true,
827
+ });
828
+ expect(f.intents.length).toBeGreaterThan(intents);
829
+ });
830
+ it('leaves a mismatch alone while lca-api reports a PIN operation in progress', async () => {
831
+ const f = await setup();
832
+ await f.strategy.ensureEscrowEnrollment!({
833
+ ...f.params,
834
+ options: { ...f.params.options, pin: '135790' },
835
+ });
836
+ // Authority committed, lca-api's lease-held write not landed yet.
837
+ f.faults.serverBlobIdentity = 'ef'.repeat(32);
838
+ f.faults.serverUpdating = true;
839
+ const intents = f.intents.length;
840
+ await expect(f.strategy.ensureEscrowEnrollment!(f.params)).resolves.toEqual({
841
+ enrolled: true,
842
+ changed: false,
843
+ });
844
+ expect(f.intents).toHaveLength(intents);
845
+ // Once the lease is gone, a copy still left behind is a real mismatch.
846
+ f.faults.serverUpdating = false;
847
+ await expect(f.strategy.ensureEscrowEnrollment!(f.params)).resolves.toEqual({
848
+ enrolled: false,
849
+ reason: 'pin-reset-required',
850
+ });
851
+ });
852
+ it('asks for a new PIN, signing nothing, when a PIN-protected copy is stale in lca-api', async () => {
853
+ const f = await setup();
854
+ await f.strategy.ensureEscrowEnrollment!({
855
+ ...f.params,
856
+ options: { ...f.params.options, pin: '135790' },
857
+ });
858
+ f.faults.serverBlobIdentity = 'ef'.repeat(32);
859
+ const intents = f.intents.length;
860
+ const writes = f.calls.filter(call => call === 'PUT:/keys/auth-share').length;
861
+ await expect(f.strategy.ensureEscrowEnrollment!(f.params)).resolves.toEqual({
862
+ enrolled: false,
863
+ reason: 'pin-reset-required',
864
+ });
865
+ expect(f.intents).toHaveLength(intents);
866
+ expect(f.calls.filter(call => call === 'PUT:/keys/auth-share')).toHaveLength(writes);
867
+ // A user-chosen PIN repairs it.
868
+ await f.strategy.setEscrowPin!({ ...f.params, pin: '246813' });
869
+ expect(f.intents.at(-1)?.intent).toMatchObject({ pinAction: 'change' });
870
+ });
871
+ it('re-reads lca-api before repairing, so a copy settled by the state read is not re-enrolled', async () => {
872
+ const f = await setup();
873
+ await f.strategy.ensureEscrowEnrollment!({
874
+ ...f.params,
875
+ options: { ...f.params.options, pin: '135790' },
876
+ });
877
+ f.faults.serverBlobIdentity = 'ef'.repeat(32);
878
+ // lca-api adopts the authority's copy while serving the authority-state read.
879
+ f.faults.beforeSnapshot = async () => {
880
+ f.faults.serverBlobIdentity = 'authority';
881
+ };
882
+ const intents = f.intents.length;
883
+ await expect(f.strategy.ensureEscrowEnrollment!(f.params)).resolves.toMatchObject({
884
+ enrolled: true,
885
+ changed: false,
886
+ });
887
+ expect(f.intents).toHaveLength(intents);
888
+ });
889
+ it('still clears the PIN after a hold recovery', async () => {
890
+ const f = await setup();
891
+ await f.strategy.ensureEscrowEnrollment!({
892
+ ...f.params,
893
+ options: { ...f.params.options, pin: '135790' },
894
+ });
895
+ const hold = await f.strategy.startEscrowRecovery!({
896
+ recoverySessionToken: 'otp-session',
897
+ expectedDid: owner.intent.did,
898
+ });
899
+ await f.strategy.executeRecovery({
900
+ token: '',
901
+ providerType: 'firebase',
902
+ input: { method: 'escrow', ...hold, resumeToken: hold.resumeToken! },
903
+ didFromPrivateKey: async () => owner.intent.did,
904
+ });
905
+ await expect(f.strategy.completeIdentityRecovery!(f.params)).resolves.toMatchObject({
906
+ escrowEnrolled: true,
907
+ });
908
+ expect(f.intents.at(-1)?.intent).toMatchObject({ action: 'replace', pinAction: 'clear' });
909
+ expect(f.enrollments.at(-1)?.pinSalt).toBeUndefined();
910
+ expect(f.state()).toMatchObject({ status: 'active', hasPin: false });
911
+ });
619
912
  it('treats a successful recovered clear-PIN enrollment as satisfying the repair', async () => {
620
913
  const f = await setup();
621
914
  await f.strategy.ensureEscrowEnrollment!({