diff --git a/prisma/migrations/20230427162323_invalid_auth_tokens/migration.sql b/prisma/migrations/20230427162323_invalid_auth_tokens/migration.sql
new file mode 100644
index 0000000..1e7d076
--- /dev/null
+++ b/prisma/migrations/20230427162323_invalid_auth_tokens/migration.sql
@@ -0,0 +1,36 @@
+/*
+ Warnings:
+
+ - The primary key for the `GitHubAuth` table will be changed. If it partially fails, the table could be left without primary key constraint.
+ - Added the required column `invalid` to the `DiscordAuth` table without a default value. This is not possible if the table is not empty.
+ - Added the required column `invalid` to the `GitHubAuth` table without a default value. This is not possible if the table is not empty.
+
+*/
+-- RedefineTables
+PRAGMA foreign_keys=OFF;
+CREATE TABLE "new_DiscordAuth" (
+ "id" TEXT NOT NULL PRIMARY KEY,
+ "userId" INTEGER NOT NULL,
+ "accessToken" TEXT NOT NULL,
+ "refreshToken" TEXT NOT NULL,
+ "expiresAt" DATETIME NOT NULL,
+ "invalid" BOOLEAN NOT NULL,
+ CONSTRAINT "DiscordAuth_userId_fkey" FOREIGN KEY ("userId") REFERENCES "User" ("id") ON DELETE RESTRICT ON UPDATE CASCADE
+);
+INSERT INTO "new_DiscordAuth" ("accessToken", "expiresAt", "id", "refreshToken", "userId") SELECT "accessToken", "expiresAt", "id", "refreshToken", "userId" FROM "DiscordAuth";
+DROP TABLE "DiscordAuth";
+ALTER TABLE "new_DiscordAuth" RENAME TO "DiscordAuth";
+CREATE UNIQUE INDEX "DiscordAuth_userId_key" ON "DiscordAuth"("userId");
+CREATE TABLE "new_GitHubAuth" (
+ "id" TEXT NOT NULL PRIMARY KEY,
+ "userId" INTEGER NOT NULL,
+ "accessToken" TEXT NOT NULL,
+ "invalid" BOOLEAN NOT NULL,
+ CONSTRAINT "GitHubAuth_userId_fkey" FOREIGN KEY ("userId") REFERENCES "User" ("id") ON DELETE RESTRICT ON UPDATE CASCADE
+);
+INSERT INTO "new_GitHubAuth" ("accessToken", "id", "userId") SELECT "accessToken", "id", "userId" FROM "GitHubAuth";
+DROP TABLE "GitHubAuth";
+ALTER TABLE "new_GitHubAuth" RENAME TO "GitHubAuth";
+CREATE UNIQUE INDEX "GitHubAuth_userId_key" ON "GitHubAuth"("userId");
+PRAGMA foreign_key_check;
+PRAGMA foreign_keys=ON;
diff --git a/prisma/schema.prisma b/prisma/schema.prisma
index fcf95a9..bf098bf 100644
--- a/prisma/schema.prisma
+++ b/prisma/schema.prisma
@@ -34,13 +34,15 @@ model DiscordAuth {
accessToken String
refreshToken String
expiresAt DateTime
+ invalid Boolean
}
model GitHubAuth {
- id Int @id
+ id String @id
user User @relation(fields: [userId], references: [id])
userId Int @unique
accessToken String
+ invalid Boolean
}
diff --git a/src/app/api/changePassword/route.ts b/src/app/api/changePassword/route.ts
index 03db8bf..2ef5152 100644
--- a/src/app/api/changePassword/route.ts
+++ b/src/app/api/changePassword/route.ts
@@ -1,4 +1,4 @@
-import { getUser } from "@/auth";
+import { getUser } from "@/auth/auth";
import { getUserInfo, setPassword, validateUser } from "@/ldap";
import { getLogger } from "@/logger";
diff --git a/src/app/api/login/route.ts b/src/app/api/login/route.ts
index 19a6f90..c22183b 100644
--- a/src/app/api/login/route.ts
+++ b/src/app/api/login/route.ts
@@ -1,5 +1,6 @@
+import { authTicketLogin } from "@/auth/auth";
import * as ldap from "@/ldap";
-import { createAuthTicket } from "@/auth";
+import { loginSchema } from "@/schemas";
type RequestBody = {
username: string;
@@ -7,22 +8,9 @@ type RequestBody = {
};
export async function POST(request: Request) {
- const { username, password } = (await request.json()) as RequestBody;
-
- if (
- username == undefined ||
- typeof username !== "string" ||
- password == undefined ||
- typeof password !== "string"
- ) {
- return new Response(
- JSON.stringify({
- ok: false,
- error: "invalidBody"
- }),
- { status: 400 }
- );
- }
+ const { username, password } = await loginSchema.validate(
+ await request.json()
+ );
const valid = await ldap.validateUser(username, password);
if (!valid) {
@@ -35,7 +23,7 @@ export async function POST(request: Request) {
);
}
- const ticket = await createAuthTicket(username);
+ const [_, ticket] = await authTicketLogin(username);
// not confident if we can set-cookie and I cba to try
return new Response(JSON.stringify({ ok: true, ticket }));
}
diff --git a/src/app/api/register/route.ts b/src/app/api/register/route.ts
index 52b03ef..76697a3 100644
--- a/src/app/api/register/route.ts
+++ b/src/app/api/register/route.ts
@@ -1,104 +1,27 @@
import * as ldap from "@/ldap";
import prisma from "@/prisma";
-import { getUser } from "@/auth";
-import { getDiscordAvatar } from "@/app/oauth/discord/oauth";
-import { getGitHubAvatar } from "@/app/oauth/github/oauth";
+import { getUser } from "@/auth/auth";
import { getLogger } from "@/logger";
+import { registerServerSchema } from "@/schemas";
-type RequestBody = {
- username: string;
- displayName: string;
- email: string;
- password: string;
- avatarBase64: string | null;
-};
+const logger = getLogger("/api/register");
export async function POST(request: Request) {
- const logger = getLogger("/api/register");
-
const user = await getUser();
if (user == null) return new Response(null, { status: 401 });
- if (user.username !== null) {
- if (!(await ldap.checkUserExists(user.username))) {
- logger.warn(
- { username: user.username },
- "user doesn't exist in ldap anymore"
- );
-
- user.username = null;
- await prisma.user.update({
- where: {
- id: user.id
- },
- data: {
- username: null
- }
- });
- } else {
- logger.info(`user ${user.username} tried to register twice`);
- // user already has an account, don't re-register
- return new Response(null, { status: 403 });
- }
- }
-
- const { username, displayName, email, password, avatarBase64 } =
- (await request.json()) as RequestBody;
-
- // runtime type verification when :pleading:
- if (
- username == undefined ||
- typeof username !== "string" ||
- displayName == undefined ||
- typeof displayName !== "string" ||
- email == undefined ||
- typeof email !== "string" ||
- password == undefined ||
- typeof password !== "string"
- ) {
- return new Response(
- JSON.stringify({
- ok: false,
- error: "invalidBody"
- }),
- { status: 400 }
+ // user already has an account, don't re-register
+ if (user.username != null) {
+ logger.info(
+ { username: user.username, id: user.id },
+ `user tried to register twice`
);
+ return new Response(null, { status: 403 });
}
- if (username.length < 1) {
- return new Response(
- JSON.stringify({
- ok: false,
- error: "usernameShort"
- }),
- { status: 400 }
- );
- }
-
- if (password.length < 12) {
- return new Response(
- JSON.stringify({
- ok: false,
- error: "passwordShort"
- }),
- { status: 400 }
- );
- }
-
- let avatarBuf: Buffer | null | undefined;
-
- if (avatarBase64 !== null && typeof avatarBase64 === "string") {
- avatarBuf = Buffer.from(avatarBase64, "base64");
- if (avatarBuf.length > 1_000_000) {
- return new Response(
- JSON.stringify({
- ok: false,
- error: "avatarBig"
- }),
- { status: 400 }
- );
- }
- }
+ const { username, displayName, email, password, avatar } =
+ await registerServerSchema.validate(await request.json());
+ let avatarBuf = avatar != null ? Buffer.from(avatar, "base64") : null;
const users = await ldap.getUsers();
for (const user of users) {
diff --git a/src/app/api/update/route.ts b/src/app/api/update/route.ts
index 5fe0868..177b837 100644
--- a/src/app/api/update/route.ts
+++ b/src/app/api/update/route.ts
@@ -1,4 +1,4 @@
-import { getUser } from "@/auth";
+import { getUser } from "@/auth/auth";
import { getUserInfo, updateUser } from "@/ldap";
import { getLogger } from "@/logger";
diff --git a/src/app/login/page.tsx b/src/app/login/page.tsx
index 9c7605c..84277c5 100644
--- a/src/app/login/page.tsx
+++ b/src/app/login/page.tsx
@@ -1,7 +1,7 @@
import styles from "@/app/page.module.css";
import React from "react";
import LoginForm from "./LoginForm";
-import { AuthState, getAuthState } from "@/auth";
+import { AuthState, getAuthState } from "@/auth/auth";
import { redirect } from "next/navigation";
export default async function Page() {
diff --git a/src/app/me/AboutMe.tsx b/src/app/me/AboutMe.tsx
index b921c5f..0a88b4f 100644
--- a/src/app/me/AboutMe.tsx
+++ b/src/app/me/AboutMe.tsx
@@ -2,7 +2,7 @@
"use client";
import { UserInfo } from "@/ldap";
-import React, { HTMLInputTypeAttribute, InputHTMLAttributes } from "react";
+import React from "react";
import styles from "./AboutMe.module.css";
import AvatarChanger from "@/components/AvatarChanger";
import Input from "@/components/Input";
diff --git a/src/app/me/page.tsx b/src/app/me/page.tsx
index 1b6731d..0e7bb70 100644
--- a/src/app/me/page.tsx
+++ b/src/app/me/page.tsx
@@ -1,4 +1,4 @@
-import { getUser } from "@/auth";
+import { getUser } from "@/auth/auth";
import { getUserInfo } from "@/ldap";
import AboutMe from "./AboutMe";
import { redirect } from "next/navigation";
diff --git a/src/app/oauth/discord/login/route.ts b/src/app/oauth/discord/login/route.ts
index 4d4c897..e973d72 100644
--- a/src/app/oauth/discord/login/route.ts
+++ b/src/app/oauth/discord/login/route.ts
@@ -1,4 +1,4 @@
-import { discordRedirectUri } from "../oauth";
+import { DiscordAuthProvider } from "@/auth/discord";
import { v4 } from "uuid";
export async function GET(request: Request) {
@@ -10,7 +10,7 @@ export async function GET(request: Request) {
params.set("client_id", process.env.DISCORD_CLIENT_ID);
params.set("scope", "guilds identify email");
params.set("state", state);
- params.set("redirect_uri", discordRedirectUri());
+ params.set("redirect_uri", DiscordAuthProvider.redirectUri);
params.set("prompt", "consent");
url += "?" + params.toString();
diff --git a/src/app/oauth/discord/oauth.ts b/src/app/oauth/discord/oauth.ts
deleted file mode 100644
index 9688726..0000000
--- a/src/app/oauth/discord/oauth.ts
+++ /dev/null
@@ -1,57 +0,0 @@
-import { v4 } from "uuid";
-
-export type DiscordAccessTokenResponse = {
- access_token: string;
- token_type: string;
- expires_in: number;
- refresh_token: string;
- scope: string;
-};
-
-export type DiscordUserResponse = {
- id: string;
- avatar: string | null;
- username: string;
- email: string | null;
-};
-
-export type DiscordGuildResponse = {
- id: string;
-};
-
-export function discordRedirectUri() {
- return `${process.env.BASE_DOMAIN}oauth/discord/redirect`;
-}
-
-export async function getDiscordUser(token: string) {
- const req = await fetch("https://discord.com/api/users/@me", {
- headers: {
- Authorization: `Bearer ${token}`
- }
- });
- const res: DiscordUserResponse = await req.json();
- return res;
-}
-
-export async function getDiscordGuilds(token: string) {
- const req = await fetch("https://discord.com/api/users/@me/guilds", {
- headers: {
- Authorization: `Bearer ${token}`
- }
- });
- const res: DiscordGuildResponse[] = await req.json();
- return res.map((guild) => guild.id);
-}
-
-export async function getDiscordAvatar(token: string) {
- const req = await fetch("https://discord.com/api/users/@me", {
- headers: {
- Authorization: `Bearer ${token}`
- }
- });
-
- const res: DiscordUserResponse = await req.json();
- if (res.avatar === null) return null;
- const file = `https://cdn.discordapp.com/avatars/${res.id}/${res.avatar}.png`;
- return file;
-}
diff --git a/src/app/oauth/discord/redirect/route.ts b/src/app/oauth/discord/redirect/route.ts
index bdb9095..b3366b1 100644
--- a/src/app/oauth/discord/redirect/route.ts
+++ b/src/app/oauth/discord/redirect/route.ts
@@ -1,159 +1,49 @@
-import { URLSearchParams } from "url";
-import {
- discordRedirectUri,
- DiscordAccessTokenResponse,
- getDiscordGuilds,
- getDiscordUser,
- getDiscordAvatar
-} from "../oauth";
-import { cookies } from "next/dist/client/components/headers";
-import prisma from "@/prisma";
-import { v4 } from "uuid";
-import * as ldap from "@/ldap";
import { getLogger } from "@/logger";
-import { AuthState, getAuthState, getUser } from "@/auth";
+import { DiscordAuthProvider } from "@/auth/discord";
+import {
+ AuthState,
+ authTicketOAuth,
+ getAuthState,
+ getCode,
+ getUser
+} from "@/auth/auth";
+
+const logger = getLogger("/oauth/discord/redirect");
export async function GET(request: Request) {
- const logger = getLogger("/oauth/discord/redirect");
+ const code = await getCode(request);
+ if (code instanceof Response) return code;
- let url = new URL(request.url);
- let code = url.searchParams.get("code");
- let state = url.searchParams.get("state");
+ const tokenBody = await DiscordAuthProvider.getToken(code);
+ if (tokenBody == null) throw "baby";
- if (code === null || state === null) {
- logger.info("request made with missing code/state");
- return new Response("missing code/state", { status: 400 });
- }
+ const provider = new DiscordAuthProvider(tokenBody.access_token);
+ const id = await provider.getId();
+ const permitted = await provider.isPermitted();
- const cookieStore = cookies();
- let cookieState = cookieStore.get("state");
- // prevent forgery
- if (cookieState?.value !== state) {
- logger.info(
- "request made with invalid state - someone attempting forgery?"
- );
- return new Response("state is invalid", { status: 400 });
- }
-
- let form = new URLSearchParams();
- form.append("client_id", process.env.DISCORD_CLIENT_ID);
- form.append("client_secret", process.env.DISCORD_CLIENT_SECRET);
- form.append("grant_type", "authorization_code");
- form.append("code", code);
- form.append("redirect_uri", discordRedirectUri());
-
- let tokenResponse = await fetch("https://discord.com/api/oauth2/token", {
- method: "POST",
- headers: {
- "Content-Type": "application/x-www-form-urlencoded"
- },
- body: form.toString()
- });
- if (!tokenResponse.ok) {
- logger.error("baby");
- throw "baby";
- }
-
- let tokenBody: DiscordAccessTokenResponse = await tokenResponse.json();
-
- const discordUser = await getDiscordUser(tokenBody.access_token);
- const guilds = await getDiscordGuilds(tokenBody.access_token);
- const allowedGuilds = process.env.DISCORD_ALLOWED_GUILDS?.split(",") ?? [];
-
- let allowed = false;
- for (const guild of allowedGuilds) if (guilds.includes(guild)) allowed = true;
- if (!allowed) {
- logger.info({ id: discordUser.id }, "user tried to sign up");
+ if (!permitted) {
+ logger.info({ id }, "user tried to sign up");
return new Response("not permitted to register account", { status: 403 });
}
- let userId = null;
+ // If someone clicked register on the front page with an existing account,
+ // wire it to their user via the auth ticket
+ let gluestickId = null;
const authState = await getAuthState();
if (authState === AuthState.LoggedIn) {
const currentUser = await getUser();
- userId = currentUser?.id;
+ gluestickId = currentUser!.id;
}
- // - create the discord auth data in prisma, which will make the user if it doesn't exist
- // - get the user from the discord auth data
- // - either create a new auth ticket or invalidate the old one
- // - update the user to point to the new auth ticket
+ const userId = await DiscordAuthProvider.update(
+ id,
+ tokenBody.access_token,
+ tokenBody.refresh_token,
+ new Date(Date.now() + tokenBody.expires_in * 1000),
+ gluestickId ?? undefined
+ );
- const discordAuth = await prisma.discordAuth.upsert({
- where: {
- id: discordUser.id
- },
- create: {
- id: discordUser.id,
- accessToken: tokenBody.access_token,
- refreshToken: tokenBody.refresh_token,
- expiresAt: new Date(Date.now() + tokenBody.expires_in * 1000),
- user:
- userId != null
- ? { connect: { id: userId } }
- : { create: { username: null } }
- },
- update: {
- accessToken: tokenBody.access_token,
- refreshToken: tokenBody.refresh_token,
- expiresAt: new Date(Date.now() + tokenBody.expires_in * 1000)
- }
- });
-
- const user = await prisma.user.findFirst({
- where: {
- id: discordAuth.userId
- }
- });
-
- // check if user got deleted from ldap, same as /api/register
- if (
- user !== null &&
- user.username !== null &&
- !(await ldap.checkUserExists(user.username))
- ) {
- logger.warn(
- { username: user.username },
- "user doesn't exist in ldap anymore"
- );
- user.username = null;
- await prisma.user.update({
- where: {
- id: user.id
- },
- data: {
- username: null
- }
- });
- }
-
- const authTicket = await prisma.authTicket.upsert({
- where: {
- userId: user!.id
- },
- create: {
- userId: user!.id,
- ticket: v4(),
- expiresAt: new Date(Date.now() + 86400000)
- },
- update: {
- ticket: v4(),
- expiresAt: new Date(Date.now() + 86400000)
- }
- });
-
- await prisma.user.update({
- where: {
- id: user!.id
- },
- data: {
- authTicket: {
- connect: {
- id: authTicket.id
- }
- }
- }
- });
+ const [user, authTicket] = await authTicketOAuth(userId);
if (user?.username !== null) {
return new Response(null, {
@@ -165,11 +55,13 @@ export async function GET(request: Request) {
});
}
- const avatarUrl = await getDiscordAvatar(tokenBody.access_token);
+ const username = await provider.getDisplayName();
+ const email = await provider.getEmail();
+ const avatarUrl = await provider.getAvatar();
const query = new URLSearchParams();
- query.append("username", discordUser.username);
- query.append("email", discordUser.email ?? "");
+ query.append("username", username);
+ query.append("email", email ?? "");
query.append("avatar", avatarUrl ?? "");
return new Response(null, {
diff --git a/src/app/oauth/github/login/route.ts b/src/app/oauth/github/login/route.ts
index af39915..312704a 100644
--- a/src/app/oauth/github/login/route.ts
+++ b/src/app/oauth/github/login/route.ts
@@ -1,3 +1,4 @@
+import { GitHubAuthProvider } from "@/auth/github";
import { v4 } from "uuid";
export async function GET(request: Request) {
@@ -8,7 +9,7 @@ export async function GET(request: Request) {
params.set("client_id", process.env.GITHUB_CLIENT_ID);
params.set("scope", "user");
params.set("state", state);
- params.set("redirect_uri", `${process.env.BASE_DOMAIN}oauth/github/redirect`);
+ params.set("redirect_uri", GitHubAuthProvider.redirectUri);
url += `?${params.toString()}`;
diff --git a/src/app/oauth/github/oauth.ts b/src/app/oauth/github/oauth.ts
deleted file mode 100644
index 4cc4d15..0000000
--- a/src/app/oauth/github/oauth.ts
+++ /dev/null
@@ -1,41 +0,0 @@
-export type GitHubAccessTokenResponse = {
- access_token: string;
- scope: string;
- token_type: string;
-};
-
-export type GitHubUserResponse = {
- login: string;
- id: number;
- avatar_url: string;
- email: string;
-};
-
-export async function getGitHubUser(token: string) {
- const req = await fetch("https://api.github.com/user", {
- headers: {
- Authorization: `Bearer ${token}`
- }
- });
- const res: GitHubUserResponse = await req.json();
- return res;
-}
-
-export async function checkInOrg(username: string) {
- const req = await fetch(
- `https://api.github.com/orgs/${process.env.GITHUB_ORG}/members`,
- {
- headers: {
- Authorization: `Bearer ${process.env.GITHUB_TOKEN}`
- }
- }
- );
-
- const res: GitHubUserResponse[] = await req.json();
- return res.some((user) => user.login === username);
-}
-
-export async function getGitHubAvatar(token: string) {
- const user = await getGitHubUser(token);
- return user.avatar_url;
-}
diff --git a/src/app/oauth/github/redirect/route.ts b/src/app/oauth/github/redirect/route.ts
index 1a9b04a..e61a8ff 100644
--- a/src/app/oauth/github/redirect/route.ts
+++ b/src/app/oauth/github/redirect/route.ts
@@ -1,141 +1,47 @@
import { getLogger } from "@/logger";
-import { cookies } from "next/dist/client/components/headers";
+import { GitHubAuthProvider } from "@/auth/github";
import {
- checkInOrg,
- getGitHubAvatar,
- getGitHubUser,
- GitHubAccessTokenResponse
-} from "../oauth";
-import prisma from "@/prisma";
-import * as ldap from "@/ldap";
-import { v4 } from "uuid";
-import { AuthState, getAuthState, getUser } from "@/auth";
+ AuthState,
+ authTicketOAuth,
+ getAuthState,
+ getCode,
+ getUser
+} from "@/auth/auth";
const logger = getLogger("/oauth/github/redirect");
export async function GET(request: Request) {
- let url = new URL(request.url);
- let code = url.searchParams.get("code");
- let state = url.searchParams.get("state");
+ const code = await getCode(request);
+ if (code instanceof Response) return code;
- if (code === null || state === null) {
- logger.info("request made with missing code/state");
- return new Response("missing code/state", { status: 400 });
- }
+ const tokenBody = await GitHubAuthProvider.getToken(code);
+ if (tokenBody == null) throw "baby";
- const cookieStore = cookies();
- let cookieState = cookieStore.get("state");
- // prevent forgery
- if (cookieState?.value !== state) {
- logger.info(
- "request made with invalid state - someone attempting forgery?"
- );
- return new Response("state is invalid", { status: 400 });
- }
+ const provider = new GitHubAuthProvider(tokenBody.access_token);
+ const id = await provider.getId();
+ const permitted = await provider.isPermitted();
- let query = new URLSearchParams();
- query.set("client_id", process.env.GITHUB_CLIENT_ID);
- query.set("client_secret", process.env.GITHUB_CLIENT_SECRET);
- query.set("code", code);
- query.set("redirect_uri", `${process.env.BASE_DOMAIN}oauth/github/redirect`);
-
- let tokenUrl = `https://github.com/login/oauth/access_token?${query.toString()}`;
- let tokenResponse = await fetch(tokenUrl, {
- method: "POST",
- headers: {
- Accept: "application/json"
- }
- });
-
- if (!tokenResponse.ok) {
- logger.error("baby");
- throw "baby";
- }
-
- let resp: GitHubAccessTokenResponse = await tokenResponse.json();
- let accessToken = resp.access_token;
- const githubUser = await getGitHubUser(accessToken);
- const inOrg = await checkInOrg(githubUser.login);
-
- if (!inOrg) {
- logger.info({ id: githubUser.login }, "user tried to sign up");
+ if (!permitted) {
+ logger.info({ id }, "user tried to sign up");
return new Response("not permitted to register account", { status: 403 });
}
- let userId = null;
+ // If someone clicked register on the front page with an existing account,
+ // wire it to their user via the auth ticket
+ let gluestickId = null;
const authState = await getAuthState();
if (authState === AuthState.LoggedIn) {
const currentUser = await getUser();
- userId = currentUser?.id;
+ gluestickId = currentUser!.id;
}
- const githubAuth = await prisma.gitHubAuth.upsert({
- where: { id: githubUser.id },
- create: {
- id: githubUser.id,
- accessToken,
- user:
- userId != null
- ? { connect: { id: userId } }
- : { create: { username: null } }
- },
- update: { accessToken }
- });
+ const userId = await GitHubAuthProvider.update(
+ id,
+ tokenBody.access_token,
+ gluestickId ?? undefined
+ );
- const user = await prisma.user.findFirst({
- where: {
- id: githubAuth.userId
- }
- });
-
- // check if user got deleted from ldap, same as /api/register
- if (
- user !== null &&
- user.username !== null &&
- !(await ldap.checkUserExists(user.username))
- ) {
- logger.warn(
- { username: user.username },
- "user doesn't exist in ldap anymore"
- );
- user.username = null;
- await prisma.user.update({
- where: {
- id: user.id
- },
- data: {
- username: null
- }
- });
- }
-
- const authTicket = await prisma.authTicket.upsert({
- where: {
- userId: user!.id
- },
- create: {
- userId: user!.id,
- ticket: v4(),
- expiresAt: new Date(Date.now() + 86400000)
- },
- update: {
- ticket: v4(),
- expiresAt: new Date(Date.now() + 86400000)
- }
- });
-
- await prisma.user.update({
- where: {
- id: user!.id
- },
- data: {
- authTicket: {
- connect: {
- id: authTicket.id
- }
- }
- }
- });
+ const [user, authTicket] = await authTicketOAuth(userId);
if (user?.username !== null) {
return new Response(null, {
@@ -147,18 +53,20 @@ export async function GET(request: Request) {
});
}
- const avatarUrl = await getGitHubAvatar(accessToken);
+ const username = await provider.getDisplayName();
+ const email = await provider.getEmail();
+ const avatarUrl = await provider.getAvatar();
- const query2 = new URLSearchParams();
- query2.append("username", githubUser.login);
- query2.append("email", githubUser.email);
- query2.append("avatar", avatarUrl);
+ const query = new URLSearchParams();
+ query.append("username", username);
+ query.append("email", email ?? "");
+ query.append("avatar", avatarUrl ?? "");
return new Response(null, {
status: 302,
headers: {
"Set-Cookie": `ticket=${authTicket.ticket}; Path=/;`,
- Location: "/register?" + query2.toString()
+ Location: "/register?" + query.toString()
}
});
}
diff --git a/src/app/register/RegisterForm.tsx b/src/app/register/RegisterForm.tsx
index bef3e61..f878614 100644
--- a/src/app/register/RegisterForm.tsx
+++ b/src/app/register/RegisterForm.tsx
@@ -19,11 +19,13 @@ type RegisterResponse = {
export default function RegisterForm({
initialDisplayName,
initialEmail,
- initialAvatarBase64
+ initialAvatarBase64,
+ avatarSource
}: {
initialDisplayName?: string;
initialEmail?: string;
initialAvatarBase64?: string;
+ avatarSource: "Discord" | "GitHub" | null;
}) {
const [globalError, setGlobalError] = React.useState