better-auth 1.3.0-beta.5 → 1.3.0-beta.7
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/adapters/drizzle-adapter/index.d.cts +2 -2
- package/dist/adapters/drizzle-adapter/index.d.mts +2 -2
- package/dist/adapters/drizzle-adapter/index.d.ts +2 -2
- package/dist/adapters/index.d.cts +3 -3
- package/dist/adapters/index.d.mts +3 -3
- package/dist/adapters/index.d.ts +3 -3
- package/dist/adapters/kysely-adapter/index.d.cts +2 -2
- package/dist/adapters/kysely-adapter/index.d.mts +2 -2
- package/dist/adapters/kysely-adapter/index.d.ts +2 -2
- package/dist/adapters/memory-adapter/index.d.cts +2 -2
- package/dist/adapters/memory-adapter/index.d.mts +2 -2
- package/dist/adapters/memory-adapter/index.d.ts +2 -2
- package/dist/adapters/mongodb-adapter/index.d.cts +2 -2
- package/dist/adapters/mongodb-adapter/index.d.mts +2 -2
- package/dist/adapters/mongodb-adapter/index.d.ts +2 -2
- package/dist/adapters/prisma-adapter/index.d.cts +2 -2
- package/dist/adapters/prisma-adapter/index.d.mts +2 -2
- package/dist/adapters/prisma-adapter/index.d.ts +2 -2
- package/dist/adapters/test.d.cts +2 -2
- package/dist/adapters/test.d.mts +2 -2
- package/dist/adapters/test.d.ts +2 -2
- package/dist/api/index.cjs +1 -1
- package/dist/api/index.d.cts +2 -2
- package/dist/api/index.d.mts +2 -2
- package/dist/api/index.d.ts +2 -2
- package/dist/api/index.mjs +2 -2
- package/dist/chunks/index.cjs +905 -0
- package/dist/chunks/index.mjs +895 -0
- package/dist/client/index.d.cts +5 -9
- package/dist/client/index.d.mts +5 -9
- package/dist/client/index.d.ts +5 -9
- package/dist/client/plugins/index.d.cts +4 -4
- package/dist/client/plugins/index.d.mts +4 -4
- package/dist/client/plugins/index.d.ts +4 -4
- package/dist/client/react/index.d.cts +9 -9
- package/dist/client/react/index.d.mts +9 -9
- package/dist/client/react/index.d.ts +9 -9
- package/dist/client/solid/index.d.cts +9 -9
- package/dist/client/solid/index.d.mts +9 -9
- package/dist/client/solid/index.d.ts +9 -9
- package/dist/client/svelte/index.d.cts +3 -3
- package/dist/client/svelte/index.d.mts +3 -3
- package/dist/client/svelte/index.d.ts +3 -3
- package/dist/client/vue/index.d.cts +3 -3
- package/dist/client/vue/index.d.mts +3 -3
- package/dist/client/vue/index.d.ts +3 -3
- package/dist/cookies/index.d.cts +2 -2
- package/dist/cookies/index.d.mts +2 -2
- package/dist/cookies/index.d.ts +2 -2
- package/dist/db/index.d.cts +3 -3
- package/dist/db/index.d.mts +3 -3
- package/dist/db/index.d.ts +3 -3
- package/dist/index.cjs +2 -2
- package/dist/index.d.cts +4 -4
- package/dist/index.d.mts +4 -4
- package/dist/index.d.ts +4 -4
- package/dist/index.mjs +2 -2
- package/dist/integrations/next-js.cjs +2 -2
- package/dist/integrations/next-js.d.cts +2 -2
- package/dist/integrations/next-js.d.mts +2 -2
- package/dist/integrations/next-js.d.ts +2 -2
- package/dist/integrations/next-js.mjs +2 -2
- package/dist/integrations/node.d.cts +2 -2
- package/dist/integrations/node.d.mts +2 -2
- package/dist/integrations/node.d.ts +2 -2
- package/dist/integrations/react-start.cjs +3 -3
- package/dist/integrations/react-start.d.cts +2 -2
- package/dist/integrations/react-start.d.mts +2 -2
- package/dist/integrations/react-start.d.ts +2 -2
- package/dist/integrations/react-start.mjs +3 -3
- package/dist/integrations/svelte-kit.cjs +1 -1
- package/dist/integrations/svelte-kit.d.cts +2 -2
- package/dist/integrations/svelte-kit.d.mts +2 -2
- package/dist/integrations/svelte-kit.d.ts +2 -2
- package/dist/integrations/svelte-kit.mjs +1 -1
- package/dist/oauth2/index.cjs +1 -1
- package/dist/oauth2/index.d.cts +4 -4
- package/dist/oauth2/index.d.mts +4 -4
- package/dist/oauth2/index.d.ts +4 -4
- package/dist/oauth2/index.mjs +1 -1
- package/dist/plugins/admin/index.cjs +2 -2
- package/dist/plugins/admin/index.d.cts +6 -5
- package/dist/plugins/admin/index.d.mts +6 -5
- package/dist/plugins/admin/index.d.ts +6 -5
- package/dist/plugins/admin/index.mjs +2 -2
- package/dist/plugins/anonymous/index.cjs +1 -1
- package/dist/plugins/anonymous/index.d.cts +2 -2
- package/dist/plugins/anonymous/index.d.mts +2 -2
- package/dist/plugins/anonymous/index.d.ts +2 -2
- package/dist/plugins/anonymous/index.mjs +1 -1
- package/dist/plugins/bearer/index.cjs +1 -1
- package/dist/plugins/bearer/index.d.cts +2 -2
- package/dist/plugins/bearer/index.d.mts +2 -2
- package/dist/plugins/bearer/index.d.ts +2 -2
- package/dist/plugins/bearer/index.mjs +1 -1
- package/dist/plugins/captcha/index.d.cts +2 -2
- package/dist/plugins/captcha/index.d.mts +2 -2
- package/dist/plugins/captcha/index.d.ts +2 -2
- package/dist/plugins/custom-session/index.cjs +1 -1
- package/dist/plugins/custom-session/index.d.cts +2 -2
- package/dist/plugins/custom-session/index.d.mts +2 -2
- package/dist/plugins/custom-session/index.d.ts +2 -2
- package/dist/plugins/custom-session/index.mjs +1 -1
- package/dist/plugins/email-otp/index.cjs +213 -101
- package/dist/plugins/email-otp/index.d.cts +101 -72
- package/dist/plugins/email-otp/index.d.mts +101 -72
- package/dist/plugins/email-otp/index.d.ts +101 -72
- package/dist/plugins/email-otp/index.mjs +213 -101
- package/dist/plugins/generic-oauth/index.cjs +1 -1
- package/dist/plugins/generic-oauth/index.d.cts +2 -2
- package/dist/plugins/generic-oauth/index.d.mts +2 -2
- package/dist/plugins/generic-oauth/index.d.ts +2 -2
- package/dist/plugins/generic-oauth/index.mjs +1 -1
- package/dist/plugins/haveibeenpwned/index.cjs +1 -1
- package/dist/plugins/haveibeenpwned/index.d.cts +2 -2
- package/dist/plugins/haveibeenpwned/index.d.mts +2 -2
- package/dist/plugins/haveibeenpwned/index.d.ts +2 -2
- package/dist/plugins/haveibeenpwned/index.mjs +1 -1
- package/dist/plugins/index.cjs +23 -1895
- package/dist/plugins/index.d.cts +4 -4
- package/dist/plugins/index.d.mts +4 -4
- package/dist/plugins/index.d.ts +4 -4
- package/dist/plugins/index.mjs +22 -1894
- package/dist/plugins/jwt/index.cjs +1 -1
- package/dist/plugins/jwt/index.d.cts +2 -2
- package/dist/plugins/jwt/index.d.mts +2 -2
- package/dist/plugins/jwt/index.d.ts +2 -2
- package/dist/plugins/jwt/index.mjs +1 -1
- package/dist/plugins/magic-link/index.cjs +39 -12
- package/dist/plugins/magic-link/index.d.cts +12 -2
- package/dist/plugins/magic-link/index.d.mts +12 -2
- package/dist/plugins/magic-link/index.d.ts +12 -2
- package/dist/plugins/magic-link/index.mjs +39 -12
- package/dist/plugins/multi-session/index.cjs +1 -1
- package/dist/plugins/multi-session/index.d.cts +2 -2
- package/dist/plugins/multi-session/index.d.mts +2 -2
- package/dist/plugins/multi-session/index.d.ts +2 -2
- package/dist/plugins/multi-session/index.mjs +1 -1
- package/dist/plugins/oauth-proxy/index.cjs +1 -1
- package/dist/plugins/oauth-proxy/index.d.cts +2 -2
- package/dist/plugins/oauth-proxy/index.d.mts +2 -2
- package/dist/plugins/oauth-proxy/index.d.ts +2 -2
- package/dist/plugins/oauth-proxy/index.mjs +1 -1
- package/dist/plugins/oidc-provider/index.cjs +2 -2
- package/dist/plugins/oidc-provider/index.d.cts +7 -7
- package/dist/plugins/oidc-provider/index.d.mts +7 -7
- package/dist/plugins/oidc-provider/index.d.ts +7 -7
- package/dist/plugins/oidc-provider/index.mjs +2 -2
- package/dist/plugins/one-tap/index.cjs +1 -1
- package/dist/plugins/one-tap/index.mjs +1 -1
- package/dist/plugins/one-time-token/index.cjs +8 -77
- package/dist/plugins/one-time-token/index.d.cts +14 -4
- package/dist/plugins/one-time-token/index.d.mts +14 -4
- package/dist/plugins/one-time-token/index.d.ts +14 -4
- package/dist/plugins/one-time-token/index.mjs +6 -79
- package/dist/plugins/open-api/index.cjs +1 -1
- package/dist/plugins/open-api/index.d.cts +2 -2
- package/dist/plugins/open-api/index.d.mts +2 -2
- package/dist/plugins/open-api/index.d.ts +2 -2
- package/dist/plugins/open-api/index.mjs +1 -1
- package/dist/plugins/organization/index.cjs +2 -2
- package/dist/plugins/organization/index.d.cts +3 -2
- package/dist/plugins/organization/index.d.mts +3 -2
- package/dist/plugins/organization/index.d.ts +3 -2
- package/dist/plugins/organization/index.mjs +2 -2
- package/dist/plugins/passkey/index.cjs +1 -1
- package/dist/plugins/passkey/index.d.cts +2 -2
- package/dist/plugins/passkey/index.d.mts +2 -2
- package/dist/plugins/passkey/index.d.ts +2 -2
- package/dist/plugins/passkey/index.mjs +1 -1
- package/dist/plugins/phone-number/index.cjs +1 -1
- package/dist/plugins/phone-number/index.d.cts +2 -2
- package/dist/plugins/phone-number/index.d.mts +2 -2
- package/dist/plugins/phone-number/index.d.ts +2 -2
- package/dist/plugins/phone-number/index.mjs +1 -1
- package/dist/plugins/sso/index.cjs +1 -1
- package/dist/plugins/sso/index.d.cts +5 -5
- package/dist/plugins/sso/index.d.mts +5 -5
- package/dist/plugins/sso/index.d.ts +5 -5
- package/dist/plugins/sso/index.mjs +1 -1
- package/dist/plugins/two-factor/index.cjs +103 -18
- package/dist/plugins/two-factor/index.d.cts +23 -7
- package/dist/plugins/two-factor/index.d.mts +23 -7
- package/dist/plugins/two-factor/index.d.ts +23 -7
- package/dist/plugins/two-factor/index.mjs +103 -18
- package/dist/plugins/username/index.cjs +4 -2
- package/dist/plugins/username/index.d.cts +2 -2
- package/dist/plugins/username/index.d.mts +2 -2
- package/dist/plugins/username/index.d.ts +2 -2
- package/dist/plugins/username/index.mjs +4 -2
- package/dist/shared/{better-auth.CqTBLifU.d.cts → better-auth.1M3xAdJC.d.cts} +45 -38
- package/dist/shared/{better-auth.RTMLk2Ya.cjs → better-auth.B2zZl7qP.cjs} +1 -1
- package/dist/shared/{better-auth.C0cDbHJn.d.mts → better-auth.BJa1oqpN.d.cts} +1 -1
- package/dist/shared/{better-auth.GYpUAWrY.d.mts → better-auth.BYIMqSU0.d.mts} +2 -2
- package/dist/shared/{better-auth.BGfHbXlu.d.ts → better-auth.Bc-1Su7g.d.ts} +45 -38
- package/dist/shared/{better-auth.B7Dt9CoJ.cjs → better-auth.BjBe8STm.cjs} +11 -2
- package/dist/shared/{better-auth.ClyLnOjY.mjs → better-auth.BtyWISFt.mjs} +152 -75
- package/dist/shared/{better-auth.GAghsvQp.d.cts → better-auth.C1otFVHS.d.mts} +1 -1
- package/dist/shared/better-auth.C6VyAxGz.mjs +2001 -0
- package/dist/shared/{better-auth.CP_AmXSW.d.mts → better-auth.CJ2ZGyoL.d.mts} +7 -3
- package/dist/shared/{better-auth.CZ3qe2fL.d.ts → better-auth.CJb2R19P.d.ts} +2 -2
- package/dist/shared/{better-auth.CRISE-Is.mjs → better-auth.CQPOI-_E.mjs} +1 -1
- package/dist/shared/{better-auth.CJDmUUCz.d.cts → better-auth.CpSq0H3M.d.cts} +2 -2
- package/dist/shared/{better-auth.DBODKok7.mjs → better-auth.D7Si_1a9.mjs} +11 -2
- package/dist/shared/{better-auth.DFU4LGhu.d.ts → better-auth.D9z1x8va.d.ts} +99 -2
- package/dist/shared/{better-auth.B8vM3gli.d.mts → better-auth.DWRzwPcP.d.mts} +45 -38
- package/dist/shared/better-auth.DZBS14g0.cjs +2007 -0
- package/dist/shared/{better-auth.B9cT0y97.d.cts → better-auth.DcwXW4BB.d.cts} +7 -3
- package/dist/shared/{better-auth.69-aSQxn.d.ts → better-auth.Dde0tveQ.d.ts} +1 -1
- package/dist/shared/{better-auth.CBQcGOAy.mjs → better-auth.Dh9fsfY2.mjs} +3 -2
- package/dist/shared/{better-auth.Ds-w2spb.cjs → better-auth.HT3cSIq4.cjs} +152 -74
- package/dist/shared/{better-auth.D0zUlh1z.cjs → better-auth.I7OjQ-oc.cjs} +3 -2
- package/dist/shared/{better-auth.BnAeoMet.d.cts → better-auth.VwFr4owi.d.cts} +99 -2
- package/dist/shared/{better-auth.BK4bljal.cjs → better-auth.Y_QHVJcB.cjs} +1 -1
- package/dist/shared/{better-auth.BzWvuaI6.d.ts → better-auth.bHQlVztX.d.ts} +7 -3
- package/dist/shared/{better-auth.CpQAMo-G.d.mts → better-auth.kvIPfj9F.d.mts} +99 -2
- package/dist/shared/{better-auth.ZAqiQx_W.mjs → better-auth.tST9Caqi.mjs} +1 -1
- package/dist/social-providers/index.cjs +2 -1
- package/dist/social-providers/index.d.cts +1 -1
- package/dist/social-providers/index.d.mts +1 -1
- package/dist/social-providers/index.d.ts +1 -1
- package/dist/social-providers/index.mjs +1 -1
- package/dist/test-utils/index.cjs +3 -3
- package/dist/test-utils/index.d.cts +76 -76
- package/dist/test-utils/index.d.mts +76 -76
- package/dist/test-utils/index.d.ts +76 -76
- package/dist/test-utils/index.mjs +3 -3
- package/dist/types/index.d.cts +3 -3
- package/dist/types/index.d.mts +3 -3
- package/dist/types/index.d.ts +3 -3
- package/package.json +2 -2
|
@@ -2,26 +2,27 @@
|
|
|
2
2
|
|
|
3
3
|
const zod = require('zod');
|
|
4
4
|
const betterCall = require('better-call');
|
|
5
|
-
const socialProviders_index = require('../../shared/better-auth.
|
|
5
|
+
const socialProviders_index = require('../../shared/better-auth.HT3cSIq4.cjs');
|
|
6
6
|
const cookies_index = require('../../cookies/index.cjs');
|
|
7
7
|
require('../../shared/better-auth.DcWKCjjf.cjs');
|
|
8
8
|
require('../../shared/better-auth.DiSjtgs9.cjs');
|
|
9
9
|
require('../../shared/better-auth.CXhVNgXP.cjs');
|
|
10
10
|
require('defu');
|
|
11
|
-
require('
|
|
11
|
+
const crypto_index = require('../../crypto/index.cjs');
|
|
12
|
+
const date = require('../../shared/better-auth.C1hdVENX.cjs');
|
|
13
|
+
const pluginHelper = require('../../shared/better-auth.DNqtHmvg.cjs');
|
|
14
|
+
const hash = require('@better-auth/utils/hash');
|
|
15
|
+
const base64 = require('@better-auth/utils/base64');
|
|
16
|
+
const random = require('../../shared/better-auth.CYeOI8C-.cjs');
|
|
17
|
+
require('@better-fetch/fetch');
|
|
18
|
+
require('jose');
|
|
12
19
|
require('@noble/ciphers/chacha');
|
|
13
20
|
require('@noble/ciphers/utils');
|
|
14
21
|
require('@noble/ciphers/webcrypto');
|
|
15
|
-
require('@better-auth/utils/base64');
|
|
16
|
-
require('jose');
|
|
17
22
|
require('@noble/hashes/scrypt');
|
|
18
23
|
require('@better-auth/utils');
|
|
19
24
|
require('@better-auth/utils/hex');
|
|
20
25
|
require('@noble/hashes/utils');
|
|
21
|
-
const random = require('../../shared/better-auth.CYeOI8C-.cjs');
|
|
22
|
-
const date = require('../../shared/better-auth.C1hdVENX.cjs');
|
|
23
|
-
const pluginHelper = require('../../shared/better-auth.DNqtHmvg.cjs');
|
|
24
|
-
require('@better-fetch/fetch');
|
|
25
26
|
require('../../shared/better-auth.C-R0J0n1.cjs');
|
|
26
27
|
require('../../shared/better-auth.ANpbi45u.cjs');
|
|
27
28
|
require('../../shared/better-auth.D3mtHEZg.cjs');
|
|
@@ -30,12 +31,31 @@ require('@better-auth/utils/binary');
|
|
|
30
31
|
require('../../shared/better-auth.BMYo0QR-.cjs');
|
|
31
32
|
require('jose/errors');
|
|
32
33
|
require('@better-auth/utils/random');
|
|
34
|
+
require('../../shared/better-auth.YUF6P-PB.cjs');
|
|
35
|
+
|
|
36
|
+
const defaultKeyHasher = async (otp) => {
|
|
37
|
+
const hash$1 = await hash.createHash("SHA-256").digest(
|
|
38
|
+
new TextEncoder().encode(otp)
|
|
39
|
+
);
|
|
40
|
+
const hashed = base64.base64Url.encode(new Uint8Array(hash$1), {
|
|
41
|
+
padding: false
|
|
42
|
+
});
|
|
43
|
+
return hashed;
|
|
44
|
+
};
|
|
45
|
+
function splitAtLastColon(input) {
|
|
46
|
+
const idx = input.lastIndexOf(":");
|
|
47
|
+
if (idx === -1) {
|
|
48
|
+
return [input, ""];
|
|
49
|
+
}
|
|
50
|
+
return [input.slice(0, idx), input.slice(idx + 1)];
|
|
51
|
+
}
|
|
33
52
|
|
|
34
53
|
const types = ["email-verification", "sign-in", "forget-password"];
|
|
35
54
|
const emailOTP = (options) => {
|
|
36
55
|
const opts = {
|
|
37
56
|
expiresIn: 5 * 60,
|
|
38
57
|
generateOTP: () => random.generateRandomString(options.otpLength ?? 6, "0-9"),
|
|
58
|
+
storeOTP: "plain",
|
|
39
59
|
...options
|
|
40
60
|
};
|
|
41
61
|
const ERROR_CODES = {
|
|
@@ -45,35 +65,71 @@ const emailOTP = (options) => {
|
|
|
45
65
|
USER_NOT_FOUND: "User not found",
|
|
46
66
|
TOO_MANY_ATTEMPTS: "Too many attempts"
|
|
47
67
|
};
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
68
|
+
async function storeOTP(ctx, otp) {
|
|
69
|
+
if (opts.storeOTP === "encrypted") {
|
|
70
|
+
return await crypto_index.symmetricEncrypt({
|
|
71
|
+
key: ctx.context.secret,
|
|
72
|
+
data: otp
|
|
73
|
+
});
|
|
74
|
+
}
|
|
75
|
+
if (opts.storeOTP === "hashed") {
|
|
76
|
+
return await defaultKeyHasher(otp);
|
|
77
|
+
}
|
|
78
|
+
if (typeof opts.storeOTP === "object" && "hash" in opts.storeOTP) {
|
|
79
|
+
return await opts.storeOTP.hash(otp);
|
|
80
|
+
}
|
|
81
|
+
if (typeof opts.storeOTP === "object" && "encrypt" in opts.storeOTP) {
|
|
82
|
+
return await opts.storeOTP.encrypt(otp);
|
|
83
|
+
}
|
|
84
|
+
return otp;
|
|
85
|
+
}
|
|
86
|
+
async function verifyStoredOTP(ctx, storedOtp, otp) {
|
|
87
|
+
if (opts.storeOTP === "encrypted") {
|
|
88
|
+
return await crypto_index.symmetricDecrypt({
|
|
89
|
+
key: ctx.context.secret,
|
|
90
|
+
data: storedOtp
|
|
91
|
+
}) === otp;
|
|
92
|
+
}
|
|
93
|
+
if (opts.storeOTP === "hashed") {
|
|
94
|
+
const hashedOtp = await defaultKeyHasher(otp);
|
|
95
|
+
return hashedOtp === storedOtp;
|
|
96
|
+
}
|
|
97
|
+
if (typeof opts.storeOTP === "object" && "hash" in opts.storeOTP) {
|
|
98
|
+
const hashedOtp = await opts.storeOTP.hash(otp);
|
|
99
|
+
return hashedOtp === storedOtp;
|
|
100
|
+
}
|
|
101
|
+
if (typeof opts.storeOTP === "object" && "decrypt" in opts.storeOTP) {
|
|
102
|
+
const decryptedOtp = await opts.storeOTP.decrypt(storedOtp);
|
|
103
|
+
return decryptedOtp === otp;
|
|
104
|
+
}
|
|
105
|
+
return otp === storedOtp;
|
|
106
|
+
}
|
|
107
|
+
const endpoints = {
|
|
108
|
+
sendVerificationOTP: socialProviders_index.createAuthEndpoint(
|
|
109
|
+
"/email-otp/send-verification-otp",
|
|
110
|
+
{
|
|
111
|
+
method: "POST",
|
|
112
|
+
body: zod.z.object({
|
|
113
|
+
email: zod.z.string({
|
|
114
|
+
description: "Email address to send the OTP"
|
|
62
115
|
}),
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
116
|
+
type: zod.z.enum(types, {
|
|
117
|
+
description: "Type of the OTP"
|
|
118
|
+
})
|
|
119
|
+
}),
|
|
120
|
+
metadata: {
|
|
121
|
+
openapi: {
|
|
122
|
+
description: "Send verification OTP",
|
|
123
|
+
responses: {
|
|
124
|
+
200: {
|
|
125
|
+
description: "Success",
|
|
126
|
+
content: {
|
|
127
|
+
"application/json": {
|
|
128
|
+
schema: {
|
|
129
|
+
type: "object",
|
|
130
|
+
properties: {
|
|
131
|
+
success: {
|
|
132
|
+
type: "boolean"
|
|
77
133
|
}
|
|
78
134
|
}
|
|
79
135
|
}
|
|
@@ -82,75 +138,101 @@ const emailOTP = (options) => {
|
|
|
82
138
|
}
|
|
83
139
|
}
|
|
84
140
|
}
|
|
85
|
-
}
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
141
|
+
}
|
|
142
|
+
},
|
|
143
|
+
async (ctx) => {
|
|
144
|
+
if (!options?.sendVerificationOTP) {
|
|
145
|
+
ctx.context.logger.error(
|
|
146
|
+
"send email verification is not implemented"
|
|
147
|
+
);
|
|
148
|
+
throw new betterCall.APIError("BAD_REQUEST", {
|
|
149
|
+
message: "send email verification is not implemented"
|
|
150
|
+
});
|
|
151
|
+
}
|
|
152
|
+
const email = ctx.body.email;
|
|
153
|
+
const emailRegex = /^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$/;
|
|
154
|
+
if (!emailRegex.test(email)) {
|
|
155
|
+
throw ctx.error("BAD_REQUEST", {
|
|
156
|
+
message: ERROR_CODES.INVALID_EMAIL
|
|
157
|
+
});
|
|
158
|
+
}
|
|
159
|
+
if (opts.disableSignUp) {
|
|
160
|
+
const user = await ctx.context.internalAdapter.findUserByEmail(email);
|
|
161
|
+
if (!user) {
|
|
91
162
|
throw new betterCall.APIError("BAD_REQUEST", {
|
|
92
|
-
message:
|
|
163
|
+
message: ERROR_CODES.USER_NOT_FOUND
|
|
93
164
|
});
|
|
94
165
|
}
|
|
95
|
-
|
|
96
|
-
const
|
|
97
|
-
if (!
|
|
98
|
-
|
|
99
|
-
|
|
166
|
+
} else if (ctx.body.type === "forget-password") {
|
|
167
|
+
const user = await ctx.context.internalAdapter.findUserByEmail(email);
|
|
168
|
+
if (!user) {
|
|
169
|
+
return ctx.json({
|
|
170
|
+
success: true
|
|
100
171
|
});
|
|
101
172
|
}
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
}
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
}
|
|
116
|
-
}
|
|
117
|
-
const otp = opts.generateOTP(
|
|
118
|
-
{ email, type: ctx.body.type },
|
|
119
|
-
ctx.request
|
|
173
|
+
}
|
|
174
|
+
let otp = opts.generateOTP({ email, type: ctx.body.type }, ctx.request);
|
|
175
|
+
let storedOTP = await storeOTP(ctx, otp);
|
|
176
|
+
await ctx.context.internalAdapter.createVerificationValue(
|
|
177
|
+
{
|
|
178
|
+
value: `${storedOTP}:0`,
|
|
179
|
+
identifier: `${ctx.body.type}-otp-${email}`,
|
|
180
|
+
expiresAt: date.getDate(opts.expiresIn, "sec")
|
|
181
|
+
},
|
|
182
|
+
ctx
|
|
183
|
+
).catch(async (error) => {
|
|
184
|
+
await ctx.context.internalAdapter.deleteVerificationByIdentifier(
|
|
185
|
+
`${ctx.body.type}-otp-${email}`
|
|
120
186
|
);
|
|
121
187
|
await ctx.context.internalAdapter.createVerificationValue(
|
|
122
188
|
{
|
|
123
|
-
value: `${
|
|
189
|
+
value: `${storedOTP}:0`,
|
|
124
190
|
identifier: `${ctx.body.type}-otp-${email}`,
|
|
125
191
|
expiresAt: date.getDate(opts.expiresIn, "sec")
|
|
126
192
|
},
|
|
127
193
|
ctx
|
|
128
|
-
).catch(async (error) => {
|
|
129
|
-
await ctx.context.internalAdapter.deleteVerificationByIdentifier(
|
|
130
|
-
`${ctx.body.type}-otp-${email}`
|
|
131
|
-
);
|
|
132
|
-
await ctx.context.internalAdapter.createVerificationValue(
|
|
133
|
-
{
|
|
134
|
-
value: `${otp}:0`,
|
|
135
|
-
identifier: `${ctx.body.type}-otp-${email}`,
|
|
136
|
-
expiresAt: date.getDate(opts.expiresIn, "sec")
|
|
137
|
-
},
|
|
138
|
-
ctx
|
|
139
|
-
);
|
|
140
|
-
});
|
|
141
|
-
await options.sendVerificationOTP(
|
|
142
|
-
{
|
|
143
|
-
email,
|
|
144
|
-
otp,
|
|
145
|
-
type: ctx.body.type
|
|
146
|
-
},
|
|
147
|
-
ctx.request
|
|
148
194
|
);
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
195
|
+
});
|
|
196
|
+
await options.sendVerificationOTP(
|
|
197
|
+
{
|
|
198
|
+
email,
|
|
199
|
+
otp,
|
|
200
|
+
type: ctx.body.type
|
|
201
|
+
},
|
|
202
|
+
ctx.request
|
|
203
|
+
);
|
|
204
|
+
return ctx.json({
|
|
205
|
+
success: true
|
|
206
|
+
});
|
|
207
|
+
}
|
|
208
|
+
)
|
|
209
|
+
};
|
|
210
|
+
return {
|
|
211
|
+
id: "email-otp",
|
|
212
|
+
init(ctx) {
|
|
213
|
+
return {
|
|
214
|
+
options: {
|
|
215
|
+
emailVerification: {
|
|
216
|
+
...opts.overrideDefaultEmailVerification ? {
|
|
217
|
+
async sendVerificationEmail(data, request) {
|
|
218
|
+
await endpoints.sendVerificationOTP({
|
|
219
|
+
//@ts-expect-error - we need to pass the context
|
|
220
|
+
context: ctx,
|
|
221
|
+
request,
|
|
222
|
+
body: {
|
|
223
|
+
email: data.user.email,
|
|
224
|
+
type: "email-verification"
|
|
225
|
+
},
|
|
226
|
+
ctx
|
|
227
|
+
});
|
|
228
|
+
}
|
|
229
|
+
} : {}
|
|
230
|
+
}
|
|
152
231
|
}
|
|
153
|
-
|
|
232
|
+
};
|
|
233
|
+
},
|
|
234
|
+
endpoints: {
|
|
235
|
+
...endpoints,
|
|
154
236
|
createVerificationOTP: socialProviders_index.createAuthEndpoint(
|
|
155
237
|
"/email-otp/create-verification-otp",
|
|
156
238
|
{
|
|
@@ -188,9 +270,10 @@ const emailOTP = (options) => {
|
|
|
188
270
|
{ email, type: ctx.body.type },
|
|
189
271
|
ctx.request
|
|
190
272
|
);
|
|
273
|
+
let storedOTP = await storeOTP(ctx, otp);
|
|
191
274
|
await ctx.context.internalAdapter.createVerificationValue(
|
|
192
275
|
{
|
|
193
|
-
value: `${
|
|
276
|
+
value: `${storedOTP}:0`,
|
|
194
277
|
identifier: `${ctx.body.type}-otp-${email}`,
|
|
195
278
|
expiresAt: date.getDate(opts.expiresIn, "sec")
|
|
196
279
|
},
|
|
@@ -246,8 +329,26 @@ const emailOTP = (options) => {
|
|
|
246
329
|
otp: null
|
|
247
330
|
});
|
|
248
331
|
}
|
|
332
|
+
if (opts.storeOTP === "hashed" || typeof opts.storeOTP === "object" && "hash" in opts.storeOTP) {
|
|
333
|
+
throw new betterCall.APIError("BAD_REQUEST", {
|
|
334
|
+
message: "OTP is hashed, cannot return the plain text OTP"
|
|
335
|
+
});
|
|
336
|
+
}
|
|
337
|
+
let [storedOtp, _attempts] = splitAtLastColon(
|
|
338
|
+
verificationValue.value
|
|
339
|
+
);
|
|
340
|
+
let otp = storedOtp;
|
|
341
|
+
if (opts.storeOTP === "encrypted") {
|
|
342
|
+
otp = await crypto_index.symmetricDecrypt({
|
|
343
|
+
key: ctx.context.secret,
|
|
344
|
+
data: storedOtp
|
|
345
|
+
});
|
|
346
|
+
}
|
|
347
|
+
if (typeof opts.storeOTP === "object" && "decrypt" in opts.storeOTP) {
|
|
348
|
+
otp = await opts.storeOTP.decrypt(storedOtp);
|
|
349
|
+
}
|
|
249
350
|
return ctx.json({
|
|
250
|
-
otp
|
|
351
|
+
otp
|
|
251
352
|
});
|
|
252
353
|
}
|
|
253
354
|
),
|
|
@@ -318,7 +419,9 @@ const emailOTP = (options) => {
|
|
|
318
419
|
message: ERROR_CODES.OTP_EXPIRED
|
|
319
420
|
});
|
|
320
421
|
}
|
|
321
|
-
const [otpValue, attempts] =
|
|
422
|
+
const [otpValue, attempts] = splitAtLastColon(
|
|
423
|
+
verificationValue.value
|
|
424
|
+
);
|
|
322
425
|
const allowedAttempts = options?.allowedAttempts || 3;
|
|
323
426
|
if (attempts && parseInt(attempts) >= allowedAttempts) {
|
|
324
427
|
await ctx.context.internalAdapter.deleteVerificationValue(
|
|
@@ -328,7 +431,8 @@ const emailOTP = (options) => {
|
|
|
328
431
|
message: ERROR_CODES.TOO_MANY_ATTEMPTS
|
|
329
432
|
});
|
|
330
433
|
}
|
|
331
|
-
|
|
434
|
+
const verified = await verifyStoredOTP(ctx, otpValue, ctx.body.otp);
|
|
435
|
+
if (!verified) {
|
|
332
436
|
await ctx.context.internalAdapter.updateVerificationValue(
|
|
333
437
|
verificationValue.id,
|
|
334
438
|
{
|
|
@@ -453,7 +557,9 @@ const emailOTP = (options) => {
|
|
|
453
557
|
message: ERROR_CODES.OTP_EXPIRED
|
|
454
558
|
});
|
|
455
559
|
}
|
|
456
|
-
const [otpValue, attempts] =
|
|
560
|
+
const [otpValue, attempts] = splitAtLastColon(
|
|
561
|
+
verificationValue.value
|
|
562
|
+
);
|
|
457
563
|
const allowedAttempts = options?.allowedAttempts || 3;
|
|
458
564
|
if (attempts && parseInt(attempts) >= allowedAttempts) {
|
|
459
565
|
await ctx.context.internalAdapter.deleteVerificationValue(
|
|
@@ -463,7 +569,8 @@ const emailOTP = (options) => {
|
|
|
463
569
|
message: ERROR_CODES.TOO_MANY_ATTEMPTS
|
|
464
570
|
});
|
|
465
571
|
}
|
|
466
|
-
|
|
572
|
+
const verified = await verifyStoredOTP(ctx, otpValue, ctx.body.otp);
|
|
573
|
+
if (!verified) {
|
|
467
574
|
await ctx.context.internalAdapter.updateVerificationValue(
|
|
468
575
|
verificationValue.id,
|
|
469
576
|
{
|
|
@@ -589,9 +696,10 @@ const emailOTP = (options) => {
|
|
|
589
696
|
{ email, type: "forget-password" },
|
|
590
697
|
ctx.request
|
|
591
698
|
);
|
|
699
|
+
let storedOTP = await storeOTP(ctx, otp);
|
|
592
700
|
await ctx.context.internalAdapter.createVerificationValue(
|
|
593
701
|
{
|
|
594
|
-
value: `${
|
|
702
|
+
value: `${storedOTP}:0`,
|
|
595
703
|
identifier: `forget-password-otp-${email}`,
|
|
596
704
|
expiresAt: date.getDate(opts.expiresIn, "sec")
|
|
597
705
|
},
|
|
@@ -677,7 +785,9 @@ const emailOTP = (options) => {
|
|
|
677
785
|
message: ERROR_CODES.OTP_EXPIRED
|
|
678
786
|
});
|
|
679
787
|
}
|
|
680
|
-
const [otpValue, attempts] =
|
|
788
|
+
const [otpValue, attempts] = splitAtLastColon(
|
|
789
|
+
verificationValue.value
|
|
790
|
+
);
|
|
681
791
|
const allowedAttempts = options?.allowedAttempts || 3;
|
|
682
792
|
if (attempts && parseInt(attempts) >= allowedAttempts) {
|
|
683
793
|
await ctx.context.internalAdapter.deleteVerificationValue(
|
|
@@ -687,7 +797,8 @@ const emailOTP = (options) => {
|
|
|
687
797
|
message: ERROR_CODES.TOO_MANY_ATTEMPTS
|
|
688
798
|
});
|
|
689
799
|
}
|
|
690
|
-
|
|
800
|
+
const verified = await verifyStoredOTP(ctx, otpValue, ctx.body.otp);
|
|
801
|
+
if (!verified) {
|
|
691
802
|
await ctx.context.internalAdapter.updateVerificationValue(
|
|
692
803
|
verificationValue.id,
|
|
693
804
|
{
|
|
@@ -753,9 +864,10 @@ const emailOTP = (options) => {
|
|
|
753
864
|
{ email, type: ctx.body.type },
|
|
754
865
|
ctx.request
|
|
755
866
|
);
|
|
867
|
+
let storedOTP = await storeOTP(ctx, otp);
|
|
756
868
|
await ctx.context.internalAdapter.createVerificationValue(
|
|
757
869
|
{
|
|
758
|
-
value: `${
|
|
870
|
+
value: `${storedOTP}:0`,
|
|
759
871
|
identifier: `email-verification-otp-${email}`,
|
|
760
872
|
expiresAt: date.getDate(opts.expiresIn, "sec")
|
|
761
873
|
},
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import * as better_call from 'better-call';
|
|
2
|
+
import { p as AuthContext, U as User, H as HookEndpointContext } from '../../shared/better-auth.1M3xAdJC.cjs';
|
|
2
3
|
import { z } from 'zod';
|
|
3
|
-
import { H as HookEndpointContext } from '../../shared/better-auth.CqTBLifU.cjs';
|
|
4
4
|
import '../../shared/better-auth.9XhOL8gb.cjs';
|
|
5
|
-
import '../../shared/better-auth.
|
|
5
|
+
import '../../shared/better-auth.VwFr4owi.cjs';
|
|
6
6
|
import 'kysely';
|
|
7
7
|
import 'better-sqlite3';
|
|
8
8
|
import 'bun:sqlite';
|
|
@@ -53,81 +53,39 @@ interface EmailOTPOptions {
|
|
|
53
53
|
* @default 3
|
|
54
54
|
*/
|
|
55
55
|
allowedAttempts?: number;
|
|
56
|
+
/**
|
|
57
|
+
* Store the OTP in your database in a secure way
|
|
58
|
+
* Note: This will not affect the OTP sent to the user, it will only affect the OTP stored in your database
|
|
59
|
+
*
|
|
60
|
+
* @default "plain"
|
|
61
|
+
*/
|
|
62
|
+
storeOTP?: "hashed" | "plain" | "encrypted" | {
|
|
63
|
+
hash: (otp: string) => Promise<string>;
|
|
64
|
+
} | {
|
|
65
|
+
encrypt: (otp: string) => Promise<string>;
|
|
66
|
+
decrypt: (otp: string) => Promise<string>;
|
|
67
|
+
};
|
|
68
|
+
/**
|
|
69
|
+
* Override the default email verification to use email otp instead
|
|
70
|
+
*
|
|
71
|
+
* @default false
|
|
72
|
+
*/
|
|
73
|
+
overrideDefaultEmailVerification?: boolean;
|
|
56
74
|
}
|
|
57
75
|
declare const emailOTP: (options: EmailOTPOptions) => {
|
|
58
76
|
id: "email-otp";
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
method?: "POST" | undefined;
|
|
68
|
-
} & {
|
|
69
|
-
query?: Record<string, any> | undefined;
|
|
70
|
-
} & {
|
|
71
|
-
params?: Record<string, any>;
|
|
72
|
-
} & {
|
|
73
|
-
request?: Request;
|
|
74
|
-
} & {
|
|
75
|
-
headers?: HeadersInit;
|
|
76
|
-
} & {
|
|
77
|
-
asResponse?: boolean;
|
|
78
|
-
returnHeaders?: boolean;
|
|
79
|
-
use?: better_call.Middleware[];
|
|
80
|
-
path?: string;
|
|
81
|
-
} & {
|
|
82
|
-
asResponse?: AsResponse | undefined;
|
|
83
|
-
returnHeaders?: ReturnHeaders | undefined;
|
|
84
|
-
}): Promise<[AsResponse] extends [true] ? Response : [ReturnHeaders] extends [true] ? {
|
|
85
|
-
headers: Headers;
|
|
86
|
-
response: {
|
|
87
|
-
success: boolean;
|
|
88
|
-
};
|
|
89
|
-
} : {
|
|
90
|
-
success: boolean;
|
|
91
|
-
}>;
|
|
92
|
-
options: {
|
|
93
|
-
method: "POST";
|
|
94
|
-
body: z.ZodObject<{
|
|
95
|
-
email: z.ZodString;
|
|
96
|
-
type: z.ZodEnum<["email-verification", "sign-in", "forget-password"]>;
|
|
97
|
-
}, "strip", z.ZodTypeAny, {
|
|
98
|
-
type: "sign-in" | "forget-password" | "email-verification";
|
|
99
|
-
email: string;
|
|
100
|
-
}, {
|
|
101
|
-
type: "sign-in" | "forget-password" | "email-verification";
|
|
102
|
-
email: string;
|
|
103
|
-
}>;
|
|
104
|
-
metadata: {
|
|
105
|
-
openapi: {
|
|
106
|
-
description: string;
|
|
107
|
-
responses: {
|
|
108
|
-
200: {
|
|
109
|
-
description: string;
|
|
110
|
-
content: {
|
|
111
|
-
"application/json": {
|
|
112
|
-
schema: {
|
|
113
|
-
type: "object";
|
|
114
|
-
properties: {
|
|
115
|
-
success: {
|
|
116
|
-
type: string;
|
|
117
|
-
};
|
|
118
|
-
};
|
|
119
|
-
};
|
|
120
|
-
};
|
|
121
|
-
};
|
|
122
|
-
};
|
|
123
|
-
};
|
|
124
|
-
};
|
|
125
|
-
};
|
|
126
|
-
} & {
|
|
127
|
-
use: any[];
|
|
77
|
+
init(ctx: AuthContext): {
|
|
78
|
+
options: {
|
|
79
|
+
emailVerification: {
|
|
80
|
+
sendVerificationEmail?: ((data: {
|
|
81
|
+
user: User;
|
|
82
|
+
url: string;
|
|
83
|
+
token: string;
|
|
84
|
+
}, request: Request | undefined) => Promise<void>) | undefined;
|
|
128
85
|
};
|
|
129
|
-
path: "/email-otp/send-verification-otp";
|
|
130
86
|
};
|
|
87
|
+
};
|
|
88
|
+
endpoints: {
|
|
131
89
|
createVerificationOTP: {
|
|
132
90
|
<AsResponse extends boolean = false, ReturnHeaders extends boolean = false>(inputCtx_0: {
|
|
133
91
|
body: {
|
|
@@ -633,6 +591,77 @@ declare const emailOTP: (options: EmailOTPOptions) => {
|
|
|
633
591
|
};
|
|
634
592
|
path: "/email-otp/reset-password";
|
|
635
593
|
};
|
|
594
|
+
sendVerificationOTP: {
|
|
595
|
+
<AsResponse extends boolean = false, ReturnHeaders extends boolean = false>(inputCtx_0: {
|
|
596
|
+
body: {
|
|
597
|
+
type: "sign-in" | "forget-password" | "email-verification";
|
|
598
|
+
email: string;
|
|
599
|
+
};
|
|
600
|
+
} & {
|
|
601
|
+
method?: "POST" | undefined;
|
|
602
|
+
} & {
|
|
603
|
+
query?: Record<string, any> | undefined;
|
|
604
|
+
} & {
|
|
605
|
+
params?: Record<string, any>;
|
|
606
|
+
} & {
|
|
607
|
+
request?: Request;
|
|
608
|
+
} & {
|
|
609
|
+
headers?: HeadersInit;
|
|
610
|
+
} & {
|
|
611
|
+
asResponse?: boolean;
|
|
612
|
+
returnHeaders?: boolean;
|
|
613
|
+
use?: better_call.Middleware[];
|
|
614
|
+
path?: string;
|
|
615
|
+
} & {
|
|
616
|
+
asResponse?: AsResponse | undefined;
|
|
617
|
+
returnHeaders?: ReturnHeaders | undefined;
|
|
618
|
+
}): Promise<[AsResponse] extends [true] ? Response : [ReturnHeaders] extends [true] ? {
|
|
619
|
+
headers: Headers;
|
|
620
|
+
response: {
|
|
621
|
+
success: boolean;
|
|
622
|
+
};
|
|
623
|
+
} : {
|
|
624
|
+
success: boolean;
|
|
625
|
+
}>;
|
|
626
|
+
options: {
|
|
627
|
+
method: "POST";
|
|
628
|
+
body: z.ZodObject<{
|
|
629
|
+
email: z.ZodString;
|
|
630
|
+
type: z.ZodEnum<["email-verification", "sign-in", "forget-password"]>;
|
|
631
|
+
}, "strip", z.ZodTypeAny, {
|
|
632
|
+
type: "sign-in" | "forget-password" | "email-verification";
|
|
633
|
+
email: string;
|
|
634
|
+
}, {
|
|
635
|
+
type: "sign-in" | "forget-password" | "email-verification";
|
|
636
|
+
email: string;
|
|
637
|
+
}>;
|
|
638
|
+
metadata: {
|
|
639
|
+
openapi: {
|
|
640
|
+
description: string;
|
|
641
|
+
responses: {
|
|
642
|
+
200: {
|
|
643
|
+
description: string;
|
|
644
|
+
content: {
|
|
645
|
+
"application/json": {
|
|
646
|
+
schema: {
|
|
647
|
+
type: "object";
|
|
648
|
+
properties: {
|
|
649
|
+
success: {
|
|
650
|
+
type: string;
|
|
651
|
+
};
|
|
652
|
+
};
|
|
653
|
+
};
|
|
654
|
+
};
|
|
655
|
+
};
|
|
656
|
+
};
|
|
657
|
+
};
|
|
658
|
+
};
|
|
659
|
+
};
|
|
660
|
+
} & {
|
|
661
|
+
use: any[];
|
|
662
|
+
};
|
|
663
|
+
path: "/email-otp/send-verification-otp";
|
|
664
|
+
};
|
|
636
665
|
};
|
|
637
666
|
hooks: {
|
|
638
667
|
after: {
|