import { and, eq, sql } from 'drizzle-orm'; import { providers } from '~~/drizzle/schema'; import { db } from '~~/server/lib/db'; /** * Tells the recovery page whether a link still works and what using it will * do: set the first password of a new account, or replace a forgotten one. Public on purpose: whoever opens it cannot sign in, that is the point. */ export default defineEventHandler(async (event) => { const link = await findRecoveryLink(getRouterParam(event, 'token')!); if (!link) { return { valid: false as const }; } // an account that never had a password is being set up, not recovered if (!await hasPassword(link.userId)) { return { valid: true as const, newAccount: true as const, email: link.email, name: link.name, }; } const withKey = await db .select({ name: providers.name }) .from(providers) .where(and(eq(providers.userId, link.userId), sql`coalesce(${providers.config}->>'apiKey', '') <> ''`)); return { valid: true as const, newAccount: false as const, email: link.email, // the providers whose saved key is lost when the link is used keyProviders: withKey.map(p => p.name), resetSecurity: link.resetSecurity, twoFactorEnabled: !!link.twoFactorEnabled, }; });