sinfactura-types 1.10.262 → 1.10.263

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
@@ -280,8 +280,16 @@ declare global {
280
280
  * - `wrong_totp` — the step-up code was wrong.
281
281
  * - `totp_replay` — an already-used code was presented again and rejected.
282
282
  * - `totp_locked` — brute-force lockout active on the TOTP leg.
283
+ * - `enrollment_required` — the credentials were correct and the store's
284
+ * mandatory-2FA grace window has closed on a user who never enrolled. Like
285
+ * `requires_2fa` this is NOT a completed login, but it is the opposite
286
+ * diagnosis: `requires_2fa` means somebody stalled at a factor they HAVE,
287
+ * this means they have none to present. ⚠️ Emitted on OPERATOR logins only
288
+ * — the mandate is scoped to operator surfaces, and there is no customer
289
+ * enrolment endpoint for a web mandate to be satisfiable against, so a
290
+ * `kind: 'CUSTOMER'` row can never carry it.
283
291
  */
284
- type LoginOutcome = 'success' | 'wrong_password' | 'disabled' | 'blocked' | 'requires_2fa' | 'wrong_totp' | 'totp_replay' | 'totp_locked';
292
+ type LoginOutcome = 'success' | 'wrong_password' | 'disabled' | 'blocked' | 'requires_2fa' | 'wrong_totp' | 'totp_replay' | 'totp_locked' | 'enrollment_required';
285
293
  /**
286
294
  * One row of `GET /auth?mode=login-history[&days=N]` — a storefront
287
295
  * customer's own login audit trail. The stored row reaches the wire
package/dist/store.d.ts CHANGED
@@ -499,6 +499,55 @@ declare global {
499
499
  */
500
500
  nextSequence?: number;
501
501
  };
502
+ /**
503
+ * Per-store mandatory-2FA obligation for OPERATOR logins.
504
+ *
505
+ * ⚠️ **It lives on the store row and NOT in the plan entitlement map,
506
+ * and that placement is the whole design.** The `mandatory2fa` FeatureKey
507
+ * gates which TIERS may impose the obligation; this leaf records whether a
508
+ * store actually has. Every other FeatureKey GRANTS a capability, so losing
509
+ * it withdraws something. This one OBLIGES — so resolving it from the
510
+ * entitlement map would mean `graceSweep` silently UN-mandating 2FA when it
511
+ * writes `planTier: 'basico'` on a delinquent store at day 14. A security
512
+ * posture does not lapse because an invoice did.
513
+ *
514
+ * Verified rather than assumed: `graceSweep` writes only `status`,
515
+ * `planTier`, `canceledFromTier`, `canceledAt` and `updatedAt`, and writes
516
+ * them to the SUBSCRIPTION row — it touches neither `totp` nor store
517
+ * config. So an obligation kept here survives the downgrade **by
518
+ * construction**, with no special case for anyone to remember and nothing
519
+ * to re-check when the sweep changes.
520
+ *
521
+ * Forward-only: absent means no obligation, and nothing backfills it.
522
+ */
523
+ mandatory2fa?: {
524
+ /** Whether operator logins for this store require an enrolled second factor. */
525
+ enabled: boolean;
526
+ /**
527
+ * ms-epoch the obligation was last turned ON. The grace window runs from
528
+ * here.
529
+ *
530
+ * ⚠️ BE-stamped, never client-writable. A client that could set this
531
+ * could set it far enough in the past to close the window on every
532
+ * operator at once — which is a lockout, not a configuration change.
533
+ */
534
+ since: number;
535
+ /**
536
+ * Days after `since` during which an unenrolled operator still receives a
537
+ * full session — flagged `mustEnroll2fa` — rather than being refused.
538
+ *
539
+ * ⚠️ **The window is what makes the mandate satisfiable at all, not a
540
+ * courtesy.** `/auth/2fa/enroll` and `/auth/2fa/verify-enrollment` both sit
541
+ * behind the `userToken` authorizer, and the shipped step-up challenge is
542
+ * stateless — it mints no partial token, the client just re-submits the
543
+ * credential. So refusing to mint a token leaves an unenrolled operator
544
+ * with no way to reach the endpoint that would let them comply: the
545
+ * mandate would brick its own remedy. Enrolment happens inside the window;
546
+ * once it closes the refusal is safe, because anyone who missed it is
547
+ * recovered by an ADMIN toggling `enabled` back off.
548
+ */
549
+ graceDays: number;
550
+ };
502
551
  };
503
552
  ecommerce?: Ecommerce;
504
553
  photoURL: string;
@@ -83,7 +83,7 @@ declare global {
83
83
  * quietly missing a feature), but it means the caller must be updated in the
84
84
  * same change. Adding a key is never only additive downstream.
85
85
  */
86
- type FeatureKey = 'maxOrdersMonth' | 'maxInvoicesMonth' | 'maxProducts' | 'maxUsers' | 'maxCustomers' | 'maxStores' | 'priceListsMax' | 'afipInvoicing' | 'suppliers' | 'domesticPayments' | 'stripePayments' | 'cashManagement' | 'multiStore' | 'importExport' | 'advancedReports' | 'customBranding' | 'prioritySupport' | 'whatsappCommerce' | 'aiFeatures' | 'mobileApp' | 'customDomain' | 'advancedPricing' | 'marketplaceChannels' | 'storefront' | 'loyalty' | 'marketing';
86
+ type FeatureKey = 'maxOrdersMonth' | 'maxInvoicesMonth' | 'maxProducts' | 'maxUsers' | 'maxCustomers' | 'maxStores' | 'priceListsMax' | 'afipInvoicing' | 'suppliers' | 'domesticPayments' | 'stripePayments' | 'cashManagement' | 'multiStore' | 'importExport' | 'advancedReports' | 'customBranding' | 'prioritySupport' | 'whatsappCommerce' | 'aiFeatures' | 'mobileApp' | 'customDomain' | 'advancedPricing' | 'marketplaceChannels' | 'storefront' | 'loyalty' | 'marketing' | 'mandatory2fa';
87
87
  /** Resolved entitlements for a specific tenant (matrix + overrides applied). */
88
88
  type ResolvedEntitlements = Record<FeatureKey, Entitlement>;
89
89
  /**
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "sinfactura-types",
3
- "version": "1.10.262",
3
+ "version": "1.10.263",
4
4
  "description": "Shared wire and entity contracts for the SINFACTURA platform.",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",