67 lines
1.5 KiB
TypeScript
67 lines
1.5 KiB
TypeScript
"use server";
|
|
|
|
import { auth } from "@/lib/auth";
|
|
import { logger } from "@/lib/logger";
|
|
import { prisma } from "@/lib/prisma";
|
|
|
|
export async function linkDiscordId(discordId: string): Promise<string | null> {
|
|
const session = await auth();
|
|
if (!session?.user?.id) return "Not logged in";
|
|
|
|
const userId = Number(session.user.id);
|
|
if (!discordId || !/^\d{17,20}$/.test(discordId.trim())) {
|
|
return "Invalid Discord ID format";
|
|
}
|
|
|
|
const discordIdClean = discordId.trim();
|
|
|
|
try {
|
|
const existing = await prisma.socialAccounts.findUnique({
|
|
where: {
|
|
provider_providerId: {
|
|
provider: "discord",
|
|
providerId: discordIdClean,
|
|
},
|
|
},
|
|
select: { userId: true },
|
|
});
|
|
if (existing && Number(existing.userId) !== userId) {
|
|
return "This Discord ID is already linked to another account";
|
|
}
|
|
} catch {
|
|
return "Failed to check Discord ID";
|
|
}
|
|
|
|
try {
|
|
await prisma.socialAccounts.upsert({
|
|
where: {
|
|
provider_providerId: {
|
|
provider: "discord",
|
|
providerId: discordIdClean,
|
|
},
|
|
},
|
|
create: {
|
|
userId: BigInt(userId),
|
|
provider: "discord",
|
|
providerId: discordIdClean,
|
|
createdAt: new Date(),
|
|
updatedAt: new Date(),
|
|
},
|
|
update: { userId: BigInt(userId), updatedAt: new Date() },
|
|
});
|
|
|
|
await prisma.user.update({
|
|
where: { id: userId },
|
|
data: { mailVerified: "1" },
|
|
});
|
|
|
|
return null;
|
|
} catch (e) {
|
|
logger.error("Failed to link Discord account", {
|
|
module: "link-discord",
|
|
error: (e as Error).message,
|
|
});
|
|
return "Failed to link Discord account";
|
|
}
|
|
}
|