fix(auth): build verify-email redirects from the configured public origin

Redirects were built relative to `request.url`, which behind a reverse proxy
resolves to the container-internal address. Verification succeeded but the
browser was sent to localhost:3000, so users saw a connection error instead of
the "email verified" confirmation.

Add getPublicOrigin() (NEXTAUTH_URL, then NEXT_PUBLIC_APP_URL, falling back to
the request origin for local development) and use it for every verify-email
redirect. The legacy GET redirect in the watch session route had the same
defect and is fixed alongside it.
This commit is contained in:
yusufipk
2026-07-25 14:57:57 +07:00
parent 0faa4b4e2a
commit 5871d4d87d
3 changed files with 33 additions and 6 deletions
+2 -2
View File
@@ -2,7 +2,7 @@ import { createHash } from 'crypto';
import { NextRequest, NextResponse } from 'next/server';
import { db } from '@/lib/db';
import { checkRateLimit, getClientIp, rateLimit, rateLimitHeaders } from '@/lib/rate-limit';
import { isTrustedSameOriginRequest } from '@/lib/request-origin';
import { getPublicOrigin, isTrustedSameOriginRequest } from '@/lib/request-origin';
import { MAX_SHARE_PASSWORD_LENGTH, validateShareLinkAccess } from '@/lib/share-links';
import {
createPendingShareValue,
@@ -48,7 +48,7 @@ function validateSameOriginRequest(request: NextRequest): NextResponse | null {
export async function GET(request: NextRequest, { params }: RouteParams) {
const { videoId } = await params;
const cleanWatchUrl = new URL(`/watch/${videoId}`, request.nextUrl.origin);
const cleanWatchUrl = new URL(`/watch/${videoId}`, getPublicOrigin(request));
const legacyShareToken = request.nextUrl.searchParams.get('shareToken');
// Keep GET route for backwards compatibility, but never establish session from GET.