@xk2800/nextjs-template 0.6.1-beta.0 → 0.6.1-beta.1
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/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.mjs +3 -3
- package/dist/admin/queries.mjs +3 -3
- package/dist/auth/helpers.d.mts +0 -15
- package/dist/auth/helpers.d.ts +0 -15
- package/dist/auth/helpers.js +173 -147
- package/dist/auth/helpers.js.map +1 -1
- package/dist/auth/helpers.mjs +6 -6
- package/dist/auth/index.d.mts +3244 -5307
- package/dist/auth/index.d.ts +3244 -5307
- package/dist/auth/index.js +173 -147
- package/dist/auth/index.js.map +1 -1
- package/dist/auth/index.mjs +6 -6
- package/dist/auth-client/index.d.mts +2353 -4792
- package/dist/auth-client/index.d.ts +2353 -4792
- package/dist/auth-client/index.js +2 -1
- package/dist/auth-client/index.js.map +1 -1
- package/dist/auth-client/index.mjs +3 -2
- 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-HJ62TBEK.mjs → chunk-AGUEAXPN.mjs} +5 -5
- package/dist/{chunk-HJ62TBEK.mjs.map → chunk-AGUEAXPN.mjs.map} +1 -1
- package/dist/{chunk-AJRWDR65.mjs → chunk-B4FKFE7P.mjs} +4 -4
- package/dist/{chunk-AJRWDR65.mjs.map → chunk-B4FKFE7P.mjs.map} +1 -1
- package/dist/{chunk-SJE6A43W.mjs → chunk-FJAZNE3I.mjs} +3 -3
- package/dist/{chunk-SJE6A43W.mjs.map → chunk-FJAZNE3I.mjs.map} +1 -1
- package/dist/{chunk-YZPJ54QG.mjs → chunk-LPL6U5RD.mjs} +3 -3
- package/dist/{chunk-YZPJ54QG.mjs.map → chunk-LPL6U5RD.mjs.map} +1 -1
- package/dist/{chunk-WYQDMN26.mjs → chunk-ZGAODGU3.mjs} +23 -143
- package/dist/chunk-ZGAODGU3.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.mjs +3 -3
- package/dist/db/schema.d.mts +1 -1
- package/dist/db/schema.d.ts +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-c2sve45Z.d.mts} +1 -1
- package/dist/{schema-B2bpUUth.d.ts → schema-c2sve45Z.d.ts} +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.mjs +4 -4
- package/dist/types/auth/loginSchema.mjs +1 -1
- package/dist/types/auth/signupSchema.mjs +1 -1
- package/dist/users/queries.mjs +3 -3
- package/lib/auth-client.ts +2 -1
- package/lib/cookie-consent.ts +54 -0
- package/package.json +4 -2
- package/dist/chunk-WYQDMN26.mjs.map +0 -1
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
var react = require('better-auth/react');
|
|
4
4
|
var plugins = require('better-auth/client/plugins');
|
|
5
|
+
var client = require('@better-auth/passkey/client');
|
|
5
6
|
|
|
6
7
|
// lib/auth-client.ts
|
|
7
8
|
var oneTapEnabled = process.env.NEXT_PUBLIC_AUTH_ENABLE_ONE_TAP === "true";
|
|
@@ -10,7 +11,7 @@ var baseAuthClient = react.createAuthClient({
|
|
|
10
11
|
plugins: [
|
|
11
12
|
plugins.adminClient(),
|
|
12
13
|
plugins.twoFactorClient(),
|
|
13
|
-
|
|
14
|
+
client.passkeyClient(),
|
|
14
15
|
...oneTapEnabled ? [
|
|
15
16
|
// On newer better-auth versions (>=1.6, within our ^1.3.34 range) the
|
|
16
17
|
// one-tap plugin's `getActions` signature doesn't structurally satisfy
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../lib/auth-client.ts"],"names":["createAuthClient","adminClient","twoFactorClient","passkeyClient","oneTapClient"],"mappings":"
|
|
1
|
+
{"version":3,"sources":["../../lib/auth-client.ts"],"names":["createAuthClient","adminClient","twoFactorClient","passkeyClient","oneTapClient"],"mappings":";;;;;;;AAKA,IAAM,aAAA,GAAgB,OAAA,CAAQ,GAAA,CAAI,+BAAA,KAAoC,MAAA;AAMtE,IAAM,iBAAiBA,sBAAA,CAAiB;AAAA,EACtC,SAAS,OAAO,MAAA,KAAW,WAAA,GAAc,MAAA,CAAO,SAAS,MAAA,GAAS,MAAA;AAAA,EAElE,OAAA,EAAS;AAAA,IACPC,mBAAA,EAAY;AAAA,IACZC,uBAAA,EAAgB;AAAA,IAChBC,oBAAA,EAAc;AAAA,IACd,GAAI,aAAA,GAAgB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,MAOlBC,oBAAA,CAAa;AAAA,QACX,QAAA,EAAU,OAAA,CAAQ,GAAA,CAAI,4BAAA,IAAgC,EAAA;AAAA;AAAA,QAEtD,UAAA,EAAY,KAAA;AAAA,QACZ,kBAAA,EAAoB,IAAA;AAAA,QACpB,OAAA,EAAS,QAAA;AAAA,QACT,iBAAA,EAAmB;AAAA;AAAA,SAEnB;AAAA;AAAA,QAEA,aAAA,EAAe;AAAA,UACb,SAAA,EAAW,GAAA;AAAA;AAAA,UACX,WAAA,EAAa;AAAA;AAAA;AACf,OACD;AAAA,QACC;AAAC;AAET,CAAC,CAAA;AAQM,IAAM,UAAA,GAAa;AAGnB,IAAM;AAAA,EACX,UAAA;AAAA,EACA,MAAA;AAAA,EACA,OAAA;AAAA,EACA;AACF,CAAA,GAAI","file":"index.js","sourcesContent":["import { createAuthClient } from \"better-auth/react\"\nimport { oneTapClient, adminClient, twoFactorClient } from \"better-auth/client/plugins\"\nimport { passkeyClient } from \"@better-auth/passkey/client\"\nimport type { BetterAuthClientPlugin } from \"better-auth/client\"\n\nconst oneTapEnabled = process.env.NEXT_PUBLIC_AUTH_ENABLE_ONE_TAP === \"true\"\n\n// Derived (not hand-written) from the plugin's own return type, so it tracks\n// whatever better-auth version is actually installed by the consumer.\ntype OneTapActions = ReturnType<ReturnType<typeof oneTapClient>[\"getActions\"]>\n\nconst baseAuthClient = createAuthClient({\n baseURL: typeof window !== \"undefined\" ? window.location.origin : undefined,\n\n plugins: [\n adminClient(),\n twoFactorClient(),\n passkeyClient(),\n ...(oneTapEnabled ? [\n // On newer better-auth versions (>=1.6, within our ^1.3.34 range) the\n // one-tap plugin's `getActions` signature doesn't structurally satisfy\n // `BetterAuthClientPlugin` (a generic-variance mismatch upstream), so\n // it can't be assigned into this array as-is. Widen it here —\n // `.oneTap` is added back to `authClient`'s type below via\n // `OneTapActions`, independent of this array's inferred plugin type.\n oneTapClient({\n clientId: process.env.NEXT_PUBLIC_GOOGLE_CLIENT_ID || \"\",\n // Optional client configuration:\n autoSelect: false,\n cancelOnTapOutside: true,\n context: \"signin\",\n additionalOptions: {\n // Any extra options for the Google initialize method\n },\n // Configure prompt behavior and exponential backoff:\n promptOptions: {\n baseDelay: 1000, // Base delay in ms (default: 1000)\n maxAttempts: 5 // Maximum number of attempts before triggering onPromptNotification (default: 5)\n }\n }) as unknown as BetterAuthClientPlugin\n ] : []),\n ]\n})\n\n// createAuthClient can't narrow `Option[\"plugins\"]` from a conditional spread,\n// so it loses the one-tap plugin's action types. Add `.oneTap` back here\n// instead of forcing the plugin into the array unconditionally — doing that\n// trips a getActions variance mismatch against BetterAuthClientPlugin on\n// newer better-auth versions (>=1.6). The env check above still fully gates\n// whether the plugin (and thus `.oneTap`) is registered at runtime.\nexport const authClient = baseAuthClient as typeof baseAuthClient & OneTapActions\n\n// Export commonly used hooks and methods for convenience\nexport const {\n useSession,\n signIn,\n signOut,\n signUp,\n} = authClient\n"]}
|
|
@@ -1,6 +1,7 @@
|
|
|
1
|
-
import '../chunk-
|
|
1
|
+
import '../chunk-3465SI5N.mjs';
|
|
2
2
|
import { createAuthClient } from 'better-auth/react';
|
|
3
|
-
import { adminClient, twoFactorClient,
|
|
3
|
+
import { adminClient, twoFactorClient, oneTapClient } from 'better-auth/client/plugins';
|
|
4
|
+
import { passkeyClient } from '@better-auth/passkey/client';
|
|
4
5
|
|
|
5
6
|
var oneTapEnabled = process.env.NEXT_PUBLIC_AUTH_ENABLE_ONE_TAP === "true";
|
|
6
7
|
var baseAuthClient = createAuthClient({
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../lib/auth-client.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"sources":["../../lib/auth-client.ts"],"names":[],"mappings":";;;;;AAKA,IAAM,aAAA,GAAgB,OAAA,CAAQ,GAAA,CAAI,+BAAA,KAAoC,MAAA;AAMtE,IAAM,iBAAiB,gBAAA,CAAiB;AAAA,EACtC,SAAS,OAAO,MAAA,KAAW,WAAA,GAAc,MAAA,CAAO,SAAS,MAAA,GAAS,MAAA;AAAA,EAElE,OAAA,EAAS;AAAA,IACP,WAAA,EAAY;AAAA,IACZ,eAAA,EAAgB;AAAA,IAChB,aAAA,EAAc;AAAA,IACd,GAAI,aAAA,GAAgB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,MAOlB,YAAA,CAAa;AAAA,QACX,QAAA,EAAU,OAAA,CAAQ,GAAA,CAAI,4BAAA,IAAgC,EAAA;AAAA;AAAA,QAEtD,UAAA,EAAY,KAAA;AAAA,QACZ,kBAAA,EAAoB,IAAA;AAAA,QACpB,OAAA,EAAS,QAAA;AAAA,QACT,iBAAA,EAAmB;AAAA;AAAA,SAEnB;AAAA;AAAA,QAEA,aAAA,EAAe;AAAA,UACb,SAAA,EAAW,GAAA;AAAA;AAAA,UACX,WAAA,EAAa;AAAA;AAAA;AACf,OACD;AAAA,QACC;AAAC;AAET,CAAC,CAAA;AAQM,IAAM,UAAA,GAAa;AAGnB,IAAM;AAAA,EACX,UAAA;AAAA,EACA,MAAA;AAAA,EACA,OAAA;AAAA,EACA;AACF,CAAA,GAAI","file":"index.mjs","sourcesContent":["import { createAuthClient } from \"better-auth/react\"\nimport { oneTapClient, adminClient, twoFactorClient } from \"better-auth/client/plugins\"\nimport { passkeyClient } from \"@better-auth/passkey/client\"\nimport type { BetterAuthClientPlugin } from \"better-auth/client\"\n\nconst oneTapEnabled = process.env.NEXT_PUBLIC_AUTH_ENABLE_ONE_TAP === \"true\"\n\n// Derived (not hand-written) from the plugin's own return type, so it tracks\n// whatever better-auth version is actually installed by the consumer.\ntype OneTapActions = ReturnType<ReturnType<typeof oneTapClient>[\"getActions\"]>\n\nconst baseAuthClient = createAuthClient({\n baseURL: typeof window !== \"undefined\" ? window.location.origin : undefined,\n\n plugins: [\n adminClient(),\n twoFactorClient(),\n passkeyClient(),\n ...(oneTapEnabled ? [\n // On newer better-auth versions (>=1.6, within our ^1.3.34 range) the\n // one-tap plugin's `getActions` signature doesn't structurally satisfy\n // `BetterAuthClientPlugin` (a generic-variance mismatch upstream), so\n // it can't be assigned into this array as-is. Widen it here —\n // `.oneTap` is added back to `authClient`'s type below via\n // `OneTapActions`, independent of this array's inferred plugin type.\n oneTapClient({\n clientId: process.env.NEXT_PUBLIC_GOOGLE_CLIENT_ID || \"\",\n // Optional client configuration:\n autoSelect: false,\n cancelOnTapOutside: true,\n context: \"signin\",\n additionalOptions: {\n // Any extra options for the Google initialize method\n },\n // Configure prompt behavior and exponential backoff:\n promptOptions: {\n baseDelay: 1000, // Base delay in ms (default: 1000)\n maxAttempts: 5 // Maximum number of attempts before triggering onPromptNotification (default: 5)\n }\n }) as unknown as BetterAuthClientPlugin\n ] : []),\n ]\n})\n\n// createAuthClient can't narrow `Option[\"plugins\"]` from a conditional spread,\n// so it loses the one-tap plugin's action types. Add `.oneTap` back here\n// instead of forcing the plugin into the array unconditionally — doing that\n// trips a getActions variance mismatch against BetterAuthClientPlugin on\n// newer better-auth versions (>=1.6). The env check above still fully gates\n// whether the plugin (and thus `.oneTap`) is registered at runtime.\nexport const authClient = baseAuthClient as typeof baseAuthClient & OneTapActions\n\n// Export commonly used hooks and methods for convenience\nexport const {\n useSession,\n signIn,\n signOut,\n signUp,\n} = authClient\n"]}
|
|
@@ -17,17 +17,11 @@ var __spreadValues = (a, b) => {
|
|
|
17
17
|
return a;
|
|
18
18
|
};
|
|
19
19
|
var __spreadProps = (a, b) => __defProps(a, __getOwnPropDescs(b));
|
|
20
|
-
var __require = /* @__PURE__ */ ((x) => typeof require !== "undefined" ? require : typeof Proxy !== "undefined" ? new Proxy(x, {
|
|
21
|
-
get: (a, b) => (typeof require !== "undefined" ? require : a)[b]
|
|
22
|
-
}) : x)(function(x) {
|
|
23
|
-
if (typeof require !== "undefined") return require.apply(this, arguments);
|
|
24
|
-
throw Error('Dynamic require of "' + x + '" is not supported');
|
|
25
|
-
});
|
|
26
20
|
var __export = (target, all) => {
|
|
27
21
|
for (var name in all)
|
|
28
22
|
__defProp(target, name, { get: all[name], enumerable: true });
|
|
29
23
|
};
|
|
30
24
|
|
|
31
|
-
export { __export,
|
|
32
|
-
//# sourceMappingURL=chunk-
|
|
33
|
-
//# sourceMappingURL=chunk-
|
|
25
|
+
export { __export, __spreadProps, __spreadValues };
|
|
26
|
+
//# sourceMappingURL=chunk-3465SI5N.mjs.map
|
|
27
|
+
//# sourceMappingURL=chunk-3465SI5N.mjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":[],"names":[],"mappings":"","file":"chunk-
|
|
1
|
+
{"version":3,"sources":[],"names":[],"mappings":"","file":"chunk-3465SI5N.mjs"}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
import { db } from './chunk-
|
|
2
|
-
import { systemSettings, DEFAULT_MAINTENANCE_EXEMPT_PATHS } from './chunk-
|
|
1
|
+
import { db } from './chunk-FJAZNE3I.mjs';
|
|
2
|
+
import { systemSettings, DEFAULT_MAINTENANCE_EXEMPT_PATHS } from './chunk-LPL6U5RD.mjs';
|
|
3
3
|
import { config } from './chunk-GTPTVNY2.mjs';
|
|
4
|
-
import { __spreadProps, __spreadValues } from './chunk-
|
|
4
|
+
import { __spreadProps, __spreadValues } from './chunk-3465SI5N.mjs';
|
|
5
5
|
import 'server-only';
|
|
6
6
|
import { eq } from 'drizzle-orm';
|
|
7
7
|
|
|
@@ -76,5 +76,5 @@ function getConfiguredAuthFlags() {
|
|
|
76
76
|
}
|
|
77
77
|
|
|
78
78
|
export { getConfiguredAuthFlags, getEffectiveAuthFlags, getSystemSettings, invalidateSystemSettingsCache, updateSystemSettings };
|
|
79
|
-
//# sourceMappingURL=chunk-
|
|
80
|
-
//# sourceMappingURL=chunk-
|
|
79
|
+
//# sourceMappingURL=chunk-AGUEAXPN.mjs.map
|
|
80
|
+
//# sourceMappingURL=chunk-AGUEAXPN.mjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../lib/settings-queries.ts"],"names":[],"mappings":"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","file":"chunk-
|
|
1
|
+
{"version":3,"sources":["../lib/settings-queries.ts"],"names":[],"mappings":"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","file":"chunk-AGUEAXPN.mjs","sourcesContent":["import \"server-only\"\nimport { db } from \"../server/db\"\nimport { systemSettings } from \"../server/db/schema\"\nimport { config } from \"../config/env\"\nimport { eq } from \"drizzle-orm\"\nimport { DEFAULT_MAINTENANCE_EXEMPT_PATHS } from \"./maintenance\"\n\nconst SETTINGS_ROW_ID = \"default\"\n// Short TTL: cheap reads (no DB round trip on every request), while an\n// admin's change is guaranteed live within this window even for a reader\n// that isn't the one who just saved (invalidateSystemSettingsCache() makes\n// it instant for that request's own process).\nconst CACHE_TTL_MS = 10_000\n\nexport type SystemSettings = typeof systemSettings.$inferSelect\n\nlet cached: { value: SystemSettings; expiresAt: number } | null = null\n\n// Fail-open shape if the DB is unreachable: auth flags fall back to their\n// config/env.ts defaults (unchanged behavior), maintenance mode is always\n// off — a DB hiccup must never lock out the whole site, including admins.\nfunction fallbackSettings(): SystemSettings {\n return {\n id: SETTINGS_ROW_ID,\n maintenanceMode: false,\n maintenanceMessage: null,\n maintenanceExemptPaths: DEFAULT_MAINTENANCE_EXEMPT_PATHS,\n authEnableGoogle: config.AUTH_ENABLE_GOOGLE,\n authEnableEmailPassword: config.AUTH_ENABLE_EMAIL_PASSWORD,\n authEnableOneTap: config.AUTH_ENABLE_ONE_TAP,\n enableSessionRevocation: config.ENABLE_SESSION_REVOCATION,\n updatedAt: new Date(0),\n updatedBy: null,\n }\n}\n\nasync function loadOrSeed(): Promise<SystemSettings> {\n const existing = await db\n .select()\n .from(systemSettings)\n .where(eq(systemSettings.id, SETTINGS_ROW_ID))\n .limit(1)\n if (existing[0]) return existing[0]\n\n // Lazy-seed on first read, from the *current* env config — not the\n // schema's hardcoded column defaults — so turning this feature on never\n // silently flips an already-deployed flag (e.g. a prod deploy that\n // already set AUTH_ENABLE_GOOGLE=false).\n const seeded = await db\n .insert(systemSettings)\n .values({\n id: SETTINGS_ROW_ID,\n maintenanceMode: false,\n authEnableGoogle: config.AUTH_ENABLE_GOOGLE,\n authEnableEmailPassword: config.AUTH_ENABLE_EMAIL_PASSWORD,\n authEnableOneTap: config.AUTH_ENABLE_ONE_TAP,\n enableSessionRevocation: config.ENABLE_SESSION_REVOCATION,\n })\n .onConflictDoNothing()\n .returning()\n\n if (seeded[0]) return seeded[0]\n\n // Lost the seed race to a concurrent first-reader.\n const retry = await db\n .select()\n .from(systemSettings)\n .where(eq(systemSettings.id, SETTINGS_ROW_ID))\n .limit(1)\n return retry[0] ?? fallbackSettings()\n}\n\nexport async function getSystemSettings(): Promise<SystemSettings> {\n const now = Date.now()\n if (cached && cached.expiresAt > now) return cached.value\n\n try {\n const value = await loadOrSeed()\n cached = { value, expiresAt: now + CACHE_TTL_MS }\n return value\n } catch (error) {\n console.error(\"Failed to load system settings, failing open:\", error)\n return fallbackSettings() // not cached — retry next request\n }\n}\n\nexport function invalidateSystemSettingsCache() {\n cached = null\n}\n\nexport type SystemSettingsPatch = Partial<Pick<SystemSettings,\n | 'maintenanceMode' | 'maintenanceMessage' | 'maintenanceExemptPaths'\n | 'authEnableGoogle' | 'authEnableEmailPassword' | 'authEnableOneTap'\n | 'enableSessionRevocation'\n>>\n\nexport async function updateSystemSettings(\n patch: SystemSettingsPatch,\n updatedBy: string\n): Promise<SystemSettings> {\n await loadOrSeed() // ensure the row exists even if nobody's read it yet\n\n const [updated] = await db\n .update(systemSettings)\n .set({ ...patch, updatedAt: new Date(), updatedBy })\n .where(eq(systemSettings.id, SETTINGS_ROW_ID))\n .returning()\n\n invalidateSystemSettingsCache()\n return updated\n}\n\n// Effective auth-method visibility = deploy-time \"configured\" (env, decides\n// whether the provider is even registered with better-auth — see\n// server/auth.ts's createAuth()) AND runtime \"offered\" (this DB flag).\nexport async function getEffectiveAuthFlags() {\n const settings = await getSystemSettings()\n return {\n google: config.AUTH_ENABLE_GOOGLE && settings.authEnableGoogle,\n emailPassword: config.AUTH_ENABLE_EMAIL_PASSWORD && settings.authEnableEmailPassword,\n oneTap: config.AUTH_ENABLE_ONE_TAP && settings.authEnableOneTap,\n }\n}\n\n// The env-only half of the AND above. The System Settings page needs this\n// to explain *why* a toggle it controls isn't taking effect — flipping the\n// DB flag on can't do anything if the env var for that method is off, so\n// the UI should say so instead of looking like a silent no-op.\nexport function getConfiguredAuthFlags() {\n return {\n google: config.AUTH_ENABLE_GOOGLE,\n emailPassword: config.AUTH_ENABLE_EMAIL_PASSWORD,\n oneTap: config.AUTH_ENABLE_ONE_TAP,\n }\n}\n"]}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { db } from './chunk-
|
|
2
|
-
import { activityLogs } from './chunk-
|
|
1
|
+
import { db } from './chunk-FJAZNE3I.mjs';
|
|
2
|
+
import { activityLogs } from './chunk-LPL6U5RD.mjs';
|
|
3
3
|
import 'server-only';
|
|
4
4
|
|
|
5
5
|
async function logActivity({
|
|
@@ -37,5 +37,5 @@ async function logActivity({
|
|
|
37
37
|
}
|
|
38
38
|
|
|
39
39
|
export { logActivity };
|
|
40
|
-
//# sourceMappingURL=chunk-
|
|
41
|
-
//# sourceMappingURL=chunk-
|
|
40
|
+
//# sourceMappingURL=chunk-B4FKFE7P.mjs.map
|
|
41
|
+
//# sourceMappingURL=chunk-B4FKFE7P.mjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../lib/activity-logger.ts"],"names":[],"mappings":";;;;AAsCA,eAAsB,WAAA,CAAY;AAAA,EAChC,MAAA;AAAA,EACA,MAAA;AAAA,EACA,WAAA;AAAA,EACA,SAAA;AAAA,EACA,SAAA;AAAA,EACA,QAAA;AAAA,EACA,WAAA;AAAA,EACA,EAAA;AAAA,EACA,OAAA;AAAA,EACA,UAAA;AAAA,EACA,OAAA;AAAA,EACA;AACF,CAAA,EAAsB;AACpB,EAAA,IAAI;AACF,IAAA,MAAM,EAAA,CAAG,MAAA,CAAO,YAAY,CAAA,CAAE,MAAA,CAAO;AAAA,MACnC,MAAA;AAAA,MACA,MAAA;AAAA,MACA,WAAA;AAAA,MACA,WAAW,SAAA,IAAa,IAAA;AAAA,MACxB,WAAW,SAAA,IAAa,IAAA;AAAA,MACxB,QAAA,EAAU,QAAA,GAAW,IAAA,CAAK,SAAA,CAAU,QAAQ,CAAA,GAAI,IAAA;AAAA,MAChD,aAAa,WAAA,IAAe,IAAA;AAAA,MAC5B,IAAI,EAAA,IAAM,IAAA;AAAA,MACV,SAAS,OAAA,IAAW,IAAA;AAAA,MACpB,YAAY,UAAA,IAAc,IAAA;AAAA,MAC1B,SAAS,OAAA,IAAW,IAAA;AAAA,MACpB,MAAM,IAAA,IAAQ;AAAA,KACf,CAAA;AAAA,EACH,SAAS,KAAA,EAAO;AACd,IAAA,OAAA,CAAQ,KAAA,CAAM,2BAA2B,KAAK,CAAA;AAAA,EAEhD;AACF","file":"chunk-
|
|
1
|
+
{"version":3,"sources":["../lib/activity-logger.ts"],"names":[],"mappings":";;;;AAsCA,eAAsB,WAAA,CAAY;AAAA,EAChC,MAAA;AAAA,EACA,MAAA;AAAA,EACA,WAAA;AAAA,EACA,SAAA;AAAA,EACA,SAAA;AAAA,EACA,QAAA;AAAA,EACA,WAAA;AAAA,EACA,EAAA;AAAA,EACA,OAAA;AAAA,EACA,UAAA;AAAA,EACA,OAAA;AAAA,EACA;AACF,CAAA,EAAsB;AACpB,EAAA,IAAI;AACF,IAAA,MAAM,EAAA,CAAG,MAAA,CAAO,YAAY,CAAA,CAAE,MAAA,CAAO;AAAA,MACnC,MAAA;AAAA,MACA,MAAA;AAAA,MACA,WAAA;AAAA,MACA,WAAW,SAAA,IAAa,IAAA;AAAA,MACxB,WAAW,SAAA,IAAa,IAAA;AAAA,MACxB,QAAA,EAAU,QAAA,GAAW,IAAA,CAAK,SAAA,CAAU,QAAQ,CAAA,GAAI,IAAA;AAAA,MAChD,aAAa,WAAA,IAAe,IAAA;AAAA,MAC5B,IAAI,EAAA,IAAM,IAAA;AAAA,MACV,SAAS,OAAA,IAAW,IAAA;AAAA,MACpB,YAAY,UAAA,IAAc,IAAA;AAAA,MAC1B,SAAS,OAAA,IAAW,IAAA;AAAA,MACpB,MAAM,IAAA,IAAQ;AAAA,KACf,CAAA;AAAA,EACH,SAAS,KAAA,EAAO;AACd,IAAA,OAAA,CAAQ,KAAA,CAAM,2BAA2B,KAAK,CAAA;AAAA,EAEhD;AACF","file":"chunk-B4FKFE7P.mjs","sourcesContent":["import \"server-only\"\nimport { db } from \"../server/db\"\nimport { activityLogs } from \"../server/db/schema\"\n\nexport type ActivityAction =\n | 'login'\n | 'logout'\n | 'login_failed'\n | 'password_changed'\n | 'email_changed'\n | 'profile_updated'\n | 'session_revoked'\n | 'user_deleted'\n | 'user_banned'\n | 'user_unbanned'\n | 'role_changed'\n | 'impersonation_started'\n | 'impersonation_stopped'\n | 'settings_changed'\n | 'passkey_added'\n | 'passkey_removed'\n\ninterface LogActivityParams {\n userId: string\n action: ActivityAction\n description: string\n ipAddress?: string | null\n userAgent?: string | null\n metadata?: Record<string, any>\n // Populated on 'login' events only — see server/auth.ts's session.create hook.\n referrerUrl?: string | null\n os?: string | null\n browser?: string | null\n deviceType?: string | null\n country?: string | null\n city?: string | null\n}\n\nexport async function logActivity({\n userId,\n action,\n description,\n ipAddress,\n userAgent,\n metadata,\n referrerUrl,\n os,\n browser,\n deviceType,\n country,\n city,\n}: LogActivityParams) {\n try {\n await db.insert(activityLogs).values({\n userId,\n action,\n description,\n ipAddress: ipAddress || null,\n userAgent: userAgent || null,\n metadata: metadata ? JSON.stringify(metadata) : null,\n referrerUrl: referrerUrl || null,\n os: os || null,\n browser: browser || null,\n deviceType: deviceType || null,\n country: country || null,\n city: city || null,\n })\n } catch (error) {\n console.error('Failed to log activity:', error)\n // Don't throw - activity logging should not break the app\n }\n}\n"]}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { schema_exports } from './chunk-
|
|
1
|
+
import { schema_exports } from './chunk-LPL6U5RD.mjs';
|
|
2
2
|
import { config } from './chunk-GTPTVNY2.mjs';
|
|
3
3
|
import 'server-only';
|
|
4
4
|
import { neon } from '@neondatabase/serverless';
|
|
@@ -26,5 +26,5 @@ if (config.DB_DRIVER === "pg") {
|
|
|
26
26
|
}
|
|
27
27
|
|
|
28
28
|
export { db };
|
|
29
|
-
//# sourceMappingURL=chunk-
|
|
30
|
-
//# sourceMappingURL=chunk-
|
|
29
|
+
//# sourceMappingURL=chunk-FJAZNE3I.mjs.map
|
|
30
|
+
//# sourceMappingURL=chunk-FJAZNE3I.mjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../server/db/index.ts"],"names":["drizzlePg","drizzle"],"mappings":";;;;;;;;AAoBA,IAAI;AAGJ,IAAI,MAAA,CAAO,cAAc,IAAA,EAAM;AAC7B,EAAA,MAAM,IAAA,GAAO,IAAI,IAAA,CAAK;AAAA,IACpB,kBAAkB,MAAA,CAAO,YAAA;AAAA,IACzB,KAAK,MAAA,CAAO,YAAA,GAAe,EAAE,kBAAA,EAAoB,OAAM,GAAI;AAAA,GAC5D,CAAA;AACD,EAAA,EAAA,GAAKA,QAAU,IAAA,EAAM;AAAA,IACnB,MAAA,EAAA,cAAA;AAAA,IACA,MAAA,EAAQ;AAAA,GACT,CAAA;AAED,EAAA,OAAA,CAAQ,IAAI,wCAAiC,CAAA;AAE/C,CAAA,MAAA,IAAW,MAAA,CAAO,cAAc,MAAA,EAAQ;AACtC,EAAA,MAAM,GAAA,GAAM,IAAA,CAAK,MAAA,CAAO,YAAa,CAAA;AACrC,EAAA,EAAA,GAAKC,UAAQ,GAAA,EAAK,EAAE,MAAA,EAAA,cAAA,EAAQ,MAAA,EAAQ,MAAM,CAAA;AAE1C,EAAA,OAAA,CAAQ,IAAI,oCAA6B,CAAA;AAE3C,CAAA,MAAO;AACL,EAAA,OAAA,CAAQ,GAAA,CAAI,yDAAA,EAA2D,MAAA,CAAO,SAAS,CAAA;AACzF","file":"chunk-
|
|
1
|
+
{"version":3,"sources":["../server/db/index.ts"],"names":["drizzlePg","drizzle"],"mappings":";;;;;;;;AAoBA,IAAI;AAGJ,IAAI,MAAA,CAAO,cAAc,IAAA,EAAM;AAC7B,EAAA,MAAM,IAAA,GAAO,IAAI,IAAA,CAAK;AAAA,IACpB,kBAAkB,MAAA,CAAO,YAAA;AAAA,IACzB,KAAK,MAAA,CAAO,YAAA,GAAe,EAAE,kBAAA,EAAoB,OAAM,GAAI;AAAA,GAC5D,CAAA;AACD,EAAA,EAAA,GAAKA,QAAU,IAAA,EAAM;AAAA,IACnB,MAAA,EAAA,cAAA;AAAA,IACA,MAAA,EAAQ;AAAA,GACT,CAAA;AAED,EAAA,OAAA,CAAQ,IAAI,wCAAiC,CAAA;AAE/C,CAAA,MAAA,IAAW,MAAA,CAAO,cAAc,MAAA,EAAQ;AACtC,EAAA,MAAM,GAAA,GAAM,IAAA,CAAK,MAAA,CAAO,YAAa,CAAA;AACrC,EAAA,EAAA,GAAKC,UAAQ,GAAA,EAAK,EAAE,MAAA,EAAA,cAAA,EAAQ,MAAA,EAAQ,MAAM,CAAA;AAE1C,EAAA,OAAA,CAAQ,IAAI,oCAA6B,CAAA;AAE3C,CAAA,MAAO;AACL,EAAA,OAAA,CAAQ,GAAA,CAAI,yDAAA,EAA2D,MAAA,CAAO,SAAS,CAAA;AACzF","file":"chunk-FJAZNE3I.mjs","sourcesContent":["import 'server-only';\n\n// neon-http driver for production\nimport { neon } from '@neondatabase/serverless';\nimport { drizzle } from 'drizzle-orm/neon-http';\n\n// postgres driver for local development\nimport { drizzle as drizzlePg } from 'drizzle-orm/node-postgres';\nimport { Pool } from 'pg';\n\nimport * as schema from './schema';\nimport { config } from '../../config/env';\n\n// Import the query builder\nimport { PostgresJsDatabase } from 'drizzle-orm/postgres-js';\nimport { NeonHttpDatabase } from 'drizzle-orm/neon-http';\n\ntype DrizzleNeon = NeonHttpDatabase<typeof schema>;\ntype DrizzlePg = PostgresJsDatabase<typeof schema>;\n\nlet db: DrizzleNeon | DrizzlePg\n\n\nif (config.DB_DRIVER === 'pg') {\n const pool = new Pool({\n connectionString: config.DATABASE_URL!,\n ssl: config.DATABASE_SSL ? { rejectUnauthorized: false } : undefined,\n });\n db = drizzlePg(pool, {\n schema,\n logger: true,\n });\n\n console.log('🟡 Using PostgreSQL (pg) driver');\n\n} else if (config.DB_DRIVER === 'neon') {\n const sql = neon(config.DATABASE_URL!);\n db = drizzle(sql, { schema, logger: true });\n\n console.log('🟢 Using Neon (HTTP) driver');\n\n} else {\n console.log('Database connection not established, unknown DB_DRIVER:', config.DB_DRIVER);\n}\n// Note: In production, you might want to disable logging or use a more sophisticated logger.\n\nexport { db }"]}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { __export } from './chunk-
|
|
1
|
+
import { __export } from './chunk-3465SI5N.mjs';
|
|
2
2
|
import { pgEnum, pgTable, timestamp, boolean, text, integer, unique, check } from 'drizzle-orm/pg-core';
|
|
3
3
|
import { sql } from 'drizzle-orm';
|
|
4
4
|
import { createId } from '@paralleldrive/cuid2';
|
|
@@ -200,5 +200,5 @@ var systemSettings = pgTable("system_settings", {
|
|
|
200
200
|
]);
|
|
201
201
|
|
|
202
202
|
export { ActivityActionEnum, DEFAULT_MAINTENANCE_EXEMPT_PATHS, RoleEnum, accounts, activityLogs, authThrottle, deviceFingerprints, passkeys, schema_exports, sessions, systemSettings, twoFactors, users, verifications };
|
|
203
|
-
//# sourceMappingURL=chunk-
|
|
204
|
-
//# sourceMappingURL=chunk-
|
|
203
|
+
//# sourceMappingURL=chunk-LPL6U5RD.mjs.map
|
|
204
|
+
//# sourceMappingURL=chunk-LPL6U5RD.mjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../server/db/schema.ts","../lib/maintenance.ts"],"names":[],"mappings":";;;;;;AAAA,IAAA,cAAA,GAAA;AAAA,QAAA,CAAA,cAAA,EAAA;AAAA,EAAA,kBAAA,EAAA,MAAA,kBAAA;AAAA,EAAA,QAAA,EAAA,MAAA,QAAA;AAAA,EAAA,QAAA,EAAA,MAAA,QAAA;AAAA,EAAA,YAAA,EAAA,MAAA,YAAA;AAAA,EAAA,YAAA,EAAA,MAAA,YAAA;AAAA,EAAA,kBAAA,EAAA,MAAA,kBAAA;AAAA,EAAA,QAAA,EAAA,MAAA,QAAA;AAAA,EAAA,QAAA,EAAA,MAAA,QAAA;AAAA,EAAA,cAAA,EAAA,MAAA,cAAA;AAAA,EAAA,UAAA,EAAA,MAAA,UAAA;AAAA,EAAA,KAAA,EAAA,MAAA,KAAA;AAAA,EAAA,aAAA,EAAA,MAAA;AAAA,CAAA,CAAA;;;ACIO,IAAM,gCAAA,GAAmC;AAAA,EAC9C,GAAA;AAAA,EACA,WAAA;AAAA,EACA,YAAA;AAAA,EACA,qBAAA;AAAA,EACA,UAAA;AAAA,EACA;AACF;;;ADNO,IAAM,WAAW,MAAA,CAAO,OAAA,EAAS,CAAC,MAAA,EAAQ,OAAO,CAAC;AAElD,IAAM,kBAAA,GAAqB,OAAO,kBAAA,EAAoB;AAAA,EAC3D,OAAA;AAAA,EACA,QAAA;AAAA,EACA,cAAA;AAAA,EACA,kBAAA;AAAA,EACA,eAAA;AAAA,EACA,iBAAA;AAAA,EACA,iBAAA;AAAA,EACA,cAAA;AAAA,EACA,aAAA;AAAA,EACA,eAAA;AAAA,EACA,cAAA;AAAA,EACA,uBAAA;AAAA,EACA,uBAAA;AAAA,EACA,kBAAA;AAAA,EACA,eAAA;AAAA,EACA;AACF,CAAC;AAEM,IAAM,KAAA,GAAQ,QAAQ,MAAA,EAAQ;AAAA,EACnC,EAAA,EAAI,IAAA,CAAK,IAAI,CAAA,CAAE,OAAA,EAAQ,CAAE,UAAA,EAAW,CAAE,UAAA,CAAW,MAAM,QAAA,EAAU,CAAA;AAAA,EACjE,IAAA,EAAM,IAAA,CAAK,MAAM,CAAA,CAAE,OAAA,EAAQ;AAAA,EAC3B,OAAO,IAAA,CAAK,OAAO,CAAA,CAAE,OAAA,GAAU,MAAA,EAAO;AAAA,EACtC,QAAA,EAAU,KAAK,UAAU,CAAA;AAAA,EACzB,eAAe,OAAA,CAAQ,eAAe,EAAE,OAAA,EAAQ,CAAE,QAAQ,KAAK,CAAA;AAAA,EAC/D,KAAA,EAAO,KAAK,OAAO,CAAA;AAAA,EACnB,MAAM,QAAA,CAAS,OAAO,EAAE,OAAA,CAAQ,MAAM,EAAE,OAAA,EAAQ;AAAA,EAChD,QAAQ,OAAA,CAAQ,QAAQ,EAAE,OAAA,CAAQ,KAAK,EAAE,OAAA,EAAQ;AAAA,EACjD,QAAA,EAAU,UAAU,UAAU,CAAA;AAAA,EAC9B,YAAA,EAAc,KAAK,cAAc,CAAA;AAAA;AAAA;AAAA;AAAA,EAIjC,UAAA,EAAY,UAAU,YAAY,CAAA;AAAA,EAClC,WAAA,EAAa,UAAU,aAAa,CAAA;AAAA,EACpC,YAAA,EAAc,UAAU,cAAc,CAAA;AAAA;AAAA;AAAA;AAAA,EAItC,kBAAkB,OAAA,CAAQ,kBAAkB,EAAE,OAAA,EAAQ,CAAE,QAAQ,KAAK,CAAA;AAAA,EACrE,WAAW,SAAA,CAAU,WAAW,CAAA,CAAE,OAAA,GAAU,UAAA,EAAW;AAAA,EACvD,WAAW,SAAA,CAAU,WAAW,CAAA,CAAE,OAAA,GAAU,UAAA;AAC9C,CAAC;AAEM,IAAM,QAAA,GAAW,QAAQ,SAAA,EAAW;AAAA,EACzC,EAAA,EAAI,IAAA,CAAK,IAAI,CAAA,CAAE,OAAA,EAAQ,CAAE,UAAA,EAAW,CAAE,UAAA,CAAW,MAAM,QAAA,EAAU,CAAA;AAAA,EACjE,SAAA,EAAW,SAAA,CAAU,WAAW,CAAA,CAAE,OAAA,EAAQ;AAAA,EAC1C,OAAO,IAAA,CAAK,OAAO,CAAA,CAAE,OAAA,GAAU,MAAA,EAAO;AAAA,EACtC,WAAW,SAAA,CAAU,WAAW,CAAA,CAAE,OAAA,GAAU,UAAA,EAAW;AAAA,EACvD,WAAW,SAAA,CAAU,WAAW,CAAA,CAAE,OAAA,GAAU,UAAA,EAAW;AAAA,EACvD,SAAA,EAAW,KAAK,WAAW,CAAA;AAAA,EAC3B,SAAA,EAAW,KAAK,WAAW,CAAA;AAAA,EAC3B,MAAA,EAAQ,IAAA,CAAK,QAAQ,CAAA,CAClB,OAAA,EAAQ,CACR,UAAA,CAAW,MAAM,KAAA,CAAM,EAAA,EAAI,EAAE,QAAA,EAAU,WAAW,CAAA;AAAA;AAAA;AAAA,EAGrD,cAAA,EAAgB,KAAK,gBAAgB;AACvC,CAAC;AAEM,IAAM,QAAA,GAAW,QAAQ,SAAA,EAAW;AAAA,EACzC,EAAA,EAAI,IAAA,CAAK,IAAI,CAAA,CAAE,OAAA,EAAQ,CAAE,UAAA,EAAW,CAAE,UAAA,CAAW,MAAM,QAAA,EAAU,CAAA;AAAA,EACjE,SAAA,EAAW,IAAA,CAAK,WAAW,CAAA,CAAE,OAAA,EAAQ;AAAA,EACrC,UAAA,EAAY,IAAA,CAAK,YAAY,CAAA,CAAE,OAAA,EAAQ;AAAA,EACvC,MAAA,EAAQ,IAAA,CAAK,QAAQ,CAAA,CAClB,OAAA,EAAQ,CACR,UAAA,CAAW,MAAM,KAAA,CAAM,EAAA,EAAI,EAAE,QAAA,EAAU,WAAW,CAAA;AAAA,EACrD,WAAA,EAAa,KAAK,aAAa,CAAA;AAAA,EAC/B,YAAA,EAAc,KAAK,cAAc,CAAA;AAAA,EACjC,OAAA,EAAS,KAAK,SAAS,CAAA;AAAA,EACvB,oBAAA,EAAsB,UAAU,sBAAsB,CAAA;AAAA,EACtD,qBAAA,EAAuB,UAAU,uBAAuB,CAAA;AAAA,EACxD,KAAA,EAAO,KAAK,OAAO,CAAA;AAAA,EACnB,QAAA,EAAU,KAAK,UAAU,CAAA;AAAA,EACzB,WAAW,SAAA,CAAU,WAAW,CAAA,CAAE,OAAA,GAAU,UAAA,EAAW;AAAA,EACvD,WAAW,SAAA,CAAU,WAAW,CAAA,CAAE,OAAA,GAAU,UAAA;AAC9C,CAAC;AAMM,IAAM,UAAA,GAAa,QAAQ,WAAA,EAAa;AAAA,EAC7C,EAAA,EAAI,IAAA,CAAK,IAAI,CAAA,CAAE,OAAA,EAAQ,CAAE,UAAA,EAAW,CAAE,UAAA,CAAW,MAAM,QAAA,EAAU,CAAA;AAAA,EACjE,MAAA,EAAQ,IAAA,CAAK,QAAQ,CAAA,CAAE,OAAA,EAAQ;AAAA,EAC/B,WAAA,EAAa,IAAA,CAAK,aAAa,CAAA,CAAE,OAAA,EAAQ;AAAA,EACzC,MAAA,EAAQ,IAAA,CAAK,QAAQ,CAAA,CAClB,OAAA,EAAQ,CACR,UAAA,CAAW,MAAM,KAAA,CAAM,EAAA,EAAI,EAAE,QAAA,EAAU,WAAW;AACvD,CAAC;AAGM,IAAM,QAAA,GAAW,QAAQ,SAAA,EAAW;AAAA,EACzC,EAAA,EAAI,IAAA,CAAK,IAAI,CAAA,CAAE,OAAA,EAAQ,CAAE,UAAA,EAAW,CAAE,UAAA,CAAW,MAAM,QAAA,EAAU,CAAA;AAAA,EACjE,IAAA,EAAM,KAAK,MAAM,CAAA;AAAA,EACjB,SAAA,EAAW,IAAA,CAAK,WAAW,CAAA,CAAE,OAAA,EAAQ;AAAA,EACrC,MAAA,EAAQ,IAAA,CAAK,QAAQ,CAAA,CAClB,OAAA,EAAQ,CACR,UAAA,CAAW,MAAM,KAAA,CAAM,EAAA,EAAI,EAAE,QAAA,EAAU,WAAW,CAAA;AAAA,EACrD,cAAc,IAAA,CAAK,cAAc,CAAA,CAAE,OAAA,GAAU,MAAA,EAAO;AAAA,EACpD,OAAA,EAAS,OAAA,CAAQ,SAAS,CAAA,CAAE,OAAA,EAAQ;AAAA,EACpC,UAAA,EAAY,IAAA,CAAK,YAAY,CAAA,CAAE,OAAA,EAAQ;AAAA,EACvC,QAAA,EAAU,OAAA,CAAQ,UAAU,CAAA,CAAE,OAAA,EAAQ;AAAA,EACtC,UAAA,EAAY,KAAK,YAAY,CAAA;AAAA,EAC7B,SAAA,EAAW,UAAU,WAAW,CAAA;AAAA,EAChC,MAAA,EAAQ,KAAK,QAAQ;AACvB,CAAC;AAEM,IAAM,aAAA,GAAgB,QAAQ,cAAA,EAAgB;AAAA,EACnD,EAAA,EAAI,IAAA,CAAK,IAAI,CAAA,CAAE,OAAA,EAAQ,CAAE,UAAA,EAAW,CAAE,UAAA,CAAW,MAAM,QAAA,EAAU,CAAA;AAAA,EACjE,UAAA,EAAY,IAAA,CAAK,YAAY,CAAA,CAAE,OAAA,EAAQ;AAAA,EACvC,KAAA,EAAO,IAAA,CAAK,OAAO,CAAA,CAAE,OAAA,EAAQ;AAAA,EAC7B,SAAA,EAAW,SAAA,CAAU,WAAW,CAAA,CAAE,OAAA,EAAQ;AAAA,EAC1C,WAAW,SAAA,CAAU,WAAW,CAAA,CAAE,OAAA,GAAU,UAAA,EAAW;AAAA,EACvD,WAAW,SAAA,CAAU,WAAW,CAAA,CAAE,OAAA,GAAU,UAAA;AAC9C,CAAC;AAEM,IAAM,YAAA,GAAe,QAAQ,cAAA,EAAgB;AAAA,EAClD,EAAA,EAAI,IAAA,CAAK,IAAI,CAAA,CAAE,OAAA,EAAQ,CAAE,UAAA,EAAW,CAAE,UAAA,CAAW,MAAM,QAAA,EAAU,CAAA;AAAA,EACjE,MAAA,EAAQ,IAAA,CAAK,QAAQ,CAAA,CAClB,OAAA,EAAQ,CACR,UAAA,CAAW,MAAM,KAAA,CAAM,EAAA,EAAI,EAAE,QAAA,EAAU,WAAW,CAAA;AAAA,EACrD,MAAA,EAAQ,kBAAA,CAAmB,QAAQ,CAAA,CAAE,OAAA,EAAQ;AAAA,EAC7C,WAAA,EAAa,IAAA,CAAK,aAAa,CAAA,CAAE,OAAA,EAAQ;AAAA,EACzC,SAAA,EAAW,KAAK,WAAW,CAAA;AAAA,EAC3B,SAAA,EAAW,KAAK,WAAW,CAAA;AAAA,EAC3B,QAAA,EAAU,KAAK,UAAU,CAAA;AAAA;AAAA;AAAA;AAAA,EAIzB,WAAA,EAAa,KAAK,aAAa,CAAA;AAAA,EAC/B,EAAA,EAAI,KAAK,IAAI,CAAA;AAAA,EACb,OAAA,EAAS,KAAK,SAAS,CAAA;AAAA,EACvB,UAAA,EAAY,KAAK,YAAY,CAAA;AAAA,EAC7B,OAAA,EAAS,KAAK,SAAS,CAAA;AAAA,EACvB,IAAA,EAAM,KAAK,MAAM,CAAA;AAAA,EACjB,WAAW,SAAA,CAAU,WAAW,CAAA,CAAE,OAAA,GAAU,UAAA;AAC9C,CAAC;AAQM,IAAM,kBAAA,GAAqB,QAAQ,oBAAA,EAAsB;AAAA,EAC9D,EAAA,EAAI,IAAA,CAAK,IAAI,CAAA,CAAE,OAAA,EAAQ,CAAE,UAAA,EAAW,CAAE,UAAA,CAAW,MAAM,QAAA,EAAU,CAAA;AAAA,EACjE,MAAA,EAAQ,IAAA,CAAK,QAAQ,CAAA,CAClB,OAAA,EAAQ,CACR,UAAA,CAAW,MAAM,KAAA,CAAM,EAAA,EAAI,EAAE,QAAA,EAAU,WAAW,CAAA;AAAA,EACrD,SAAA,EAAW,IAAA,CAAK,WAAW,CAAA,CAAE,OAAA,EAAQ;AAAA;AAAA;AAAA;AAAA;AAAA,EAKrC,SAAA,EAAW,KAAK,WAAW,CAAA;AAAA,EAC3B,SAAA,EAAW,KAAK,WAAW,CAAA;AAAA,EAC3B,OAAA,EAAS,KAAK,SAAS,CAAA;AAAA,EACvB,IAAA,EAAM,KAAK,MAAM,CAAA;AAAA,EACjB,WAAW,SAAA,CAAU,WAAW,CAAA,CAAE,OAAA,GAAU,UAAA;AAC9C,CAAA,EAAG,CAAC,KAAA,KAAU;AAAA,EACZ,OAAO,iCAAiC,CAAA,CAAE,GAAG,KAAA,CAAM,MAAA,EAAQ,MAAM,SAAS;AAC5E,CAAC;AASM,IAAM,YAAA,GAAe,QAAQ,eAAA,EAAiB;AAAA,EACnD,aAAa,IAAA,CAAK,aAAa,CAAA,CAAE,OAAA,GAAU,UAAA,EAAW;AAAA,EACtD,OAAO,OAAA,CAAQ,OAAO,EAAE,OAAA,EAAQ,CAAE,QAAQ,CAAC,CAAA;AAAA,EAC3C,aAAa,SAAA,CAAU,aAAa,CAAA,CAAE,OAAA,GAAU,UAAA,EAAW;AAAA;AAAA;AAAA;AAAA;AAAA,EAK3D,eAAe,SAAA,CAAU,eAAe,CAAA,CAAE,OAAA,GAAU,UAAA,EAAW;AAAA,EAC/D,SAAA,EAAW,KAAK,WAAW,CAAA;AAAA,EAC3B,SAAA,EAAW,KAAK,WAAW,CAAA;AAAA,EAC3B,SAAA,EAAW,KAAK,WAAW,CAAA;AAAA,EAC3B,QAAA,EAAU,KAAK,UAAU;AAAA;AAC3B,CAAC;AAKM,IAAM,cAAA,GAAiB,QAAQ,iBAAA,EAAmB;AAAA,EACvD,IAAI,IAAA,CAAK,IAAI,EAAE,UAAA,EAAW,CAAE,QAAQ,SAAS,CAAA;AAAA,EAC7C,iBAAiB,OAAA,CAAQ,iBAAiB,EAAE,OAAA,EAAQ,CAAE,QAAQ,KAAK,CAAA;AAAA,EACnE,kBAAA,EAAoB,KAAK,oBAAoB,CAAA;AAAA;AAAA;AAAA,EAG7C,sBAAA,EAAwB,KAAK,wBAAwB,CAAA,CAAE,OAAM,CAAE,OAAA,EAAQ,CAAE,OAAA,CAAQ,gCAAgC,CAAA;AAAA,EACjH,kBAAkB,OAAA,CAAQ,kBAAkB,EAAE,OAAA,EAAQ,CAAE,QAAQ,IAAI,CAAA;AAAA,EACpE,yBAAyB,OAAA,CAAQ,yBAAyB,EAAE,OAAA,EAAQ,CAAE,QAAQ,IAAI,CAAA;AAAA,EAClF,kBAAkB,OAAA,CAAQ,kBAAkB,EAAE,OAAA,EAAQ,CAAE,QAAQ,KAAK,CAAA;AAAA,EACrE,yBAAyB,OAAA,CAAQ,yBAAyB,EAAE,OAAA,EAAQ,CAAE,QAAQ,IAAI,CAAA;AAAA,EAClF,WAAW,SAAA,CAAU,WAAW,CAAA,CAAE,OAAA,GAAU,UAAA,EAAW;AAAA;AAAA;AAAA;AAAA,EAIvD,SAAA,EAAW,IAAA,CAAK,WAAW,CAAA,CAAE,UAAA,CAAW,MAAM,KAAA,CAAM,EAAA,EAAI,EAAE,QAAA,EAAU,UAAA,EAAY;AAClF,CAAA,EAAG,CAAC,KAAA,KAAU;AAAA,EACZ,KAAA,CAAM,2BAAA,EAA6B,GAAA,CAAA,EAAM,KAAA,CAAM,EAAE,CAAA,YAAA,CAAc;AACjE,CAAC","file":"chunk-YZPJ54QG.mjs","sourcesContent":["import { boolean, check, integer, pgEnum, pgTable, text, timestamp, unique } from \"drizzle-orm/pg-core\";\nimport { sql } from \"drizzle-orm\";\nimport { createId } from '@paralleldrive/cuid2'\nimport { DEFAULT_MAINTENANCE_EXEMPT_PATHS } from \"../../lib/maintenance\";\n\nexport const RoleEnum = pgEnum('roles', ['user', 'admin'])\n\nexport const ActivityActionEnum = pgEnum('activity_actions', [\n 'login',\n 'logout',\n 'login_failed',\n 'password_changed',\n 'email_changed',\n 'profile_updated',\n 'session_revoked',\n 'user_deleted',\n 'user_banned',\n 'user_unbanned',\n 'role_changed',\n 'impersonation_started',\n 'impersonation_stopped',\n 'settings_changed',\n 'passkey_added',\n 'passkey_removed',\n])\n\nexport const users = pgTable(\"user\", {\n id: text(\"id\").notNull().primaryKey().$defaultFn(() => createId()),\n name: text('name').notNull(),\n email: text('email').notNull().unique(),\n password: text('password'),\n emailVerified: boolean(\"emailVerified\").notNull().default(false),\n image: text(\"image\"),\n role: RoleEnum('roles').default('user').notNull(),\n banned: boolean('banned').default(false).notNull(),\n bannedAt: timestamp('bannedAt'),\n bannedReason: text('bannedReason'),\n // Required by better-auth's admin plugin schema (auto-expiring bans). We\n // never set this ourselves, so it stays null and bans behave as permanent,\n // same as before the plugin was added.\n banExpires: timestamp('banExpires'),\n lastLoginAt: timestamp('lastLoginAt'),\n lastActiveAt: timestamp('lastActiveAt'),\n // Set by better-auth's twoFactor plugin — true once the user has\n // completed TOTP setup (see twoFactor pgTable below for the secret /\n // backup codes themselves).\n twoFactorEnabled: boolean('twoFactorEnabled').notNull().default(false),\n createdAt: timestamp('createdAt').notNull().defaultNow(),\n updatedAt: timestamp('updatedAt').notNull().defaultNow(),\n});\n\nexport const sessions = pgTable(\"session\", {\n id: text(\"id\").notNull().primaryKey().$defaultFn(() => createId()),\n expiresAt: timestamp(\"expiresAt\").notNull(),\n token: text(\"token\").notNull().unique(),\n createdAt: timestamp(\"createdAt\").notNull().defaultNow(),\n updatedAt: timestamp(\"updatedAt\").notNull().defaultNow(),\n ipAddress: text(\"ipAddress\"),\n userAgent: text(\"userAgent\"),\n userId: text(\"userId\")\n .notNull()\n .references(() => users.id, { onDelete: \"cascade\" }),\n // Set by better-auth's admin plugin while this session is an admin\n // impersonating another user; holds the impersonating admin's user id.\n impersonatedBy: text(\"impersonatedBy\"),\n});\n\nexport const accounts = pgTable(\"account\", {\n id: text(\"id\").notNull().primaryKey().$defaultFn(() => createId()),\n accountId: text(\"accountId\").notNull(),\n providerId: text(\"providerId\").notNull(),\n userId: text(\"userId\")\n .notNull()\n .references(() => users.id, { onDelete: \"cascade\" }),\n accessToken: text(\"accessToken\"),\n refreshToken: text(\"refreshToken\"),\n idToken: text(\"idToken\"),\n accessTokenExpiresAt: timestamp(\"accessTokenExpiresAt\"),\n refreshTokenExpiresAt: timestamp(\"refreshTokenExpiresAt\"),\n scope: text(\"scope\"),\n password: text(\"password\"),\n createdAt: timestamp(\"createdAt\").notNull().defaultNow(),\n updatedAt: timestamp(\"updatedAt\").notNull().defaultNow(),\n});\n\n// Better-auth's twoFactor plugin. One row per user (created on first\n// `enable`); secret and backupCodes are its own encrypted-at-rest strings,\n// field names/types must match its expectations exactly (drizzleAdapter in\n// server/auth.ts maps this table to the plugin's \"twoFactor\" model as-is).\nexport const twoFactors = pgTable(\"twoFactor\", {\n id: text(\"id\").notNull().primaryKey().$defaultFn(() => createId()),\n secret: text(\"secret\").notNull(),\n backupCodes: text(\"backupCodes\").notNull(),\n userId: text(\"userId\")\n .notNull()\n .references(() => users.id, { onDelete: \"cascade\" }),\n});\n\n// Better-auth's passkey plugin — one row per registered WebAuthn credential.\nexport const passkeys = pgTable(\"passkey\", {\n id: text(\"id\").notNull().primaryKey().$defaultFn(() => createId()),\n name: text(\"name\"),\n publicKey: text(\"publicKey\").notNull(),\n userId: text(\"userId\")\n .notNull()\n .references(() => users.id, { onDelete: \"cascade\" }),\n credentialID: text(\"credentialID\").notNull().unique(),\n counter: integer(\"counter\").notNull(),\n deviceType: text(\"deviceType\").notNull(),\n backedUp: boolean(\"backedUp\").notNull(),\n transports: text(\"transports\"),\n createdAt: timestamp(\"createdAt\"),\n aaguid: text(\"aaguid\"),\n});\n\nexport const verifications = pgTable(\"verification\", {\n id: text(\"id\").notNull().primaryKey().$defaultFn(() => createId()),\n identifier: text(\"identifier\").notNull(),\n value: text(\"value\").notNull(),\n expiresAt: timestamp(\"expiresAt\").notNull(),\n createdAt: timestamp(\"createdAt\").notNull().defaultNow(),\n updatedAt: timestamp(\"updatedAt\").notNull().defaultNow(),\n});\n\nexport const activityLogs = pgTable(\"activity_log\", {\n id: text(\"id\").notNull().primaryKey().$defaultFn(() => createId()),\n userId: text(\"userId\")\n .notNull()\n .references(() => users.id, { onDelete: \"cascade\" }),\n action: ActivityActionEnum('action').notNull(),\n description: text('description').notNull(),\n ipAddress: text('ipAddress'),\n userAgent: text('userAgent'),\n metadata: text('metadata'),\n // Populated on 'login' events only (registration + sign-in) — parsed from\n // userAgent/ipAddress at write time so the record stays stable even if\n // the parsing library or geoip database changes later.\n referrerUrl: text('referrerUrl'),\n os: text('os'),\n browser: text('browser'),\n deviceType: text('deviceType'),\n country: text('country'),\n city: text('city'),\n createdAt: timestamp('createdAt').notNull().defaultNow(),\n});\n\n// One row per (user, device fingerprint) pair. Its only job is to answer\n// \"has this account signed in from this device before?\" — no matching row ⇒\n// send a new-device alert (see app/api/device-check/route.ts). visitorId is\n// FingerprintJS's identifier, computed client-side in\n// components/auth/deviceCheck.tsx. UA+IP are deliberately NOT the signal here:\n// they churn constantly on mobile and would alert on every other login.\nexport const deviceFingerprints = pgTable(\"device_fingerprint\", {\n id: text(\"id\").notNull().primaryKey().$defaultFn(() => createId()),\n userId: text(\"userId\")\n .notNull()\n .references(() => users.id, { onDelete: \"cascade\" }),\n visitorId: text(\"visitorId\").notNull(),\n // Context captured at first-seen time — for the admin panel's \"New devices\"\n // card and the alert email. Not part of the new-vs-known decision (that's\n // visitorId only), just so an admin can eyeball whether a sign-in looks like\n // a hijack. Nullable: an old row predates these columns, or geoip missed.\n ipAddress: text(\"ipAddress\"),\n userAgent: text(\"userAgent\"),\n country: text(\"country\"),\n city: text(\"city\"),\n createdAt: timestamp(\"createdAt\").notNull().defaultNow(),\n}, (table) => [\n unique(\"device_fingerprint_user_visitor\").on(table.userId, table.visitorId),\n]);\n\n// Per-device abuse throttle for /sign-in/email and /sign-up/email — one\n// fixed-window counter row per FingerprintJS visitorId (sent by the auth\n// forms as the x-device-fingerprint header; see lib/auth-throttle.ts).\n// Keyed by device, not IP: IP is shared behind corporate NAT / CGNAT / VPN,\n// so an IP counter throttles coworkers together while missing an abuser who\n// rotates IPs. Rows whose window has elapsed are dead weight but harmless\n// (reset on the next attempt) — prune on a cron if the table ever grows.\nexport const authThrottle = pgTable(\"auth_throttle\", {\n fingerprint: text(\"fingerprint\").notNull().primaryKey(),\n count: integer(\"count\").notNull().default(0),\n windowStart: timestamp(\"windowStart\").notNull().defaultNow(),\n // Blockable data points, overwritten on every attempt (last-write-wins) so\n // the admin panel can show who to block — by IP or by fingerprint — with no\n // join and no per-attempt history table. windowStart anchors the counter's\n // window; lastAttemptAt is just \"most recently seen\".\n lastAttemptAt: timestamp(\"lastAttemptAt\").notNull().defaultNow(),\n ipAddress: text(\"ipAddress\"),\n userAgent: text(\"userAgent\"),\n lastEmail: text(\"lastEmail\"),\n lastKind: text(\"lastKind\"), // 'signin' | 'signup'\n});\n\n// Singleton row (id is always 'default') holding admin-editable settings for\n// config that used to be env-var-only. See lib/settings-queries.ts for the\n// cached read path and lazy-seed-from-env behavior.\nexport const systemSettings = pgTable(\"system_settings\", {\n id: text(\"id\").primaryKey().default(\"default\"),\n maintenanceMode: boolean(\"maintenanceMode\").notNull().default(false),\n maintenanceMessage: text(\"maintenanceMessage\"),\n // Path prefixes that stay reachable while maintenance mode is on (see\n // lib/maintenance.ts — a few auth paths are always open on top of these).\n maintenanceExemptPaths: text(\"maintenanceExemptPaths\").array().notNull().default(DEFAULT_MAINTENANCE_EXEMPT_PATHS),\n authEnableGoogle: boolean(\"authEnableGoogle\").notNull().default(true),\n authEnableEmailPassword: boolean(\"authEnableEmailPassword\").notNull().default(true),\n authEnableOneTap: boolean(\"authEnableOneTap\").notNull().default(false),\n enableSessionRevocation: boolean(\"enableSessionRevocation\").notNull().default(true),\n updatedAt: timestamp(\"updatedAt\").notNull().defaultNow(),\n // Who last changed a setting. This row doesn't \"belong\" to that admin the\n // way sessions/activityLogs belong to their user, so deleting that admin's\n // account should null this out rather than cascade-delete the singleton row.\n updatedBy: text(\"updatedBy\").references(() => users.id, { onDelete: \"set null\" }),\n}, (table) => [\n check(\"system_settings_singleton\", sql`${table.id} = 'default'`),\n]);","// Pure path logic for maintenance mode — no DB / server-only imports, so it\n// can run in proxy.ts and in the admin form alike.\n\n// Default for the admin-editable exempt list: the public marketing pages.\nexport const DEFAULT_MAINTENANCE_EXEMPT_PATHS = [\n \"/\",\n \"/features\",\n \"/changelog\",\n \"/changelog-template\",\n \"/privacy\",\n \"/terms\",\n]\n\n// Always reachable, whatever the admin saves — otherwise an admin could\n// lock themselves out of the sign-in flow needed to turn maintenance off.\nexport const ALWAYS_OPEN_PATHS = [\n \"/maintenance\",\n \"/login\", // includes /login/2fa\n \"/forgot-password\",\n \"/reset-password\",\n \"/api/auth\",\n \"/api/settings/public\", // login page reads the One Tap flag from here\n]\n\n// `/foo` matches `/foo` and `/foo/...` but not `/foobar`; `/` matches only `/`.\nfunction matches(pathname: string, prefix: string) {\n const p = prefix.length > 1 ? prefix.replace(/\\/+$/, \"\") : prefix\n return pathname === p || (p !== \"/\" && pathname.startsWith(p + \"/\"))\n}\n\nexport function isMaintenanceExempt(pathname: string, exemptPaths: string[]) {\n return [...ALWAYS_OPEN_PATHS, ...exemptPaths].some((p) => matches(pathname, p))\n}\n"]}
|
|
1
|
+
{"version":3,"sources":["../server/db/schema.ts","../lib/maintenance.ts"],"names":[],"mappings":"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","file":"chunk-LPL6U5RD.mjs","sourcesContent":["import { boolean, check, integer, pgEnum, pgTable, text, timestamp, unique } from \"drizzle-orm/pg-core\";\nimport { sql } from \"drizzle-orm\";\nimport { createId } from '@paralleldrive/cuid2'\nimport { DEFAULT_MAINTENANCE_EXEMPT_PATHS } from \"../../lib/maintenance\";\n\nexport const RoleEnum = pgEnum('roles', ['user', 'admin'])\n\nexport const ActivityActionEnum = pgEnum('activity_actions', [\n 'login',\n 'logout',\n 'login_failed',\n 'password_changed',\n 'email_changed',\n 'profile_updated',\n 'session_revoked',\n 'user_deleted',\n 'user_banned',\n 'user_unbanned',\n 'role_changed',\n 'impersonation_started',\n 'impersonation_stopped',\n 'settings_changed',\n 'passkey_added',\n 'passkey_removed',\n])\n\nexport const users = pgTable(\"user\", {\n id: text(\"id\").notNull().primaryKey().$defaultFn(() => createId()),\n name: text('name').notNull(),\n email: text('email').notNull().unique(),\n password: text('password'),\n emailVerified: boolean(\"emailVerified\").notNull().default(false),\n image: text(\"image\"),\n role: RoleEnum('roles').default('user').notNull(),\n banned: boolean('banned').default(false).notNull(),\n bannedAt: timestamp('bannedAt'),\n bannedReason: text('bannedReason'),\n // Required by better-auth's admin plugin schema (auto-expiring bans). We\n // never set this ourselves, so it stays null and bans behave as permanent,\n // same as before the plugin was added.\n banExpires: timestamp('banExpires'),\n lastLoginAt: timestamp('lastLoginAt'),\n lastActiveAt: timestamp('lastActiveAt'),\n // Set by better-auth's twoFactor plugin — true once the user has\n // completed TOTP setup (see twoFactor pgTable below for the secret /\n // backup codes themselves).\n twoFactorEnabled: boolean('twoFactorEnabled').notNull().default(false),\n createdAt: timestamp('createdAt').notNull().defaultNow(),\n updatedAt: timestamp('updatedAt').notNull().defaultNow(),\n});\n\nexport const sessions = pgTable(\"session\", {\n id: text(\"id\").notNull().primaryKey().$defaultFn(() => createId()),\n expiresAt: timestamp(\"expiresAt\").notNull(),\n token: text(\"token\").notNull().unique(),\n createdAt: timestamp(\"createdAt\").notNull().defaultNow(),\n updatedAt: timestamp(\"updatedAt\").notNull().defaultNow(),\n ipAddress: text(\"ipAddress\"),\n userAgent: text(\"userAgent\"),\n userId: text(\"userId\")\n .notNull()\n .references(() => users.id, { onDelete: \"cascade\" }),\n // Set by better-auth's admin plugin while this session is an admin\n // impersonating another user; holds the impersonating admin's user id.\n impersonatedBy: text(\"impersonatedBy\"),\n});\n\nexport const accounts = pgTable(\"account\", {\n id: text(\"id\").notNull().primaryKey().$defaultFn(() => createId()),\n accountId: text(\"accountId\").notNull(),\n providerId: text(\"providerId\").notNull(),\n userId: text(\"userId\")\n .notNull()\n .references(() => users.id, { onDelete: \"cascade\" }),\n accessToken: text(\"accessToken\"),\n refreshToken: text(\"refreshToken\"),\n idToken: text(\"idToken\"),\n accessTokenExpiresAt: timestamp(\"accessTokenExpiresAt\"),\n refreshTokenExpiresAt: timestamp(\"refreshTokenExpiresAt\"),\n scope: text(\"scope\"),\n password: text(\"password\"),\n createdAt: timestamp(\"createdAt\").notNull().defaultNow(),\n updatedAt: timestamp(\"updatedAt\").notNull().defaultNow(),\n});\n\n// Better-auth's twoFactor plugin. One row per user (created on first\n// `enable`); secret and backupCodes are its own encrypted-at-rest strings,\n// field names/types must match its expectations exactly (drizzleAdapter in\n// server/auth.ts maps this table to the plugin's \"twoFactor\" model as-is).\nexport const twoFactors = pgTable(\"twoFactor\", {\n id: text(\"id\").notNull().primaryKey().$defaultFn(() => createId()),\n secret: text(\"secret\").notNull(),\n backupCodes: text(\"backupCodes\").notNull(),\n userId: text(\"userId\")\n .notNull()\n .references(() => users.id, { onDelete: \"cascade\" }),\n});\n\n// Better-auth's passkey plugin — one row per registered WebAuthn credential.\nexport const passkeys = pgTable(\"passkey\", {\n id: text(\"id\").notNull().primaryKey().$defaultFn(() => createId()),\n name: text(\"name\"),\n publicKey: text(\"publicKey\").notNull(),\n userId: text(\"userId\")\n .notNull()\n .references(() => users.id, { onDelete: \"cascade\" }),\n credentialID: text(\"credentialID\").notNull().unique(),\n counter: integer(\"counter\").notNull(),\n deviceType: text(\"deviceType\").notNull(),\n backedUp: boolean(\"backedUp\").notNull(),\n transports: text(\"transports\"),\n createdAt: timestamp(\"createdAt\"),\n aaguid: text(\"aaguid\"),\n});\n\nexport const verifications = pgTable(\"verification\", {\n id: text(\"id\").notNull().primaryKey().$defaultFn(() => createId()),\n identifier: text(\"identifier\").notNull(),\n value: text(\"value\").notNull(),\n expiresAt: timestamp(\"expiresAt\").notNull(),\n createdAt: timestamp(\"createdAt\").notNull().defaultNow(),\n updatedAt: timestamp(\"updatedAt\").notNull().defaultNow(),\n});\n\nexport const activityLogs = pgTable(\"activity_log\", {\n id: text(\"id\").notNull().primaryKey().$defaultFn(() => createId()),\n userId: text(\"userId\")\n .notNull()\n .references(() => users.id, { onDelete: \"cascade\" }),\n action: ActivityActionEnum('action').notNull(),\n description: text('description').notNull(),\n ipAddress: text('ipAddress'),\n userAgent: text('userAgent'),\n metadata: text('metadata'),\n // Populated on 'login' events only (registration + sign-in) — parsed from\n // userAgent/ipAddress at write time so the record stays stable even if\n // the parsing library or geoip database changes later.\n referrerUrl: text('referrerUrl'),\n os: text('os'),\n browser: text('browser'),\n deviceType: text('deviceType'),\n country: text('country'),\n city: text('city'),\n createdAt: timestamp('createdAt').notNull().defaultNow(),\n});\n\n// One row per (user, device fingerprint) pair. Its only job is to answer\n// \"has this account signed in from this device before?\" — no matching row ⇒\n// send a new-device alert (see app/api/device-check/route.ts). visitorId is\n// FingerprintJS's identifier, computed client-side in\n// components/auth/deviceCheck.tsx. UA+IP are deliberately NOT the signal here:\n// they churn constantly on mobile and would alert on every other login.\nexport const deviceFingerprints = pgTable(\"device_fingerprint\", {\n id: text(\"id\").notNull().primaryKey().$defaultFn(() => createId()),\n userId: text(\"userId\")\n .notNull()\n .references(() => users.id, { onDelete: \"cascade\" }),\n visitorId: text(\"visitorId\").notNull(),\n // Context captured at first-seen time — for the admin panel's \"New devices\"\n // card and the alert email. Not part of the new-vs-known decision (that's\n // visitorId only), just so an admin can eyeball whether a sign-in looks like\n // a hijack. Nullable: an old row predates these columns, or geoip missed.\n ipAddress: text(\"ipAddress\"),\n userAgent: text(\"userAgent\"),\n country: text(\"country\"),\n city: text(\"city\"),\n createdAt: timestamp(\"createdAt\").notNull().defaultNow(),\n}, (table) => [\n unique(\"device_fingerprint_user_visitor\").on(table.userId, table.visitorId),\n]);\n\n// Per-device abuse throttle for /sign-in/email and /sign-up/email — one\n// fixed-window counter row per FingerprintJS visitorId (sent by the auth\n// forms as the x-device-fingerprint header; see lib/auth-throttle.ts).\n// Keyed by device, not IP: IP is shared behind corporate NAT / CGNAT / VPN,\n// so an IP counter throttles coworkers together while missing an abuser who\n// rotates IPs. Rows whose window has elapsed are dead weight but harmless\n// (reset on the next attempt) — prune on a cron if the table ever grows.\nexport const authThrottle = pgTable(\"auth_throttle\", {\n fingerprint: text(\"fingerprint\").notNull().primaryKey(),\n count: integer(\"count\").notNull().default(0),\n windowStart: timestamp(\"windowStart\").notNull().defaultNow(),\n // Blockable data points, overwritten on every attempt (last-write-wins) so\n // the admin panel can show who to block — by IP or by fingerprint — with no\n // join and no per-attempt history table. windowStart anchors the counter's\n // window; lastAttemptAt is just \"most recently seen\".\n lastAttemptAt: timestamp(\"lastAttemptAt\").notNull().defaultNow(),\n ipAddress: text(\"ipAddress\"),\n userAgent: text(\"userAgent\"),\n lastEmail: text(\"lastEmail\"),\n lastKind: text(\"lastKind\"), // 'signin' | 'signup'\n});\n\n// Singleton row (id is always 'default') holding admin-editable settings for\n// config that used to be env-var-only. See lib/settings-queries.ts for the\n// cached read path and lazy-seed-from-env behavior.\nexport const systemSettings = pgTable(\"system_settings\", {\n id: text(\"id\").primaryKey().default(\"default\"),\n maintenanceMode: boolean(\"maintenanceMode\").notNull().default(false),\n maintenanceMessage: text(\"maintenanceMessage\"),\n // Path prefixes that stay reachable while maintenance mode is on (see\n // lib/maintenance.ts — a few auth paths are always open on top of these).\n maintenanceExemptPaths: text(\"maintenanceExemptPaths\").array().notNull().default(DEFAULT_MAINTENANCE_EXEMPT_PATHS),\n authEnableGoogle: boolean(\"authEnableGoogle\").notNull().default(true),\n authEnableEmailPassword: boolean(\"authEnableEmailPassword\").notNull().default(true),\n authEnableOneTap: boolean(\"authEnableOneTap\").notNull().default(false),\n enableSessionRevocation: boolean(\"enableSessionRevocation\").notNull().default(true),\n updatedAt: timestamp(\"updatedAt\").notNull().defaultNow(),\n // Who last changed a setting. This row doesn't \"belong\" to that admin the\n // way sessions/activityLogs belong to their user, so deleting that admin's\n // account should null this out rather than cascade-delete the singleton row.\n updatedBy: text(\"updatedBy\").references(() => users.id, { onDelete: \"set null\" }),\n}, (table) => [\n check(\"system_settings_singleton\", sql`${table.id} = 'default'`),\n]);","// Pure path logic for maintenance mode — no DB / server-only imports, so it\n// can run in proxy.ts and in the admin form alike.\n\n// Default for the admin-editable exempt list: the public marketing pages.\nexport const DEFAULT_MAINTENANCE_EXEMPT_PATHS = [\n \"/\",\n \"/features\",\n \"/changelog\",\n \"/changelog-template\",\n \"/privacy\",\n \"/terms\",\n]\n\n// Always reachable, whatever the admin saves — otherwise an admin could\n// lock themselves out of the sign-in flow needed to turn maintenance off.\nexport const ALWAYS_OPEN_PATHS = [\n \"/maintenance\",\n \"/login\", // includes /login/2fa\n \"/forgot-password\",\n \"/reset-password\",\n \"/api/auth\",\n \"/api/settings/public\", // login page reads the One Tap flag from here\n]\n\n// `/foo` matches `/foo` and `/foo/...` but not `/foobar`; `/` matches only `/`.\nfunction matches(pathname: string, prefix: string) {\n const p = prefix.length > 1 ? prefix.replace(/\\/+$/, \"\") : prefix\n return pathname === p || (p !== \"/\" && pathname.startsWith(p + \"/\"))\n}\n\nexport function isMaintenanceExempt(pathname: string, exemptPaths: string[]) {\n return [...ALWAYS_OPEN_PATHS, ...exemptPaths].some((p) => matches(pathname, p))\n}\n"]}
|
|
@@ -1,21 +1,18 @@
|
|
|
1
|
-
import { logActivity } from './chunk-
|
|
1
|
+
import { logActivity } from './chunk-B4FKFE7P.mjs';
|
|
2
2
|
import { getClientIp, parseUserAgent, lookupGeoLocation, formatLocation, formatDeviceInfo, WINDOW_MS, isOverLimit, MAX_IP } from './chunk-N6ECRCHY.mjs';
|
|
3
|
-
import { getEffectiveAuthFlags } from './chunk-
|
|
4
|
-
import { db } from './chunk-
|
|
5
|
-
import { users, sessions, passkeys, twoFactors, verifications, accounts, authThrottle } from './chunk-
|
|
3
|
+
import { getEffectiveAuthFlags } from './chunk-AGUEAXPN.mjs';
|
|
4
|
+
import { db } from './chunk-FJAZNE3I.mjs';
|
|
5
|
+
import { users, sessions, passkeys, twoFactors, verifications, accounts, authThrottle } from './chunk-LPL6U5RD.mjs';
|
|
6
6
|
import { config } from './chunk-GTPTVNY2.mjs';
|
|
7
|
-
import { __spreadValues, __spreadProps
|
|
7
|
+
import { __spreadValues, __spreadProps } from './chunk-3465SI5N.mjs';
|
|
8
8
|
import 'server-only';
|
|
9
9
|
import { betterAuth } from 'better-auth';
|
|
10
10
|
import { drizzleAdapter } from 'better-auth/adapters/drizzle';
|
|
11
|
+
import { createId } from '@paralleldrive/cuid2';
|
|
11
12
|
import { eq, sql } from 'drizzle-orm';
|
|
12
|
-
import bcrypt from 'bcrypt';
|
|
13
13
|
import { oneTap, admin, twoFactor } from 'better-auth/plugins';
|
|
14
|
-
import { passkey } from 'better-auth/
|
|
14
|
+
import { passkey } from '@better-auth/passkey';
|
|
15
15
|
import { createAuthMiddleware, APIError, getSessionFromCtx } from 'better-auth/api';
|
|
16
|
-
import { Resend } from 'resend';
|
|
17
|
-
import { Html, Head, Tailwind, Body, Container, Section, Heading, Text, Button, Link } from '@react-email/components';
|
|
18
|
-
import { jsxs, jsx } from 'react/jsx-runtime';
|
|
19
16
|
|
|
20
17
|
// lib/cookie-names.ts
|
|
21
18
|
var LOGIN_REFERRER_COOKIE = "login_referrer";
|
|
@@ -60,128 +57,13 @@ async function clearDeviceThrottle(fingerprint) {
|
|
|
60
57
|
}
|
|
61
58
|
var EMAIL_FROM = "Acme <onboarding@xavierkhew.xyz>";
|
|
62
59
|
var resend;
|
|
63
|
-
function getResend() {
|
|
64
|
-
if (!resend)
|
|
60
|
+
async function getResend() {
|
|
61
|
+
if (!resend) {
|
|
62
|
+
const { Resend } = await import('resend');
|
|
63
|
+
resend = new Resend(config.RESEND_API_KEY);
|
|
64
|
+
}
|
|
65
65
|
return resend;
|
|
66
66
|
}
|
|
67
|
-
function EmailTemplateResetPassword({ firstName, url }) {
|
|
68
|
-
return /* @__PURE__ */ jsxs(Html, { children: [
|
|
69
|
-
/* @__PURE__ */ jsx(Head, {}),
|
|
70
|
-
/* @__PURE__ */ jsx(Body, { style: { backgroundColor: "#ffffff", fontFamily: "Arial, sans-serif" }, children: /* @__PURE__ */ jsx(Container, { style: { margin: "0 auto", padding: "20px 0 48px", maxWidth: "560px" }, children: /* @__PURE__ */ jsxs(Section, { style: { backgroundColor: "#f8f9fa", borderRadius: "12px", padding: "40px", textAlign: "center" }, children: [
|
|
71
|
-
/* @__PURE__ */ jsx(Heading, { style: { fontSize: "28px", fontWeight: "bold", marginBottom: "12px", color: "#1a1a1a" }, children: "Reset your password" }),
|
|
72
|
-
/* @__PURE__ */ jsxs(Text, { style: { fontSize: "16px", color: "#666666", marginBottom: "32px", lineHeight: "24px" }, children: [
|
|
73
|
-
"Hi ",
|
|
74
|
-
firstName,
|
|
75
|
-
", 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."
|
|
76
|
-
] }),
|
|
77
|
-
/* @__PURE__ */ jsx(Section, { style: { marginBottom: "32px" }, children: /* @__PURE__ */ jsx(
|
|
78
|
-
Button,
|
|
79
|
-
{
|
|
80
|
-
href: url,
|
|
81
|
-
style: {
|
|
82
|
-
backgroundColor: "#000000",
|
|
83
|
-
color: "#ffffff",
|
|
84
|
-
padding: "12px 32px",
|
|
85
|
-
borderRadius: "6px",
|
|
86
|
-
textDecoration: "none",
|
|
87
|
-
fontSize: "16px",
|
|
88
|
-
fontWeight: "bold"
|
|
89
|
-
},
|
|
90
|
-
children: "Reset password"
|
|
91
|
-
}
|
|
92
|
-
) }),
|
|
93
|
-
/* @__PURE__ */ jsxs(Text, { style: { fontSize: "13px", color: "#999999", lineHeight: "20px", wordBreak: "break-all" }, children: [
|
|
94
|
-
"Or paste this link into your browser:",
|
|
95
|
-
/* @__PURE__ */ jsx("br", {}),
|
|
96
|
-
/* @__PURE__ */ jsx("a", { href: url, style: { color: "#000000", textDecoration: "underline" }, children: url })
|
|
97
|
-
] })
|
|
98
|
-
] }) }) })
|
|
99
|
-
] });
|
|
100
|
-
}
|
|
101
|
-
function EmailTemplateVerifyEmail({ firstName, url }) {
|
|
102
|
-
return /* @__PURE__ */ jsxs(Html, { children: [
|
|
103
|
-
/* @__PURE__ */ jsx(Head, {}),
|
|
104
|
-
/* @__PURE__ */ jsx(Tailwind, { children: /* @__PURE__ */ jsx(Body, { className: "bg-white font-sans", children: /* @__PURE__ */ jsx(Container, { className: "mx-auto max-w-[560px] px-0 pt-5 pb-12", children: /* @__PURE__ */ jsxs(Section, { className: "rounded-xl bg-[#f8f9fa] p-10 text-center", children: [
|
|
105
|
-
/* @__PURE__ */ jsx(Heading, { className: "mb-3 text-[28px] font-bold text-[#1a1a1a]", children: "Confirm your email" }),
|
|
106
|
-
/* @__PURE__ */ jsxs(Text, { className: "mb-8 text-base leading-6 text-[#666666]", children: [
|
|
107
|
-
"Hi ",
|
|
108
|
-
firstName,
|
|
109
|
-
", click the button below to verify this email address. If you didn't create an account, you can safely ignore this email."
|
|
110
|
-
] }),
|
|
111
|
-
/* @__PURE__ */ jsx(Section, { className: "mb-8", children: /* @__PURE__ */ jsx(
|
|
112
|
-
Button,
|
|
113
|
-
{
|
|
114
|
-
href: url,
|
|
115
|
-
className: "rounded-md bg-black px-8 py-3 text-base font-bold text-white no-underline",
|
|
116
|
-
children: "Verify email"
|
|
117
|
-
}
|
|
118
|
-
) }),
|
|
119
|
-
/* @__PURE__ */ jsxs(Text, { className: "text-[13px] leading-5 break-all text-[#999999]", children: [
|
|
120
|
-
"Or paste this link into your browser:",
|
|
121
|
-
/* @__PURE__ */ jsx("br", {}),
|
|
122
|
-
/* @__PURE__ */ jsx(Link, { href: url, className: "text-black underline", children: url })
|
|
123
|
-
] })
|
|
124
|
-
] }) }) }) })
|
|
125
|
-
] });
|
|
126
|
-
}
|
|
127
|
-
function EmailTemplatePasskeyChange({
|
|
128
|
-
firstName,
|
|
129
|
-
action,
|
|
130
|
-
device,
|
|
131
|
-
location,
|
|
132
|
-
ipAddress,
|
|
133
|
-
when,
|
|
134
|
-
manageUrl
|
|
135
|
-
}) {
|
|
136
|
-
const verb = action === "added" ? "added to" : "removed from";
|
|
137
|
-
return /* @__PURE__ */ jsxs(Html, { children: [
|
|
138
|
-
/* @__PURE__ */ jsx(Head, {}),
|
|
139
|
-
/* @__PURE__ */ jsx(Tailwind, { children: /* @__PURE__ */ jsx(Body, { className: "bg-white font-sans", children: /* @__PURE__ */ jsx(Container, { className: "mx-auto max-w-[560px] px-0 pt-5 pb-12", children: /* @__PURE__ */ jsxs(Section, { className: "rounded-xl bg-[#f8f9fa] p-10", children: [
|
|
140
|
-
/* @__PURE__ */ jsxs(Heading, { className: "mb-3 text-center text-2xl font-bold text-[#1a1a1a]", children: [
|
|
141
|
-
"A passkey was ",
|
|
142
|
-
action
|
|
143
|
-
] }),
|
|
144
|
-
/* @__PURE__ */ jsxs(Text, { className: "mb-6 text-base leading-6 text-[#666666]", children: [
|
|
145
|
-
"Hi ",
|
|
146
|
-
firstName,
|
|
147
|
-
", a passkey was just ",
|
|
148
|
-
verb,
|
|
149
|
-
" your account."
|
|
150
|
-
] }),
|
|
151
|
-
/* @__PURE__ */ jsxs(Section, { className: "mb-6 rounded-lg bg-white p-5", children: [
|
|
152
|
-
/* @__PURE__ */ jsxs(Text, { className: "m-0 mb-2 text-sm leading-5 text-[#1a1a1a]", children: [
|
|
153
|
-
/* @__PURE__ */ jsx("strong", { children: "Device:" }),
|
|
154
|
-
" ",
|
|
155
|
-
device
|
|
156
|
-
] }),
|
|
157
|
-
/* @__PURE__ */ jsxs(Text, { className: "m-0 mb-2 text-sm leading-5 text-[#1a1a1a]", children: [
|
|
158
|
-
/* @__PURE__ */ jsx("strong", { children: "Approx. location:" }),
|
|
159
|
-
" ",
|
|
160
|
-
location
|
|
161
|
-
] }),
|
|
162
|
-
/* @__PURE__ */ jsxs(Text, { className: "m-0 mb-2 text-sm leading-5 text-[#1a1a1a]", children: [
|
|
163
|
-
/* @__PURE__ */ jsx("strong", { children: "IP address:" }),
|
|
164
|
-
" ",
|
|
165
|
-
ipAddress
|
|
166
|
-
] }),
|
|
167
|
-
/* @__PURE__ */ jsxs(Text, { className: "m-0 text-sm leading-5 text-[#1a1a1a]", children: [
|
|
168
|
-
/* @__PURE__ */ jsx("strong", { children: "When:" }),
|
|
169
|
-
" ",
|
|
170
|
-
when
|
|
171
|
-
] })
|
|
172
|
-
] }),
|
|
173
|
-
manageUrl && /* @__PURE__ */ jsx(Section, { className: "mb-6 text-center", children: /* @__PURE__ */ jsx(
|
|
174
|
-
Button,
|
|
175
|
-
{
|
|
176
|
-
href: manageUrl,
|
|
177
|
-
className: "rounded-lg bg-[#1a1a1a] px-6 py-3 text-sm font-bold text-white no-underline",
|
|
178
|
-
children: "Review your passkeys"
|
|
179
|
-
}
|
|
180
|
-
) }),
|
|
181
|
-
/* @__PURE__ */ jsx(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." })
|
|
182
|
-
] }) }) }) })
|
|
183
|
-
] });
|
|
184
|
-
}
|
|
185
67
|
|
|
186
68
|
// server/auth.ts
|
|
187
69
|
async function logFailedLogin(ctx) {
|
|
@@ -218,7 +100,8 @@ async function notifyPasskeyChange(ctx, action) {
|
|
|
218
100
|
userAgent: (_b = (_a = ctx.headers) == null ? void 0 : _a.get("user-agent")) != null ? _b : null
|
|
219
101
|
});
|
|
220
102
|
if (!config.RESEND_API_KEY) return;
|
|
221
|
-
await
|
|
103
|
+
const { EmailTemplatePasskeyChange } = await import('./email-template-passkey-change-F5Q2SXHD.mjs');
|
|
104
|
+
await (await getResend()).emails.send({
|
|
222
105
|
from: EMAIL_FROM,
|
|
223
106
|
to: [user.email],
|
|
224
107
|
subject: action === "added" ? "A passkey was added to your account" : "A passkey was removed from your account",
|
|
@@ -281,18 +164,12 @@ function createAuth(overrides = {}) {
|
|
|
281
164
|
emailAndPassword: {
|
|
282
165
|
enabled: emailAndPasswordEnabled,
|
|
283
166
|
requireEmailVerification: false,
|
|
284
|
-
// Use bcrypt to maintain compatibility with existing user passwords
|
|
285
|
-
async hash(password) {
|
|
286
|
-
return await bcrypt.hash(password, 10);
|
|
287
|
-
},
|
|
288
|
-
async verify({ hash, password }) {
|
|
289
|
-
return await bcrypt.compare(password, hash);
|
|
290
|
-
},
|
|
291
167
|
// `url` is fully composed by better-auth (baseURL + verification token +
|
|
292
168
|
// callbackURL) — see app/(auth)/forgot-password and reset-password for
|
|
293
169
|
// the pages this points at.
|
|
294
170
|
async sendResetPassword({ user, url }) {
|
|
295
|
-
await
|
|
171
|
+
const { EmailTemplateResetPassword } = await import('./email-template-reset-password-QTCQNXOD.mjs');
|
|
172
|
+
await (await getResend()).emails.send({
|
|
296
173
|
from: EMAIL_FROM,
|
|
297
174
|
to: [user.email],
|
|
298
175
|
subject: "Reset your password",
|
|
@@ -308,7 +185,8 @@ function createAuth(overrides = {}) {
|
|
|
308
185
|
emailVerification: {
|
|
309
186
|
autoSignInAfterVerification: true,
|
|
310
187
|
async sendVerificationEmail({ user, url }) {
|
|
311
|
-
await
|
|
188
|
+
const { EmailTemplateVerifyEmail } = await import('./email-template-verify-email-WZDCCAKK.mjs');
|
|
189
|
+
await (await getResend()).emails.send({
|
|
312
190
|
from: EMAIL_FROM,
|
|
313
191
|
to: [user.email],
|
|
314
192
|
subject: "Confirm your email",
|
|
@@ -333,7 +211,9 @@ function createAuth(overrides = {}) {
|
|
|
333
211
|
},
|
|
334
212
|
// Advanced options
|
|
335
213
|
advanced: {
|
|
336
|
-
|
|
214
|
+
database: {
|
|
215
|
+
generateId: () => createId()
|
|
216
|
+
}
|
|
337
217
|
},
|
|
338
218
|
// Every new session row corresponds to a sign-in (credential or OAuth) —
|
|
339
219
|
// use that as the "last logged in" signal rather than session updates,
|
|
@@ -552,5 +432,5 @@ var auth = new Proxy({}, {
|
|
|
552
432
|
});
|
|
553
433
|
|
|
554
434
|
export { auth, createAuth };
|
|
555
|
-
//# sourceMappingURL=chunk-
|
|
556
|
-
//# sourceMappingURL=chunk-
|
|
435
|
+
//# sourceMappingURL=chunk-ZGAODGU3.mjs.map
|
|
436
|
+
//# sourceMappingURL=chunk-ZGAODGU3.mjs.map
|