@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 +33 -0
- package/dist/cli/migrate.js +15 -2
- package/dist/cli/migrate.js.map +4 -4
- package/dist/index.d.ts +10 -4
- package/dist/index.js +221 -24
- package/dist/index.js.map +13 -12
- package/dist/manifest.js +8 -1
- package/dist/manifest.js.map +3 -3
- package/dist/manifest.json +9 -0
- package/dist/mfa/challenge.d.ts +4 -2
- package/dist/mfa/config.d.ts +6 -0
- package/dist/mfa/postgresMfaStore.d.ts +45 -0
- package/dist/mfa/routes.d.ts +9 -4
- package/dist/mfa/sms.d.ts +38 -5
- package/dist/mfa/types.d.ts +4 -0
- package/dist/server.d.ts +1 -0
- package/dist/server.js +221 -25
- package/dist/server.js.map +14 -13
- package/dist/types.d.ts +5 -1
- package/dist/verification/types.d.ts +47 -0
- package/package.json +1 -1
package/dist/server.js
CHANGED
|
@@ -6849,6 +6849,7 @@ var DEFAULT_SMS_CODE_LENGTH = 6;
|
|
|
6849
6849
|
var SMS_CODE_TTL_MINUTES = 5;
|
|
6850
6850
|
var DEFAULT_SMS_CODE_TTL_MS = SMS_CODE_TTL_MINUTES * SECONDS_IN_A_MINUTE * MILLISECONDS_IN_A_SECOND;
|
|
6851
6851
|
var DEFAULT_SMS_MAX_ATTEMPTS = 3;
|
|
6852
|
+
var DEFAULT_SMS_RESEND_COOLDOWN_MS = 30 * MILLISECONDS_IN_A_SECOND;
|
|
6852
6853
|
var DEFAULT_TOTP_MAX_ATTEMPTS = 5;
|
|
6853
6854
|
|
|
6854
6855
|
// src/mfa/secret.ts
|
|
@@ -6859,6 +6860,20 @@ var encryptTotpSecret = (secret, encryptionKey) => encryptionKey ? encryptSecret
|
|
|
6859
6860
|
// src/mfa/sms.ts
|
|
6860
6861
|
init_crypto();
|
|
6861
6862
|
import { Elysia as Elysia17, t as t11 } from "elysia";
|
|
6863
|
+
|
|
6864
|
+
// src/verification/types.ts
|
|
6865
|
+
class VerificationProviderError extends Error {
|
|
6866
|
+
kind;
|
|
6867
|
+
provider;
|
|
6868
|
+
constructor(input) {
|
|
6869
|
+
super(input.message, { cause: input.cause });
|
|
6870
|
+
this.name = "VerificationProviderError";
|
|
6871
|
+
this.kind = input.kind;
|
|
6872
|
+
this.provider = input.provider;
|
|
6873
|
+
}
|
|
6874
|
+
}
|
|
6875
|
+
|
|
6876
|
+
// src/mfa/sms.ts
|
|
6862
6877
|
var DECIMAL_RADIX2 = 10;
|
|
6863
6878
|
var MASK_VISIBLE_DIGITS = 4;
|
|
6864
6879
|
var E164_PATTERN = /^\+[1-9]\d{7,14}$/u;
|
|
@@ -6873,28 +6888,83 @@ var issueSmsCode = async (codeLength, ttlMs) => {
|
|
|
6873
6888
|
const expiresAt = Date.now() + ttlMs;
|
|
6874
6889
|
return { code, expiresAt, hash };
|
|
6875
6890
|
};
|
|
6891
|
+
var checkWithVerificationProvider = async (provider, input) => {
|
|
6892
|
+
try {
|
|
6893
|
+
return { result: await provider.check(input) };
|
|
6894
|
+
} catch (error) {
|
|
6895
|
+
const mapped = mapVerificationProviderError(error);
|
|
6896
|
+
if (mapped === undefined)
|
|
6897
|
+
throw error;
|
|
6898
|
+
return { error: mapped };
|
|
6899
|
+
}
|
|
6900
|
+
};
|
|
6876
6901
|
var isE164Phone = (phone) => E164_PATTERN.test(phone);
|
|
6877
6902
|
var issueAndStoreSmsCode = async ({
|
|
6878
6903
|
codeLength,
|
|
6879
6904
|
enrollment,
|
|
6880
6905
|
mfaStore,
|
|
6881
6906
|
onSendSmsCode,
|
|
6882
|
-
|
|
6907
|
+
purpose,
|
|
6908
|
+
verificationProvider,
|
|
6909
|
+
ttlMs,
|
|
6910
|
+
userId
|
|
6883
6911
|
}) => {
|
|
6884
6912
|
const phone = enrollment.smsPhone;
|
|
6885
6913
|
if (phone === undefined)
|
|
6886
6914
|
return;
|
|
6915
|
+
if (verificationProvider !== undefined) {
|
|
6916
|
+
const started = await verificationProvider.start({
|
|
6917
|
+
channel: "sms",
|
|
6918
|
+
purpose,
|
|
6919
|
+
subject: userId,
|
|
6920
|
+
to: phone
|
|
6921
|
+
});
|
|
6922
|
+
await mfaStore.saveEnrollment({
|
|
6923
|
+
...enrollment,
|
|
6924
|
+
smsCodeSentAt: Date.now(),
|
|
6925
|
+
smsFailedAttempts: 0,
|
|
6926
|
+
smsPendingCodeExpiresAt: started.expiresAt,
|
|
6927
|
+
smsPendingCodeHash: undefined,
|
|
6928
|
+
smsPendingPurpose: purpose,
|
|
6929
|
+
smsProviderReference: started.reference,
|
|
6930
|
+
updatedAt: Date.now()
|
|
6931
|
+
});
|
|
6932
|
+
return started.expiresAt;
|
|
6933
|
+
}
|
|
6887
6934
|
const { code, expiresAt, hash } = await issueSmsCode(codeLength, ttlMs);
|
|
6888
6935
|
await mfaStore.saveEnrollment({
|
|
6889
6936
|
...enrollment,
|
|
6937
|
+
smsCodeSentAt: Date.now(),
|
|
6890
6938
|
smsFailedAttempts: 0,
|
|
6891
6939
|
smsPendingCodeExpiresAt: expiresAt,
|
|
6892
6940
|
smsPendingCodeHash: hash,
|
|
6941
|
+
smsPendingPurpose: purpose,
|
|
6942
|
+
smsProviderReference: undefined,
|
|
6893
6943
|
updatedAt: Date.now()
|
|
6894
6944
|
});
|
|
6895
|
-
await onSendSmsCode?.({ code, expiresAt, phone });
|
|
6945
|
+
await onSendSmsCode?.({ code, expiresAt, phone, purpose, userId });
|
|
6896
6946
|
return expiresAt;
|
|
6897
6947
|
};
|
|
6948
|
+
var mapVerificationProviderError = (error) => {
|
|
6949
|
+
if (!(error instanceof VerificationProviderError))
|
|
6950
|
+
return;
|
|
6951
|
+
if (error.kind === "rate_limited") {
|
|
6952
|
+
return {
|
|
6953
|
+
message: "Verification provider rate limit reached",
|
|
6954
|
+
status: "Too Many Requests"
|
|
6955
|
+
};
|
|
6956
|
+
}
|
|
6957
|
+
if (error.kind === "invalid_destination") {
|
|
6958
|
+
return {
|
|
6959
|
+
message: "Phone number cannot receive verification codes",
|
|
6960
|
+
status: "Bad Request"
|
|
6961
|
+
};
|
|
6962
|
+
}
|
|
6963
|
+
return {
|
|
6964
|
+
message: "Verification provider unavailable",
|
|
6965
|
+
status: "Service Unavailable"
|
|
6966
|
+
};
|
|
6967
|
+
};
|
|
6898
6968
|
var maskPhone = (phone) => {
|
|
6899
6969
|
const visible = phone.slice(-MASK_VISIBLE_DIGITS);
|
|
6900
6970
|
const maskedLength = Math.max(phone.length - MASK_VISIBLE_DIGITS, 0);
|
|
@@ -6906,9 +6976,11 @@ var mfaSmsRoutes = ({
|
|
|
6906
6976
|
mfaStore,
|
|
6907
6977
|
onMfaEnrolled,
|
|
6908
6978
|
onSendSmsCode,
|
|
6979
|
+
verificationProvider,
|
|
6909
6980
|
smsCodeLength = DEFAULT_SMS_CODE_LENGTH,
|
|
6910
6981
|
smsCodeTtlMs = DEFAULT_SMS_CODE_TTL_MS,
|
|
6911
6982
|
smsMaxAttempts = DEFAULT_SMS_MAX_ATTEMPTS,
|
|
6983
|
+
smsResendCooldownMs = DEFAULT_SMS_RESEND_COOLDOWN_MS,
|
|
6912
6984
|
smsSetupRoute = "/auth/mfa/sms/setup",
|
|
6913
6985
|
smsVerifyRoute = "/auth/mfa/sms/verify"
|
|
6914
6986
|
}) => new Elysia17().use(sessionStore()).post(smsSetupRoute, async ({
|
|
@@ -6917,7 +6989,7 @@ var mfaSmsRoutes = ({
|
|
|
6917
6989
|
status,
|
|
6918
6990
|
store: { session }
|
|
6919
6991
|
}) => {
|
|
6920
|
-
if (onSendSmsCode === undefined) {
|
|
6992
|
+
if (onSendSmsCode === undefined && verificationProvider === undefined) {
|
|
6921
6993
|
return status("Not Implemented", "SMS MFA is not configured");
|
|
6922
6994
|
}
|
|
6923
6995
|
const userSession = await loadSessionFromSource({
|
|
@@ -6934,21 +7006,51 @@ var mfaSmsRoutes = ({
|
|
|
6934
7006
|
const userId = getUserId(userSession.user);
|
|
6935
7007
|
const existing = await mfaStore.getEnrollment(userId);
|
|
6936
7008
|
const now = Date.now();
|
|
6937
|
-
|
|
7009
|
+
if (existing?.smsCodeSentAt !== undefined && now - existing.smsCodeSentAt < smsResendCooldownMs) {
|
|
7010
|
+
return status("Too Many Requests", "SMS resend cooldown active");
|
|
7011
|
+
}
|
|
7012
|
+
let started;
|
|
7013
|
+
try {
|
|
7014
|
+
started = verificationProvider ? await verificationProvider.start({
|
|
7015
|
+
channel: "sms",
|
|
7016
|
+
purpose: "mfa_enrollment",
|
|
7017
|
+
subject: userId,
|
|
7018
|
+
to: phone
|
|
7019
|
+
}) : undefined;
|
|
7020
|
+
} catch (error) {
|
|
7021
|
+
const mapped = mapVerificationProviderError(error);
|
|
7022
|
+
if (mapped === undefined)
|
|
7023
|
+
throw error;
|
|
7024
|
+
return status(mapped.status, mapped.message);
|
|
7025
|
+
}
|
|
7026
|
+
const local = started ? undefined : await issueSmsCode(smsCodeLength, smsCodeTtlMs);
|
|
6938
7027
|
await mfaStore.saveEnrollment({
|
|
6939
7028
|
backupCodeHashes: existing?.backupCodeHashes ?? [],
|
|
6940
7029
|
createdAt: existing?.createdAt ?? now,
|
|
7030
|
+
lastUsedAt: existing?.lastUsedAt,
|
|
7031
|
+
smsCodeSentAt: now,
|
|
6941
7032
|
smsFailedAttempts: 0,
|
|
6942
|
-
smsPendingCodeExpiresAt: expiresAt,
|
|
6943
|
-
smsPendingCodeHash: hash,
|
|
7033
|
+
smsPendingCodeExpiresAt: started?.expiresAt ?? local?.expiresAt,
|
|
7034
|
+
smsPendingCodeHash: local?.hash,
|
|
7035
|
+
smsPendingPurpose: "mfa_enrollment",
|
|
6944
7036
|
smsPhone: phone,
|
|
7037
|
+
smsProviderReference: started?.reference,
|
|
6945
7038
|
smsVerified: false,
|
|
7039
|
+
totpFailedAttempts: existing?.totpFailedAttempts ?? 0,
|
|
6946
7040
|
totpSecretCiphertext: existing?.totpSecretCiphertext,
|
|
6947
7041
|
totpVerified: existing?.totpVerified ?? false,
|
|
6948
7042
|
updatedAt: now,
|
|
6949
7043
|
userId
|
|
6950
7044
|
});
|
|
6951
|
-
|
|
7045
|
+
if (local !== undefined && onSendSmsCode !== undefined) {
|
|
7046
|
+
await onSendSmsCode({
|
|
7047
|
+
code: local.code,
|
|
7048
|
+
expiresAt: local.expiresAt,
|
|
7049
|
+
phone,
|
|
7050
|
+
purpose: "mfa_enrollment",
|
|
7051
|
+
userId
|
|
7052
|
+
});
|
|
7053
|
+
}
|
|
6952
7054
|
return status("OK", { phone: maskPhone(phone) });
|
|
6953
7055
|
}, {
|
|
6954
7056
|
body: t11.Object({ phone: t11.String() }),
|
|
@@ -6969,29 +7071,58 @@ var mfaSmsRoutes = ({
|
|
|
6969
7071
|
}
|
|
6970
7072
|
const userId = getUserId(userSession.user);
|
|
6971
7073
|
const enrollment = await mfaStore.getEnrollment(userId);
|
|
6972
|
-
if (!enrollment?.
|
|
7074
|
+
if (!enrollment?.smsPhone) {
|
|
7075
|
+
return status("Bad Request", "No SMS enrollment in progress");
|
|
7076
|
+
}
|
|
7077
|
+
const localCodeHash = enrollment.smsPendingCodeHash;
|
|
7078
|
+
const localCodeExpiresAt = enrollment.smsPendingCodeExpiresAt;
|
|
7079
|
+
const providerReference = enrollment.smsProviderReference;
|
|
7080
|
+
if (enrollment.smsPendingPurpose !== "mfa_enrollment" || localCodeExpiresAt === undefined) {
|
|
6973
7081
|
return status("Bad Request", "No SMS enrollment in progress");
|
|
6974
7082
|
}
|
|
6975
|
-
if (
|
|
7083
|
+
if (verificationProvider === undefined && localCodeHash === undefined) {
|
|
7084
|
+
return status("Bad Request", "No SMS enrollment in progress");
|
|
7085
|
+
}
|
|
7086
|
+
if (Date.now() > localCodeExpiresAt) {
|
|
6976
7087
|
return status("Bad Request", "SMS code expired");
|
|
6977
7088
|
}
|
|
6978
7089
|
if ((enrollment.smsFailedAttempts ?? 0) >= smsMaxAttempts) {
|
|
6979
7090
|
return status("Too Many Requests", "Too many attempts");
|
|
6980
7091
|
}
|
|
6981
|
-
|
|
7092
|
+
let providerResult;
|
|
7093
|
+
if (verificationProvider !== undefined) {
|
|
7094
|
+
if (providerReference === undefined) {
|
|
7095
|
+
return status("Bad Request", "No SMS enrollment in progress");
|
|
7096
|
+
}
|
|
7097
|
+
const checked = await checkWithVerificationProvider(verificationProvider, {
|
|
7098
|
+
channel: "sms",
|
|
7099
|
+
code,
|
|
7100
|
+
purpose: "mfa_enrollment",
|
|
7101
|
+
reference: providerReference,
|
|
7102
|
+
subject: userId,
|
|
7103
|
+
to: enrollment.smsPhone
|
|
7104
|
+
});
|
|
7105
|
+
if (checked.error !== undefined) {
|
|
7106
|
+
return status(checked.error.status, checked.error.message);
|
|
7107
|
+
}
|
|
7108
|
+
providerResult = checked.result;
|
|
7109
|
+
}
|
|
7110
|
+
const codeValid = providerResult ? providerResult.status === "approved" : localCodeHash !== undefined && await constantTimeEqual(await hashToken(code), localCodeHash);
|
|
6982
7111
|
if (!codeValid) {
|
|
6983
7112
|
await mfaStore.saveEnrollment({
|
|
6984
7113
|
...enrollment,
|
|
6985
7114
|
smsFailedAttempts: (enrollment.smsFailedAttempts ?? 0) + 1,
|
|
6986
7115
|
updatedAt: Date.now()
|
|
6987
7116
|
});
|
|
6988
|
-
return status("Bad Request", "Invalid SMS code");
|
|
7117
|
+
return status(providerResult?.status === "max_attempts_reached" ? "Too Many Requests" : "Bad Request", providerResult?.status === "expired" ? "SMS code expired" : "Invalid SMS code");
|
|
6989
7118
|
}
|
|
6990
7119
|
await mfaStore.saveEnrollment({
|
|
6991
7120
|
...enrollment,
|
|
6992
7121
|
smsFailedAttempts: 0,
|
|
6993
7122
|
smsPendingCodeExpiresAt: undefined,
|
|
6994
7123
|
smsPendingCodeHash: undefined,
|
|
7124
|
+
smsPendingPurpose: undefined,
|
|
7125
|
+
smsProviderReference: undefined,
|
|
6995
7126
|
smsVerified: true,
|
|
6996
7127
|
updatedAt: Date.now()
|
|
6997
7128
|
});
|
|
@@ -7014,10 +7145,12 @@ var mfaChallenge = ({
|
|
|
7014
7145
|
onMfaChallengeError,
|
|
7015
7146
|
onMfaChallengeSuccess,
|
|
7016
7147
|
onSendSmsCode,
|
|
7148
|
+
verificationProvider,
|
|
7017
7149
|
sessionDurationMs = DEFAULT_MFA_SESSION_TTL_MS,
|
|
7018
7150
|
smsCodeLength = DEFAULT_SMS_CODE_LENGTH,
|
|
7019
7151
|
smsCodeTtlMs = DEFAULT_SMS_CODE_TTL_MS,
|
|
7020
7152
|
smsMaxAttempts = DEFAULT_SMS_MAX_ATTEMPTS,
|
|
7153
|
+
smsResendCooldownMs = DEFAULT_SMS_RESEND_COOLDOWN_MS,
|
|
7021
7154
|
totpMaxAttempts = DEFAULT_TOTP_MAX_ATTEMPTS
|
|
7022
7155
|
}) => new Elysia18().use(sessionStore()).post(challengeRoute, async ({
|
|
7023
7156
|
body: { action, code, factor },
|
|
@@ -7059,27 +7192,48 @@ var mfaChallenge = ({
|
|
|
7059
7192
|
await onMfaChallengeSuccess?.({ user, userSessionId });
|
|
7060
7193
|
return status("OK", { status: "authenticated" });
|
|
7061
7194
|
};
|
|
7062
|
-
const
|
|
7063
|
-
if (
|
|
7064
|
-
return status("
|
|
7195
|
+
const sendSmsChallenge = async () => {
|
|
7196
|
+
if (enrollment.smsCodeSentAt !== undefined && Date.now() - enrollment.smsCodeSentAt < smsResendCooldownMs) {
|
|
7197
|
+
return status("Too Many Requests", "SMS resend cooldown active");
|
|
7065
7198
|
}
|
|
7066
|
-
|
|
7199
|
+
try {
|
|
7067
7200
|
await issueAndStoreSmsCode({
|
|
7068
7201
|
codeLength: smsCodeLength,
|
|
7069
7202
|
enrollment,
|
|
7070
7203
|
mfaStore,
|
|
7071
7204
|
onSendSmsCode,
|
|
7072
|
-
|
|
7205
|
+
purpose: "mfa_challenge",
|
|
7206
|
+
ttlMs: smsCodeTtlMs,
|
|
7207
|
+
userId: getUserId(user),
|
|
7208
|
+
verificationProvider
|
|
7073
7209
|
});
|
|
7074
|
-
|
|
7210
|
+
} catch (error) {
|
|
7211
|
+
const mapped = mapVerificationProviderError(error);
|
|
7212
|
+
if (mapped === undefined)
|
|
7213
|
+
throw error;
|
|
7214
|
+
return status(mapped.status, mapped.message);
|
|
7075
7215
|
}
|
|
7216
|
+
return status("OK", { status: "sent" });
|
|
7217
|
+
};
|
|
7218
|
+
const runSmsChallenge = async () => {
|
|
7219
|
+
if (!enrollment.smsVerified || !enrollment.smsPhone) {
|
|
7220
|
+
return status("Unauthorized", "No MFA challenge in progress");
|
|
7221
|
+
}
|
|
7222
|
+
if (action === "send")
|
|
7223
|
+
return sendSmsChallenge();
|
|
7076
7224
|
if (code === undefined) {
|
|
7077
7225
|
return status("Bad Request", "SMS code required");
|
|
7078
7226
|
}
|
|
7079
|
-
|
|
7227
|
+
const localCodeHash = enrollment.smsPendingCodeHash;
|
|
7228
|
+
const localCodeExpiresAt = enrollment.smsPendingCodeExpiresAt;
|
|
7229
|
+
const providerReference = enrollment.smsProviderReference;
|
|
7230
|
+
if (enrollment.smsPendingPurpose !== "mfa_challenge" || localCodeExpiresAt === undefined) {
|
|
7080
7231
|
return status("Bad Request", "No SMS code in progress");
|
|
7081
7232
|
}
|
|
7082
|
-
if (
|
|
7233
|
+
if (verificationProvider === undefined && localCodeHash === undefined) {
|
|
7234
|
+
return status("Bad Request", "No SMS code in progress");
|
|
7235
|
+
}
|
|
7236
|
+
if (Date.now() > localCodeExpiresAt) {
|
|
7083
7237
|
return status("Unauthorized", "SMS code expired");
|
|
7084
7238
|
}
|
|
7085
7239
|
if ((enrollment.smsFailedAttempts ?? 0) >= smsMaxAttempts) {
|
|
@@ -7089,7 +7243,25 @@ var mfaChallenge = ({
|
|
|
7089
7243
|
});
|
|
7090
7244
|
return status("Unauthorized", "Too many attempts");
|
|
7091
7245
|
}
|
|
7092
|
-
|
|
7246
|
+
let providerResult;
|
|
7247
|
+
if (verificationProvider !== undefined) {
|
|
7248
|
+
if (providerReference === undefined) {
|
|
7249
|
+
return status("Bad Request", "No SMS code in progress");
|
|
7250
|
+
}
|
|
7251
|
+
const checked = await checkWithVerificationProvider(verificationProvider, {
|
|
7252
|
+
channel: "sms",
|
|
7253
|
+
code,
|
|
7254
|
+
purpose: "mfa_challenge",
|
|
7255
|
+
reference: providerReference,
|
|
7256
|
+
subject: getUserId(user),
|
|
7257
|
+
to: enrollment.smsPhone
|
|
7258
|
+
});
|
|
7259
|
+
if (checked.error !== undefined) {
|
|
7260
|
+
return status(checked.error.status, checked.error.message);
|
|
7261
|
+
}
|
|
7262
|
+
providerResult = checked.result;
|
|
7263
|
+
}
|
|
7264
|
+
const smsValid = providerResult ? providerResult.status === "approved" : localCodeHash !== undefined && await constantTimeEqual(await hashToken(code), localCodeHash);
|
|
7093
7265
|
if (!smsValid) {
|
|
7094
7266
|
await mfaStore.saveEnrollment({
|
|
7095
7267
|
...enrollment,
|
|
@@ -7100,7 +7272,7 @@ var mfaChallenge = ({
|
|
|
7100
7272
|
error: new Error("invalid_mfa_code"),
|
|
7101
7273
|
userId: getUserId(user)
|
|
7102
7274
|
});
|
|
7103
|
-
return status("Unauthorized", "Invalid MFA code");
|
|
7275
|
+
return status(providerResult?.status === "max_attempts_reached" ? "Too Many Requests" : "Unauthorized", providerResult?.status === "expired" ? "SMS code expired" : "Invalid MFA code");
|
|
7104
7276
|
}
|
|
7105
7277
|
await mfaStore.saveEnrollment({
|
|
7106
7278
|
...enrollment,
|
|
@@ -7108,6 +7280,8 @@ var mfaChallenge = ({
|
|
|
7108
7280
|
smsFailedAttempts: 0,
|
|
7109
7281
|
smsPendingCodeExpiresAt: undefined,
|
|
7110
7282
|
smsPendingCodeHash: undefined,
|
|
7283
|
+
smsPendingPurpose: undefined,
|
|
7284
|
+
smsProviderReference: undefined,
|
|
7111
7285
|
updatedAt: Date.now()
|
|
7112
7286
|
});
|
|
7113
7287
|
return promote();
|
|
@@ -32836,12 +33010,15 @@ var mfaEnrollmentsTable = pgTable("auth_mfa_enrollments", {
|
|
|
32836
33010
|
backup_code_hashes: jsonb("backup_code_hashes").$type().notNull().default([]),
|
|
32837
33011
|
created_at_ms: bigint("created_at_ms", { mode: "number" }).notNull(),
|
|
32838
33012
|
last_used_at_ms: bigint("last_used_at_ms", { mode: "number" }),
|
|
33013
|
+
sms_code_sent_at_ms: bigint("sms_code_sent_at_ms", { mode: "number" }),
|
|
32839
33014
|
sms_failed_attempts: smallint("sms_failed_attempts").notNull().default(0),
|
|
32840
33015
|
sms_pending_code_expires_at_ms: bigint("sms_pending_code_expires_at_ms", {
|
|
32841
33016
|
mode: "number"
|
|
32842
33017
|
}),
|
|
32843
33018
|
sms_pending_code_hash: text("sms_pending_code_hash"),
|
|
33019
|
+
sms_pending_purpose: text("sms_pending_purpose").$type(),
|
|
32844
33020
|
sms_phone: varchar("sms_phone", { length: PHONE_LENGTH }),
|
|
33021
|
+
sms_provider_reference: text("sms_provider_reference"),
|
|
32845
33022
|
sms_verified: boolean("sms_verified").notNull().default(false),
|
|
32846
33023
|
totp_failed_attempts: smallint("totp_failed_attempts").notNull().default(0),
|
|
32847
33024
|
totp_secret_ciphertext: text("totp_secret_ciphertext"),
|
|
@@ -32853,10 +33030,13 @@ var toEnrollment = (row) => ({
|
|
|
32853
33030
|
backupCodeHashes: row.backup_code_hashes,
|
|
32854
33031
|
createdAt: row.created_at_ms,
|
|
32855
33032
|
lastUsedAt: row.last_used_at_ms ?? undefined,
|
|
33033
|
+
smsCodeSentAt: row.sms_code_sent_at_ms ?? undefined,
|
|
32856
33034
|
smsFailedAttempts: row.sms_failed_attempts,
|
|
32857
33035
|
smsPendingCodeExpiresAt: row.sms_pending_code_expires_at_ms ?? undefined,
|
|
32858
33036
|
smsPendingCodeHash: row.sms_pending_code_hash ?? undefined,
|
|
33037
|
+
smsPendingPurpose: row.sms_pending_purpose ?? undefined,
|
|
32859
33038
|
smsPhone: row.sms_phone ?? undefined,
|
|
33039
|
+
smsProviderReference: row.sms_provider_reference ?? undefined,
|
|
32860
33040
|
smsVerified: row.sms_verified,
|
|
32861
33041
|
totpFailedAttempts: row.totp_failed_attempts,
|
|
32862
33042
|
totpSecretCiphertext: row.totp_secret_ciphertext ?? undefined,
|
|
@@ -32882,10 +33062,13 @@ var createPostgresMfaStore = (db) => ({
|
|
|
32882
33062
|
backup_code_hashes: enrollment.backupCodeHashes,
|
|
32883
33063
|
created_at_ms: enrollment.createdAt,
|
|
32884
33064
|
last_used_at_ms: enrollment.lastUsedAt ?? null,
|
|
33065
|
+
sms_code_sent_at_ms: enrollment.smsCodeSentAt ?? null,
|
|
32885
33066
|
sms_failed_attempts: enrollment.smsFailedAttempts ?? 0,
|
|
32886
33067
|
sms_pending_code_expires_at_ms: enrollment.smsPendingCodeExpiresAt ?? null,
|
|
32887
33068
|
sms_pending_code_hash: enrollment.smsPendingCodeHash ?? null,
|
|
33069
|
+
sms_pending_purpose: enrollment.smsPendingPurpose ?? null,
|
|
32888
33070
|
sms_phone: enrollment.smsPhone ?? null,
|
|
33071
|
+
sms_provider_reference: enrollment.smsProviderReference ?? null,
|
|
32889
33072
|
sms_verified: enrollment.smsVerified,
|
|
32890
33073
|
totp_failed_attempts: enrollment.totpFailedAttempts ?? 0,
|
|
32891
33074
|
totp_secret_ciphertext: enrollment.totpSecretCiphertext ?? null,
|
|
@@ -37234,6 +37417,15 @@ var mfaTotpLockoutMigration = {
|
|
|
37234
37417
|
id: "0003_totp_lockout",
|
|
37235
37418
|
sql: 'ALTER TABLE "auth_mfa_enrollments" ADD COLUMN IF NOT EXISTS "totp_failed_attempts" smallint NOT NULL DEFAULT 0;'
|
|
37236
37419
|
};
|
|
37420
|
+
var mfaSmsDeliveryPolicyMigration = {
|
|
37421
|
+
id: "0004_sms_delivery_policy",
|
|
37422
|
+
sql: [
|
|
37423
|
+
'ALTER TABLE "auth_mfa_enrollments" ADD COLUMN IF NOT EXISTS "sms_code_sent_at_ms" bigint;',
|
|
37424
|
+
'ALTER TABLE "auth_mfa_enrollments" ADD COLUMN IF NOT EXISTS "sms_pending_purpose" text;',
|
|
37425
|
+
'ALTER TABLE "auth_mfa_enrollments" ADD COLUMN IF NOT EXISTS "sms_provider_reference" text;'
|
|
37426
|
+
].join(`
|
|
37427
|
+
`)
|
|
37428
|
+
};
|
|
37237
37429
|
var oidcResourceAudienceMigration = {
|
|
37238
37430
|
id: "0002_resource_audience",
|
|
37239
37431
|
sql: [
|
|
@@ -37288,7 +37480,8 @@ var blockMigrations = {
|
|
|
37288
37480
|
migrations: [
|
|
37289
37481
|
...initMigration("mfa", [mfaEnrollmentsTable]).migrations,
|
|
37290
37482
|
mfaSmsColumnsMigration,
|
|
37291
|
-
mfaTotpLockoutMigration
|
|
37483
|
+
mfaTotpLockoutMigration,
|
|
37484
|
+
mfaSmsDeliveryPolicyMigration
|
|
37292
37485
|
]
|
|
37293
37486
|
},
|
|
37294
37487
|
oidc: {
|
|
@@ -37801,6 +37994,7 @@ var buildAuthApplications = async (configuration) => {
|
|
|
37801
37994
|
credentials,
|
|
37802
37995
|
customProviders,
|
|
37803
37996
|
mfa,
|
|
37997
|
+
verificationProvider,
|
|
37804
37998
|
passwordless,
|
|
37805
37999
|
lockout,
|
|
37806
38000
|
sessions,
|
|
@@ -38033,7 +38227,8 @@ var buildAuthApplications = async (configuration) => {
|
|
|
38033
38227
|
auditedMfa ? mfaRoutes({
|
|
38034
38228
|
...auditedMfa,
|
|
38035
38229
|
authSessionStore,
|
|
38036
|
-
cookieSecure: resolvedCookieSecure
|
|
38230
|
+
cookieSecure: resolvedCookieSecure,
|
|
38231
|
+
verificationProvider
|
|
38037
38232
|
}) : new Elysia45,
|
|
38038
38233
|
passwordless ? passwordlessRoutes({
|
|
38039
38234
|
...passwordless,
|
|
@@ -38280,8 +38475,9 @@ export {
|
|
|
38280
38475
|
createPostgresScimTokenStore,
|
|
38281
38476
|
createNodeSamlAdapter,
|
|
38282
38477
|
createAuthContext,
|
|
38283
|
-
auth2 as auth
|
|
38478
|
+
auth2 as auth,
|
|
38479
|
+
VerificationProviderError
|
|
38284
38480
|
};
|
|
38285
38481
|
|
|
38286
|
-
//# debugId=
|
|
38482
|
+
//# debugId=AAFF3B14FB3E90D564756E2164756E21
|
|
38287
38483
|
//# sourceMappingURL=server.js.map
|