diff --git a/dashboard/app/api/admin/settings/route.ts b/dashboard/app/api/admin/settings/route.ts index 4796920..2a3a688 100644 --- a/dashboard/app/api/admin/settings/route.ts +++ b/dashboard/app/api/admin/settings/route.ts @@ -2,11 +2,11 @@ export const dynamic = 'force-dynamic' import { NextRequest, NextResponse } from 'next/server' -import { getAccountServiceBaseUrl } from '@lib/serviceConfig' +import { getAccountServiceApiBaseUrl } from '@lib/serviceConfig' import { getAccountSession, userHasRole } from '@server/account/session' import type { AccountUserRole } from '@server/account/session' -const ACCOUNT_API_BASE = `${getAccountServiceBaseUrl()}/api/auth` +const ACCOUNT_API_BASE = getAccountServiceApiBaseUrl() const READ_ROLES: AccountUserRole[] = ['admin', 'operator'] const WRITE_ROLES: AccountUserRole[] = ['admin'] diff --git a/dashboard/app/api/admin/users/[userId]/role/route.ts b/dashboard/app/api/admin/users/[userId]/role/route.ts index 0aee558..c1785db 100644 --- a/dashboard/app/api/admin/users/[userId]/role/route.ts +++ b/dashboard/app/api/admin/users/[userId]/role/route.ts @@ -2,11 +2,11 @@ export const dynamic = 'force-dynamic' import { NextRequest, NextResponse } from 'next/server' -import { getAccountServiceBaseUrl } from '@lib/serviceConfig' +import { getAccountServiceApiBaseUrl } from '@lib/serviceConfig' import { getAccountSession, userHasRole } from '@server/account/session' import type { AccountUserRole } from '@server/account/session' -const ACCOUNT_API_BASE = `${getAccountServiceBaseUrl()}/api/auth` +const ACCOUNT_API_BASE = getAccountServiceApiBaseUrl() const REQUIRED_ROLES: AccountUserRole[] = ['admin'] type ErrorPayload = { diff --git a/dashboard/app/api/admin/users/metrics/route.ts b/dashboard/app/api/admin/users/metrics/route.ts index d8777c5..27827a3 100644 --- a/dashboard/app/api/admin/users/metrics/route.ts +++ b/dashboard/app/api/admin/users/metrics/route.ts @@ -2,11 +2,11 @@ export const dynamic = 'force-dynamic' import { NextRequest, NextResponse } from 'next/server' -import { getAccountServiceBaseUrl } from '@lib/serviceConfig' +import { getAccountServiceApiBaseUrl } from '@lib/serviceConfig' import { getAccountSession, userHasRole } from '@server/account/session' import type { AccountUserRole } from '@server/account/session' -const ACCOUNT_API_BASE = `${getAccountServiceBaseUrl()}/api/auth` +const ACCOUNT_API_BASE = getAccountServiceApiBaseUrl() const ALLOWED_ROLES: AccountUserRole[] = ['admin', 'operator'] diff --git a/dashboard/app/api/auth/login/route.ts b/dashboard/app/api/auth/login/route.ts index c39cf45..12ba73f 100644 --- a/dashboard/app/api/auth/login/route.ts +++ b/dashboard/app/api/auth/login/route.ts @@ -2,10 +2,9 @@ import { cookies } from 'next/headers' import { NextRequest, NextResponse } from 'next/server' import { applyMfaCookie, applySessionCookie, clearMfaCookie, clearSessionCookie, deriveMaxAgeFromExpires, MFA_COOKIE_NAME } from '@lib/authGateway' -import { getAccountServiceBaseUrl } from '@lib/serviceConfig' +import { getAccountServiceApiBaseUrl } from '@lib/serviceConfig' -const ACCOUNT_SERVICE_URL = getAccountServiceBaseUrl() -const ACCOUNT_API_BASE = `${ACCOUNT_SERVICE_URL}/api/auth` +const ACCOUNT_API_BASE = getAccountServiceApiBaseUrl() type LoginPayload = { email?: string diff --git a/dashboard/app/api/auth/mfa/disable/route.ts b/dashboard/app/api/auth/mfa/disable/route.ts index 03c385d..59e9330 100644 --- a/dashboard/app/api/auth/mfa/disable/route.ts +++ b/dashboard/app/api/auth/mfa/disable/route.ts @@ -2,10 +2,9 @@ import { cookies } from 'next/headers' import { NextRequest, NextResponse } from 'next/server' import { SESSION_COOKIE_NAME, clearSessionCookie } from '@lib/authGateway' -import { getAccountServiceBaseUrl } from '@lib/serviceConfig' +import { getAccountServiceApiBaseUrl } from '@lib/serviceConfig' -const ACCOUNT_SERVICE_URL = getAccountServiceBaseUrl() -const ACCOUNT_API_BASE = `${ACCOUNT_SERVICE_URL}/api/auth` +const ACCOUNT_API_BASE = getAccountServiceApiBaseUrl() export async function POST(request: NextRequest) { void request diff --git a/dashboard/app/api/auth/mfa/setup/route.ts b/dashboard/app/api/auth/mfa/setup/route.ts index 6a16e11..362fddc 100644 --- a/dashboard/app/api/auth/mfa/setup/route.ts +++ b/dashboard/app/api/auth/mfa/setup/route.ts @@ -2,10 +2,9 @@ import { cookies } from 'next/headers' import { NextRequest, NextResponse } from 'next/server' import { applyMfaCookie, MFA_COOKIE_NAME, SESSION_COOKIE_NAME } from '@lib/authGateway' -import { getAccountServiceBaseUrl } from '@lib/serviceConfig' +import { getAccountServiceApiBaseUrl } from '@lib/serviceConfig' -const ACCOUNT_SERVICE_URL = getAccountServiceBaseUrl() -const ACCOUNT_API_BASE = `${ACCOUNT_SERVICE_URL}/api/auth` +const ACCOUNT_API_BASE = getAccountServiceApiBaseUrl() // This Next.js route proxies MFA provisioning requests to the account service. // The UI calls /api/auth/mfa/setup, which in turn forwards to the Go backend diff --git a/dashboard/app/api/auth/mfa/status/route.ts b/dashboard/app/api/auth/mfa/status/route.ts index 3d333ad..836b611 100644 --- a/dashboard/app/api/auth/mfa/status/route.ts +++ b/dashboard/app/api/auth/mfa/status/route.ts @@ -2,10 +2,9 @@ import { cookies } from 'next/headers' import { NextRequest, NextResponse } from 'next/server' import { MFA_COOKIE_NAME, SESSION_COOKIE_NAME } from '@lib/authGateway' -import { getAccountServiceBaseUrl } from '@lib/serviceConfig' +import { getAccountServiceApiBaseUrl } from '@lib/serviceConfig' -const ACCOUNT_SERVICE_URL = getAccountServiceBaseUrl() -const ACCOUNT_API_BASE = `${ACCOUNT_SERVICE_URL}/api/auth` +const ACCOUNT_API_BASE = getAccountServiceApiBaseUrl() export async function GET(request: NextRequest) { const cookieStore = cookies() diff --git a/dashboard/app/api/auth/mfa/verify/route.ts b/dashboard/app/api/auth/mfa/verify/route.ts index b261c05..a7ba33e 100644 --- a/dashboard/app/api/auth/mfa/verify/route.ts +++ b/dashboard/app/api/auth/mfa/verify/route.ts @@ -9,10 +9,9 @@ import { deriveMaxAgeFromExpires, MFA_COOKIE_NAME, } from '@lib/authGateway' -import { getAccountServiceBaseUrl } from '@lib/serviceConfig' +import { getAccountServiceApiBaseUrl } from '@lib/serviceConfig' -const ACCOUNT_SERVICE_URL = getAccountServiceBaseUrl() -const ACCOUNT_API_BASE = `${ACCOUNT_SERVICE_URL}/api/auth` +const ACCOUNT_API_BASE = getAccountServiceApiBaseUrl() type VerifyPayload = { token?: string diff --git a/dashboard/app/api/auth/register/route.ts b/dashboard/app/api/auth/register/route.ts index 639b7d0..fe0652c 100644 --- a/dashboard/app/api/auth/register/route.ts +++ b/dashboard/app/api/auth/register/route.ts @@ -1,9 +1,8 @@ import { NextRequest, NextResponse } from 'next/server' -import { getAccountServiceBaseUrl } from '@lib/serviceConfig' +import { getAccountServiceApiBaseUrl } from '@lib/serviceConfig' -const ACCOUNT_SERVICE_URL = getAccountServiceBaseUrl() -const ACCOUNT_API_BASE = `${ACCOUNT_SERVICE_URL}/api/auth` +const ACCOUNT_API_BASE = getAccountServiceApiBaseUrl() type RegistrationPayload = { name?: string diff --git a/dashboard/app/api/auth/session/route.ts b/dashboard/app/api/auth/session/route.ts index 3202cf0..ef928bd 100644 --- a/dashboard/app/api/auth/session/route.ts +++ b/dashboard/app/api/auth/session/route.ts @@ -2,10 +2,9 @@ import { cookies } from 'next/headers' import { NextRequest, NextResponse } from 'next/server' import { SESSION_COOKIE_NAME, clearSessionCookie } from '@lib/authGateway' -import { getAccountServiceBaseUrl } from '@lib/serviceConfig' +import { getAccountServiceApiBaseUrl } from '@lib/serviceConfig' -const ACCOUNT_SERVICE_URL = getAccountServiceBaseUrl() -const ACCOUNT_API_BASE = `${ACCOUNT_SERVICE_URL}/api/auth` +const ACCOUNT_API_BASE = getAccountServiceApiBaseUrl() type AccountUser = { id?: string diff --git a/dashboard/app/api/auth/verify-email/route.ts b/dashboard/app/api/auth/verify-email/route.ts index e154183..51656ae 100644 --- a/dashboard/app/api/auth/verify-email/route.ts +++ b/dashboard/app/api/auth/verify-email/route.ts @@ -1,9 +1,8 @@ import { NextRequest, NextResponse } from 'next/server' -import { getAccountServiceBaseUrl } from '@lib/serviceConfig' +import { getAccountServiceApiBaseUrl } from '@lib/serviceConfig' -const ACCOUNT_SERVICE_URL = getAccountServiceBaseUrl() -const ACCOUNT_API_BASE = `${ACCOUNT_SERVICE_URL}/api/auth` +const ACCOUNT_API_BASE = getAccountServiceApiBaseUrl() type VerifyPayload = { email?: string diff --git a/dashboard/app/api/auth/verify-email/send/route.ts b/dashboard/app/api/auth/verify-email/send/route.ts index df2927f..f406162 100644 --- a/dashboard/app/api/auth/verify-email/send/route.ts +++ b/dashboard/app/api/auth/verify-email/send/route.ts @@ -1,9 +1,8 @@ import { NextRequest, NextResponse } from 'next/server' -import { getAccountServiceBaseUrl } from '@lib/serviceConfig' +import { getAccountServiceApiBaseUrl } from '@lib/serviceConfig' -const ACCOUNT_SERVICE_URL = getAccountServiceBaseUrl() -const ACCOUNT_API_BASE = `${ACCOUNT_SERVICE_URL}/api/auth` +const ACCOUNT_API_BASE = getAccountServiceApiBaseUrl() type SendPayload = { email?: string diff --git a/dashboard/lib/serviceConfig.ts b/dashboard/lib/serviceConfig.ts index 40bc815..afcbd47 100644 --- a/dashboard/lib/serviceConfig.ts +++ b/dashboard/lib/serviceConfig.ts @@ -210,6 +210,21 @@ export function getAccountServiceBaseUrl(): string { return normalizeBrowserBaseUrl(resolved) } +export function getAccountServiceApiBaseUrl(): string { + const accountBaseUrl = getAccountServiceBaseUrl() + const apiPath = '/api/auth/' + try { + const url = new URL(apiPath, accountBaseUrl) + return normalizeBaseUrl(url.toString()) + } catch (error) { + if (process.env.NODE_ENV !== 'production') { + console.warn('Failed to resolve account service API base URL, falling back to concatenation', error) + } + const normalizedBase = normalizeBaseUrl(accountBaseUrl) + return normalizeBaseUrl(`${normalizedBase}${apiPath}`) + } +} + export function getServerServiceBaseUrl(): string { const configured = readEnvValue( 'SERVER_SERVICE_URL', diff --git a/dashboard/server/account/session.ts b/dashboard/server/account/session.ts index fa91c53..77f6e98 100644 --- a/dashboard/server/account/session.ts +++ b/dashboard/server/account/session.ts @@ -4,10 +4,9 @@ import { cookies } from 'next/headers' import type { NextRequest } from 'next/server' import { SESSION_COOKIE_NAME } from '@lib/authGateway' -import { getAccountServiceBaseUrl } from '@lib/serviceConfig' +import { getAccountServiceApiBaseUrl } from '@lib/serviceConfig' -const ACCOUNT_SERVICE_BASE = getAccountServiceBaseUrl() -const ACCOUNT_API_BASE = `${ACCOUNT_SERVICE_BASE}/api/auth` +const ACCOUNT_API_BASE = getAccountServiceApiBaseUrl() export type AccountUserRole = 'guest' | 'user' | 'operator' | 'admin'