41 lines
1.4 KiB
TypeScript
41 lines
1.4 KiB
TypeScript
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,
|
|
};
|
|
});
|