@absolutejs/auth 0.57.9 → 0.58.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/README.md CHANGED
@@ -89,6 +89,39 @@ The concrete SimpleWebAuthn adapter follows the same boundary:
89
89
  import { createSimpleWebAuthnAdapter } from '@absolutejs/auth/webauthn';
90
90
  ```
91
91
 
92
+ ### Provider-managed phone verification
93
+
94
+ `verificationProvider` is the vendor-neutral challenge lifecycle used by SMS
95
+ MFA. Auth owns enrollment, resend cooldowns, failed-attempt policy, audit, and
96
+ session promotion; the provider generates, delivers, and checks the code.
97
+
98
+ ```ts
99
+ import { auth } from '@absolutejs/auth/server';
100
+ import { createTwilioVerificationProvider } from '@absolutejs/auth-twilio';
101
+ import { Twilio } from 'twilio';
102
+
103
+ const authPlugin = await auth({
104
+ // credentials, mfa, stores, providersConfiguration, etc.
105
+ verificationProvider: createTwilioVerificationProvider({
106
+ client: new Twilio(
107
+ process.env.TWILIO_ACCOUNT_SID!,
108
+ process.env.TWILIO_AUTH_TOKEN!
109
+ ),
110
+ verifyServiceSid: process.env.TWILIO_VERIFY_SERVICE_SID!,
111
+ serviceTokenTtlMs: 10 * 60 * 1000
112
+ })
113
+ });
114
+ ```
115
+
116
+ Without a provider, `mfa.onSendSmsCode` keeps codes local and accepts any
117
+ application-owned delivery system such as `@absolutejs/dispatch`. Its payload
118
+ includes `purpose` and `userId` for safe templates, audit correlation, and
119
+ tenant routing. Provider and local-code sends share the default 30-second
120
+ per-enrollment resend cooldown; configure `mfa.smsResendCooldownMs` when needed.
121
+
122
+ Production databases must run the `mfa` migration block after upgrading to add
123
+ the durable cooldown timestamp.
124
+
92
125
  ### Delegated AI agents
93
126
 
94
127
  The `agentAuth` block provides a standards-first agent identity layer. It
@@ -2688,12 +2688,15 @@ var mfaEnrollmentsTable = pgTable9("auth_mfa_enrollments", {
2688
2688
  backup_code_hashes: jsonb3("backup_code_hashes").$type().notNull().default([]),
2689
2689
  created_at_ms: bigint7("created_at_ms", { mode: "number" }).notNull(),
2690
2690
  last_used_at_ms: bigint7("last_used_at_ms", { mode: "number" }),
2691
+ sms_code_sent_at_ms: bigint7("sms_code_sent_at_ms", { mode: "number" }),
2691
2692
  sms_failed_attempts: smallint("sms_failed_attempts").notNull().default(0),
2692
2693
  sms_pending_code_expires_at_ms: bigint7("sms_pending_code_expires_at_ms", {
2693
2694
  mode: "number"
2694
2695
  }),
2695
2696
  sms_pending_code_hash: text4("sms_pending_code_hash"),
2697
+ sms_pending_purpose: text4("sms_pending_purpose").$type(),
2696
2698
  sms_phone: varchar9("sms_phone", { length: PHONE_LENGTH }),
2699
+ sms_provider_reference: text4("sms_provider_reference"),
2697
2700
  sms_verified: boolean3("sms_verified").notNull().default(false),
2698
2701
  totp_failed_attempts: smallint("totp_failed_attempts").notNull().default(0),
2699
2702
  totp_secret_ciphertext: text4("totp_secret_ciphertext"),
@@ -3240,6 +3243,15 @@ var mfaTotpLockoutMigration = {
3240
3243
  id: "0003_totp_lockout",
3241
3244
  sql: 'ALTER TABLE "auth_mfa_enrollments" ADD COLUMN IF NOT EXISTS "totp_failed_attempts" smallint NOT NULL DEFAULT 0;'
3242
3245
  };
3246
+ var mfaSmsDeliveryPolicyMigration = {
3247
+ id: "0004_sms_delivery_policy",
3248
+ sql: [
3249
+ 'ALTER TABLE "auth_mfa_enrollments" ADD COLUMN IF NOT EXISTS "sms_code_sent_at_ms" bigint;',
3250
+ 'ALTER TABLE "auth_mfa_enrollments" ADD COLUMN IF NOT EXISTS "sms_pending_purpose" text;',
3251
+ 'ALTER TABLE "auth_mfa_enrollments" ADD COLUMN IF NOT EXISTS "sms_provider_reference" text;'
3252
+ ].join(`
3253
+ `)
3254
+ };
3243
3255
  var oidcResourceAudienceMigration = {
3244
3256
  id: "0002_resource_audience",
3245
3257
  sql: [
@@ -3294,7 +3306,8 @@ var blockMigrations = {
3294
3306
  migrations: [
3295
3307
  ...initMigration("mfa", [mfaEnrollmentsTable]).migrations,
3296
3308
  mfaSmsColumnsMigration,
3297
- mfaTotpLockoutMigration
3309
+ mfaTotpLockoutMigration,
3310
+ mfaSmsDeliveryPolicyMigration
3298
3311
  ]
3299
3312
  },
3300
3313
  oidc: {
@@ -3531,5 +3544,5 @@ var main = async () => {
3531
3544
  };
3532
3545
  await main();
3533
3546
 
3534
- //# debugId=CF3F65D5B7AF923D64756E2164756E21
3547
+ //# debugId=19A5010083F8B61F64756E2164756E21
3535
3548
  //# sourceMappingURL=migrate.js.map