chore: update docker
This commit is contained in:
@@ -1,18 +1,13 @@
|
||||
import { env, getVaultToken } from '../config/env';
|
||||
import { vaultAppRoleLogin } from '../config/vault';
|
||||
import { fetchJwtKeysFromVault, swapKeyMap, getKeyMapSize } from './jwt.service';
|
||||
import { fetchCsrfConfig, swapCsrfConfig } from './csrf.service';
|
||||
import { logger } from '../lib/logger';
|
||||
import{env}from '../config/env';
|
||||
import{vaultAppRoleLogin}from '../config/vault';
|
||||
import{fetchJwtKeysFromVault,swapKeyMap,getKeyMapSize}from './jwt.service';
|
||||
import{fetchCsrfConfig,swapCsrfConfig}from './csrf.service';
|
||||
import{logger}from '../lib/logger';
|
||||
|
||||
const DEFAULT_INTERVAL_MS = 60 * 60 * 1000; // 1 hour
|
||||
const DEFAULT_INTERVAL_MS = 60 * 60 * 1000;
|
||||
|
||||
let timer: NodeJS.Timeout | null = null;
|
||||
let currentVaultToken: string | null = null;
|
||||
|
||||
/**
|
||||
* Atomic refresh: pre-fetch JWT keys + CSRF config, swap globals only if BOTH succeed.
|
||||
* При любой ошибке оставляем старые значения в памяти, сервис продолжает работать.
|
||||
*/
|
||||
export async function refreshAllKeys(): Promise<void> {
|
||||
const { addr, roleId, secretId, mount, jwtKidPath, jwtKidsPrefix, csrfPath } = env.vault;
|
||||
|
||||
@@ -21,25 +16,17 @@ export async function refreshAllKeys(): Promise<void> {
|
||||
return;
|
||||
}
|
||||
|
||||
// Vault token: используем закэшированный из initEnv, либо логинимся заново
|
||||
let token = currentVaultToken || getVaultToken();
|
||||
const token = await vaultAppRoleLogin(addr, roleId, secretId);
|
||||
if (!token) {
|
||||
const fresh = await vaultAppRoleLogin(addr, roleId, secretId);
|
||||
if (!fresh) {
|
||||
logger.error('Key refresh: Vault AppRole login failed');
|
||||
return;
|
||||
}
|
||||
token = fresh;
|
||||
currentVaultToken = fresh;
|
||||
logger.error('Key refresh: Vault AppRole login failed');
|
||||
return;
|
||||
}
|
||||
|
||||
// ── Pre-fetch обоих секретов параллельно (НЕ мутируя глобал) ───────────
|
||||
const jwtPromise = fetchJwtKeysFromVault(addr, token, mount, jwtKidPath, jwtKidsPrefix);
|
||||
const csrfPromise = csrfPath ? fetchCsrfConfig(addr, token, mount, csrfPath) : Promise.resolve(null);
|
||||
|
||||
const [jwtResult, csrfResult] = await Promise.allSettled([jwtPromise, csrfPromise]);
|
||||
|
||||
// ── Атомарность: если хоть один обязательный fetch упал — НИЧЕГО не меняем ──
|
||||
if (jwtResult.status === 'rejected') {
|
||||
logger.error(`Key refresh ABORTED — JWT keys fetch failed: ${jwtResult.reason?.message || jwtResult.reason}`);
|
||||
return;
|
||||
@@ -49,7 +36,6 @@ export async function refreshAllKeys(): Promise<void> {
|
||||
return;
|
||||
}
|
||||
|
||||
// ── Atomic swap (синхронные операции, нельзя прервать) ──────────────────
|
||||
swapKeyMap(jwtResult.value);
|
||||
if (csrfResult.status === 'fulfilled' && csrfResult.value) {
|
||||
swapCsrfConfig(csrfResult.value);
|
||||
@@ -61,6 +47,7 @@ export async function refreshAllKeys(): Promise<void> {
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
export function startKeyRotation(intervalMs: number = DEFAULT_INTERVAL_MS): void {
|
||||
if (timer) return;
|
||||
timer = setInterval(() => {
|
||||
@@ -68,12 +55,11 @@ export function startKeyRotation(intervalMs: number = DEFAULT_INTERVAL_MS): void
|
||||
void refreshAllKeys().catch((err) =>
|
||||
logger.error(`Key rotation tick failed: ${err?.message || err}`)
|
||||
);
|
||||
// На каждый тик — invalidate Vault token (он мог истечь), будет re-login
|
||||
currentVaultToken = null;
|
||||
}, intervalMs);
|
||||
logger.info(`Key rotation scheduled (every ${intervalMs}ms)`);
|
||||
}
|
||||
|
||||
|
||||
export function stopKeyRotation(): void {
|
||||
if (timer) {
|
||||
clearInterval(timer);
|
||||
|
||||
Reference in New Issue
Block a user