feat(apps): make environment URLs prod-ready (env-driven, not hardcoded .local)
ci / typecheck (map[dir:apps/booking name:booking]) (push) Has been cancelled
ci / typecheck (map[dir:apps/portal name:portal]) (push) Has been cancelled
ci / typecheck (map[dir:apps/website name:website]) (push) Has been cancelled
ci / typecheck (map[dir:services/platform-api name:platform-api]) (push) Has been cancelled
ci / test (push) Has been cancelled

The apps were wired for the dev (.local) environment. Drive the base URLs from
env so one build serves dev and prod (.eu):

- portal nuxt.config: OIDC authorization/token/userinfo/discovery URLs +
  redirectUri now derive from NUXT_PUBLIC_AUTH_URL / NUXT_PUBLIC_PORTAL_URL
  (+ PORTAL_OIDC_APP_SLUG); .local defaults keep dev working with no env.
- portal sign-out handler: end-session + post-logout URLs env-driven.
- portal scheduling page: booking base/host from runtimeConfig.public.bookingUrl
  (NUXT_PUBLIC_BOOKING_URL).
- platform-api: tenant mail domain suffix from PLATFORM_TENANT_DOMAIN (dezky.eu
  in prod), defaulting to dezky.local.

(booking needs no change — its only .local ref is the dev-server allowedHosts.)
This commit is contained in:
Ronni Baslund
2026-06-08 22:18:51 +02:00
parent f331e3c1e6
commit 955357a91a
4 changed files with 30 additions and 12 deletions
+14 -5
View File
@@ -1,6 +1,14 @@
// Nuxt 3 configuration for Dezky portal
// https://nuxt.com/docs/api/configuration/nuxt-config
// Base URLs are environment-driven so one build runs in dev (.local) and
// production (.eu). NUXT_PUBLIC_AUTH_URL / NUXT_PUBLIC_PORTAL_URL are set at
// BUILD (CI) and RUNTIME (fleet/apps/portal.yaml + portal-secrets); the .local
// defaults keep local dev working with no env.
const AUTH_URL = (process.env.NUXT_PUBLIC_AUTH_URL || 'https://auth.dezky.local').replace(/\/$/, '')
const PORTAL_URL = (process.env.NUXT_PUBLIC_PORTAL_URL || 'https://app.dezky.local').replace(/\/$/, '')
const PORTAL_OIDC_APP_SLUG = process.env.PORTAL_OIDC_APP_SLUG || 'dezky-portal'
export default defineNuxtConfig({
compatibilityDate: '2026-01-01',
devtools: { enabled: true },
@@ -40,6 +48,7 @@ export default defineNuxtConfig({
public: {
authUrl: process.env.NUXT_PUBLIC_AUTH_URL,
portalUrl: process.env.NUXT_PUBLIC_PORTAL_URL,
bookingUrl: process.env.NUXT_PUBLIC_BOOKING_URL || 'https://booking.dezky.local',
},
},
@@ -69,10 +78,10 @@ export default defineNuxtConfig({
// NUXT_OIDC_* per-container; locally we just read them directly.
clientId: process.env.PORTAL_OIDC_CLIENT_ID || process.env.NUXT_OIDC_CLIENT_ID || '',
clientSecret: process.env.PORTAL_OIDC_CLIENT_SECRET || process.env.NUXT_OIDC_CLIENT_SECRET || '',
redirectUri: process.env.NUXT_OIDC_REDIRECT_URI || 'https://app.dezky.local/auth/oidc/callback',
authorizationUrl: 'https://auth.dezky.local/application/o/authorize/',
tokenUrl: 'https://auth.dezky.local/application/o/token/',
userInfoUrl: 'https://auth.dezky.local/application/o/userinfo/',
redirectUri: process.env.NUXT_OIDC_REDIRECT_URI || `${PORTAL_URL}/auth/oidc/callback`,
authorizationUrl: `${AUTH_URL}/application/o/authorize/`,
tokenUrl: `${AUTH_URL}/application/o/token/`,
userInfoUrl: `${AUTH_URL}/application/o/userinfo/`,
// Logout is handled by our custom /api/auth/sign-out endpoint, not the
// module's RP-initiated chain. Authentik 2025.10 doesn't reliably
// honor `post_logout_redirect_uri` from the provider invalidation
@@ -82,7 +91,7 @@ export default defineNuxtConfig({
logoutUrl: '',
// Discovery URL — used by id_token validation to fetch JWKS + issuer
openIdConfiguration:
'https://auth.dezky.local/application/o/dezky-portal/.well-known/openid-configuration',
`${AUTH_URL}/application/o/${PORTAL_OIDC_APP_SLUG}/.well-known/openid-configuration`,
// offline_access asks Authentik for a refresh token. Without it there's
// nothing to refresh with, so session.automaticRefresh can't run and the
// module's refresh() falls back to a full login() redirect on token
+3 -2
View File
@@ -49,7 +49,8 @@ const toast = useToast()
const { tenant } = useTenant()
const slug = computed(() => tenant.value?.slug ?? '')
const { request } = useApiFetch()
const bookingBase = 'https://booking.dezky.local'
const bookingBase = (useRuntimeConfig().public.bookingUrl as string) || 'https://booking.dezky.local'
const bookingHost = bookingBase.replace(/^https?:\/\//, '')
const base = computed(() => `/api/tenants/${slug.value}/scheduling`)
@@ -894,7 +895,7 @@ const maskSecret = (s: string) => (s.length > 12 ? `${s.slice(0, 9)}…${s.slice
<template v-if="!hostForm.slug">Used in the public booking link.</template>
<template v-else-if="!slugValid">Lowercase letters, numbers and hyphens (240 chars).</template>
<template v-else-if="slugTaken">{{ hostForm.slug }} is already taken.</template>
<template v-else>booking.dezky.local/{{ slug }}/{{ hostForm.slug }} · available </template>
<template v-else>{{ bookingHost }}/{{ slug }}/{{ hostForm.slug }} · available </template>
</span>
</label>
<label class="field"><Eyebrow>Timezone</Eyebrow>
+8 -2
View File
@@ -24,8 +24,14 @@
import { getUserSession, clearUserSession } from 'nuxt-oidc-auth/runtime/server/utils/session.js'
const END_SESSION = 'https://auth.dezky.local/application/o/dezky-portal/end-session/'
const POST_LOGOUT_REDIRECT = 'https://app.dezky.local/signed-out'
// Environment-driven so one build serves dev (.local) and prod (.eu). The
// public runtime config carries authUrl/portalUrl (NUXT_PUBLIC_AUTH_URL /
// NUXT_PUBLIC_PORTAL_URL); fall back to the dev hosts.
const AUTH_URL = (process.env.NUXT_PUBLIC_AUTH_URL || 'https://auth.dezky.local').replace(/\/$/, '')
const PORTAL_URL = (process.env.NUXT_PUBLIC_PORTAL_URL || 'https://app.dezky.local').replace(/\/$/, '')
const OIDC_APP_SLUG = process.env.PORTAL_OIDC_APP_SLUG || 'dezky-portal'
const END_SESSION = `${AUTH_URL}/application/o/${OIDC_APP_SLUG}/end-session/`
const POST_LOGOUT_REDIRECT = `${PORTAL_URL}/signed-out`
export default defineEventHandler(async (event) => {
const session = await getUserSession(event).catch(() => ({} as any))