diff --git a/server/auth.ts b/server/auth.ts index 647724d..b5774b7 100644 --- a/server/auth.ts +++ b/server/auth.ts @@ -3,9 +3,9 @@ import path from 'path' import bcrypt from 'bcrypt' import jwt from 'jsonwebtoken' import type { Request, Response, NextFunction } from 'express' +import { JWT_SECRET } from './secret.js' const DATA_PATH = path.join(process.cwd(), 'data', 'auth.json') -const JWT_SECRET = process.env.JWT_SECRET || 'fankarr-secret-change-me' const SALT_ROUNDS = 10 interface AuthData { @@ -63,7 +63,7 @@ export function authSetup(req: Request, res: Response): void { const passwordHash = bcrypt.hashSync(password, SALT_ROUNDS) writeAuth({ username, passwordHash }) - const token = jwt.sign({ username }, JWT_SECRET, { expiresIn: '30d' }) + const token = jwt.sign({ username }, JWT_SECRET, { expiresIn: '1d' }) res.cookie('fankarr_token', token, { httpOnly: true, sameSite: 'lax' }) res.json({ success: true }) } @@ -87,7 +87,7 @@ export function authLogin(req: Request, res: Response): void { return } - const token = jwt.sign({ username }, JWT_SECRET, { expiresIn: '30d' }) + const token = jwt.sign({ username }, JWT_SECRET, { expiresIn: '1d' }) res.cookie('fankarr_token', token, { httpOnly: true, sameSite: 'lax' }) res.json({ success: true }) } diff --git a/server/secret.ts b/server/secret.ts new file mode 100644 index 0000000..80544b7 --- /dev/null +++ b/server/secret.ts @@ -0,0 +1,44 @@ +/** + * secret.ts + * ========= + * Génère et persiste le JWT secret dans data/secret.key + * Si JWT_SECRET est défini en variable d'environnement, il est utilisé tel quel. + * Sinon, on lit data/secret.key — s'il n'existe pas, on en génère un et on le sauvegarde. + */ + +import fs from 'fs' +import path from 'path' +import crypto from 'crypto' + +const SECRET_PATH = path.join(process.cwd(), 'data', 'secret.key') + +function generateSecret(): string { + return crypto.randomBytes(48).toString('hex') +} + +function loadOrCreateSecret(): string { + // 1. Variable d'environnement — priorité absolue + if (process.env.JWT_SECRET && process.env.JWT_SECRET !== 'fankarr-secret-change-me') { + return process.env.JWT_SECRET + } + + // 2. Fichier existant + if (fs.existsSync(SECRET_PATH)) { + const secret = fs.readFileSync(SECRET_PATH, 'utf-8').trim() + if (secret.length > 0) return secret + } + + // 3. Génération + sauvegarde + const secret = generateSecret() + try { + fs.mkdirSync(path.dirname(SECRET_PATH), { recursive: true }) + fs.writeFileSync(SECRET_PATH, secret, { encoding: 'utf-8', mode: 0o600 }) + console.log('[auth] JWT secret généré et sauvegardé dans data/secret.key') + } catch (err) { + console.error('[auth] Impossible de sauvegarder le secret:', err) + } + + return secret +} + +export const JWT_SECRET: string = loadOrCreateSecret() \ No newline at end of file diff --git a/src/views/SerieView.vue b/src/views/SerieView.vue index 3850149..0e20ac5 100644 --- a/src/views/SerieView.vue +++ b/src/views/SerieView.vue @@ -273,7 +273,7 @@ async function download(key: string, torrent_url: string | null, magnet: string downloading.value = key const result = await store.download(torrent_url, magnet) downloading.value = null - if (result.success) showToast('success', 'Ajouté à qBittorrent !') + if (result.success) showToast('success', 'Téléchargement lancé') else showToast('error', result.error ?? 'Erreur inconnue') }