From a0bfeae74286eb0b81d615e43ab1fedb81be22a1 Mon Sep 17 00:00:00 2001 From: Khalim Conn-Kowlessar Date: Tue, 10 Mar 2026 14:59:35 +0000 Subject: [PATCH 1/2] changing magic links url to protect against microsoft defender and host domna logo --- public/domna-email-logo.png | Bin 0 -> 42982 bytes src/app/api/auth/[...nextauth]/authOptions.ts | 6 ++-- src/app/email_templates/magic_link.ts | 34 +++++++++++++++--- src/app/login/page.tsx | 20 +++++++++++ 4 files changed, 53 insertions(+), 7 deletions(-) create mode 100644 public/domna-email-logo.png create mode 100644 src/app/login/page.tsx diff --git a/public/domna-email-logo.png b/public/domna-email-logo.png new file mode 100644 index 0000000000000000000000000000000000000000..459375f65cfd73ab6d32f075343cf912486153fd GIT binary patch literal 42982 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 literal 0 HcmV?d00001 diff --git a/src/app/api/auth/[...nextauth]/authOptions.ts b/src/app/api/auth/[...nextauth]/authOptions.ts index abcd186..09b6b70 100644 --- a/src/app/api/auth/[...nextauth]/authOptions.ts +++ b/src/app/api/auth/[...nextauth]/authOptions.ts @@ -146,8 +146,8 @@ export const AuthOptions: NextAuthOptions = { .where( and( eq(accounts.userId, dbUser.id), - eq(accounts.provider, account.provider) - ) + eq(accounts.provider, account.provider), + ), ); const emailVerified = @@ -157,7 +157,7 @@ export const AuthOptions: NextAuthOptions = { // This handles the case where we had not set up accounts but // signed up users with oauth console.log( - `Linking ${account.provider} account for user ${normalisedEmail}` + `Linking ${account.provider} account for user ${normalisedEmail}`, ); await db diff --git a/src/app/email_templates/magic_link.ts b/src/app/email_templates/magic_link.ts index 12d3f43..e6582ef 100644 --- a/src/app/email_templates/magic_link.ts +++ b/src/app/email_templates/magic_link.ts @@ -13,7 +13,20 @@ export async function MagicLinksEmail({ url: string; provider: { server: any; from: string }; }) { - const { host } = new URL(url); + const parsed = new URL(url); + const host = parsed.host; + + const baseUrl = parsed.origin; + const logoUrl = `${baseUrl}/domna-email-logo.png`; + + const token = parsed.searchParams.get("token"); + + if (!token) { + throw new Error("Magic link token missing"); + } + + // Create a clean login link instead of the NextAuth callback + const loginUrl = `${parsed.origin}/login?t=${token}`; const transport = createTransport(provider.server); @@ -26,8 +39,19 @@ export async function MagicLinksEmail({ to: identifier, from: provider.from, subject: "Your secure Ara sign-in link", - text: plainText({ url, host }), - html: domnaHtml({ url, host, brandColor, accentColor, brown, background }), + text: plainText({ url: loginUrl, host }), + html: domnaHtml({ + url: loginUrl, + logoUrl, + host, + brandColor, + accentColor, + brown, + background, + }), + headers: { + "List-Unsubscribe": ``, + }, }); const failed = result.rejected.filter(Boolean); @@ -38,6 +62,7 @@ export async function MagicLinksEmail({ function domnaHtml({ url, + logoUrl, host, brandColor, accentColor, @@ -45,6 +70,7 @@ function domnaHtml({ background, }: { url: string; + logoUrl: string; host: string; brandColor: string; accentColor: string; @@ -60,7 +86,7 @@ function domnaHtml({ Domna Logo { + const token = params.get("t"); + + if (!token) return; + + const callback = `/api/auth/callback/email?token=${token}`; + + window.location.href = callback; + }, [params]); + + return

Signing you in…

; +} From 684caad9ea83e981c6db0aceb388ec57a7940543 Mon Sep 17 00:00:00 2001 From: Khalim Conn-Kowlessar Date: Tue, 10 Mar 2026 15:28:01 +0000 Subject: [PATCH 2/2] added safe url structure for magic links and self hosted logo --- src/app/email_templates/magic_link.ts | 9 +++++---- src/app/login/[token]/[email]/page.tsx | 19 +++++++++++++++++++ src/app/login/page.tsx | 20 -------------------- 3 files changed, 24 insertions(+), 24 deletions(-) create mode 100644 src/app/login/[token]/[email]/page.tsx delete mode 100644 src/app/login/page.tsx diff --git a/src/app/email_templates/magic_link.ts b/src/app/email_templates/magic_link.ts index e6582ef..82c44a8 100644 --- a/src/app/email_templates/magic_link.ts +++ b/src/app/email_templates/magic_link.ts @@ -20,13 +20,14 @@ export async function MagicLinksEmail({ const logoUrl = `${baseUrl}/domna-email-logo.png`; const token = parsed.searchParams.get("token"); + const email = parsed.searchParams.get("email"); - if (!token) { - throw new Error("Magic link token missing"); + if (!token || !email) { + throw new Error("Magic link token or email missing"); } // Create a clean login link instead of the NextAuth callback - const loginUrl = `${parsed.origin}/login?t=${token}`; + const loginUrl = `${parsed.origin}/login/${token}/${encodeURIComponent(email)}`; const transport = createTransport(provider.server); @@ -38,7 +39,7 @@ export async function MagicLinksEmail({ const result = await transport.sendMail({ to: identifier, from: provider.from, - subject: "Your secure Ara sign-in link", + subject: "Sign in to Ara", text: plainText({ url: loginUrl, host }), html: domnaHtml({ url: loginUrl, diff --git a/src/app/login/[token]/[email]/page.tsx b/src/app/login/[token]/[email]/page.tsx new file mode 100644 index 0000000..94fef5d --- /dev/null +++ b/src/app/login/[token]/[email]/page.tsx @@ -0,0 +1,19 @@ +import { redirect } from "next/navigation"; + +export default async function LoginPage({ + params, +}: { + params: Promise<{ token: string; email: string }>; +}) { + const { token, email } = await params; + + if (!token || !email) { + redirect("/"); + } + + const decodedEmail = decodeURIComponent(email); + + redirect( + `/api/auth/callback/email?token=${token}&email=${encodeURIComponent(decodedEmail)}`, + ); +} diff --git a/src/app/login/page.tsx b/src/app/login/page.tsx deleted file mode 100644 index d5b83da..0000000 --- a/src/app/login/page.tsx +++ /dev/null @@ -1,20 +0,0 @@ -"use client"; - -import { useEffect } from "react"; -import { useSearchParams } from "next/navigation"; - -export default function LoginPage() { - const params = useSearchParams(); - - useEffect(() => { - const token = params.get("t"); - - if (!token) return; - - const callback = `/api/auth/callback/email?token=${token}`; - - window.location.href = callback; - }, [params]); - - return

Signing you in…

; -}