From b2e1ab2d2fb40b4f9206db8ecb1a0ccc886fbfa1 Mon Sep 17 00:00:00 2001 From: trafficlunar Date: Sat, 24 Oct 2026 00:30:01 +0100 Subject: [PATCH 1/2] fix: auth errors - Fixes Discord not logging in - Also shows the login page but with an error message for future errors --- backend/src/app/login/route.ts | 7 +++++ backend/src/lib/auth.ts | 3 +- frontend/src/main.tsx | 4 +-- frontend/src/pages/account-error.tsx | 37 +++++++++++++++++++++++++ frontend/src/pages/breach-notice.tsx | 41 ---------------------------- frontend/src/pages/login.tsx | 18 ++++++++++-- 6 files changed, 64 insertions(+), 46 deletions(-) create mode 100644 backend/src/app/login/route.ts create mode 100644 frontend/src/pages/account-error.tsx delete mode 100644 frontend/src/pages/breach-notice.tsx diff --git a/backend/src/app/login/route.ts b/backend/src/app/login/route.ts new file mode 100644 index 0000000..cbb82d3 --- /dev/null +++ b/backend/src/app/login/route.ts @@ -0,0 +1,7 @@ +import { NextRequest, NextResponse } from "next/server"; + +export function GET(req: NextRequest) { + const target = new URL("/login", process.env.FRONTEND_URL ?? "http://localhost:5173"); + target.search = req.nextUrl.search; // keeps ?error= + return NextResponse.redirect(target); +} diff --git a/backend/src/lib/auth.ts b/backend/src/lib/auth.ts index f7e4198..e7c3ffd 100644 --- a/backend/src/lib/auth.ts +++ b/backend/src/lib/auth.ts @@ -8,7 +8,7 @@ import { prisma } from "@/lib/prisma"; export const { handlers, signIn, signOut, auth } = NextAuth({ adapter: PrismaAdapter(prisma), - providers: [Discord, Github({ issuer: "https://github.com/login/oauth" }), Google], + providers: [Discord({ issuer: "https://discord.com" }), Github({ issuer: "https://github.com/login/oauth" }), Google], trustHost: true, cookies: { sessionToken: { @@ -26,6 +26,7 @@ export const { handlers, signIn, signOut, auth } = NextAuth({ strategy: "database", maxAge: 30 * 24 * 60 * 60, }, + pages: { signIn: "/login", error: "/login" }, callbacks: { async signIn({ user }) { const blacklist = process.env.BLACKLISTED_EMAILS ? process.env.BLACKLISTED_EMAILS.split(",").map((item) => item.trim().toLowerCase()) : []; diff --git a/frontend/src/main.tsx b/frontend/src/main.tsx index 610cbf3..a8499b2 100644 --- a/frontend/src/main.tsx +++ b/frontend/src/main.tsx @@ -23,8 +23,8 @@ import ReportMiiPage from "./pages/report/mii.tsx"; import ReportUserPage from "./pages/report/user.tsx"; import EditMiiPage from "./pages/edit.tsx"; import PunishedPage from "./pages/punished.tsx"; -import BreachNoticePage from "./pages/breach-notice.tsx"; import AccountDeletionPage from "./pages/account-deletion.tsx"; +import AccountErrorPage from "./pages/account-error.tsx"; createRoot(document.getElementById("root")!).render( @@ -50,8 +50,8 @@ createRoot(document.getElementById("root")!).render( } /> } /> } /> - } /> } /> + } /> } /> diff --git a/frontend/src/pages/account-error.tsx b/frontend/src/pages/account-error.tsx new file mode 100644 index 0000000..755f838 --- /dev/null +++ b/frontend/src/pages/account-error.tsx @@ -0,0 +1,37 @@ +const ERRORS: Record = { + OAuthAccountNotLinked: { + title: "Account already exists", + messages: [ + "An account with this email already exists, but it was created using a different login method.", + "Please sign in with the provider you originally used (Google, GitHub, or Discord).", + ], + }, + Configuration: { + title: "Server error", + messages: ["There is a problem with the server configuration. Please e-mail hello@trafficlunar.net or message @trafficlunar on Discord"], + }, +}; + +const FALLBACK = { + title: "Sign in failed", + messages: ["Something went wrong while signing in. Please try again."], +}; + +export default function AccountErrorPage() { + const code = new URLSearchParams(window.location.search).get("error") ?? ""; + const { title, messages } = ERRORS[code] ?? FALLBACK; + + return ( +
+
+

{title}

+ {messages.map((message) => ( +

{message}

+ ))} + + Back to home + +
+
+ ); +} diff --git a/frontend/src/pages/breach-notice.tsx b/frontend/src/pages/breach-notice.tsx deleted file mode 100644 index 49559fd..0000000 --- a/frontend/src/pages/breach-notice.tsx +++ /dev/null @@ -1,41 +0,0 @@ -export default function BreachNoticePage() { - return ( -
-

Breach Notice

-

- Date: 13 May 2026 -

- -
- -

- I have been made aware today (13 May 2026) that there has been a security breach on 6 May 2026 of the website. The following information have been - collected: -

- -
    -
  • User IDs
  • -
  • Email addresses
  • -
  • Email verfication statuses
  • -
  • Avatar images
  • -
  • About Me descriptions
  • -
  • Profile creation dates
  • -
  • Profile update dates
  • -
  • Profile picture update dates
  • -
  • Amount of Miis you have liked
  • -
- -

- The only data that wouldn't normally be viewable is your email address (the same thing you would give to people to receive emails), everything else was - publicly viewable (such as on the profile pages). The code that caused this to happen has already been fixed. -

-

- As far as I'm aware, no other information have been collected. The breach has been notified to the Information Commissioner's Office. Please take care - when opening any suspicious emails. TomodachiShare does not send any emails. Please do not click on any suspicious links. -

-

- Your Discord/Google/GitHub accounts are completely unaffected by this. -

-
- ); -} diff --git a/frontend/src/pages/login.tsx b/frontend/src/pages/login.tsx index 864e649..6f7926d 100644 --- a/frontend/src/pages/login.tsx +++ b/frontend/src/pages/login.tsx @@ -1,20 +1,34 @@ import { Icon } from "@iconify/react"; import { useStore } from "@nanostores/react"; -import { Link, Navigate } from "react-router"; +import { Link, Navigate, useSearchParams } from "react-router"; import { session } from "../session"; +const API_URL = import.meta.env.VITE_API_URL; + +const ERRORS: Record = { + OAuthAccountNotLinked: + "An account with this email already exists, but it was created with a different login method. Please sign in with the provider you originally used.", + AccessDenied: "You don't have permission to sign in with this account.", + Configuration: "There is a problem with the server configuration. Please e-mail hello@trafficlunar.net or message @trafficlunar on Discord", +}; + export default function LoginPage() { const $session = useStore(session); + const [searchParams] = useSearchParams(); + if ($session === undefined) return
Loading...
; if ($session) return ; - const API_URL = import.meta.env.VITE_API_URL; + const code = searchParams.get("error"); + const errorMessage = code ? (ERRORS[code] ?? "Something went wrong while signing in. Please try again. Message trafficlunar if this continues") : null; return (

Welcome to TomodachiShare!

+ {errorMessage &&

Error: {errorMessage}

} +

Choose your login method From c835d5284e6b02efbe8d1e439c797a9549d1f7b2 Mon Sep 17 00:00:00 2001 From: trafficlunar Date: Sat, 24 Oct 2026 00:36:02 +0100 Subject: [PATCH 2/2] fix: env variable typo --- backend/src/app/login/route.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/backend/src/app/login/route.ts b/backend/src/app/login/route.ts index cbb82d3..a99c514 100644 --- a/backend/src/app/login/route.ts +++ b/backend/src/app/login/route.ts @@ -1,7 +1,7 @@ import { NextRequest, NextResponse } from "next/server"; export function GET(req: NextRequest) { - const target = new URL("/login", process.env.FRONTEND_URL ?? "http://localhost:5173"); + const target = new URL("/login", process.env.NEXT_PUBLIC_FRONTEND_URL ?? "http://localhost:5173"); target.search = req.nextUrl.search; // keeps ?error= return NextResponse.redirect(target); }