feat: support d'un chemin de base (BASE_URL) pour reverse proxy
FanKarr supposait jusqu'ici être servi à la racine du domaine. La variable
d'environnement BASE_URL (ex. /fankarr) permet de l'héberger dans un
sous-dossier, sans reconstruire l'image : le préfixe est appliqué au démarrage.
- server/config.ts : BASE_URL normalisée et validée ('' = racine)
- server/index.ts : toutes les routes montées sous BASE_URL via un Router,
index.html servi avec <base href> et window.__BASE_URL__, redirection de /
- server/auth.ts : cookie de session limité au chemin de base
- src/base-url.ts : préfixage des appels fetch('/api/…') en un point unique,
helpers withBase / absoluteUrl
- src/router : createWebHistory(BASE_URL)
- vite.config.ts : base './' (assets relatifs, résolus par <base href>)
Comportement inchangé lorsque BASE_URL n'est pas défini.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
1 parent
e8dc76e94a
commit
be97aa0dea
12 files changed
+163
-35
No files matched your search
+9
-3
@@ -4,7 +4,7 @@ import bcrypt from 'bcryptjs'
|
||||
import jwt from 'jsonwebtoken'
|
||||
import type { Request, Response, NextFunction } from 'express'
|
||||
import { JWT_SECRET } from './secret.js'
|
||||
import { DATA_DIR } from './config.js'
|
||||
import { DATA_DIR, BASE_URL } from './config.js'
|
||||
import { logger } from './logger.js'
|
||||
import {
|
||||
findByUsername, findById, findByApiToken,
|
||||
@@ -26,6 +26,10 @@ const RAW_EXPIRY = process.env.AUTH_TOKEN_EXPIRY ?? '30d'
|
||||
const NO_EXPIRY = RAW_EXPIRY === '0' || RAW_EXPIRY.toLowerCase() === 'never'
|
||||
const TOKEN_EXPIRY: string | undefined = NO_EXPIRY ? undefined : RAW_EXPIRY
|
||||
|
||||
// Le cookie est limité au chemin de base : deux instances derrière le même
|
||||
// domaine (/fankarr, /fankarr-test) ne partagent pas leur session
|
||||
const COOKIE_PATH = BASE_URL || '/'
|
||||
|
||||
function signToken(user: User): string {
|
||||
const payload = { id: user.id, username: user.username, role: user.role }
|
||||
return NO_EXPIRY
|
||||
@@ -36,7 +40,7 @@ function signToken(user: User): string {
|
||||
function setCookieAndRespond(res: Response, user: User): void {
|
||||
user.lastLoginAt = markLogin(user.id) ?? user.lastLoginAt
|
||||
const token = signToken(user)
|
||||
res.cookie('fankarr_token', token, { httpOnly: true, sameSite: 'lax' })
|
||||
res.cookie('fankarr_token', token, { httpOnly: true, sameSite: 'lax', path: COOKIE_PATH })
|
||||
res.json({ success: true, user: safeUser(user) })
|
||||
}
|
||||
|
||||
@@ -118,7 +122,9 @@ export function authLogout(req: Request, res: Response): void {
|
||||
logger.info('auth', `Déconnexion de « ${p.username} »`)
|
||||
} catch {}
|
||||
}
|
||||
res.clearCookie('fankarr_token')
|
||||
res.clearCookie('fankarr_token', { path: COOKIE_PATH })
|
||||
// Cookie éventuellement posé à la racine avant l'activation de BASE_URL
|
||||
if (BASE_URL) res.clearCookie('fankarr_token', { path: '/' })
|
||||
res.json({ success: true })
|
||||
}
|
||||
|
||||
|
||||
Reference in new issue
Block a user