fix(operator,portal): env-driven sign-out URLs + host labels (no more .local in prod)

Operator sign-out hardcoded the dev Authentik end-session URL, so prod
logout landed on auth.dezky.local. Mirror the portal's env-driven pattern
(NUXT_PUBLIC_AUTH_URL/NUXT_PUBLIC_OPERATOR_URL with .local fallbacks).
Expose authUrl/operatorUrl via public runtimeConfig and use them for the
Authentik admin links and the cosmetic host labels (sidebar, eyebrows,
auth-page hints). Portal: signed-out + webmail copy now derive their hosts
from runtime config (new public.mailUrl, NUXT_PUBLIC_MAIL_URL in prod).
This commit is contained in:
Ronni Baslund
2026-06-10 19:51:25 +02:00
parent 45ed282eed
commit 0840efb759
14 changed files with 41 additions and 15 deletions
+4 -3
View File
@@ -1,4 +1,5 @@
<script setup lang="ts">
const mailHost = new URL(useRuntimeConfig().public.mailUrl as string).host
// Users & groups. The Users tab is real — workspace members come from
// /api/tenants/:slug/users (platform-api UserDocument). The Groups,
// Invitations and Service-accounts tabs have no backend yet (no Group /
@@ -902,7 +903,7 @@ async function submitCreateMailbox() {
<div v-if="resetResult" class="invite-result">
<div class="ir-check"><UiIcon name="key" :size="20" /></div>
<div class="ir-title">Password reset</div>
<p class="ir-sub">Share this securely. It works for both sign-in and webmail at <Mono>mail.dezky.local</Mono>.</p>
<p class="ir-sub">Share this securely. It works for both sign-in and webmail at <Mono>{{ mailHost }}</Mono>.</p>
<div class="cred">
<div class="cred-row">
<span class="cred-k">Email</span><Mono class="cred-v">{{ resetResult.email }}</Mono>
@@ -1011,7 +1012,7 @@ async function submitCreateMailbox() {
<div v-if="mailboxResult" class="invite-result">
<div class="ir-check"><UiIcon name="check" :size="22" :stroke-width="2.5" /></div>
<div class="ir-title">{{ mailboxResult.email }} is ready</div>
<p class="ir-sub">Share these securely. They sign in to webmail at <Mono>mail.dezky.local</Mono> with this password — their portal sign-in is unchanged.</p>
<p class="ir-sub">Share these securely. They sign in to webmail at <Mono>{{ mailHost }}</Mono> with this password — their portal sign-in is unchanged.</p>
<div class="cred">
<div class="cred-row">
<span class="cred-k">Mailbox</span><Mono class="cred-v">{{ mailboxResult.email }}</Mono>
@@ -1045,7 +1046,7 @@ async function submitCreateMailbox() {
<div v-else-if="inviteResult" class="invite-result">
<div class="ir-check"><UiIcon name="check" :size="22" :stroke-width="2.5" /></div>
<div class="ir-title">{{ inviteResult.email }} is ready</div>
<p class="ir-sub">Share these credentials securely. They sign in to the portal and to webmail at <Mono>mail.dezky.local</Mono>.</p>
<p class="ir-sub">Share these credentials securely. They sign in to the portal and to webmail at <Mono>{{ mailHost }}</Mono>.</p>
<div class="cred">
<div class="cred-row">
<span class="cred-k">Email</span><Mono class="cred-v">{{ inviteResult.email }}</Mono>
+2 -1
View File
@@ -1,4 +1,5 @@
<script setup lang="ts">
const portalHost = new URL(useRuntimeConfig().public.portalUrl as string).host
// Sign-out landing. /api/auth/sign-out cleared the local session and bounced
// through Authentik's end-session endpoint, which ended the IdP session.
// At this point the user has no portal session and no Authentik session —
@@ -30,7 +31,7 @@ function signInAgain() {
<AuthFooterLink>
Closing the tab? Your data stays put on
<span class="mono">app.dezky.local</span>.
<span class="mono">{{ portalHost }}</span>.
</AuthFooterLink>
</AuthShell>
</template>