@absolutejs/auth 0.49.2 → 0.50.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/dist/index.js CHANGED
@@ -885,7 +885,10 @@ var providers = defineProviders({
885
885
  url: "https://services.leadconnectorhq.com/users/me"
886
886
  },
887
887
  scopeRequired: true,
888
- subject: ["id"],
888
+ subject: ["locationId"],
889
+ subjectBySource: {
890
+ tokenResponse: ["locationId"]
891
+ },
889
892
  subjectType: "string",
890
893
  tokenRequest: {
891
894
  authIn: "body",
@@ -3341,6 +3344,12 @@ var resolveOAuthAuthorization = async ({
3341
3344
  providerConfiguration: providers[authProvider],
3342
3345
  source: "idToken"
3343
3346
  });
3347
+ } else if (providers[authProvider].subjectBySource?.tokenResponse) {
3348
+ userIdentity = normalizeProviderIdentity({
3349
+ identity: tokenResponse,
3350
+ providerConfiguration: providers[authProvider],
3351
+ source: "tokenResponse"
3352
+ });
3344
3353
  } else if (authProvider === "withings") {
3345
3354
  userIdentity = { userid: tokenResponse.body.userid };
3346
3355
  accessToken = tokenResponse.body.access_token;
@@ -4345,6 +4354,7 @@ var DEFAULT_SMS_CODE_LENGTH = 6;
4345
4354
  var SMS_CODE_TTL_MINUTES = 5;
4346
4355
  var DEFAULT_SMS_CODE_TTL_MS = SMS_CODE_TTL_MINUTES * SECONDS_IN_A_MINUTE * MILLISECONDS_IN_A_SECOND;
4347
4356
  var DEFAULT_SMS_MAX_ATTEMPTS = 3;
4357
+ var DEFAULT_TOTP_MAX_ATTEMPTS = 5;
4348
4358
 
4349
4359
  // src/mfa/secret.ts
4350
4360
  init_crypto();
@@ -4512,7 +4522,8 @@ var mfaChallenge = ({
4512
4522
  sessionDurationMs = DEFAULT_MFA_SESSION_TTL_MS,
4513
4523
  smsCodeLength = DEFAULT_SMS_CODE_LENGTH,
4514
4524
  smsCodeTtlMs = DEFAULT_SMS_CODE_TTL_MS,
4515
- smsMaxAttempts = DEFAULT_SMS_MAX_ATTEMPTS
4525
+ smsMaxAttempts = DEFAULT_SMS_MAX_ATTEMPTS,
4526
+ totpMaxAttempts = DEFAULT_TOTP_MAX_ATTEMPTS
4516
4527
  }) => new Elysia13().use(sessionStore()).post(challengeRoute, async ({
4517
4528
  body: { action, code, factor },
4518
4529
  cookie: { user_session_id },
@@ -4611,12 +4622,24 @@ var mfaChallenge = ({
4611
4622
  if (code === undefined) {
4612
4623
  return status("Unauthorized", "Invalid MFA code");
4613
4624
  }
4625
+ if ((enrollment.totpFailedAttempts ?? 0) >= totpMaxAttempts) {
4626
+ await onMfaChallengeError?.({
4627
+ error: new Error("mfa_totp_attempts_exceeded"),
4628
+ userId: getUserId(user)
4629
+ });
4630
+ return status("Unauthorized", "Too many attempts");
4631
+ }
4614
4632
  const totpValid = enrollment.totpVerified && enrollment.totpSecretCiphertext ? await verifyTotp({
4615
4633
  secret: await decryptTotpSecret(enrollment.totpSecretCiphertext, encryptionKey),
4616
4634
  token: code
4617
4635
  }) : false;
4618
4636
  const remainingBackupHashes = totpValid ? undefined : await consumeBackupCode(code, enrollment.backupCodeHashes);
4619
4637
  if (!totpValid && remainingBackupHashes === undefined) {
4638
+ await mfaStore.saveEnrollment({
4639
+ ...enrollment,
4640
+ totpFailedAttempts: (enrollment.totpFailedAttempts ?? 0) + 1,
4641
+ updatedAt: Date.now()
4642
+ });
4620
4643
  await onMfaChallengeError?.({
4621
4644
  error: new Error("invalid_mfa_code"),
4622
4645
  userId: getUserId(user)
@@ -4627,6 +4650,7 @@ var mfaChallenge = ({
4627
4650
  ...enrollment,
4628
4651
  backupCodeHashes: remainingBackupHashes ?? enrollment.backupCodeHashes,
4629
4652
  lastUsedAt: Date.now(),
4653
+ totpFailedAttempts: 0,
4630
4654
  updatedAt: Date.now()
4631
4655
  });
4632
4656
  return promote();
@@ -23194,6 +23218,7 @@ var mfaEnrollmentsTable = pgTable("auth_mfa_enrollments", {
23194
23218
  sms_pending_code_hash: text("sms_pending_code_hash"),
23195
23219
  sms_phone: varchar("sms_phone", { length: PHONE_LENGTH }),
23196
23220
  sms_verified: boolean("sms_verified").notNull().default(false),
23221
+ totp_failed_attempts: smallint("totp_failed_attempts").notNull().default(0),
23197
23222
  totp_secret_ciphertext: text("totp_secret_ciphertext"),
23198
23223
  totp_verified: boolean("totp_verified").notNull().default(false),
23199
23224
  updated_at_ms: bigint("updated_at_ms", { mode: "number" }).notNull(),
@@ -23208,6 +23233,7 @@ var toEnrollment = (row) => ({
23208
23233
  smsPendingCodeHash: row.sms_pending_code_hash ?? undefined,
23209
23234
  smsPhone: row.sms_phone ?? undefined,
23210
23235
  smsVerified: row.sms_verified,
23236
+ totpFailedAttempts: row.totp_failed_attempts,
23211
23237
  totpSecretCiphertext: row.totp_secret_ciphertext ?? undefined,
23212
23238
  totpVerified: row.totp_verified,
23213
23239
  updatedAt: row.updated_at_ms,
@@ -23236,6 +23262,7 @@ var createPostgresMfaStore = (db) => ({
23236
23262
  sms_pending_code_hash: enrollment.smsPendingCodeHash ?? null,
23237
23263
  sms_phone: enrollment.smsPhone ?? null,
23238
23264
  sms_verified: enrollment.smsVerified,
23265
+ totp_failed_attempts: enrollment.totpFailedAttempts ?? 0,
23239
23266
  totp_secret_ciphertext: enrollment.totpSecretCiphertext ?? null,
23240
23267
  totp_verified: enrollment.totpVerified,
23241
23268
  updated_at_ms: enrollment.updatedAt,
@@ -26564,6 +26591,10 @@ var mfaSmsColumnsMigration = {
26564
26591
  ].join(`
26565
26592
  `)
26566
26593
  };
26594
+ var mfaTotpLockoutMigration = {
26595
+ id: "0003_totp_lockout",
26596
+ sql: 'ALTER TABLE "auth_mfa_enrollments" ADD COLUMN IF NOT EXISTS "totp_failed_attempts" smallint NOT NULL DEFAULT 0;'
26597
+ };
26567
26598
  var blockMigrations = {
26568
26599
  adaptive: initMigration("adaptive", [knownDevicesTable, loginHistoryTable]),
26569
26600
  apikeys: initMigration("apikeys", [
@@ -26587,7 +26618,8 @@ var blockMigrations = {
26587
26618
  block: "mfa",
26588
26619
  migrations: [
26589
26620
  ...initMigration("mfa", [mfaEnrollmentsTable]).migrations,
26590
- mfaSmsColumnsMigration
26621
+ mfaSmsColumnsMigration,
26622
+ mfaTotpLockoutMigration
26591
26623
  ]
26592
26624
  },
26593
26625
  oidc: initMigration("oidc", [
@@ -27863,6 +27895,7 @@ export {
27863
27895
  DEFAULT_VP_ROUTE,
27864
27896
  DEFAULT_VERIFICATION_TOKEN_TTL_MS,
27865
27897
  DEFAULT_VCI_ROUTE,
27898
+ DEFAULT_TOTP_MAX_ATTEMPTS,
27866
27899
  DEFAULT_TOKEN_ROUTE,
27867
27900
  DEFAULT_STATUS_ROUTE,
27868
27901
  DEFAULT_SSO_SESSION_TTL_MS,
@@ -27894,5 +27927,5 @@ export {
27894
27927
  AuthIdentityConflictError
27895
27928
  };
27896
27929
 
27897
- //# debugId=F74A795104D4323264756E2164756E21
27930
+ //# debugId=47718768D4F1D77064756E2164756E21
27898
27931
  //# sourceMappingURL=index.js.map