From d7c837ff25f80dd058832c94a7717c9fb52d248d Mon Sep 17 00:00:00 2001 From: wood chen Date: Sun, 23 Feb 2025 05:37:05 +0800 Subject: [PATCH] feat: Enhance Discourse OAuth authentication with flexible credential handling --- src/app/(oauth)/q58/callback/page.tsx | 14 ++++++++ src/auth.config.ts | 48 +++++++++++++++++++++++---- 2 files changed, 55 insertions(+), 7 deletions(-) diff --git a/src/app/(oauth)/q58/callback/page.tsx b/src/app/(oauth)/q58/callback/page.tsx index 3059649..bdb594d 100644 --- a/src/app/(oauth)/q58/callback/page.tsx +++ b/src/app/(oauth)/q58/callback/page.tsx @@ -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); diff --git a/src/auth.config.ts b/src/auth.config.ts index b93490c..f4cdaa0 100644 --- a/src/auth.config.ts +++ b/src/auth.config.ts @@ -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; }, }), ],