Add Discord verification option for users without email
This commit is contained in:
1 parent
eb01b14379
commit
43c0ba6614
6 files changed
+257
-56
No files matched your search
+46
-11
@@ -117,24 +117,38 @@ export const { handlers, signIn, signOut, auth } = NextAuth({
|
||||
callbacks: {
|
||||
async signIn({ user, account }) {
|
||||
if (account?.provider === "credentials") return true;
|
||||
// OAuth: only allow if a hotel account with this email already exists.
|
||||
// OAuth: try to match by email first.
|
||||
const email = user.email;
|
||||
if (!email) return "/login?error=NoEmail";
|
||||
try {
|
||||
const dbUser = await prisma.user.findFirst({
|
||||
where: { mail: email },
|
||||
select: { id: true },
|
||||
});
|
||||
return dbUser ? true : "/login?error=NoAccount";
|
||||
} catch {
|
||||
return "/login?error=Unavailable";
|
||||
if (email) {
|
||||
try {
|
||||
const dbUser = await prisma.user.findFirst({
|
||||
where: { mail: email },
|
||||
select: { id: true },
|
||||
});
|
||||
if (dbUser) return true;
|
||||
} catch {
|
||||
return "/login?error=Unavailable";
|
||||
}
|
||||
}
|
||||
// If email didn't match, try Discord ID via SocialAccounts.
|
||||
if (account?.provider === "discord" && account.providerAccountId) {
|
||||
try {
|
||||
const linked = await prisma.socialAccounts.findUnique({
|
||||
where: { provider_providerId: { provider: "discord", providerId: account.providerAccountId } },
|
||||
select: { userId: true },
|
||||
});
|
||||
if (linked) return true;
|
||||
} catch {
|
||||
return "/login?error=Unavailable";
|
||||
}
|
||||
}
|
||||
return "/login?error=NoAccount";
|
||||
},
|
||||
async jwt({ token, user, account }) {
|
||||
if (user && account?.provider === "credentials") {
|
||||
token.rank = (user as { rank?: number }).rank;
|
||||
} else if (user?.email) {
|
||||
// OAuth: bind the session to the matching hotel account.
|
||||
// OAuth with email: bind to matching hotel account.
|
||||
try {
|
||||
const dbUser = await prisma.user.findFirst({
|
||||
where: { mail: user.email },
|
||||
@@ -149,6 +163,27 @@ export const { handlers, signIn, signOut, auth } = NextAuth({
|
||||
// leave token as-is on lookup failure
|
||||
}
|
||||
}
|
||||
// OAuth without email match: try Discord ID via SocialAccounts.
|
||||
if (!token.sub && account?.provider === "discord" && account.providerAccountId) {
|
||||
try {
|
||||
const linked = await prisma.socialAccounts.findUnique({
|
||||
where: { provider_providerId: { provider: "discord", providerId: account.providerAccountId } },
|
||||
});
|
||||
if (linked) {
|
||||
const dbUser = await prisma.user.findUnique({
|
||||
where: { id: Number(linked.userId) },
|
||||
select: { id: true, rank: true, username: true },
|
||||
});
|
||||
if (dbUser) {
|
||||
token.sub = String(dbUser.id);
|
||||
token.rank = dbUser.rank;
|
||||
token.name = dbUser.username;
|
||||
}
|
||||
}
|
||||
} catch {
|
||||
// leave token as-is on lookup failure
|
||||
}
|
||||
}
|
||||
return token;
|
||||
},
|
||||
session({ session, token }) {
|
||||
|
||||
Reference in new issue
Block a user