fix: resolve OAuth redirects dynamically using client-facing headers

This commit is contained in:
Marcio Bevervanso 2026-06-07 22:01:52 -03:00
parent 568fb16a89
commit f47c9e58ce
5 changed files with 42 additions and 10 deletions

View file

@ -6,17 +6,19 @@ import { NextRequest, NextResponse } from 'next/server';
import { cookies } from 'next/headers';
import { setSessionCookies } from '@/lib/auth/session';
import { getSettings } from '@/lib/settings';
import { getRequestBaseUrl } from '@/lib/url';
export async function GET(request: NextRequest) {
const code = request.nextUrl.searchParams.get('code');
const error = request.nextUrl.searchParams.get('error');
const baseUrl = getRequestBaseUrl(request);
if (error || !code) {
const errorDesc =
request.nextUrl.searchParams.get('error_description') || 'Login cancelled';
return NextResponse.redirect(
new URL(`/login?error=${encodeURIComponent(errorDesc)}`, request.url)
new URL(`/login?error=${encodeURIComponent(errorDesc)}`, baseUrl)
);
}
@ -32,7 +34,7 @@ export async function GET(request: NextRequest) {
const redirectUri =
process.env.META_REDIRECT_URI ||
'https://admanager.seureview.com.br/api/auth/callback';
new URL('/api/auth/callback', baseUrl).toString();
if (!appId || !appSecret) {
return NextResponse.redirect(
@ -40,7 +42,7 @@ export async function GET(request: NextRequest) {
`/login?error=${encodeURIComponent(
'Credenciais Meta não configuradas no sistema.'
)}`,
request.url
baseUrl
)
);
}
@ -96,14 +98,14 @@ export async function GET(request: NextRequest) {
});
// 5. Redirect to dashboard
return NextResponse.redirect(new URL('/dashboard', request.url));
return NextResponse.redirect(new URL('/dashboard', baseUrl));
} catch (err) {
console.error('[Auth] OAuth error:', err);
return NextResponse.redirect(
new URL(
`/login?error=${encodeURIComponent('Erro na autenticação')}`,
request.url
baseUrl
)
);
}

View file

@ -5,9 +5,11 @@
import { NextRequest, NextResponse } from 'next/server';
import { cookies } from 'next/headers';
import { clearSessionCookies } from '@/lib/auth/session';
import { getRequestBaseUrl } from '@/lib/url';
export async function POST(request: NextRequest) {
const cookieStore = await cookies();
clearSessionCookies(cookieStore);
return NextResponse.redirect(new URL('/login', request.url));
const baseUrl = getRequestBaseUrl(request);
return NextResponse.redirect(new URL('/login', baseUrl));
}

View file

@ -2,10 +2,11 @@
// OAuth — Redirect to Meta Login
// ============================================
import { NextResponse } from 'next/server';
import { NextRequest, NextResponse } from 'next/server';
import { getSettings } from '@/lib/settings';
import { getRequestBaseUrl } from '@/lib/url';
export async function GET() {
export async function GET(request: NextRequest) {
const settings = getSettings();
const appId =
@ -14,7 +15,7 @@ export async function GET() {
const redirectUri =
process.env.META_REDIRECT_URI ||
'https://admanager.seureview.com.br/api/auth/callback';
new URL('/api/auth/callback', getRequestBaseUrl(request)).toString();
if (!appId || appId === 'your_meta_app_id') {
return NextResponse.json(

25
src/lib/url.ts Normal file
View file

@ -0,0 +1,25 @@
import { NextRequest } from 'next/server';
/**
* Gets the correct client-facing base URL (protocol + host) of the request.
* Handles reverse proxies by checking standard headers like X-Forwarded-Host and X-Forwarded-Proto.
*/
export function getRequestBaseUrl(request: NextRequest): URL {
const forwardedHost = request.headers.get('x-forwarded-host');
const forwardedProto = request.headers.get('x-forwarded-proto') || 'https';
if (forwardedHost) {
const host = forwardedHost.split(',')[0].trim();
const proto = forwardedProto.split(',')[0].trim();
return new URL(`${proto}://${host}`);
}
const hostHeader = request.headers.get('host');
if (hostHeader) {
// Standard local dev or direct connection
const proto = request.headers.get('x-forwarded-proto') || 'http';
return new URL(`${proto}://${hostHeader}`);
}
return new URL(request.url);
}

View file

@ -3,6 +3,7 @@
// ============================================
import { NextRequest, NextResponse } from 'next/server';
import { getRequestBaseUrl } from '@/lib/url';
export function middleware(request: NextRequest) {
const { pathname } = request.nextUrl;
@ -20,7 +21,8 @@ export function middleware(request: NextRequest) {
if (process.env.NODE_ENV === 'development') {
return NextResponse.next();
}
return NextResponse.redirect(new URL('/login', request.url));
const baseUrl = getRequestBaseUrl(request);
return NextResponse.redirect(new URL('/login', baseUrl));
}
return NextResponse.next();