Merge pull request 'fix/login-redirect-URL' (#439) from fix/login-redirect-URL into development
Reviewed-on: ADUANASOFT/anexo76#439
This commit is contained in:
22
.env.example
22
.env.example
@@ -35,6 +35,28 @@ CORS_ORIGINS=http://localhost:5173,http://localhost:3000
|
|||||||
NODE_ENV=development
|
NODE_ENV=development
|
||||||
VITE_API_URL=http://localhost:8000/api
|
VITE_API_URL=http://localhost:8000/api
|
||||||
INTERNAL_API_URL=http://backend:8000/api
|
INTERNAL_API_URL=http://backend:8000/api
|
||||||
|
|
||||||
|
# ⚠️ ADVERTENCIA PRODUCCIÓN — ORIGIN, VITE_HUB_URL y APP_PUBLIC_URL
|
||||||
|
# ─────────────────────────────────────────────────────────────────────
|
||||||
|
# Docker Compose carga ESTE archivo (.env raíz) automáticamente cuando
|
||||||
|
# se ejecuta: docker compose -f docker-compose.prod.yml up
|
||||||
|
#
|
||||||
|
# Si estas variables tienen valores localhost aquí, PISARÁN los defaults
|
||||||
|
# de docker-compose.prod.yml y causarán que el login falle en producción
|
||||||
|
# (redirect_uri y KC URL apuntarán a localhost).
|
||||||
|
#
|
||||||
|
# Para dev local (docker-compose.yml): dejar localhost.
|
||||||
|
# Para producción (docker-compose.prod.yml): asegurarse que el servidor
|
||||||
|
# NO tenga este .env raíz con valores localhost, O usar:
|
||||||
|
# docker compose --env-file .env.prod -f docker-compose.prod.yml up
|
||||||
|
#
|
||||||
|
# Variables críticas para producción:
|
||||||
|
# ORIGIN=https://anexo76-dev.aduanasoft.com ← determina url.origin en SvelteKit
|
||||||
|
# VITE_HUB_URL=https://workspace.aduanasoft.com
|
||||||
|
# APP_PUBLIC_URL=https://anexo76-dev.aduanasoft.com
|
||||||
|
ORIGIN=http://localhost:5173
|
||||||
|
VITE_HUB_URL=http://localhost:3001
|
||||||
|
APP_PUBLIC_URL=http://localhost:5173
|
||||||
VITE_KEYCLOAK_REALM=master
|
VITE_KEYCLOAK_REALM=master
|
||||||
VITE_KEYCLOAK_URL=http://localhost:8080/kcauth
|
VITE_KEYCLOAK_URL=http://localhost:8080/kcauth
|
||||||
VITE_KEYCLOAK_CLIENT_ID=anexo76-frontend
|
VITE_KEYCLOAK_CLIENT_ID=anexo76-frontend
|
||||||
|
|||||||
2
Jenkinsfile
vendored
2
Jenkinsfile
vendored
@@ -273,7 +273,7 @@ pipeline {
|
|||||||
docker build --progress=plain \
|
docker build --progress=plain \
|
||||||
--build-arg VITE_API_URL=\${A76_URL}/api/ \
|
--build-arg VITE_API_URL=\${A76_URL}/api/ \
|
||||||
--build-arg VITE_KEYCLOAK_URL=\${A76_URL}/kcauth/ \
|
--build-arg VITE_KEYCLOAK_URL=\${A76_URL}/kcauth/ \
|
||||||
--build-arg VITE_KEYCLOAK_CLIENT_ID=hub-frontend \
|
--build-arg VITE_KEYCLOAK_CLIENT_ID=anexo76-frontend \
|
||||||
--build-arg INTERNAL_API_URL=http://backend:3467/api/ \
|
--build-arg INTERNAL_API_URL=http://backend:3467/api/ \
|
||||||
-t ${IMAGE_FRONTEND}:${env.APP_VERSION} \
|
-t ${IMAGE_FRONTEND}:${env.APP_VERSION} \
|
||||||
-t ${IMAGE_FRONTEND}:latest \
|
-t ${IMAGE_FRONTEND}:latest \
|
||||||
|
|||||||
@@ -240,6 +240,10 @@ services:
|
|||||||
- INTERNAL_API_URL=${INTERNAL_API_URL:-http://backend:8000/api/}
|
- INTERNAL_API_URL=${INTERNAL_API_URL:-http://backend:8000/api/}
|
||||||
- INTERNAL_HUB_URL=https://workspace.aduanasoft.com
|
- INTERNAL_HUB_URL=https://workspace.aduanasoft.com
|
||||||
- HUB_URL=https://workspace.aduanasoft.com
|
- HUB_URL=https://workspace.aduanasoft.com
|
||||||
|
# VITE_HUB_URL: URL pública del Hub para el browser (bakeada en build, pero también se lee
|
||||||
|
# en runtime por $env/dynamic/private en workspace-auth.ts). El root .env puede tener
|
||||||
|
# localhost; isDevOnlyUrl() lo descarta y cae a HUB_URL (correcto arriba).
|
||||||
|
- VITE_HUB_URL=https://workspace.aduanasoft.com
|
||||||
- VITE_KEYCLOAK_URL=${VITE_KEYCLOAK_URL:-https://anexo76-dev.aduanasoft.com/kcauth/}
|
- VITE_KEYCLOAK_URL=${VITE_KEYCLOAK_URL:-https://anexo76-dev.aduanasoft.com/kcauth/}
|
||||||
- VITE_KEYCLOAK_REALM=${VITE_KEYCLOAK_REALM:-master}
|
- VITE_KEYCLOAK_REALM=${VITE_KEYCLOAK_REALM:-master}
|
||||||
- VITE_KEYCLOAK_CLIENT_ID=${VITE_KEYCLOAK_CLIENT_ID:-anexo76-frontend}
|
- VITE_KEYCLOAK_CLIENT_ID=${VITE_KEYCLOAK_CLIENT_ID:-anexo76-frontend}
|
||||||
@@ -247,8 +251,14 @@ services:
|
|||||||
- KEYCLOAK_REALM=${KEYCLOAK_REALM:-master}
|
- KEYCLOAK_REALM=${KEYCLOAK_REALM:-master}
|
||||||
- KEYCLOAK_CLIENT_ID=${KEYCLOAK_CLIENT_ID:-anexo76-backend}
|
- KEYCLOAK_CLIENT_ID=${KEYCLOAK_CLIENT_ID:-anexo76-backend}
|
||||||
- KEYCLOAK_CLIENT_SECRET=${KEYCLOAK_CLIENT_SECRET:-dev-secret}
|
- KEYCLOAK_CLIENT_SECRET=${KEYCLOAK_CLIENT_SECRET:-dev-secret}
|
||||||
# SvelteKit ORIGIN — evita que request.url.origin use la IP/puerto interno del contenedor
|
# SvelteKit ORIGIN — determina url.origin en load functions y el flag secure de cookies.
|
||||||
|
# ⚠️ Docker Compose carga el .env raíz automáticamente. Si ese .env tiene
|
||||||
|
# ORIGIN=http://localhost:5173 (valor dev), sobreescribe el default de abajo.
|
||||||
|
# SITE_URL es el fallback que usa el código cuando url.origin es localhost.
|
||||||
- ORIGIN=${ORIGIN:-https://anexo76-dev.aduanasoft.com}
|
- ORIGIN=${ORIGIN:-https://anexo76-dev.aduanasoft.com}
|
||||||
|
# SITE_URL: hardcoded — no depende del .env raíz.
|
||||||
|
# resolveSystemBaseUrl() lo usa cuando ORIGIN tiene localhost (root .env de dev en prod).
|
||||||
|
- SITE_URL=https://anexo76-dev.aduanasoft.com
|
||||||
ports:
|
ports:
|
||||||
- "5111:5173"
|
- "5111:5173"
|
||||||
depends_on:
|
depends_on:
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
# ─── Copia este archivo a .env y ajusta los valores para dev local ─────────────
|
# ─── Copia este archivo a .env y ajusta los valores para dev local ─────────────
|
||||||
|
# ─── Para PRODUCCIÓN ver el bloque al final de este archivo ──────────────────
|
||||||
|
|
||||||
# API de Anexo76 (frontend y SSR)
|
# API de Anexo76 (frontend y SSR)
|
||||||
VITE_API_URL=http://localhost:8000/api/
|
VITE_API_URL=http://localhost:8000/api/
|
||||||
@@ -9,14 +10,30 @@ VITE_HUB_URL=http://localhost:3001
|
|||||||
HUB_URL=http://localhost:3001
|
HUB_URL=http://localhost:3001
|
||||||
INTERNAL_HUB_URL=http://localhost:8001
|
INTERNAL_HUB_URL=http://localhost:8001
|
||||||
|
|
||||||
# Keycloak
|
# Keycloak — URL pública que el BROWSER usará (se bakea en el build)
|
||||||
VITE_KEYCLOAK_URL=http://localhost:8085/kcauth
|
VITE_KEYCLOAK_URL=http://localhost:8085/kcauth
|
||||||
VITE_KEYCLOAK_REALM=master
|
VITE_KEYCLOAK_REALM=master
|
||||||
VITE_KEYCLOAK_CLIENT_ID=hub-frontend
|
VITE_KEYCLOAK_CLIENT_ID=anexo76-frontend
|
||||||
|
# Keycloak — URL interna que el SERVIDOR usará (no va al browser)
|
||||||
KEYCLOAK_URL=http://localhost:8085/kcauth
|
KEYCLOAK_URL=http://localhost:8085/kcauth
|
||||||
KEYCLOAK_REALM=master
|
KEYCLOAK_REALM=master
|
||||||
KEYCLOAK_CLIENT_ID=hub-frontend
|
KEYCLOAK_CLIENT_ID=anexo76-frontend
|
||||||
# KEYCLOAK_CLIENT_SECRET= # solo si el cliente KC no es público
|
# KEYCLOAK_CLIENT_SECRET= # solo si el cliente KC no es público
|
||||||
|
|
||||||
# SvelteKit — necesario para cookies secure y URLs SSR correctas
|
# SvelteKit — necesario para cookies secure y URLs SSR correctas.
|
||||||
|
# ⚠️ En producción DEBE apuntar al dominio público real, no a localhost.
|
||||||
|
# Si este valor es localhost, url.origin en los load functions será localhost
|
||||||
|
# y los redirect_uri de Keycloak apuntarán a localhost (bug de login).
|
||||||
ORIGIN=http://localhost:5173
|
ORIGIN=http://localhost:5173
|
||||||
|
|
||||||
|
# ─── PRODUCCIÓN: vars adicionales críticas ────────────────────────────────────
|
||||||
|
# SITE_URL es el fallback de seguridad cuando ORIGIN no se pudo corregir a tiempo.
|
||||||
|
# El código lo usa para construir redirect_uri cuando url.origin es localhost.
|
||||||
|
# Recomendado: definir TANTO ORIGIN como SITE_URL con el mismo valor en prod.
|
||||||
|
#
|
||||||
|
# SITE_URL=https://anexo76-dev.aduanasoft.com
|
||||||
|
# ORIGIN=https://anexo76-dev.aduanasoft.com
|
||||||
|
# VITE_HUB_URL=https://hub-dev.aduanasoft.com (o la URL del Hub en prod)
|
||||||
|
# HUB_URL=https://hub-dev.aduanasoft.com
|
||||||
|
# VITE_KEYCLOAK_URL= # vacío → se deriva del hostname del browser automáticamente
|
||||||
|
# KEYCLOAK_URL=http://keycloak:8080 # URL interna del contenedor KC (si en Docker)
|
||||||
|
|||||||
@@ -22,9 +22,16 @@ ENV VITE_API_URL=${VITE_API_URL}
|
|||||||
ARG VITE_KEYCLOAK_URL
|
ARG VITE_KEYCLOAK_URL
|
||||||
ENV VITE_KEYCLOAK_URL=${VITE_KEYCLOAK_URL}
|
ENV VITE_KEYCLOAK_URL=${VITE_KEYCLOAK_URL}
|
||||||
|
|
||||||
ARG VITE_KEYCLOAK_CLIENT_ID=hub-frontend
|
ARG VITE_KEYCLOAK_REALM=master
|
||||||
|
ENV VITE_KEYCLOAK_REALM=${VITE_KEYCLOAK_REALM}
|
||||||
|
|
||||||
|
ARG VITE_KEYCLOAK_CLIENT_ID=anexo76-frontend
|
||||||
ENV VITE_KEYCLOAK_CLIENT_ID=${VITE_KEYCLOAK_CLIENT_ID}
|
ENV VITE_KEYCLOAK_CLIENT_ID=${VITE_KEYCLOAK_CLIENT_ID}
|
||||||
|
|
||||||
|
# URL pública del Hub Workspace (bakeada en build para el browser)
|
||||||
|
ARG VITE_HUB_URL=https://workspace.aduanasoft.com
|
||||||
|
ENV VITE_HUB_URL=${VITE_HUB_URL}
|
||||||
|
|
||||||
ARG INTERNAL_API_URL
|
ARG INTERNAL_API_URL
|
||||||
ENV INTERNAL_API_URL=${INTERNAL_API_URL}
|
ENV INTERNAL_API_URL=${INTERNAL_API_URL}
|
||||||
|
|
||||||
|
|||||||
@@ -50,8 +50,49 @@ export interface AuthState {
|
|||||||
// Configuración de Keycloak
|
// Configuración de Keycloak
|
||||||
// ─────────────────────────────────────────────────────────
|
// ─────────────────────────────────────────────────────────
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Devuelve la URL pública de Keycloak correcta para el browser.
|
||||||
|
* Si VITE_KEYCLOAK_URL está bakeado con localhost/127.0.0.1 pero el browser
|
||||||
|
* no está en localhost (producción), se ignora el valor bakeado y se deriva
|
||||||
|
* del hostname real del browser. Protege contra builds con .env de dev en prod.
|
||||||
|
*/
|
||||||
|
function resolveKeycloakUrl(): string {
|
||||||
|
const configured = (import.meta.env.VITE_KEYCLOAK_URL || '').replace(/\/+$/, '');
|
||||||
|
|
||||||
|
if (typeof window === 'undefined') {
|
||||||
|
// SSR: usar el valor configurado tal cual (el server tiene las vars correctas)
|
||||||
|
return configured || 'http://localhost:8085/kcauth';
|
||||||
|
}
|
||||||
|
|
||||||
|
const browserHostname = window.location.hostname;
|
||||||
|
const isLocalBrowser = browserHostname === 'localhost' || browserHostname === '127.0.0.1';
|
||||||
|
|
||||||
|
if (configured) {
|
||||||
|
try {
|
||||||
|
const parsed = new URL(configured);
|
||||||
|
const configuredHost = parsed.hostname;
|
||||||
|
const isLocalConfigured = configuredHost === 'localhost' || configuredHost === '127.0.0.1';
|
||||||
|
// Si el build fue con localhost pero el browser NO está en localhost → derivar del hostname real
|
||||||
|
if (isLocalConfigured && !isLocalBrowser) {
|
||||||
|
const protocol = window.location.protocol === 'https:' ? 'https:' : 'http:';
|
||||||
|
return `${protocol}//${browserHostname}/kcauth`;
|
||||||
|
}
|
||||||
|
} catch {
|
||||||
|
// URL malformada — caer al fallback
|
||||||
|
}
|
||||||
|
return configured;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (isLocalBrowser) {
|
||||||
|
return 'http://localhost:8085/kcauth';
|
||||||
|
}
|
||||||
|
|
||||||
|
const protocol = window.location.protocol === 'https:' ? 'https:' : 'http:';
|
||||||
|
return `${protocol}//${browserHostname}/kcauth`;
|
||||||
|
}
|
||||||
|
|
||||||
const keycloakConfig = {
|
const keycloakConfig = {
|
||||||
url: import.meta.env.VITE_KEYCLOAK_URL,
|
url: resolveKeycloakUrl(),
|
||||||
realm: import.meta.env.VITE_KEYCLOAK_REALM,
|
realm: import.meta.env.VITE_KEYCLOAK_REALM,
|
||||||
clientId: import.meta.env.VITE_KEYCLOAK_CLIENT_ID
|
clientId: import.meta.env.VITE_KEYCLOAK_CLIENT_ID
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -19,11 +19,25 @@ function stripTrailingSlashes(value: string): string {
|
|||||||
return value.replace(/\/+$/, '');
|
return value.replace(/\/+$/, '');
|
||||||
}
|
}
|
||||||
|
|
||||||
function isInternalOnlyHost(rawUrl: string): boolean {
|
/**
|
||||||
|
* Detecta si una URL apunta a un host que solo es accesible localmente:
|
||||||
|
* localhost, 127.0.0.1, IPs de red LAN/privada y hostnames internos de Docker.
|
||||||
|
* Estas URLs no son válidas como redirect_uri ni como KC public URL en producción.
|
||||||
|
*/
|
||||||
|
function isDevOnlyUrl(rawUrl: string): boolean {
|
||||||
try {
|
try {
|
||||||
const parsed = new URL(rawUrl);
|
const parsed = new URL(rawUrl);
|
||||||
const host = parsed.hostname.toLowerCase();
|
const host = parsed.hostname.toLowerCase();
|
||||||
return host === 'host.docker.internal' || host === 'backend' || host === 'hub-keycloak';
|
return (
|
||||||
|
host === 'localhost' ||
|
||||||
|
host === '127.0.0.1' ||
|
||||||
|
host === 'host.docker.internal' ||
|
||||||
|
host === 'backend' ||
|
||||||
|
host === 'hub-keycloak' ||
|
||||||
|
/^192\.168\./.test(host) ||
|
||||||
|
/^10\./.test(host) ||
|
||||||
|
/^172\.(1[6-9]|2\d|3[01])\./.test(host)
|
||||||
|
);
|
||||||
} catch {
|
} catch {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@@ -37,7 +51,7 @@ export function getWorkspaceBaseUrl(): string {
|
|||||||
].filter(Boolean);
|
].filter(Boolean);
|
||||||
|
|
||||||
for (const candidate of candidates) {
|
for (const candidate of candidates) {
|
||||||
if (!isInternalOnlyHost(candidate)) {
|
if (!isDevOnlyUrl(candidate)) {
|
||||||
return stripTrailingSlashes(candidate);
|
return stripTrailingSlashes(candidate);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -45,6 +59,44 @@ export function getWorkspaceBaseUrl(): string {
|
|||||||
return DEFAULT_WORKSPACE_BASE_URL;
|
return DEFAULT_WORKSPACE_BASE_URL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Normaliza la URL base del sistema (Anexo76) para construir redirect_uri seguros.
|
||||||
|
*
|
||||||
|
* Problema habitual en producción: SvelteKit deriva `url.origin` de la variable de entorno
|
||||||
|
* `ORIGIN`. Si el contenedor se despliega con `ORIGIN=http://localhost:5173` (valor del .env
|
||||||
|
* de dev), todos los redirect_uri generados por el servidor apuntan a localhost.
|
||||||
|
*
|
||||||
|
* Esta función:
|
||||||
|
* 1. Usa `requestOrigin` si ya es una URL pública (no dev-only).
|
||||||
|
* 2. Si es localhost, busca `SITE_URL` (env var de producción recomendada) como fallback.
|
||||||
|
* 3. Como último recurso devuelve requestOrigin tal cual (entorno dev genuino).
|
||||||
|
*
|
||||||
|
* Var de entorno recomendada en producción:
|
||||||
|
* SITE_URL=https://anexo76-dev.aduanasoft.com (además de arreglar ORIGIN)
|
||||||
|
*/
|
||||||
|
export function resolveSystemBaseUrl(requestOrigin: string): string {
|
||||||
|
if (!isDevOnlyUrl(requestOrigin)) {
|
||||||
|
return stripTrailingSlashes(requestOrigin);
|
||||||
|
}
|
||||||
|
|
||||||
|
// requestOrigin es dev-only → ORIGIN env var apunta a localhost en producción.
|
||||||
|
// Buscar URL pública en env vars adicionales.
|
||||||
|
const candidates = [
|
||||||
|
(env.SITE_URL || '').trim(),
|
||||||
|
(env.APP_URL || '').trim(),
|
||||||
|
(env.PUBLIC_URL || '').trim(),
|
||||||
|
];
|
||||||
|
|
||||||
|
for (const candidate of candidates) {
|
||||||
|
if (candidate && !isDevOnlyUrl(candidate)) {
|
||||||
|
return stripTrailingSlashes(candidate);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Entorno dev genuino: devolver requestOrigin tal cual
|
||||||
|
return stripTrailingSlashes(requestOrigin);
|
||||||
|
}
|
||||||
|
|
||||||
export type WorkspaceLoginUrlOptions = {
|
export type WorkspaceLoginUrlOptions = {
|
||||||
/**
|
/**
|
||||||
* URL del login del Hub sin `return_to`. Usar en `post_logout_redirect_uri` para que,
|
* URL del login del Hub sin `return_to`. Usar en `post_logout_redirect_uri` para que,
|
||||||
@@ -81,7 +133,10 @@ export function storeReturnPath(cookies: Cookies, path: string): void {
|
|||||||
|
|
||||||
export function getPublicKeycloakBaseUrl(): string {
|
export function getPublicKeycloakBaseUrl(): string {
|
||||||
const configuredKeycloakUrl = (env.VITE_KEYCLOAK_URL || '').trim();
|
const configuredKeycloakUrl = (env.VITE_KEYCLOAK_URL || '').trim();
|
||||||
if (configuredKeycloakUrl) {
|
// Si VITE_KEYCLOAK_URL apunta a un host dev-only (localhost, IP LAN, Docker service),
|
||||||
|
// ignorarlo y derivar la URL del hostname público del Workspace.
|
||||||
|
// Esto protege contra builds donde el .env de dev llega a producción por error.
|
||||||
|
if (configuredKeycloakUrl && !isDevOnlyUrl(configuredKeycloakUrl)) {
|
||||||
return stripTrailingSlashes(configuredKeycloakUrl);
|
return stripTrailingSlashes(configuredKeycloakUrl);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -93,7 +148,7 @@ export function getKeycloakRealm(): string {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export function getKeycloakClientId(): string {
|
export function getKeycloakClientId(): string {
|
||||||
return (env.KEYCLOAK_CLIENT_ID || env.VITE_KEYCLOAK_CLIENT_ID || 'hub-frontend').trim();
|
return (env.KEYCLOAK_CLIENT_ID || env.VITE_KEYCLOAK_CLIENT_ID || 'anexo76-frontend').trim();
|
||||||
}
|
}
|
||||||
|
|
||||||
export function getCleanReturnPath(url: URL): string {
|
export function getCleanReturnPath(url: URL): string {
|
||||||
@@ -133,7 +188,9 @@ export function clearWorkspaceReturnPath(cookies: Cookies): void {
|
|||||||
|
|
||||||
export function buildKeycloakAuthorizationUrl(systemBaseUrl: string, redirectPath: string): string {
|
export function buildKeycloakAuthorizationUrl(systemBaseUrl: string, redirectPath: string): string {
|
||||||
const keycloakBaseUrl = getPublicKeycloakBaseUrl();
|
const keycloakBaseUrl = getPublicKeycloakBaseUrl();
|
||||||
const redirectUri = `${systemBaseUrl}/auth/callback`;
|
// resolveSystemBaseUrl corrige el caso donde url.origin es localhost por ORIGIN env var mal configurado
|
||||||
|
const publicBase = resolveSystemBaseUrl(systemBaseUrl);
|
||||||
|
const redirectUri = `${publicBase}/auth/callback`;
|
||||||
const state = JSON.stringify({ redirect_url: redirectPath });
|
const state = JSON.stringify({ redirect_url: redirectPath });
|
||||||
const params = new URLSearchParams({
|
const params = new URLSearchParams({
|
||||||
client_id: getKeycloakClientId(),
|
client_id: getKeycloakClientId(),
|
||||||
@@ -154,7 +211,9 @@ export function buildKeycloakAuthorizationUrl(systemBaseUrl: string, redirectPat
|
|||||||
*/
|
*/
|
||||||
export function buildKeycloakLoginUrl(systemBaseUrl: string, redirectPath: string): string {
|
export function buildKeycloakLoginUrl(systemBaseUrl: string, redirectPath: string): string {
|
||||||
const keycloakBaseUrl = getPublicKeycloakBaseUrl();
|
const keycloakBaseUrl = getPublicKeycloakBaseUrl();
|
||||||
const redirectUri = `${systemBaseUrl}/auth/callback`;
|
// resolveSystemBaseUrl corrige el caso donde url.origin es localhost por ORIGIN env var mal configurado
|
||||||
|
const publicBase = resolveSystemBaseUrl(systemBaseUrl);
|
||||||
|
const redirectUri = `${publicBase}/auth/callback`;
|
||||||
const state = JSON.stringify({ redirect_url: redirectPath });
|
const state = JSON.stringify({ redirect_url: redirectPath });
|
||||||
const params = new URLSearchParams({
|
const params = new URLSearchParams({
|
||||||
client_id: getKeycloakClientId(),
|
client_id: getKeycloakClientId(),
|
||||||
|
|||||||
@@ -45,8 +45,11 @@ export const load: PageServerLoad = async ({ url, cookies, fetch }) => {
|
|||||||
const KEYCLOAK_CLIENT_ID = process.env.KEYCLOAK_CLIENT_ID || process.env.VITE_KEYCLOAK_CLIENT_ID || 'anexo76-backend';
|
const KEYCLOAK_CLIENT_ID = process.env.KEYCLOAK_CLIENT_ID || process.env.VITE_KEYCLOAK_CLIENT_ID || 'anexo76-backend';
|
||||||
const KEYCLOAK_CLIENT_SECRET = process.env.KEYCLOAK_CLIENT_SECRET || '';
|
const KEYCLOAK_CLIENT_SECRET = process.env.KEYCLOAK_CLIENT_SECRET || '';
|
||||||
|
|
||||||
// La redirect_uri debe coincidir exactamente con la registrada en Keycloak
|
// La redirect_uri debe coincidir exactamente con la registrada en Keycloak.
|
||||||
const redirectUri = `${url.origin}/auth/callback`;
|
// resolveSystemBaseUrl corrige el caso donde url.origin es localhost porque
|
||||||
|
// ORIGIN env var apunta a localhost en producción (usa SITE_URL como fallback).
|
||||||
|
const { resolveSystemBaseUrl } = await import('$lib/server/workspace-auth');
|
||||||
|
const redirectUri = `${resolveSystemBaseUrl(url.origin)}/auth/callback`;
|
||||||
|
|
||||||
const tokenEndpoint = `${KEYCLOAK_URL}/realms/${KEYCLOAK_REALM}/protocol/openid-connect/token`;
|
const tokenEndpoint = `${KEYCLOAK_URL}/realms/${KEYCLOAK_REALM}/protocol/openid-connect/token`;
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user