feat: Enhance Discourse OAuth authentication with flexible credential handling

This commit is contained in:
wood chen 2025-02-23 05:37:05 +08:00
parent 71ad4d48ce
commit d7c837ff25
2 changed files with 55 additions and 7 deletions

View File

@ -1,5 +1,6 @@
import { Suspense } from "react";
import { redirect } from "next/navigation";
import { signIn } from "@/auth";
import { discourseCallbackVerify } from "@/lib/discourse/verify";
import { findAuthorization } from "@/lib/dto/authorization";
@ -33,6 +34,19 @@ export default async function DiscourseCallbackPage({
searchParams.sig,
);
// 设置用户会话
await signIn("credentials", {
id: user.id,
username: user.username,
email: user.email,
name: user.name,
avatarUrl: user.avatarUrl,
role: user.role,
moderator: user.moderator,
groups: JSON.stringify(user.groups),
redirect: false,
});
// check authorization
const authorization = await findAuthorization(user.id, client.id);

View File

@ -1,3 +1,4 @@
import { UserRole } from "@prisma/client";
import type { NextAuthConfig } from "next-auth";
import Credentials from "next-auth/providers/credentials";
@ -8,14 +9,47 @@ export default {
providers: [
Credentials({
credentials: {
sso: {},
sig: {},
id: { type: "text" },
username: { type: "text" },
email: { type: "text" },
name: { type: "text" },
avatarUrl: { type: "text" },
role: { type: "text" },
moderator: { type: "text" },
groups: { type: "text" },
sso: { type: "text" },
sig: { type: "text" },
},
authorize: async (credentials) => {
const sso = credentials.sso as string;
const sig = credentials.sig as string;
const user = await discourseCallbackVerify(sso, sig);
return user;
async authorize(credentials) {
if (!credentials) return null;
// 如果是 SSO 登录
if (credentials.sso && credentials.sig) {
return await discourseCallbackVerify(
credentials.sso as string,
credentials.sig as string,
);
}
// 如果是直接传入用户数据
if (credentials.id && credentials.username && credentials.email) {
return {
id: credentials.id as string,
username: credentials.username as string,
email: credentials.email as string,
name: (credentials.name as string) || null,
avatarUrl: (credentials.avatarUrl as string) || null,
role: ((credentials.role as string) || "USER") as UserRole,
moderator: credentials.moderator === "true",
groups: credentials.groups
? JSON.parse(credentials.groups as string)
: [],
createdAt: new Date(),
updatedAt: new Date(),
};
}
return null;
},
}),
],