/opt/canhelp/node_modules/better-auth/dist/db
NameSizeModeActions
adapter-base.d.mts4250644editdlrm
adapter-base.mjs9940644editdlrm
adapter-base.mjs.map20200644editdlrm
adapter-kysely.d.mts3280644editdlrm
adapter-kysely.mjs8460644editdlrm
adapter-kysely.mjs.map15010644editdlrm
field-converter.d.mts4440644editdlrm
field-converter.mjs6270644editdlrm
field-converter.mjs.map14230644editdlrm
field.d.mts37030644editdlrm
get-migration.d.mts8040644editdlrm
get-migration.mjs123110644editdlrm
get-migration.mjs.map260160644editdlrm
get-schema.d.mts3590644editdlrm
get-schema.mjs9960644editdlrm
get-schema.mjs.map20290644editdlrm
index.d.mts12150644editdlrm
index.mjs18300644editdlrm
index.mjs.map3850644editdlrm
internal-adapter.d.mts6390644editdlrm
internal-adapter.mjs217620644editdlrm
internal-adapter.mjs.map510020644editdlrm
schema.d.mts25860644editdlrm
schema.mjs49830644editdlrm
schema.mjs.map103770644editdlrm
to-zod.d.mts15830644editdlrm
to-zod.mjs8650644editdlrm
to-zod.mjs.map34010644editdlrm
verification-token-storage.mjs10840644editdlrm
verification-token-storage.mjs.map21790644editdlrm
with-hooks.d.mts17300644editdlrm
with-hooks.mjs71400644editdlrm
with-hooks.mjs.map162870644editdlrm
Edit: /opt/canhelp/node_modules/better-auth/dist/db/internal-adapter.mjs (21762B)
import { getIp } from "../utils/get-request-ip.mjs"; import { getDate } from "../utils/date.mjs"; import { getSessionDefaultFields, parseSessionOutput, parseUserOutput } from "./schema.mjs"; import { getStorageOption, processIdentifier } from "./verification-token-storage.mjs"; import { getWithHooks } from "./with-hooks.mjs"; import { getCurrentAdapter, getCurrentAuthContext, runWithTransaction } from "@better-auth/core/context"; import { generateId } from "@better-auth/core/utils/id"; import { safeJSONParse } from "@better-auth/core/utils/json"; //#region src/db/internal-adapter.ts function getTTLSeconds(expiresAt, now = Date.now()) { const expiresMs = typeof expiresAt === "number" ? expiresAt : expiresAt.getTime(); return Math.max(Math.floor((expiresMs - now) / 1e3), 0); } const createInternalAdapter = (adapter, ctx) => { const logger = ctx.logger; const options = ctx.options; const secondaryStorage = options.secondaryStorage; const sessionExpiration = options.session?.expiresIn || 3600 * 24 * 7; const { createWithHooks, updateWithHooks, updateManyWithHooks, deleteWithHooks, deleteManyWithHooks } = getWithHooks(adapter, ctx); async function refreshUserSessions(user) { if (!secondaryStorage) return; const listRaw = await secondaryStorage.get(`active-sessions-${user.id}`); if (!listRaw) return; const now = Date.now(); const validSessions = (safeJSONParse(listRaw) || []).filter((s) => s.expiresAt > now); await Promise.all(validSessions.map(async ({ token }) => { const cached = await secondaryStorage.get(token); if (!cached) return; const parsed = safeJSONParse(cached); if (!parsed) return; const sessionTTL = getTTLSeconds(parsed.session.expiresAt, now); await secondaryStorage.set(token, JSON.stringify({ session: parsed.session, user }), Math.floor(sessionTTL)); })); } return { createOAuthUser: async (user, account) => { return runWithTransaction(adapter, async () => { const createdUser = await createWithHooks({ createdAt: /* @__PURE__ */ new Date(), updatedAt: /* @__PURE__ */ new Date(), ...user }, "user", void 0); return { user: createdUser, account: await createWithHooks({ ...account, userId: createdUser.id, createdAt: /* @__PURE__ */ new Date(), updatedAt: /* @__PURE__ */ new Date() }, "account", void 0) }; }); }, createUser: async (user) => { return await createWithHooks({ createdAt: /* @__PURE__ */ new Date(), updatedAt: /* @__PURE__ */ new Date(), ...user, email: user.email?.toLowerCase() }, "user", void 0); }, createAccount: async (account) => { return await createWithHooks({ createdAt: /* @__PURE__ */ new Date(), updatedAt: /* @__PURE__ */ new Date(), ...account }, "account", void 0); }, listSessions: async (userId, options) => { if (secondaryStorage) { const currentList = await secondaryStorage.get(`active-sessions-${userId}`); if (!currentList) return []; const list = safeJSONParse(currentList) || []; const now = Date.now(); const seenTokens = /* @__PURE__ */ new Set(); const sessions = []; for (const { token, expiresAt } of list) { if (expiresAt <= now || seenTokens.has(token)) continue; seenTokens.add(token); const data = await secondaryStorage.get(token); if (!data) continue; try { const parsed = typeof data === "string" ? JSON.parse(data) : data; if (!parsed?.session) continue; sessions.push(parseSessionOutput(ctx.options, { ...parsed.session, expiresAt: new Date(parsed.session.expiresAt) })); } catch { continue; } } return sessions; } return await (await getCurrentAdapter(adapter)).findMany({ model: "session", where: [{ field: "userId", value: userId }, ...options?.onlyActiveSessions ? [{ field: "expiresAt", value: /* @__PURE__ */ new Date(), operator: "gt" }] : []] }); }, listUsers: async (limit, offset, sortBy, where) => { return await (await getCurrentAdapter(adapter)).findMany({ model: "user", limit, offset, sortBy, where }); }, countTotalUsers: async (where) => { const total = await (await getCurrentAdapter(adapter)).count({ model: "user", where }); if (typeof total === "string") return parseInt(total); return total; }, deleteUser: async (userId) => { if (!secondaryStorage || options.session?.storeSessionInDatabase) await deleteManyWithHooks([{ field: "userId", value: userId }], "session", void 0); await deleteManyWithHooks([{ field: "userId", value: userId }], "account", void 0); await deleteWithHooks([{ field: "id", value: userId }], "user", void 0); }, createSession: async (userId, dontRememberMe, override, overrideAll) => { const headers = await (async () => { const ctx = await getCurrentAuthContext().catch(() => null); return ctx?.headers || ctx?.request?.headers; })(); const storeInDb = options.session?.storeSessionInDatabase; const { id: _, ...rest } = override || {}; const defaultAdditionalFields = getSessionDefaultFields(options); const data = { ipAddress: headers ? getIp(headers, options) || "" : "", userAgent: headers?.get("user-agent") || "", ...rest, expiresAt: dontRememberMe ? getDate(3600 * 24, "sec") : getDate(sessionExpiration, "sec"), userId, token: generateId(32), createdAt: /* @__PURE__ */ new Date(), updatedAt: /* @__PURE__ */ new Date(), ...defaultAdditionalFields, ...overrideAll ? rest : {} }; return await createWithHooks(data, "session", secondaryStorage ? { fn: async (sessionData) => { /** * store the session token for the user * so we can retrieve it later for listing sessions */ const currentList = await secondaryStorage.get(`active-sessions-${userId}`); let list = []; const now = Date.now(); if (currentList) { list = safeJSONParse(currentList) || []; list = list.filter((session) => session.expiresAt > now && session.token !== data.token); } const sorted = [...list, { token: data.token, expiresAt: data.expiresAt.getTime() }].sort((a, b) => a.expiresAt - b.expiresAt); const furthestSessionTTL = getTTLSeconds(sorted.at(-1)?.expiresAt ?? data.expiresAt.getTime(), now); if (furthestSessionTTL > 0) await secondaryStorage.set(`active-sessions-${userId}`, JSON.stringify(sorted), furthestSessionTTL); const user = await (await getCurrentAdapter(adapter)).findOne({ model: "user", where: [{ field: "id", value: userId }] }); const sessionTTL = getTTLSeconds(data.expiresAt, now); if (sessionTTL > 0) await secondaryStorage.set(data.token, JSON.stringify({ session: sessionData, user }), sessionTTL); return sessionData; }, executeMainFn: storeInDb } : void 0); }, findSession: async (token) => { if (secondaryStorage) { const sessionStringified = await secondaryStorage.get(token); if (!sessionStringified && (!options.session?.storeSessionInDatabase || ctx.options.session?.preserveSessionInDatabase)) return null; if (sessionStringified) { const s = safeJSONParse(sessionStringified); if (!s) return null; return { session: parseSessionOutput(ctx.options, { ...s.session, expiresAt: new Date(s.session.expiresAt), createdAt: new Date(s.session.createdAt), updatedAt: new Date(s.session.updatedAt) }), user: parseUserOutput(ctx.options, { ...s.user, createdAt: new Date(s.user.createdAt), updatedAt: new Date(s.user.updatedAt) }) }; } } const result = await (await getCurrentAdapter(adapter)).findOne({ model: "session", where: [{ value: token, field: "token" }], join: { user: true } }); if (!result) return null; const { user, ...session } = result; if (!user) return null; return { session: parseSessionOutput(ctx.options, session), user: parseUserOutput(ctx.options, user) }; }, findSessions: async (sessionTokens, options) => { if (secondaryStorage) { const sessions = []; for (const sessionToken of sessionTokens) { const sessionStringified = await secondaryStorage.get(sessionToken); if (sessionStringified) try { const s = typeof sessionStringified === "string" ? JSON.parse(sessionStringified) : sessionStringified; if (!s) return []; const expiresAt = new Date(s.session.expiresAt); if (options?.onlyActiveSessions && expiresAt <= /* @__PURE__ */ new Date()) continue; const session = { session: { ...s.session, expiresAt: new Date(s.session.expiresAt) }, user: { ...s.user, createdAt: new Date(s.user.createdAt), updatedAt: new Date(s.user.updatedAt) } }; sessions.push(session); } catch { continue; } } return sessions; } const sessions = await (await getCurrentAdapter(adapter)).findMany({ model: "session", where: [{ field: "token", value: sessionTokens, operator: "in" }, ...options?.onlyActiveSessions ? [{ field: "expiresAt", value: /* @__PURE__ */ new Date(), operator: "gt" }] : []], join: { user: true } }); if (!sessions.length) return []; if (sessions.some((session) => !session.user)) return []; return sessions.map((_session) => { const { user, ...session } = _session; return { session, user }; }); }, updateSession: async (sessionToken, session) => { return await updateWithHooks(session, [{ field: "token", value: sessionToken }], "session", secondaryStorage ? { async fn(data) { const currentSession = await secondaryStorage.get(sessionToken); if (!currentSession) return null; const parsedSession = safeJSONParse(currentSession); if (!parsedSession) return null; const mergedSession = { ...parsedSession.session, ...data, expiresAt: new Date(data.expiresAt ?? parsedSession.session.expiresAt), createdAt: new Date(parsedSession.session.createdAt), updatedAt: new Date(data.updatedAt ?? parsedSession.session.updatedAt) }; const updatedSession = parseSessionOutput(ctx.options, mergedSession); const now = Date.now(); const expiresMs = new Date(updatedSession.expiresAt).getTime(); const sessionTTL = getTTLSeconds(expiresMs, now); if (sessionTTL > 0) { await secondaryStorage.set(sessionToken, JSON.stringify({ session: updatedSession, user: parsedSession.user }), sessionTTL); const listKey = `active-sessions-${updatedSession.userId}`; const listRaw = await secondaryStorage.get(listKey); const sorted = (listRaw ? safeJSONParse(listRaw) || [] : []).filter((s) => s.token !== sessionToken && s.expiresAt > now).concat([{ token: sessionToken, expiresAt: expiresMs }]).sort((a, b) => a.expiresAt - b.expiresAt); const furthestSessionExp = sorted.at(-1)?.expiresAt; if (furthestSessionExp && furthestSessionExp > now) await secondaryStorage.set(listKey, JSON.stringify(sorted), getTTLSeconds(furthestSessionExp, now)); else await secondaryStorage.delete(listKey); } return updatedSession; }, executeMainFn: options.session?.storeSessionInDatabase } : void 0); }, deleteSession: async (token) => { if (secondaryStorage) { const data = await secondaryStorage.get(token); if (data) { const { session } = safeJSONParse(data) ?? {}; if (!session) { logger.error("Session not found in secondary storage"); return; } const userId = session.userId; const currentList = await secondaryStorage.get(`active-sessions-${userId}`); if (currentList) { const list = safeJSONParse(currentList) || []; const now = Date.now(); const filtered = list.filter((session) => session.expiresAt > now && session.token !== token); const furthestSessionExp = filtered.sort((a, b) => a.expiresAt - b.expiresAt).at(-1)?.expiresAt; if (filtered.length > 0 && furthestSessionExp && furthestSessionExp > Date.now()) await secondaryStorage.set(`active-sessions-${userId}`, JSON.stringify(filtered), getTTLSeconds(furthestSessionExp, now)); else await secondaryStorage.delete(`active-sessions-${userId}`); } else logger.error("Active sessions list not found in secondary storage"); } await secondaryStorage.delete(token); if (!options.session?.storeSessionInDatabase || ctx.options.session?.preserveSessionInDatabase) return; } await deleteWithHooks([{ field: "token", value: token }], "session", void 0); }, deleteAccounts: async (userId) => { await deleteManyWithHooks([{ field: "userId", value: userId }], "account", void 0); }, deleteAccount: async (accountId) => { await deleteWithHooks([{ field: "id", value: accountId }], "account", void 0); }, deleteSessions: async (userIdOrSessionTokens) => { if (secondaryStorage) { if (typeof userIdOrSessionTokens === "string") { const activeSession = await secondaryStorage.get(`active-sessions-${userIdOrSessionTokens}`); const sessions = activeSession ? safeJSONParse(activeSession) : []; if (!sessions) return; for (const session of sessions) await secondaryStorage.delete(session.token); await secondaryStorage.delete(`active-sessions-${userIdOrSessionTokens}`); } else for (const sessionToken of userIdOrSessionTokens) if (await secondaryStorage.get(sessionToken)) await secondaryStorage.delete(sessionToken); if (!options.session?.storeSessionInDatabase || ctx.options.session?.preserveSessionInDatabase) return; } await deleteManyWithHooks([{ field: Array.isArray(userIdOrSessionTokens) ? "token" : "userId", value: userIdOrSessionTokens, operator: Array.isArray(userIdOrSessionTokens) ? "in" : void 0 }], "session", void 0); }, findOAuthUser: async (email, accountId, providerId) => { const account = await (await getCurrentAdapter(adapter)).findOne({ model: "account", where: [{ value: accountId, field: "accountId" }, { value: providerId, field: "providerId" }], join: { user: true } }); if (account) if (account.user) return { user: account.user, linkedAccount: account, accounts: [account] }; else { const user = await (await getCurrentAdapter(adapter)).findOne({ model: "user", where: [{ value: email.toLowerCase(), field: "email" }] }); if (user) return { user, linkedAccount: account, accounts: [account] }; return null; } else { const user = await (await getCurrentAdapter(adapter)).findOne({ model: "user", where: [{ value: email.toLowerCase(), field: "email" }] }); if (user) return { user, linkedAccount: null, accounts: await (await getCurrentAdapter(adapter)).findMany({ model: "account", where: [{ value: user.id, field: "userId" }] }) || [] }; else return null; } }, findUserByEmail: async (email, options) => { const result = await (await getCurrentAdapter(adapter)).findOne({ model: "user", where: [{ value: email.toLowerCase(), field: "email" }], join: { ...options?.includeAccounts ? { account: true } : {} } }); if (!result) return null; const { account: accounts, ...user } = result; return { user, accounts: accounts ?? [] }; }, findUserById: async (userId) => { if (!userId) return null; return await (await getCurrentAdapter(adapter)).findOne({ model: "user", where: [{ field: "id", value: userId }] }); }, linkAccount: async (account) => { return await createWithHooks({ createdAt: /* @__PURE__ */ new Date(), updatedAt: /* @__PURE__ */ new Date(), ...account }, "account", void 0); }, updateUser: async (userId, data) => { const user = await updateWithHooks(data, [{ field: "id", value: userId }], "user", void 0); await refreshUserSessions(user); return user; }, updateUserByEmail: async (email, data) => { const user = await updateWithHooks(data, [{ field: "email", value: email.toLowerCase() }], "user", void 0); await refreshUserSessions(user); return user; }, updatePassword: async (userId, password) => { await updateManyWithHooks({ password }, [{ field: "userId", value: userId }, { field: "providerId", value: "credential" }], "account", void 0); }, findAccounts: async (userId) => { return await (await getCurrentAdapter(adapter)).findMany({ model: "account", where: [{ field: "userId", value: userId }] }); }, findAccount: async (accountId) => { return await (await getCurrentAdapter(adapter)).findOne({ model: "account", where: [{ field: "accountId", value: accountId }] }); }, findAccountByProviderId: async (accountId, providerId) => { return await (await getCurrentAdapter(adapter)).findOne({ model: "account", where: [{ field: "accountId", value: accountId }, { field: "providerId", value: providerId }] }); }, findAccountByUserId: async (userId) => { return await (await getCurrentAdapter(adapter)).findMany({ model: "account", where: [{ field: "userId", value: userId }] }); }, updateAccount: async (id, data) => { return await updateWithHooks(data, [{ field: "id", value: id }], "account", void 0); }, createVerificationValue: async (data) => { const storageOption = getStorageOption(data.identifier, options.verification?.storeIdentifier); const storedIdentifier = await processIdentifier(data.identifier, storageOption); return await createWithHooks({ createdAt: /* @__PURE__ */ new Date(), updatedAt: /* @__PURE__ */ new Date(), ...data, identifier: storedIdentifier }, "verification", secondaryStorage ? { async fn(verificationData) { const ttl = getTTLSeconds(verificationData.expiresAt); if (ttl > 0) await secondaryStorage.set(`verification:${storedIdentifier}`, JSON.stringify(verificationData), ttl); return verificationData; }, executeMainFn: options.verification?.storeInDatabase } : void 0); }, findVerificationValue: async (identifier) => { const storageOption = getStorageOption(identifier, options.verification?.storeIdentifier); const storedIdentifier = await processIdentifier(identifier, storageOption); if (secondaryStorage) { const cached = await secondaryStorage.get(`verification:${storedIdentifier}`); if (cached) { const parsed = safeJSONParse(cached); if (parsed) return parsed; } if (storageOption && storageOption !== "plain") { const plainCached = await secondaryStorage.get(`verification:${identifier}`); if (plainCached) { const parsed = safeJSONParse(plainCached); if (parsed) return parsed; } } if (!options.verification?.storeInDatabase) return null; } const currentAdapter = await getCurrentAdapter(adapter); async function findByIdentifier(id) { return currentAdapter.findMany({ model: "verification", where: [{ field: "identifier", value: id }], sortBy: { field: "createdAt", direction: "desc" }, limit: 1 }); } let verification = await findByIdentifier(storedIdentifier); if (!verification.length && storageOption && storageOption !== "plain") verification = await findByIdentifier(identifier); if (!options.verification?.disableCleanup) await deleteManyWithHooks([{ field: "expiresAt", value: /* @__PURE__ */ new Date(), operator: "lt" }], "verification", void 0); return verification[0] || null; }, deleteVerificationByIdentifier: async (identifier) => { const storedIdentifier = await processIdentifier(identifier, getStorageOption(identifier, options.verification?.storeIdentifier)); if (secondaryStorage) await secondaryStorage.delete(`verification:${storedIdentifier}`); if (!secondaryStorage || options.verification?.storeInDatabase) await deleteWithHooks([{ field: "identifier", value: storedIdentifier }], "verification", void 0); }, updateVerificationByIdentifier: async (identifier, data) => { const storedIdentifier = await processIdentifier(identifier, getStorageOption(identifier, options.verification?.storeIdentifier)); if (secondaryStorage) { const cached = await secondaryStorage.get(`verification:${storedIdentifier}`); if (cached) { const parsed = safeJSONParse(cached); if (parsed) { const updated = { ...parsed, ...data }; const expiresAt = updated.expiresAt ?? parsed.expiresAt; const ttl = getTTLSeconds(expiresAt instanceof Date ? expiresAt : new Date(expiresAt)); if (ttl > 0) await secondaryStorage.set(`verification:${storedIdentifier}`, JSON.stringify(updated), ttl); if (!options.verification?.storeInDatabase) return updated; } } } if (!secondaryStorage || options.verification?.storeInDatabase) return await updateWithHooks(data, [{ field: "identifier", value: storedIdentifier }], "verification", void 0); return data; } }; }; //#endregion export { createInternalAdapter }; //# sourceMappingURL=internal-adapter.mjs.map