sinfactura-types 1.10.509 → 1.10.511

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/auth.d.ts CHANGED
@@ -408,21 +408,32 @@ declare global {
408
408
  * on `message`. `revoked` echoes the `jti` that was ended.
409
409
  *
410
410
  * `logged_out_self` means the caller revoked the session it is currently
411
- * using: the response also clears the refresh cookie, so the client is now
412
- * signed out and must route to login instead of re-rendering the device
413
- * list. `session_revoked` means some OTHER device was ended and this
414
- * session continues.
411
+ * using — any row of the caller's own session family: the response also
412
+ * clears the refresh cookie, so the client is now signed out and must route
413
+ * to login instead of re-rendering the device list. `session_revoked` means
414
+ * some OTHER device was ended and this session continues.
415
+ *
416
+ * ⚠️ `logged_out_self` can carry `complete: false`: the cookie was cleared,
417
+ * but the sweep of the caller's own session did not finish, so a copy of it
418
+ * may still be live elsewhere. Say so, and suggest signing in again and
419
+ * ending the other sessions — do not report a clean sign-out. The field is
420
+ * absent when the sweep finished.
421
+ *
422
+ * ⚠️ An unfinished sweep of ANOTHER session is NOT a 200. It answers **502**
423
+ * with `error: 'REVOKE_INCOMPLETE'` and a `revokedCount`: that device may
424
+ * still be signed in. Read the outcome from the STATUS and surface a retry —
425
+ * safe, but not guaranteed to finish, so do not retry in a loop.
415
426
  *
416
427
  * ⚠️ A miss does NOT always answer 404. When the session lookup was capped
417
428
  * — the same shortfall `CustomerSessionsResponse.complete: false` reports —
418
429
  * and the target `jti` was not among the rows read, the endpoint answers
419
- * **409** with `error: 'session_lookup_incomplete'` INSTEAD of a 404, on
430
+ * **409** with `error: 'SESSION_LOOKUP_INCOMPLETE'` INSTEAD of a 404, on
420
431
  * purpose: a miss on a capped list is not proof of absence.
421
432
  *
422
433
  * Treating that 409 as "already gone" is the dangerous handling. It tells
423
434
  * someone their stolen device was killed while its token is still live. The
424
435
  * 409 means "ask again" — retry, or fall back to `revoke-others`, which
425
- * needs no lookup. Only a genuine 404 `session_unknown` means the session
436
+ * needs no lookup. Only a genuine 404 `SESSION_UNKNOWN` means the session
426
437
  * does not exist.
427
438
  */
428
439
  type RevokeSessionResult = {
@@ -431,14 +442,18 @@ declare global {
431
442
  } | {
432
443
  message: 'logged_out_self';
433
444
  revoked: string;
445
+ /** Present (and `false`) only when the sweep of the caller's own session did not finish. */
446
+ complete?: false;
434
447
  };
435
448
  /**
436
- * `POST /auth { mode: 'revoke-others' }` — the 200 body. Every session in
437
- * the caller's partition except the one making the request is dead.
449
+ * `POST /auth { mode: 'revoke-others' }` — the 200 body. The sweep ended
450
+ * every session in the caller's partition but the caller's own, and its last
451
+ * read found none left. ⚠️ That is the strongest answer the api can give, not
452
+ * proof: a refresh landing during the sweep can still leave its session live.
438
453
  *
439
454
  * `complete` is the literal `true` and carries no information on its own,
440
455
  * because an INCOMPLETE sweep is deliberately NOT a 200: it answers **502**
441
- * with `error: 'revoke_incomplete'` and a `revokedCount` that is a PARTIAL
456
+ * with `error: 'REVOKE_INCOMPLETE'` and a `revokedCount` that is a PARTIAL
442
457
  * count. Some refresh tokens survived that sweep and are STILL USABLE.
443
458
  *
444
459
  * So read the outcome from the STATUS, never from the count. On 200 the
@@ -1091,6 +1106,13 @@ declare global {
1091
1106
  * customer to link rather than showing a generic failure; the relay address
1092
1107
  * itself is deliberately not carried, since it is re-derivable from the token
1093
1108
  * on the next sign-in.
1109
+ *
1110
+ * ⚠️ `link-sign-in-method` and `unlink-sign-in-method` also require the
1111
+ * presented refresh token's OWN row to be live, so they can answer three
1112
+ * `RefreshErrorCode` members before any of the above: `401
1113
+ * REFRESH_TOKEN_UNKNOWN` (missing, mismatched or already-ended row), `409
1114
+ * CONCURRENT_ROTATION` (a rotation under 30 s ago — retry once with the new
1115
+ * token) and `401 FAMILY_REVOKED` (a replay — the session is revoked as theft).
1094
1116
  */
1095
1117
  export declare const SIGN_IN_METHOD_ERROR_CODES: readonly ["SIGN_IN_METHOD_LAST_CREDENTIAL", "SIGN_IN_METHOD_NOT_LINKED", "SIGN_IN_METHOD_ALREADY_LINKED", "SIGN_IN_PROVIDER_REFUSED", "SIGN_IN_UID_MISMATCH", "SIGN_IN_IDENTITY_MISMATCH", "SIGN_IN_IDENTITY_UNVERIFIED", "INVALID_ID_TOKEN", "SIGN_IN_PROVIDER_UNSUPPORTED", "SIGN_IN_METHODS_CONFLICT", "SIGN_IN_RELAY_IDENTITY_UNRESOLVED"];
1096
1118
  export type SignInMethodErrorCode = (typeof SIGN_IN_METHOD_ERROR_CODES)[number];
@@ -1335,9 +1357,10 @@ export type TwoFactorManagementErrorCode = (typeof TWO_FACTOR_MANAGEMENT_ERROR_C
1335
1357
  export declare const PASSKEY_ERROR_CODES: readonly ["PASSKEY_DISABLED", "IMPERSONATION_PASSKEY_FORBIDDEN", "TOTP_REQUIRED_BEFORE_PASSKEY", "PASSKEY_LIMIT_REACHED", "INVALID_CHALLENGE", "CHALLENGE_ALREADY_USED", "PASSKEY_REGISTRATION_INVALID", "PASSKEY_ALREADY_REGISTERED", "PASSKEY_NOT_FOUND", "USER_NOT_FOUND", "INVALID_2FA_CODE", "2FA_LOCKED"];
1336
1358
  export type PasskeyErrorCode = (typeof PASSKEY_ERROR_CODES)[number];
1337
1359
  /**
1338
- * Refusals from the session-management legs — `stacks/lambdas/auth/_revokeSession.ts`
1339
- * and `_revokeOthers.ts`. Shared by the operator and customer hosts, which run
1340
- * the same handlers.
1360
+ * Refusals from the session-management legs — `revoke-session` and
1361
+ * `revoke-others` on both the operator host (`stacks/lambdas/auth/`) and the
1362
+ * customer host (`stacks/web/lambdas/auth/`), two handler pairs that answer the
1363
+ * same codes.
1341
1364
  *
1342
1365
  * - `SESSION_LOOKUP_INCOMPLETE` · 409 — the session list was capped before the
1343
1366
  * target `jti` was reached, so the api cannot prove the session does not
@@ -1345,9 +1368,26 @@ export type PasskeyErrorCode = (typeof PASSKEY_ERROR_CODES)[number];
1345
1368
  * reason: one means "not found", the other means "not looked at". Collapsing
1346
1369
  * them tells a user a device is gone when it may still be live.
1347
1370
  * - `SESSION_UNKNOWN` · 404 — genuinely absent. Not retryable.
1348
- * - `REVOKE_INCOMPLETE` · 502 — a revoke-others sweep ended partway. Some
1349
- * sessions WERE revoked; the body carries `revokedCount`. Retry to finish —
1350
- * the operation is idempotent over the sessions already ended.
1371
+ * - `REVOKE_INCOMPLETE` · 502 — a revoke-others sweep, or a revoke-session sweep
1372
+ * of ANOTHER session, ended partway. (Revoking the caller's OWN session — any
1373
+ * row of its family — answers `200 logged_out_self` with `complete: false`
1374
+ * instead: the delivery is cleared, so there is nothing to retry with.) Some sessions WERE revoked; the body carries `revokedCount`. A
1375
+ * retry is safe (idempotent over the sessions already ended) and finishes a
1376
+ * sweep a failed write or a racing rotation cut short — but it reads from
1377
+ * the top again, so it is not guaranteed to finish; do not retry in a loop.
1378
+ *
1379
+ * ⚠️ Both legs can also answer three `RefreshErrorCode` members: they require
1380
+ * the presented token's OWN row to be live, so a missing, mismatched or
1381
+ * already-ended row is `401 REFRESH_TOKEN_UNKNOWN`, a row a rotation stamped
1382
+ * under 30 s ago is `409 CONCURRENT_ROTATION` (retry once with the new token),
1383
+ * and a row a rotation stamped longer ago is a replay — the session is revoked
1384
+ * as theft and the answer is `401 FAMILY_REVOKED`.
1385
+ *
1386
+ * ⚠️ The READ modes on the same refresh credential — `GET /auth?mode=sessions`,
1387
+ * `?mode=login-history` and the customer host's `?mode=sign-in-methods` — make
1388
+ * the same check and answer the same two 401s (a replay revokes the session
1389
+ * there too). They never answer the 409: a row a rotation stamped under 30 s
1390
+ * ago is served.
1351
1391
  */
1352
1392
  export declare const SESSION_ACTION_ERROR_CODES: readonly ["SESSION_LOOKUP_INCOMPLETE", "SESSION_UNKNOWN", "REVOKE_INCOMPLETE"];
1353
1393
  export type SessionActionErrorCode = (typeof SESSION_ACTION_ERROR_CODES)[number];
package/dist/auth.js CHANGED
@@ -59,6 +59,13 @@
59
59
  * customer to link rather than showing a generic failure; the relay address
60
60
  * itself is deliberately not carried, since it is re-derivable from the token
61
61
  * on the next sign-in.
62
+ *
63
+ * ⚠️ `link-sign-in-method` and `unlink-sign-in-method` also require the
64
+ * presented refresh token's OWN row to be live, so they can answer three
65
+ * `RefreshErrorCode` members before any of the above: `401
66
+ * REFRESH_TOKEN_UNKNOWN` (missing, mismatched or already-ended row), `409
67
+ * CONCURRENT_ROTATION` (a rotation under 30 s ago — retry once with the new
68
+ * token) and `401 FAMILY_REVOKED` (a replay — the session is revoked as theft).
62
69
  */
63
70
  export const SIGN_IN_METHOD_ERROR_CODES = [
64
71
  'SIGN_IN_METHOD_LAST_CREDENTIAL',
@@ -354,9 +361,10 @@ export const PASSKEY_ERROR_CODES = [
354
361
  '2FA_LOCKED',
355
362
  ];
356
363
  /**
357
- * Refusals from the session-management legs — `stacks/lambdas/auth/_revokeSession.ts`
358
- * and `_revokeOthers.ts`. Shared by the operator and customer hosts, which run
359
- * the same handlers.
364
+ * Refusals from the session-management legs — `revoke-session` and
365
+ * `revoke-others` on both the operator host (`stacks/lambdas/auth/`) and the
366
+ * customer host (`stacks/web/lambdas/auth/`), two handler pairs that answer the
367
+ * same codes.
360
368
  *
361
369
  * - `SESSION_LOOKUP_INCOMPLETE` · 409 — the session list was capped before the
362
370
  * target `jti` was reached, so the api cannot prove the session does not
@@ -364,9 +372,26 @@ export const PASSKEY_ERROR_CODES = [
364
372
  * reason: one means "not found", the other means "not looked at". Collapsing
365
373
  * them tells a user a device is gone when it may still be live.
366
374
  * - `SESSION_UNKNOWN` · 404 — genuinely absent. Not retryable.
367
- * - `REVOKE_INCOMPLETE` · 502 — a revoke-others sweep ended partway. Some
368
- * sessions WERE revoked; the body carries `revokedCount`. Retry to finish —
369
- * the operation is idempotent over the sessions already ended.
375
+ * - `REVOKE_INCOMPLETE` · 502 — a revoke-others sweep, or a revoke-session sweep
376
+ * of ANOTHER session, ended partway. (Revoking the caller's OWN session — any
377
+ * row of its family — answers `200 logged_out_self` with `complete: false`
378
+ * instead: the delivery is cleared, so there is nothing to retry with.) Some sessions WERE revoked; the body carries `revokedCount`. A
379
+ * retry is safe (idempotent over the sessions already ended) and finishes a
380
+ * sweep a failed write or a racing rotation cut short — but it reads from
381
+ * the top again, so it is not guaranteed to finish; do not retry in a loop.
382
+ *
383
+ * ⚠️ Both legs can also answer three `RefreshErrorCode` members: they require
384
+ * the presented token's OWN row to be live, so a missing, mismatched or
385
+ * already-ended row is `401 REFRESH_TOKEN_UNKNOWN`, a row a rotation stamped
386
+ * under 30 s ago is `409 CONCURRENT_ROTATION` (retry once with the new token),
387
+ * and a row a rotation stamped longer ago is a replay — the session is revoked
388
+ * as theft and the answer is `401 FAMILY_REVOKED`.
389
+ *
390
+ * ⚠️ The READ modes on the same refresh credential — `GET /auth?mode=sessions`,
391
+ * `?mode=login-history` and the customer host's `?mode=sign-in-methods` — make
392
+ * the same check and answer the same two 401s (a replay revokes the session
393
+ * there too). They never answer the 409: a row a rotation stamped under 30 s
394
+ * ago is served.
370
395
  */
371
396
  export const SESSION_ACTION_ERROR_CODES = [
372
397
  'SESSION_LOOKUP_INCOMPLETE',
package/dist/cjs/auth.js CHANGED
@@ -62,6 +62,13 @@ exports.SESSION_ACTION_ERROR_CODES = exports.PASSKEY_ERROR_CODES = exports.TWO_F
62
62
  * customer to link rather than showing a generic failure; the relay address
63
63
  * itself is deliberately not carried, since it is re-derivable from the token
64
64
  * on the next sign-in.
65
+ *
66
+ * ⚠️ `link-sign-in-method` and `unlink-sign-in-method` also require the
67
+ * presented refresh token's OWN row to be live, so they can answer three
68
+ * `RefreshErrorCode` members before any of the above: `401
69
+ * REFRESH_TOKEN_UNKNOWN` (missing, mismatched or already-ended row), `409
70
+ * CONCURRENT_ROTATION` (a rotation under 30 s ago — retry once with the new
71
+ * token) and `401 FAMILY_REVOKED` (a replay — the session is revoked as theft).
65
72
  */
66
73
  exports.SIGN_IN_METHOD_ERROR_CODES = [
67
74
  'SIGN_IN_METHOD_LAST_CREDENTIAL',
@@ -357,9 +364,10 @@ exports.PASSKEY_ERROR_CODES = [
357
364
  '2FA_LOCKED',
358
365
  ];
359
366
  /**
360
- * Refusals from the session-management legs — `stacks/lambdas/auth/_revokeSession.ts`
361
- * and `_revokeOthers.ts`. Shared by the operator and customer hosts, which run
362
- * the same handlers.
367
+ * Refusals from the session-management legs — `revoke-session` and
368
+ * `revoke-others` on both the operator host (`stacks/lambdas/auth/`) and the
369
+ * customer host (`stacks/web/lambdas/auth/`), two handler pairs that answer the
370
+ * same codes.
363
371
  *
364
372
  * - `SESSION_LOOKUP_INCOMPLETE` · 409 — the session list was capped before the
365
373
  * target `jti` was reached, so the api cannot prove the session does not
@@ -367,9 +375,26 @@ exports.PASSKEY_ERROR_CODES = [
367
375
  * reason: one means "not found", the other means "not looked at". Collapsing
368
376
  * them tells a user a device is gone when it may still be live.
369
377
  * - `SESSION_UNKNOWN` · 404 — genuinely absent. Not retryable.
370
- * - `REVOKE_INCOMPLETE` · 502 — a revoke-others sweep ended partway. Some
371
- * sessions WERE revoked; the body carries `revokedCount`. Retry to finish —
372
- * the operation is idempotent over the sessions already ended.
378
+ * - `REVOKE_INCOMPLETE` · 502 — a revoke-others sweep, or a revoke-session sweep
379
+ * of ANOTHER session, ended partway. (Revoking the caller's OWN session — any
380
+ * row of its family — answers `200 logged_out_self` with `complete: false`
381
+ * instead: the delivery is cleared, so there is nothing to retry with.) Some sessions WERE revoked; the body carries `revokedCount`. A
382
+ * retry is safe (idempotent over the sessions already ended) and finishes a
383
+ * sweep a failed write or a racing rotation cut short — but it reads from
384
+ * the top again, so it is not guaranteed to finish; do not retry in a loop.
385
+ *
386
+ * ⚠️ Both legs can also answer three `RefreshErrorCode` members: they require
387
+ * the presented token's OWN row to be live, so a missing, mismatched or
388
+ * already-ended row is `401 REFRESH_TOKEN_UNKNOWN`, a row a rotation stamped
389
+ * under 30 s ago is `409 CONCURRENT_ROTATION` (retry once with the new token),
390
+ * and a row a rotation stamped longer ago is a replay — the session is revoked
391
+ * as theft and the answer is `401 FAMILY_REVOKED`.
392
+ *
393
+ * ⚠️ The READ modes on the same refresh credential — `GET /auth?mode=sessions`,
394
+ * `?mode=login-history` and the customer host's `?mode=sign-in-methods` — make
395
+ * the same check and answer the same two 401s (a replay revokes the session
396
+ * there too). They never answer the 409: a row a rotation stamped under 30 s
397
+ * ago is served.
373
398
  */
374
399
  exports.SESSION_ACTION_ERROR_CODES = [
375
400
  'SESSION_LOOKUP_INCOMPLETE',
@@ -1014,9 +1014,10 @@ declare global {
1014
1014
  /**
1015
1015
  * `data` of the STOREFRONT erasure (`POST /user` mode `anonymize`): the
1016
1016
  * operator result minus the notes counts, which would tell the subject how
1017
- * many operator notes existed about them.
1017
+ * many operator notes existed about them, and minus the RMA reason counts,
1018
+ * for the same reason (the rejection reasons are operator-written).
1018
1019
  */
1019
- type WebAnonymizeCustomerResult = Omit<AnonymizeCustomerResult, 'notesErased' | 'notesEraseComplete'>;
1020
+ type WebAnonymizeCustomerResult = Omit<AnonymizeCustomerResult, 'notesErased' | 'notesEraseComplete' | 'rmaReasonsErased' | 'rmaEraseComplete'>;
1020
1021
  /**
1021
1022
  * The outcome of a Ley 25.326 art. 16 erasure (`anonymizeCustomer`). The
1022
1023
  * row is anonymised in place and KEPT — see `Customer.anonymizedAt`.
@@ -1093,6 +1094,20 @@ declare global {
1093
1094
  * On BOTH wires — counts only.
1094
1095
  */
1095
1096
  contactsEraseComplete: boolean;
1097
+ /**
1098
+ * `RMA#` rows of this customer whose free text (`requestReason`,
1099
+ * `rejectionReason`) this erasure REMOVEd. The RMA row itself is kept —
1100
+ * it is the store's record of a return. Operator wire only.
1101
+ */
1102
+ rmaReasonsErased: number;
1103
+ /**
1104
+ * `false` when the RMA rows could not be read or written to the end, so a
1105
+ * reason may remain. Re-issuing the erasure re-runs the step; BOTH erasure
1106
+ * handlers write a deduped `ERROR` row (`CUSTOMER_ANONYMIZE_RMA_INCOMPLETE`).
1107
+ * Operator wire only — the storefront response omits both
1108
+ * (`WebAnonymizeCustomerResult`).
1109
+ */
1110
+ rmaEraseComplete: boolean;
1096
1111
  /**
1097
1112
  * The subject's `ORDER#` rows whose frozen recipient this erasure scrubbed —
1098
1113
  * `customer` reduced to `{ customerId }`, `deliveryAddress` removed, the
@@ -631,7 +631,16 @@ export interface TenantActiveSessionsResponse {
631
631
  sessions: TenantActiveSessionSummary[];
632
632
  complete: boolean;
633
633
  }
634
- /** Revoke-all result. Idempotent: revoking with no sessions is `revoked: 0`, not an error. */
634
+ /**
635
+ * Revoke-all result. Idempotent: revoking with no sessions is `revoked: 0`, not an error.
636
+ *
637
+ * ⚠️ A 200 always carries `complete: true`. A sweep that did not finish answers
638
+ * `502 REVOKE_INCOMPLETE` with this same `{ revoked, failed, complete: false }`
639
+ * beside `error` — some of the user's sessions may still be live, so branch on
640
+ * the STATUS. A retry is safe and finishes a sweep a failed write or a racing
641
+ * rotation cut short, but it reads from the top again and is not guaranteed to
642
+ * finish.
643
+ */
635
644
  export interface TenantUserSessionsRevokeResponse {
636
645
  revoked: number;
637
646
  failed: number;
package/dist/rma.d.ts CHANGED
@@ -70,23 +70,36 @@ declare global {
70
70
  /**
71
71
  * The order's customer. Present so an operator can find the RMA by
72
72
  * customer; a walk-in order's synthetic system customer is a legal value.
73
+ * ABSENT when the order carries no `customerId` (a legacy order) — never
74
+ * `''`, which DynamoDB refuses as a `PK-customerId` index key.
75
+ *
76
+ * Optional, and it has to be: `Order.customerId` is itself optional, the
77
+ * row cannot store an empty string, and a `''` synthesised at read time
78
+ * would be a customer id that names nobody in a `string` slot — the
79
+ * failure `Order.customerId` documents. Refusing the return instead would
80
+ * leave every legacy order un-returnable.
73
81
  */
74
- customerId: string;
82
+ customerId?: string;
75
83
  status: RmaStatus;
76
84
  items: RmaItem[];
77
85
  /** Operator who entered the request — typically off a phone call. */
78
86
  requestedBy: string;
79
87
  requestedAt: number;
80
- /** Free text from the customer, relayed by the operator. Bounded. */
88
+ /**
89
+ * Free text from the customer, relayed by the operator. Bounded. Not
90
+ * written for a customer whose data was erased, and REMOVEd from the row
91
+ * by an erasure (Ley 25.326 art. 16).
92
+ */
81
93
  requestReason?: string;
82
94
  authorizedBy?: string;
83
95
  authorizedAt?: number;
84
96
  rejectedBy?: string;
85
97
  rejectedAt?: number;
86
98
  /**
87
- * Required on `rejected` — enforced by the handler, not by this type.
88
- * Optional here because it is absent on every other status, and a
89
- * required field would make the union unrepresentable.
99
+ * Required in the reject REQUEST (`RmaRejectInput`), not on the row: a
100
+ * `rejected` RMA carries it unless its customer's data was erased — it is
101
+ * not written for an already-erased customer, and an erasure REMOVEs it
102
+ * (Ley 25.326 art. 16). Absent on every other status.
90
103
  */
91
104
  rejectionReason?: string;
92
105
  receivedAt?: number;
@@ -1207,6 +1207,13 @@ declare global {
1207
1207
  event: 'User Sessions Revoked';
1208
1208
  target_user_id: string;
1209
1209
  revoked_count: number;
1210
+ /**
1211
+ * Whether the sweep FINISHED: its last read of the target's sessions found
1212
+ * none left to end. `false` means some may still be live — the operator was
1213
+ * answered `502 REVOKE_INCOMPLETE`. Absent on rows written before it was
1214
+ * recorded.
1215
+ */
1216
+ complete?: boolean;
1210
1217
  }
1211
1218
  /**
1212
1219
  * A staff user was REMOVED by anonymising their row in place
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "sinfactura-types",
3
- "version": "1.10.509",
3
+ "version": "1.10.511",
4
4
  "description": "Shared wire and entity contracts for the SINFACTURA platform.",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",