@xk2800/nextjs-template 0.6.1-beta.0 → 0.6.1-beta.2
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/components/auth/forgotPasswordForm.tsx +1 -1
- package/components/dashboard/twoFactorCard.tsx +2 -1
- package/dist/activity/logger.js +5 -1
- package/dist/activity/logger.js.map +1 -1
- package/dist/activity/logger.mjs +4 -4
- package/dist/activity/queries.d.mts +1 -1
- package/dist/activity/queries.d.ts +1 -1
- package/dist/activity/queries.js +5 -1
- package/dist/activity/queries.js.map +1 -1
- package/dist/activity/queries.mjs +3 -3
- package/dist/admin/queries.js +5 -1
- package/dist/admin/queries.js.map +1 -1
- package/dist/admin/queries.mjs +3 -3
- package/dist/auth/helpers.d.mts +3 -3
- package/dist/auth/helpers.d.ts +3 -3
- package/dist/auth/helpers.js +183 -151
- package/dist/auth/helpers.js.map +1 -1
- package/dist/auth/helpers.mjs +6 -6
- package/dist/auth/index.d.mts +3313 -5326
- package/dist/auth/index.d.ts +3313 -5326
- package/dist/auth/index.js +183 -151
- package/dist/auth/index.js.map +1 -1
- package/dist/auth/index.mjs +6 -6
- package/dist/auth-client/index.d.mts +5052 -4718
- package/dist/auth-client/index.d.ts +5052 -4718
- package/dist/auth-client/index.js +3 -9
- package/dist/auth-client/index.js.map +1 -1
- package/dist/auth-client/index.mjs +4 -10
- package/dist/auth-client/index.mjs.map +1 -1
- package/dist/{chunk-YN4436PK.mjs → chunk-3465SI5N.mjs} +3 -9
- package/dist/{chunk-YN4436PK.mjs.map → chunk-3465SI5N.mjs.map} +1 -1
- package/dist/{chunk-YZPJ54QG.mjs → chunk-4B7MJOLH.mjs} +8 -4
- package/dist/chunk-4B7MJOLH.mjs.map +1 -0
- package/dist/{chunk-SJE6A43W.mjs → chunk-5PYDAD4P.mjs} +3 -3
- package/dist/{chunk-SJE6A43W.mjs.map → chunk-5PYDAD4P.mjs.map} +1 -1
- package/dist/{chunk-HJ62TBEK.mjs → chunk-IF3JZRSZ.mjs} +5 -5
- package/dist/{chunk-HJ62TBEK.mjs.map → chunk-IF3JZRSZ.mjs.map} +1 -1
- package/dist/{chunk-AJRWDR65.mjs → chunk-OHAUKE2Q.mjs} +4 -4
- package/dist/{chunk-AJRWDR65.mjs.map → chunk-OHAUKE2Q.mjs.map} +1 -1
- package/dist/{chunk-WYQDMN26.mjs → chunk-V72CFFU2.mjs} +29 -147
- package/dist/chunk-V72CFFU2.mjs.map +1 -0
- package/dist/config/env.mjs +1 -1
- package/dist/db/index.d.mts +1 -1
- package/dist/db/index.d.ts +1 -1
- package/dist/db/index.js +5 -1
- package/dist/db/index.js.map +1 -1
- package/dist/db/index.mjs +3 -3
- package/dist/db/schema.d.mts +1 -1
- package/dist/db/schema.d.ts +1 -1
- package/dist/db/schema.js +5 -1
- package/dist/db/schema.js.map +1 -1
- package/dist/db/schema.mjs +2 -2
- package/dist/email-template-passkey-change-F5Q2SXHD.mjs +66 -0
- package/dist/email-template-passkey-change-F5Q2SXHD.mjs.map +1 -0
- package/dist/email-template-reset-password-QTCQNXOD.mjs +42 -0
- package/dist/email-template-reset-password-QTCQNXOD.mjs.map +1 -0
- package/dist/email-template-verify-email-WZDCCAKK.mjs +34 -0
- package/dist/email-template-verify-email-WZDCCAKK.mjs.map +1 -0
- package/dist/{schema-B2bpUUth.d.mts → schema-BrBmQFkn.d.mts} +52 -1
- package/dist/{schema-B2bpUUth.d.ts → schema-BrBmQFkn.d.ts} +52 -1
- package/dist/sessions/queries.js +5 -1
- package/dist/sessions/queries.js.map +1 -1
- package/dist/sessions/queries.mjs +3 -3
- package/dist/settings/queries.d.mts +1 -1
- package/dist/settings/queries.d.ts +1 -1
- package/dist/settings/queries.js +5 -1
- package/dist/settings/queries.js.map +1 -1
- package/dist/settings/queries.mjs +4 -4
- package/dist/types/auth/loginSchema.mjs +1 -1
- package/dist/types/auth/signupSchema.mjs +1 -1
- package/dist/users/queries.js +5 -1
- package/dist/users/queries.js.map +1 -1
- package/dist/users/queries.mjs +3 -3
- package/lib/auth-client.ts +4 -22
- package/lib/cookie-consent.ts +54 -0
- package/package.json +5 -3
- package/dist/chunk-WYQDMN26.mjs.map +0 -1
- package/dist/chunk-YZPJ54QG.mjs.map +0 -1
package/dist/auth/helpers.js
CHANGED
|
@@ -1,37 +1,35 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
|
+
var components = require('@react-email/components');
|
|
4
|
+
var jsxRuntime = require('react/jsx-runtime');
|
|
3
5
|
require('server-only');
|
|
4
6
|
var react = require('react');
|
|
5
7
|
var betterAuth = require('better-auth');
|
|
6
8
|
var drizzle = require('better-auth/adapters/drizzle');
|
|
9
|
+
var cuid2 = require('@paralleldrive/cuid2');
|
|
7
10
|
var drizzleOrm = require('drizzle-orm');
|
|
8
11
|
var serverless = require('@neondatabase/serverless');
|
|
9
12
|
var neonHttp = require('drizzle-orm/neon-http');
|
|
10
13
|
var nodePostgres = require('drizzle-orm/node-postgres');
|
|
11
14
|
var pg = require('pg');
|
|
12
15
|
var pgCore = require('drizzle-orm/pg-core');
|
|
13
|
-
var cuid2 = require('@paralleldrive/cuid2');
|
|
14
16
|
var zod = require('zod');
|
|
15
|
-
var bcrypt = require('bcrypt');
|
|
16
17
|
var plugins = require('better-auth/plugins');
|
|
17
|
-
var passkey = require('better-auth/
|
|
18
|
+
var passkey = require('@better-auth/passkey');
|
|
18
19
|
var api = require('better-auth/api');
|
|
19
20
|
var uaParserJs = require('ua-parser-js');
|
|
20
21
|
var geoip = require('geoip-lite');
|
|
21
|
-
var resend$1 = require('resend');
|
|
22
|
-
var components = require('@react-email/components');
|
|
23
|
-
var jsxRuntime = require('react/jsx-runtime');
|
|
24
22
|
var headers = require('next/headers');
|
|
25
23
|
var navigation = require('next/navigation');
|
|
26
24
|
|
|
27
25
|
function _interopDefault (e) { return e && e.__esModule ? e : { default: e }; }
|
|
28
26
|
|
|
29
|
-
var bcrypt__default = /*#__PURE__*/_interopDefault(bcrypt);
|
|
30
27
|
var geoip__default = /*#__PURE__*/_interopDefault(geoip);
|
|
31
28
|
|
|
32
29
|
var __defProp = Object.defineProperty;
|
|
33
30
|
var __defProps = Object.defineProperties;
|
|
34
31
|
var __getOwnPropDescs = Object.getOwnPropertyDescriptors;
|
|
32
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
35
33
|
var __getOwnPropSymbols = Object.getOwnPropertySymbols;
|
|
36
34
|
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
37
35
|
var __propIsEnum = Object.prototype.propertyIsEnumerable;
|
|
@@ -48,17 +46,162 @@ var __spreadValues = (a, b) => {
|
|
|
48
46
|
return a;
|
|
49
47
|
};
|
|
50
48
|
var __spreadProps = (a, b) => __defProps(a, __getOwnPropDescs(b));
|
|
51
|
-
var
|
|
52
|
-
|
|
53
|
-
}
|
|
54
|
-
if (typeof require !== "undefined") return require.apply(this, arguments);
|
|
55
|
-
throw Error('Dynamic require of "' + x + '" is not supported');
|
|
56
|
-
});
|
|
49
|
+
var __esm = (fn, res) => function __init() {
|
|
50
|
+
return fn && (res = (0, fn[__getOwnPropNames(fn)[0]])(fn = 0)), res;
|
|
51
|
+
};
|
|
57
52
|
var __export = (target, all) => {
|
|
58
53
|
for (var name in all)
|
|
59
54
|
__defProp(target, name, { get: all[name], enumerable: true });
|
|
60
55
|
};
|
|
61
56
|
|
|
57
|
+
// components/email/email-template-passkey-change.tsx
|
|
58
|
+
var email_template_passkey_change_exports = {};
|
|
59
|
+
__export(email_template_passkey_change_exports, {
|
|
60
|
+
EmailTemplatePasskeyChange: () => EmailTemplatePasskeyChange
|
|
61
|
+
});
|
|
62
|
+
function EmailTemplatePasskeyChange({
|
|
63
|
+
firstName,
|
|
64
|
+
action,
|
|
65
|
+
device,
|
|
66
|
+
location,
|
|
67
|
+
ipAddress,
|
|
68
|
+
when,
|
|
69
|
+
manageUrl
|
|
70
|
+
}) {
|
|
71
|
+
const verb = action === "added" ? "added to" : "removed from";
|
|
72
|
+
return /* @__PURE__ */ jsxRuntime.jsxs(components.Html, { children: [
|
|
73
|
+
/* @__PURE__ */ jsxRuntime.jsx(components.Head, {}),
|
|
74
|
+
/* @__PURE__ */ jsxRuntime.jsx(components.Tailwind, { children: /* @__PURE__ */ jsxRuntime.jsx(components.Body, { className: "bg-white font-sans", children: /* @__PURE__ */ jsxRuntime.jsx(components.Container, { className: "mx-auto max-w-[560px] px-0 pt-5 pb-12", children: /* @__PURE__ */ jsxRuntime.jsxs(components.Section, { className: "rounded-xl bg-[#f8f9fa] p-10", children: [
|
|
75
|
+
/* @__PURE__ */ jsxRuntime.jsxs(components.Heading, { className: "mb-3 text-center text-2xl font-bold text-[#1a1a1a]", children: [
|
|
76
|
+
"A passkey was ",
|
|
77
|
+
action
|
|
78
|
+
] }),
|
|
79
|
+
/* @__PURE__ */ jsxRuntime.jsxs(components.Text, { className: "mb-6 text-base leading-6 text-[#666666]", children: [
|
|
80
|
+
"Hi ",
|
|
81
|
+
firstName,
|
|
82
|
+
", a passkey was just ",
|
|
83
|
+
verb,
|
|
84
|
+
" your account."
|
|
85
|
+
] }),
|
|
86
|
+
/* @__PURE__ */ jsxRuntime.jsxs(components.Section, { className: "mb-6 rounded-lg bg-white p-5", children: [
|
|
87
|
+
/* @__PURE__ */ jsxRuntime.jsxs(components.Text, { className: "m-0 mb-2 text-sm leading-5 text-[#1a1a1a]", children: [
|
|
88
|
+
/* @__PURE__ */ jsxRuntime.jsx("strong", { children: "Device:" }),
|
|
89
|
+
" ",
|
|
90
|
+
device
|
|
91
|
+
] }),
|
|
92
|
+
/* @__PURE__ */ jsxRuntime.jsxs(components.Text, { className: "m-0 mb-2 text-sm leading-5 text-[#1a1a1a]", children: [
|
|
93
|
+
/* @__PURE__ */ jsxRuntime.jsx("strong", { children: "Approx. location:" }),
|
|
94
|
+
" ",
|
|
95
|
+
location
|
|
96
|
+
] }),
|
|
97
|
+
/* @__PURE__ */ jsxRuntime.jsxs(components.Text, { className: "m-0 mb-2 text-sm leading-5 text-[#1a1a1a]", children: [
|
|
98
|
+
/* @__PURE__ */ jsxRuntime.jsx("strong", { children: "IP address:" }),
|
|
99
|
+
" ",
|
|
100
|
+
ipAddress
|
|
101
|
+
] }),
|
|
102
|
+
/* @__PURE__ */ jsxRuntime.jsxs(components.Text, { className: "m-0 text-sm leading-5 text-[#1a1a1a]", children: [
|
|
103
|
+
/* @__PURE__ */ jsxRuntime.jsx("strong", { children: "When:" }),
|
|
104
|
+
" ",
|
|
105
|
+
when
|
|
106
|
+
] })
|
|
107
|
+
] }),
|
|
108
|
+
manageUrl && /* @__PURE__ */ jsxRuntime.jsx(components.Section, { className: "mb-6 text-center", children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
109
|
+
components.Button,
|
|
110
|
+
{
|
|
111
|
+
href: manageUrl,
|
|
112
|
+
className: "rounded-lg bg-[#1a1a1a] px-6 py-3 text-sm font-bold text-white no-underline",
|
|
113
|
+
children: "Review your passkeys"
|
|
114
|
+
}
|
|
115
|
+
) }),
|
|
116
|
+
/* @__PURE__ */ jsxRuntime.jsx(components.Text, { className: "text-sm leading-[22px] text-[#666666]", children: "If this was you, no action is needed. If you don't recognize it, change your password now and review your passkeys and active sessions." })
|
|
117
|
+
] }) }) }) })
|
|
118
|
+
] });
|
|
119
|
+
}
|
|
120
|
+
var init_email_template_passkey_change = __esm({
|
|
121
|
+
"components/email/email-template-passkey-change.tsx"() {
|
|
122
|
+
}
|
|
123
|
+
});
|
|
124
|
+
|
|
125
|
+
// components/email/email-template-reset-password.tsx
|
|
126
|
+
var email_template_reset_password_exports = {};
|
|
127
|
+
__export(email_template_reset_password_exports, {
|
|
128
|
+
EmailTemplateResetPassword: () => EmailTemplateResetPassword
|
|
129
|
+
});
|
|
130
|
+
function EmailTemplateResetPassword({ firstName, url }) {
|
|
131
|
+
return /* @__PURE__ */ jsxRuntime.jsxs(components.Html, { children: [
|
|
132
|
+
/* @__PURE__ */ jsxRuntime.jsx(components.Head, {}),
|
|
133
|
+
/* @__PURE__ */ jsxRuntime.jsx(components.Body, { style: { backgroundColor: "#ffffff", fontFamily: "Arial, sans-serif" }, children: /* @__PURE__ */ jsxRuntime.jsx(components.Container, { style: { margin: "0 auto", padding: "20px 0 48px", maxWidth: "560px" }, children: /* @__PURE__ */ jsxRuntime.jsxs(components.Section, { style: { backgroundColor: "#f8f9fa", borderRadius: "12px", padding: "40px", textAlign: "center" }, children: [
|
|
134
|
+
/* @__PURE__ */ jsxRuntime.jsx(components.Heading, { style: { fontSize: "28px", fontWeight: "bold", marginBottom: "12px", color: "#1a1a1a" }, children: "Reset your password" }),
|
|
135
|
+
/* @__PURE__ */ jsxRuntime.jsxs(components.Text, { style: { fontSize: "16px", color: "#666666", marginBottom: "32px", lineHeight: "24px" }, children: [
|
|
136
|
+
"Hi ",
|
|
137
|
+
firstName,
|
|
138
|
+
", we got a request to reset your password. This link expires in an hour \u2014 if you didn't ask for this, you can safely ignore this email."
|
|
139
|
+
] }),
|
|
140
|
+
/* @__PURE__ */ jsxRuntime.jsx(components.Section, { style: { marginBottom: "32px" }, children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
141
|
+
components.Button,
|
|
142
|
+
{
|
|
143
|
+
href: url,
|
|
144
|
+
style: {
|
|
145
|
+
backgroundColor: "#000000",
|
|
146
|
+
color: "#ffffff",
|
|
147
|
+
padding: "12px 32px",
|
|
148
|
+
borderRadius: "6px",
|
|
149
|
+
textDecoration: "none",
|
|
150
|
+
fontSize: "16px",
|
|
151
|
+
fontWeight: "bold"
|
|
152
|
+
},
|
|
153
|
+
children: "Reset password"
|
|
154
|
+
}
|
|
155
|
+
) }),
|
|
156
|
+
/* @__PURE__ */ jsxRuntime.jsxs(components.Text, { style: { fontSize: "13px", color: "#999999", lineHeight: "20px", wordBreak: "break-all" }, children: [
|
|
157
|
+
"Or paste this link into your browser:",
|
|
158
|
+
/* @__PURE__ */ jsxRuntime.jsx("br", {}),
|
|
159
|
+
/* @__PURE__ */ jsxRuntime.jsx("a", { href: url, style: { color: "#000000", textDecoration: "underline" }, children: url })
|
|
160
|
+
] })
|
|
161
|
+
] }) }) })
|
|
162
|
+
] });
|
|
163
|
+
}
|
|
164
|
+
var init_email_template_reset_password = __esm({
|
|
165
|
+
"components/email/email-template-reset-password.tsx"() {
|
|
166
|
+
}
|
|
167
|
+
});
|
|
168
|
+
|
|
169
|
+
// components/email/email-template-verify-email.tsx
|
|
170
|
+
var email_template_verify_email_exports = {};
|
|
171
|
+
__export(email_template_verify_email_exports, {
|
|
172
|
+
EmailTemplateVerifyEmail: () => EmailTemplateVerifyEmail
|
|
173
|
+
});
|
|
174
|
+
function EmailTemplateVerifyEmail({ firstName, url }) {
|
|
175
|
+
return /* @__PURE__ */ jsxRuntime.jsxs(components.Html, { children: [
|
|
176
|
+
/* @__PURE__ */ jsxRuntime.jsx(components.Head, {}),
|
|
177
|
+
/* @__PURE__ */ jsxRuntime.jsx(components.Tailwind, { children: /* @__PURE__ */ jsxRuntime.jsx(components.Body, { className: "bg-white font-sans", children: /* @__PURE__ */ jsxRuntime.jsx(components.Container, { className: "mx-auto max-w-[560px] px-0 pt-5 pb-12", children: /* @__PURE__ */ jsxRuntime.jsxs(components.Section, { className: "rounded-xl bg-[#f8f9fa] p-10 text-center", children: [
|
|
178
|
+
/* @__PURE__ */ jsxRuntime.jsx(components.Heading, { className: "mb-3 text-[28px] font-bold text-[#1a1a1a]", children: "Confirm your email" }),
|
|
179
|
+
/* @__PURE__ */ jsxRuntime.jsxs(components.Text, { className: "mb-8 text-base leading-6 text-[#666666]", children: [
|
|
180
|
+
"Hi ",
|
|
181
|
+
firstName,
|
|
182
|
+
", click the button below to verify this email address. If you didn't create an account, you can safely ignore this email."
|
|
183
|
+
] }),
|
|
184
|
+
/* @__PURE__ */ jsxRuntime.jsx(components.Section, { className: "mb-8", children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
185
|
+
components.Button,
|
|
186
|
+
{
|
|
187
|
+
href: url,
|
|
188
|
+
className: "rounded-md bg-black px-8 py-3 text-base font-bold text-white no-underline",
|
|
189
|
+
children: "Verify email"
|
|
190
|
+
}
|
|
191
|
+
) }),
|
|
192
|
+
/* @__PURE__ */ jsxRuntime.jsxs(components.Text, { className: "text-[13px] leading-5 break-all text-[#999999]", children: [
|
|
193
|
+
"Or paste this link into your browser:",
|
|
194
|
+
/* @__PURE__ */ jsxRuntime.jsx("br", {}),
|
|
195
|
+
/* @__PURE__ */ jsxRuntime.jsx(components.Link, { href: url, className: "text-black underline", children: url })
|
|
196
|
+
] })
|
|
197
|
+
] }) }) }) })
|
|
198
|
+
] });
|
|
199
|
+
}
|
|
200
|
+
var init_email_template_verify_email = __esm({
|
|
201
|
+
"components/email/email-template-verify-email.tsx"() {
|
|
202
|
+
}
|
|
203
|
+
});
|
|
204
|
+
|
|
62
205
|
// server/db/schema.ts
|
|
63
206
|
var schema_exports = {};
|
|
64
207
|
__export(schema_exports, {
|
|
@@ -162,7 +305,11 @@ var twoFactors = pgCore.pgTable("twoFactor", {
|
|
|
162
305
|
id: pgCore.text("id").notNull().primaryKey().$defaultFn(() => cuid2.createId()),
|
|
163
306
|
secret: pgCore.text("secret").notNull(),
|
|
164
307
|
backupCodes: pgCore.text("backupCodes").notNull(),
|
|
165
|
-
userId: pgCore.text("userId").notNull().references(() => users.id, { onDelete: "cascade" })
|
|
308
|
+
userId: pgCore.text("userId").notNull().references(() => users.id, { onDelete: "cascade" }),
|
|
309
|
+
// Added in better-auth 1.7 (TOTP lockout). Defaults match the plugin's.
|
|
310
|
+
verified: pgCore.boolean("verified").default(true),
|
|
311
|
+
failedVerificationCount: pgCore.integer("failedVerificationCount").default(0),
|
|
312
|
+
lockedUntil: pgCore.timestamp("lockedUntil")
|
|
166
313
|
});
|
|
167
314
|
var passkeys = pgCore.pgTable("passkey", {
|
|
168
315
|
id: pgCore.text("id").notNull().primaryKey().$defaultFn(() => cuid2.createId()),
|
|
@@ -490,128 +637,13 @@ async function getEffectiveAuthFlags() {
|
|
|
490
637
|
}
|
|
491
638
|
var EMAIL_FROM = "Acme <onboarding@xavierkhew.xyz>";
|
|
492
639
|
var resend;
|
|
493
|
-
function getResend() {
|
|
494
|
-
if (!resend)
|
|
640
|
+
async function getResend() {
|
|
641
|
+
if (!resend) {
|
|
642
|
+
const { Resend } = await import('resend');
|
|
643
|
+
resend = new Resend(config.RESEND_API_KEY);
|
|
644
|
+
}
|
|
495
645
|
return resend;
|
|
496
646
|
}
|
|
497
|
-
function EmailTemplateResetPassword({ firstName, url }) {
|
|
498
|
-
return /* @__PURE__ */ jsxRuntime.jsxs(components.Html, { children: [
|
|
499
|
-
/* @__PURE__ */ jsxRuntime.jsx(components.Head, {}),
|
|
500
|
-
/* @__PURE__ */ jsxRuntime.jsx(components.Body, { style: { backgroundColor: "#ffffff", fontFamily: "Arial, sans-serif" }, children: /* @__PURE__ */ jsxRuntime.jsx(components.Container, { style: { margin: "0 auto", padding: "20px 0 48px", maxWidth: "560px" }, children: /* @__PURE__ */ jsxRuntime.jsxs(components.Section, { style: { backgroundColor: "#f8f9fa", borderRadius: "12px", padding: "40px", textAlign: "center" }, children: [
|
|
501
|
-
/* @__PURE__ */ jsxRuntime.jsx(components.Heading, { style: { fontSize: "28px", fontWeight: "bold", marginBottom: "12px", color: "#1a1a1a" }, children: "Reset your password" }),
|
|
502
|
-
/* @__PURE__ */ jsxRuntime.jsxs(components.Text, { style: { fontSize: "16px", color: "#666666", marginBottom: "32px", lineHeight: "24px" }, children: [
|
|
503
|
-
"Hi ",
|
|
504
|
-
firstName,
|
|
505
|
-
", we got a request to reset your password. This link expires in an hour \u2014 if you didn't ask for this, you can safely ignore this email."
|
|
506
|
-
] }),
|
|
507
|
-
/* @__PURE__ */ jsxRuntime.jsx(components.Section, { style: { marginBottom: "32px" }, children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
508
|
-
components.Button,
|
|
509
|
-
{
|
|
510
|
-
href: url,
|
|
511
|
-
style: {
|
|
512
|
-
backgroundColor: "#000000",
|
|
513
|
-
color: "#ffffff",
|
|
514
|
-
padding: "12px 32px",
|
|
515
|
-
borderRadius: "6px",
|
|
516
|
-
textDecoration: "none",
|
|
517
|
-
fontSize: "16px",
|
|
518
|
-
fontWeight: "bold"
|
|
519
|
-
},
|
|
520
|
-
children: "Reset password"
|
|
521
|
-
}
|
|
522
|
-
) }),
|
|
523
|
-
/* @__PURE__ */ jsxRuntime.jsxs(components.Text, { style: { fontSize: "13px", color: "#999999", lineHeight: "20px", wordBreak: "break-all" }, children: [
|
|
524
|
-
"Or paste this link into your browser:",
|
|
525
|
-
/* @__PURE__ */ jsxRuntime.jsx("br", {}),
|
|
526
|
-
/* @__PURE__ */ jsxRuntime.jsx("a", { href: url, style: { color: "#000000", textDecoration: "underline" }, children: url })
|
|
527
|
-
] })
|
|
528
|
-
] }) }) })
|
|
529
|
-
] });
|
|
530
|
-
}
|
|
531
|
-
function EmailTemplateVerifyEmail({ firstName, url }) {
|
|
532
|
-
return /* @__PURE__ */ jsxRuntime.jsxs(components.Html, { children: [
|
|
533
|
-
/* @__PURE__ */ jsxRuntime.jsx(components.Head, {}),
|
|
534
|
-
/* @__PURE__ */ jsxRuntime.jsx(components.Tailwind, { children: /* @__PURE__ */ jsxRuntime.jsx(components.Body, { className: "bg-white font-sans", children: /* @__PURE__ */ jsxRuntime.jsx(components.Container, { className: "mx-auto max-w-[560px] px-0 pt-5 pb-12", children: /* @__PURE__ */ jsxRuntime.jsxs(components.Section, { className: "rounded-xl bg-[#f8f9fa] p-10 text-center", children: [
|
|
535
|
-
/* @__PURE__ */ jsxRuntime.jsx(components.Heading, { className: "mb-3 text-[28px] font-bold text-[#1a1a1a]", children: "Confirm your email" }),
|
|
536
|
-
/* @__PURE__ */ jsxRuntime.jsxs(components.Text, { className: "mb-8 text-base leading-6 text-[#666666]", children: [
|
|
537
|
-
"Hi ",
|
|
538
|
-
firstName,
|
|
539
|
-
", click the button below to verify this email address. If you didn't create an account, you can safely ignore this email."
|
|
540
|
-
] }),
|
|
541
|
-
/* @__PURE__ */ jsxRuntime.jsx(components.Section, { className: "mb-8", children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
542
|
-
components.Button,
|
|
543
|
-
{
|
|
544
|
-
href: url,
|
|
545
|
-
className: "rounded-md bg-black px-8 py-3 text-base font-bold text-white no-underline",
|
|
546
|
-
children: "Verify email"
|
|
547
|
-
}
|
|
548
|
-
) }),
|
|
549
|
-
/* @__PURE__ */ jsxRuntime.jsxs(components.Text, { className: "text-[13px] leading-5 break-all text-[#999999]", children: [
|
|
550
|
-
"Or paste this link into your browser:",
|
|
551
|
-
/* @__PURE__ */ jsxRuntime.jsx("br", {}),
|
|
552
|
-
/* @__PURE__ */ jsxRuntime.jsx(components.Link, { href: url, className: "text-black underline", children: url })
|
|
553
|
-
] })
|
|
554
|
-
] }) }) }) })
|
|
555
|
-
] });
|
|
556
|
-
}
|
|
557
|
-
function EmailTemplatePasskeyChange({
|
|
558
|
-
firstName,
|
|
559
|
-
action,
|
|
560
|
-
device,
|
|
561
|
-
location,
|
|
562
|
-
ipAddress,
|
|
563
|
-
when,
|
|
564
|
-
manageUrl
|
|
565
|
-
}) {
|
|
566
|
-
const verb = action === "added" ? "added to" : "removed from";
|
|
567
|
-
return /* @__PURE__ */ jsxRuntime.jsxs(components.Html, { children: [
|
|
568
|
-
/* @__PURE__ */ jsxRuntime.jsx(components.Head, {}),
|
|
569
|
-
/* @__PURE__ */ jsxRuntime.jsx(components.Tailwind, { children: /* @__PURE__ */ jsxRuntime.jsx(components.Body, { className: "bg-white font-sans", children: /* @__PURE__ */ jsxRuntime.jsx(components.Container, { className: "mx-auto max-w-[560px] px-0 pt-5 pb-12", children: /* @__PURE__ */ jsxRuntime.jsxs(components.Section, { className: "rounded-xl bg-[#f8f9fa] p-10", children: [
|
|
570
|
-
/* @__PURE__ */ jsxRuntime.jsxs(components.Heading, { className: "mb-3 text-center text-2xl font-bold text-[#1a1a1a]", children: [
|
|
571
|
-
"A passkey was ",
|
|
572
|
-
action
|
|
573
|
-
] }),
|
|
574
|
-
/* @__PURE__ */ jsxRuntime.jsxs(components.Text, { className: "mb-6 text-base leading-6 text-[#666666]", children: [
|
|
575
|
-
"Hi ",
|
|
576
|
-
firstName,
|
|
577
|
-
", a passkey was just ",
|
|
578
|
-
verb,
|
|
579
|
-
" your account."
|
|
580
|
-
] }),
|
|
581
|
-
/* @__PURE__ */ jsxRuntime.jsxs(components.Section, { className: "mb-6 rounded-lg bg-white p-5", children: [
|
|
582
|
-
/* @__PURE__ */ jsxRuntime.jsxs(components.Text, { className: "m-0 mb-2 text-sm leading-5 text-[#1a1a1a]", children: [
|
|
583
|
-
/* @__PURE__ */ jsxRuntime.jsx("strong", { children: "Device:" }),
|
|
584
|
-
" ",
|
|
585
|
-
device
|
|
586
|
-
] }),
|
|
587
|
-
/* @__PURE__ */ jsxRuntime.jsxs(components.Text, { className: "m-0 mb-2 text-sm leading-5 text-[#1a1a1a]", children: [
|
|
588
|
-
/* @__PURE__ */ jsxRuntime.jsx("strong", { children: "Approx. location:" }),
|
|
589
|
-
" ",
|
|
590
|
-
location
|
|
591
|
-
] }),
|
|
592
|
-
/* @__PURE__ */ jsxRuntime.jsxs(components.Text, { className: "m-0 mb-2 text-sm leading-5 text-[#1a1a1a]", children: [
|
|
593
|
-
/* @__PURE__ */ jsxRuntime.jsx("strong", { children: "IP address:" }),
|
|
594
|
-
" ",
|
|
595
|
-
ipAddress
|
|
596
|
-
] }),
|
|
597
|
-
/* @__PURE__ */ jsxRuntime.jsxs(components.Text, { className: "m-0 text-sm leading-5 text-[#1a1a1a]", children: [
|
|
598
|
-
/* @__PURE__ */ jsxRuntime.jsx("strong", { children: "When:" }),
|
|
599
|
-
" ",
|
|
600
|
-
when
|
|
601
|
-
] })
|
|
602
|
-
] }),
|
|
603
|
-
manageUrl && /* @__PURE__ */ jsxRuntime.jsx(components.Section, { className: "mb-6 text-center", children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
604
|
-
components.Button,
|
|
605
|
-
{
|
|
606
|
-
href: manageUrl,
|
|
607
|
-
className: "rounded-lg bg-[#1a1a1a] px-6 py-3 text-sm font-bold text-white no-underline",
|
|
608
|
-
children: "Review your passkeys"
|
|
609
|
-
}
|
|
610
|
-
) }),
|
|
611
|
-
/* @__PURE__ */ jsxRuntime.jsx(components.Text, { className: "text-sm leading-[22px] text-[#666666]", children: "If this was you, no action is needed. If you don't recognize it, change your password now and review your passkeys and active sessions." })
|
|
612
|
-
] }) }) }) })
|
|
613
|
-
] });
|
|
614
|
-
}
|
|
615
647
|
|
|
616
648
|
// server/auth.ts
|
|
617
649
|
async function logFailedLogin(ctx) {
|
|
@@ -648,11 +680,12 @@ async function notifyPasskeyChange(ctx, action) {
|
|
|
648
680
|
userAgent: (_b = (_a = ctx.headers) == null ? void 0 : _a.get("user-agent")) != null ? _b : null
|
|
649
681
|
});
|
|
650
682
|
if (!config.RESEND_API_KEY) return;
|
|
651
|
-
await
|
|
683
|
+
const { EmailTemplatePasskeyChange: EmailTemplatePasskeyChange2 } = await Promise.resolve().then(() => (init_email_template_passkey_change(), email_template_passkey_change_exports));
|
|
684
|
+
await (await getResend()).emails.send({
|
|
652
685
|
from: EMAIL_FROM,
|
|
653
686
|
to: [user.email],
|
|
654
687
|
subject: action === "added" ? "A passkey was added to your account" : "A passkey was removed from your account",
|
|
655
|
-
react:
|
|
688
|
+
react: EmailTemplatePasskeyChange2({
|
|
656
689
|
firstName: user.name || "there",
|
|
657
690
|
action,
|
|
658
691
|
device: formatDeviceInfo(parseUserAgent((_d = (_c = ctx.headers) == null ? void 0 : _c.get("user-agent")) != null ? _d : null)),
|
|
@@ -711,22 +744,16 @@ function createAuth(overrides = {}) {
|
|
|
711
744
|
emailAndPassword: {
|
|
712
745
|
enabled: emailAndPasswordEnabled,
|
|
713
746
|
requireEmailVerification: false,
|
|
714
|
-
// Use bcrypt to maintain compatibility with existing user passwords
|
|
715
|
-
async hash(password) {
|
|
716
|
-
return await bcrypt__default.default.hash(password, 10);
|
|
717
|
-
},
|
|
718
|
-
async verify({ hash, password }) {
|
|
719
|
-
return await bcrypt__default.default.compare(password, hash);
|
|
720
|
-
},
|
|
721
747
|
// `url` is fully composed by better-auth (baseURL + verification token +
|
|
722
748
|
// callbackURL) — see app/(auth)/forgot-password and reset-password for
|
|
723
749
|
// the pages this points at.
|
|
724
750
|
async sendResetPassword({ user, url }) {
|
|
725
|
-
await
|
|
751
|
+
const { EmailTemplateResetPassword: EmailTemplateResetPassword2 } = await Promise.resolve().then(() => (init_email_template_reset_password(), email_template_reset_password_exports));
|
|
752
|
+
await (await getResend()).emails.send({
|
|
726
753
|
from: EMAIL_FROM,
|
|
727
754
|
to: [user.email],
|
|
728
755
|
subject: "Reset your password",
|
|
729
|
-
react:
|
|
756
|
+
react: EmailTemplateResetPassword2({ firstName: user.name || "there", url })
|
|
730
757
|
});
|
|
731
758
|
}
|
|
732
759
|
},
|
|
@@ -738,11 +765,12 @@ function createAuth(overrides = {}) {
|
|
|
738
765
|
emailVerification: {
|
|
739
766
|
autoSignInAfterVerification: true,
|
|
740
767
|
async sendVerificationEmail({ user, url }) {
|
|
741
|
-
await
|
|
768
|
+
const { EmailTemplateVerifyEmail: EmailTemplateVerifyEmail2 } = await Promise.resolve().then(() => (init_email_template_verify_email(), email_template_verify_email_exports));
|
|
769
|
+
await (await getResend()).emails.send({
|
|
742
770
|
from: EMAIL_FROM,
|
|
743
771
|
to: [user.email],
|
|
744
772
|
subject: "Confirm your email",
|
|
745
|
-
react:
|
|
773
|
+
react: EmailTemplateVerifyEmail2({ firstName: user.name || "there", url })
|
|
746
774
|
});
|
|
747
775
|
}
|
|
748
776
|
},
|
|
@@ -763,7 +791,9 @@ function createAuth(overrides = {}) {
|
|
|
763
791
|
},
|
|
764
792
|
// Advanced options
|
|
765
793
|
advanced: {
|
|
766
|
-
|
|
794
|
+
database: {
|
|
795
|
+
generateId: () => cuid2.createId()
|
|
796
|
+
}
|
|
767
797
|
},
|
|
768
798
|
// Every new session row corresponds to a sign-in (credential or OAuth) —
|
|
769
799
|
// use that as the "last logged in" signal rather than session updates,
|
|
@@ -925,8 +955,6 @@ function createAuth(overrides = {}) {
|
|
|
925
955
|
errorURL: "/login"
|
|
926
956
|
},
|
|
927
957
|
plugins: [
|
|
928
|
-
// checks to see if oneTap is enabled and if google provider is available, then add the oneTap plugin
|
|
929
|
-
...config.AUTH_ENABLE_ONE_TAP && Boolean(socialProviders.google) ? [plugins.oneTap()] : [],
|
|
930
958
|
// Registered for impersonation (auth.api.impersonateUser / stopImpersonating)
|
|
931
959
|
// only — role/ban/delete stay on our own custom routes above. adminRoles
|
|
932
960
|
// matches our existing role column so the plugin's own permission checks
|
|
@@ -952,7 +980,11 @@ function createAuth(overrides = {}) {
|
|
|
952
980
|
rpID: new URL(baseURL).hostname,
|
|
953
981
|
rpName: config.APP_NAME,
|
|
954
982
|
origin: baseURL
|
|
955
|
-
})
|
|
983
|
+
}),
|
|
984
|
+
// checks to see if oneTap is enabled and if google provider is available, then add the oneTap plugin.
|
|
985
|
+
// Keep this spread last: a leading spread turns `plugins` from a tuple into a plain
|
|
986
|
+
// array and better-auth 1.7 then drops plugin fields (e.g. session.impersonatedBy).
|
|
987
|
+
...config.AUTH_ENABLE_ONE_TAP && Boolean(socialProviders.google) ? [plugins.oneTap()] : []
|
|
956
988
|
]
|
|
957
989
|
});
|
|
958
990
|
}
|