mirror of
https://github.com/woodchen-ink/Q58Connect.git
synced 2025-07-18 05:51:55 +08:00
refactor: Rename Q58 OAuth callback to Discourse OAuth
This commit is contained in:
parent
569ba4c186
commit
42036544bf
@ -1,22 +1,22 @@
|
||||
import { Suspense } from "react";
|
||||
import { redirect } from "next/navigation";
|
||||
|
||||
import { discourseCallbackVerify } from "@/lib/discourse/verify";
|
||||
import { findAuthorization } from "@/lib/dto/authorization";
|
||||
import { getClientByClientId } from "@/lib/dto/client";
|
||||
import { getAuthorizeUrl } from "@/lib/oauth/authorize-url";
|
||||
import { q58CallbackVerify } from "@/lib/q58/verify";
|
||||
import { AuthorizationCard } from "@/components/auth/authorization-card";
|
||||
|
||||
export interface Q58CallbackParams extends Record<string, string> {
|
||||
export interface DiscourseCallbackParams extends Record<string, string> {
|
||||
sig: string;
|
||||
sso: string;
|
||||
oauth: string;
|
||||
}
|
||||
|
||||
export default async function Q58CallbackPage({
|
||||
export default async function DiscourseCallbackPage({
|
||||
searchParams,
|
||||
}: {
|
||||
searchParams: Q58CallbackParams;
|
||||
searchParams: DiscourseCallbackParams;
|
||||
}) {
|
||||
const oauthParams = new URLSearchParams(atob(searchParams.oauth));
|
||||
// check client info
|
||||
@ -28,7 +28,10 @@ export default async function Q58CallbackPage({
|
||||
}
|
||||
|
||||
// verify discourse callback
|
||||
const user = await q58CallbackVerify(searchParams.sso, searchParams.sig);
|
||||
const user = await discourseCallbackVerify(
|
||||
searchParams.sso,
|
||||
searchParams.sig,
|
||||
);
|
||||
|
||||
// check authorization
|
||||
const authorization = await findAuthorization(user.id, client.id);
|
||||
|
@ -1,7 +1,7 @@
|
||||
import type { NextAuthConfig } from "next-auth";
|
||||
import Credentials from "next-auth/providers/credentials";
|
||||
|
||||
import { q58CallbackVerify } from "./lib/q58/verify";
|
||||
import { discourseCallbackVerify } from "./lib/discourse/verify";
|
||||
|
||||
// Notice this is only an object, not a full Auth.js instance
|
||||
export default {
|
||||
@ -14,7 +14,7 @@ export default {
|
||||
authorize: async (credentials) => {
|
||||
const sso = credentials.sso as string;
|
||||
const sig = credentials.sig as string;
|
||||
const user = await q58CallbackVerify(sso, sig);
|
||||
const user = await discourseCallbackVerify(sso, sig);
|
||||
return user;
|
||||
},
|
||||
}),
|
||||
|
@ -8,11 +8,11 @@ import hmacSHA256 from "crypto-js/hmac-sha256";
|
||||
import { AUTH_NONCE } from "@/lib/constants";
|
||||
import { createUser, getUserById, updateUser } from "@/lib/dto/user";
|
||||
|
||||
const Q58_SECRET = process.env.DISCOURSE_SECRET as string;
|
||||
const DISCOUSE_SECRET = process.env.DISCOURSE_SECRET as string;
|
||||
|
||||
export async function q58CallbackVerify(sso: string, sig: string) {
|
||||
export async function discourseCallbackVerify(sso: string, sig: string) {
|
||||
// 校验数据正确性
|
||||
if (hmacSHA256(sso, Q58_SECRET).toString(Hex) != sig) {
|
||||
if (hmacSHA256(sso, DISCOUSE_SECRET).toString(Hex) != sig) {
|
||||
throw new Error("Request params is invalid (code: -1001).");
|
||||
}
|
||||
// 校验 nonce
|
||||
|
@ -1,74 +0,0 @@
|
||||
import "server-only";
|
||||
|
||||
import { cookies } from "next/headers";
|
||||
import { UserRole } from "@prisma/client";
|
||||
import Hex from "crypto-js/enc-hex";
|
||||
import hmacSHA256 from "crypto-js/hmac-sha256";
|
||||
|
||||
import { AUTH_NONCE } from "@/lib/constants";
|
||||
import { createUser, getUserById, updateUser } from "@/lib/dto/user";
|
||||
|
||||
const Q58_SECRET = process.env.DISCOURSE_SECRET as string;
|
||||
|
||||
export async function q58CallbackVerify(sso: string, sig: string) {
|
||||
// 校验数据正确性
|
||||
if (hmacSHA256(sso, Q58_SECRET).toString(Hex) != sig) {
|
||||
throw new Error("Request params is invalid (code: -1001).");
|
||||
}
|
||||
// 校验 nonce
|
||||
const cookieStore = cookies();
|
||||
let searchParams = new URLSearchParams(atob(sso as string));
|
||||
const nonce = searchParams.get("nonce");
|
||||
if (!cookieStore.has(AUTH_NONCE) || !nonce) {
|
||||
throw new Error("Request params is invalid (code: -1002).");
|
||||
}
|
||||
if (cookieStore.get(AUTH_NONCE)?.value != nonce) {
|
||||
throw new Error("Request params is invalid (code: -1003).");
|
||||
}
|
||||
// cookieStore.delete(AUTH_NONCE);
|
||||
|
||||
const id = searchParams.get("external_id");
|
||||
const email = searchParams.get("email");
|
||||
const username = searchParams.get("username");
|
||||
const name = searchParams.get("name");
|
||||
const avatarUrl = searchParams.get("avatar_url");
|
||||
const isAdmin = searchParams.get("admin") == "true";
|
||||
const moderator = searchParams.get("moderator") == "true";
|
||||
const groups = searchParams.get("groups")?.split(",");
|
||||
if (!id || !email || !username) {
|
||||
throw new Error("User not found.");
|
||||
}
|
||||
|
||||
// 查数据库是否有人
|
||||
let dbUser = await getUserById(id);
|
||||
if (dbUser) {
|
||||
// 更新
|
||||
dbUser = await updateUser(id, {
|
||||
username,
|
||||
email,
|
||||
name,
|
||||
avatarUrl,
|
||||
role: isAdmin ? UserRole.ADMIN : UserRole.USER,
|
||||
moderator,
|
||||
groups,
|
||||
});
|
||||
} else {
|
||||
// 创建
|
||||
dbUser = await createUser({
|
||||
id,
|
||||
username,
|
||||
email,
|
||||
name,
|
||||
avatarUrl,
|
||||
role: isAdmin ? UserRole.ADMIN : UserRole.USER,
|
||||
moderator,
|
||||
groups,
|
||||
});
|
||||
}
|
||||
|
||||
if (!dbUser) {
|
||||
throw new Error("User not create success.");
|
||||
}
|
||||
|
||||
return dbUser;
|
||||
}
|
@ -1,7 +1,12 @@
|
||||
import "server-only";
|
||||
|
||||
import { cache } from "react";
|
||||
import { auth } from "@/auth";
|
||||
|
||||
export const getCurrentUser = cache(async () => {
|
||||
const session = await auth();
|
||||
return session?.user;
|
||||
if (!session?.user) {
|
||||
return undefined;
|
||||
}
|
||||
return session.user;
|
||||
});
|
||||
|
Loading…
x
Reference in New Issue
Block a user