This commit is contained in:
Linus Rath
2026-06-03 19:34:20 +02:00
5 changed files with 33 additions and 9 deletions
+1 -1
View File
@@ -98,7 +98,7 @@ async function migrateAdminJson(): Promise<boolean> {
lastLogin: data.lastLogin ?? null,
passwordChangedAt: data.passwordChangedAt ?? now,
};
const configData: AdminConfigData = { passwordHash: data.passwordHash };
const configData: AdminConfigData = { passwordHash: data.passwordHash, passwordHashFile: undefined };
await ensureStateDir();
const statePath = getStatePath('admin-state.json');
+14 -4
View File
@@ -9,6 +9,7 @@ import {
assertWritable,
} from './paths';
import type { AdminConfigData, AdminStateData } from './types';
import { readFileEnv } from '../read-file-env';
const SCRYPT_KEYLEN = 64;
const SCRYPT_COST = 16384; // 2^14
@@ -146,7 +147,7 @@ export async function initAdminPassword(): Promise<boolean> {
}
const hash = isHashed(envPassword) ? envPassword : await hashPassword(envPassword);
cachedConfig = { passwordHash: hash };
cachedConfig = { passwordHash: hash, passwordHashFile: undefined };
cachedState = freshState();
await writeConfigData(cachedConfig);
await writeStateData(cachedState);
@@ -165,7 +166,16 @@ export async function initAdminPassword(): Promise<boolean> {
export async function verifyAdminPassword(password: string): Promise<boolean> {
if (!cachedConfig) cachedConfig = await readConfigData();
if (!cachedConfig) return false;
return verifyPassword(password, cachedConfig.passwordHash);
if (cachedConfig.passwordHash) {
return verifyPassword(password, cachedConfig.passwordHash);
} else if (cachedConfig.passwordHashFile) {
let passwordHash = readFileEnv(cachedConfig.passwordHashFile);
if (passwordHash) {
return verifyPassword(password, passwordHash);
}
}
logger.error('The admin password hash could neither be retrieved from passwordHash nor from passwordHashFile in admin.json');
return false;
}
/**
@@ -176,7 +186,7 @@ export async function changeAdminPassword(currentPassword: string, newPassword:
if (!valid) return false;
const hash = await hashPassword(newPassword);
cachedConfig = { passwordHash: hash };
cachedConfig = { passwordHash: hash, passwordHashFile: undefined };
await writeConfigData(cachedConfig);
cachedState = {
@@ -205,7 +215,7 @@ export async function setInitialAdminPassword(
const existing = await readConfigData();
if (existing && !options.allowOverwrite) return false;
const hash = await hashPassword(newPassword);
cachedConfig = { passwordHash: hash };
cachedConfig = { passwordHash: hash, passwordHashFile: undefined };
cachedState = freshState();
await writeConfigData(cachedConfig);
await writeStateData(cachedState);
+2 -1
View File
@@ -6,7 +6,8 @@
* is config; mutable timestamps live in AdminStateData.
*/
export interface AdminConfigData {
passwordHash: string;
passwordHash: string | undefined;
passwordHashFile: string | undefined;
}
/**