Oprava: aplikace padala pri startu v produkcnim rezimu
Dockerfile nastavuje NODE_ENV=production a config.ts pri chybejicim JWT_SECRET vyhazoval vyjimku. AppFactory tu promennou nastavenou nema, takze se container po startu ukoncil a sluzba byla nedostupna (502). Chybejici JWT_SECRET uz start neshodi. Vygeneruje se nahodny klic platny do restartu containeru a do logu jde varovani. Klic zapsany v kodu se nepouziva, aby nevznikla bezpecnostni dira. Dusledek: bez nastavene promenne prestanou po restartu platit vydane tokeny. JWT_SECRET se ma nastavit jako promenna aplikace v AppFactory.
This commit is contained in:
@@ -0,0 +1 @@
|
||||
[config] JWT_SECRET neni nastavena. Pouzivam nahodny klic platny jen do restartu containeru. Nastavte JWT_SECRET jako promennou aplikace v AppFactory.
|
||||
@@ -0,0 +1,4 @@
|
||||
[start] csbot-prototype bezi na portu 3000
|
||||
[start] ROOT_PATH: /apps/csbot-prototype
|
||||
[start] health: /apps/csbot-prototype/health, docs: /apps/csbot-prototype/docs
|
||||
[req] GET /health
|
||||
+27
-9
@@ -2,19 +2,37 @@
|
||||
* Konfigurace z environment variables.
|
||||
* AppFactory je predava containeru, viz AGENTS.md, sekce Variables a secrets.
|
||||
* Zadna hodnota se nehardcoduje a zadny secret se neloguje.
|
||||
*
|
||||
* Pravidlo: chybejici konfigurace nesmi shodit start aplikace. Container,
|
||||
* ktery nenastartuje, je pro AppFactory nefunkcni sluzba.
|
||||
*/
|
||||
|
||||
import { randomBytes } from 'node:crypto';
|
||||
|
||||
const isProduction = process.env.NODE_ENV === 'production';
|
||||
|
||||
function requiredInProduction(name: string, fallback: string): string {
|
||||
const value = process.env[name];
|
||||
/**
|
||||
* Tajny klic pro podpis tokenu.
|
||||
*
|
||||
* Kdyz promenna chybi, NEPADAME a ani nepouzijeme klic zapsany v kodu.
|
||||
* Aplikace musi nastartovat a odpovidat na /health, jinak ji AppFactory
|
||||
* vyhodnoti jako nefunkcni. Misto toho se vygeneruje nahodny klic pro
|
||||
* beh procesu a do logu jde hlasite varovani.
|
||||
*
|
||||
* Dusledek: po restartu containeru prestanou platit vydane tokeny
|
||||
* a uzivatele se musi prihlasit znovu. Proto se JWT_SECRET ma nastavit
|
||||
* jako promenna aplikace v AppFactory.
|
||||
*/
|
||||
function resolveJwtSecret(): string {
|
||||
const value = process.env.JWT_SECRET;
|
||||
if (value && value.trim().length > 0) return value;
|
||||
if (isProduction) {
|
||||
// Zamerne padame pri startu - tichy fallback na dev secret by byl bezpecnostni dira.
|
||||
throw new Error(`Chybi povinna promenna prostredi ${name} (NODE_ENV=production).`);
|
||||
}
|
||||
console.warn(`[config] ${name} neni nastavena, pouzivam DEV fallback. Nepouzivat v produkci.`);
|
||||
return fallback;
|
||||
|
||||
const generated = randomBytes(32).toString('base64url');
|
||||
console.warn(
|
||||
'[config] JWT_SECRET neni nastavena. Pouzivam nahodny klic platny jen do restartu ' +
|
||||
'containeru. Nastavte JWT_SECRET jako promennou aplikace v AppFactory.',
|
||||
);
|
||||
return generated;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -34,7 +52,7 @@ export const config = {
|
||||
/** Port urcuje AppFactory sablona, vychozi 3000. Nemenit bez upravy metadat. */
|
||||
port: Number(process.env.PORT ?? 3000),
|
||||
rootPath: normalizeRootPath(process.env.ROOT_PATH),
|
||||
jwtSecret: requiredInProduction('JWT_SECRET', 'dev-only-secret-nepouzivat-v-produkci'),
|
||||
jwtSecret: resolveJwtSecret(),
|
||||
jwtExpiresIn: process.env.JWT_EXPIRES_IN ?? '8h',
|
||||
/**
|
||||
* Povolene originy pro CORS. V nasazeni bezi web i API na stejne domene,
|
||||
|
||||
Reference in New Issue
Block a user