mirror of
https://github.com/immich-app/immich
synced 2026-08-29 13:15:45 +00:00
refactor: encode at point of usage
This commit is contained in:
parent
5c6e04cc8f
commit
8676a042eb
4 changed files with 17 additions and 21 deletions
|
|
@ -49,12 +49,12 @@ export class MaintenanceWorkerRepository implements OnGatewayConnection, OnGatew
|
|||
}
|
||||
|
||||
async exitMaintenanceMode(): Promise<void> {
|
||||
const state: MaintenanceModeState<string> = { isMaintenanceMode: false as const };
|
||||
const state: MaintenanceModeState = { isMaintenanceMode: false as const };
|
||||
await this.systemMetadataRepository.set(SystemMetadataKey.MaintenanceMode, state);
|
||||
this.restartApp(state);
|
||||
}
|
||||
|
||||
async maintenanceSecret(): Promise<Uint8Array> {
|
||||
async maintenanceSecret(): Promise<string> {
|
||||
const result = await this.systemMetadataRepository.get(SystemMetadataKey.MaintenanceMode);
|
||||
if (!result) {
|
||||
throw new Error('Unreachable: Missing metadata for maintenance mode.');
|
||||
|
|
@ -64,7 +64,7 @@ export class MaintenanceWorkerRepository implements OnGatewayConnection, OnGatew
|
|||
throw new Error('Unreachable: Not in maintenance mode.');
|
||||
}
|
||||
|
||||
return new TextEncoder().encode(result.secret);
|
||||
return result.secret;
|
||||
}
|
||||
|
||||
async logSecret(): Promise<void> {
|
||||
|
|
@ -101,7 +101,7 @@ export class MaintenanceWorkerRepository implements OnGatewayConnection, OnGatew
|
|||
|
||||
try {
|
||||
const secret = await this.maintenanceSecret();
|
||||
const result = await jose.jwtVerify<MaintenanceAuthDto>(jwtToken, secret);
|
||||
const result = await jose.jwtVerify<MaintenanceAuthDto>(jwtToken, new TextEncoder().encode(secret));
|
||||
return result.payload;
|
||||
} catch {
|
||||
throw new UnauthorizedException('Invalid JWT Token');
|
||||
|
|
|
|||
|
|
@ -21,17 +21,13 @@ export class MaintenanceRepository {
|
|||
private systemMetadataRepository: SystemMetadataRepository,
|
||||
) {}
|
||||
|
||||
getMaintenanceMode(): Promise<MaintenanceModeState<Uint8Array>> {
|
||||
getMaintenanceMode(): Promise<MaintenanceModeState> {
|
||||
return this.systemMetadataRepository
|
||||
.get(SystemMetadataKey.MaintenanceMode)
|
||||
.then((state) =>
|
||||
state?.isMaintenanceMode
|
||||
? { isMaintenanceMode: true, secret: new TextEncoder().encode(state.secret) }
|
||||
: { isMaintenanceMode: false as const },
|
||||
);
|
||||
.then((state) => state ?? { isMaintenanceMode: false as const });
|
||||
}
|
||||
|
||||
async setMaintenanceMode(state: MaintenanceModeState<string>) {
|
||||
async setMaintenanceMode(state: MaintenanceModeState) {
|
||||
await this.systemMetadataRepository.set(SystemMetadataKey.MaintenanceMode, state);
|
||||
await this.eventRepository.emit('AppRestart', state);
|
||||
}
|
||||
|
|
@ -51,14 +47,14 @@ export class MaintenanceRepository {
|
|||
});
|
||||
}
|
||||
|
||||
async enterMaintenanceMode(): Promise<{ secret: Uint8Array }> {
|
||||
async enterMaintenanceMode(): Promise<{ secret: string }> {
|
||||
const secret = randomBytes(64).toString('hex');
|
||||
const state: MaintenanceModeState<string> = { isMaintenanceMode: true, secret };
|
||||
const state: MaintenanceModeState = { isMaintenanceMode: true, secret };
|
||||
|
||||
await this.systemMetadataRepository.set(SystemMetadataKey.MaintenanceMode, state);
|
||||
await this.eventRepository.emit('AppRestart', state);
|
||||
|
||||
return { secret: new TextEncoder().encode(secret) };
|
||||
return { secret };
|
||||
}
|
||||
|
||||
exitApp() {
|
||||
|
|
@ -70,7 +66,7 @@ export class MaintenanceRepository {
|
|||
/* eslint-enable unicorn/no-process-exit */
|
||||
}
|
||||
|
||||
async createLoginUrl(baseUrl: string, auth: MaintenanceAuthDto, secret?: Uint8Array) {
|
||||
async createLoginUrl(baseUrl: string, auth: MaintenanceAuthDto, secret?: string) {
|
||||
secret ??= await this.getMaintenanceMode().then((state) => {
|
||||
if (!state.isMaintenanceMode) {
|
||||
throw new Error('Not in maintenance mode.');
|
||||
|
|
@ -82,18 +78,18 @@ export class MaintenanceRepository {
|
|||
return await MaintenanceRepository.createLoginUrl(baseUrl, auth, secret!);
|
||||
}
|
||||
|
||||
static async createLoginUrl(baseUrl: string, auth: MaintenanceAuthDto, secret: Uint8Array) {
|
||||
static async createLoginUrl(baseUrl: string, auth: MaintenanceAuthDto, secret: string) {
|
||||
return `${baseUrl}/maintenance?token=${encodeURIComponent(await MaintenanceRepository.createJwt(secret!, auth))}`;
|
||||
}
|
||||
|
||||
static async createJwt(secret: Uint8Array, data: MaintenanceAuthDto) {
|
||||
static async createJwt(secret: string, data: MaintenanceAuthDto) {
|
||||
const alg = 'HS256';
|
||||
|
||||
return await new SignJWT({ ...data })
|
||||
.setProtectedHeader({ alg })
|
||||
.setIssuedAt()
|
||||
.setExpirationTime('4h')
|
||||
.sign(secret);
|
||||
.sign(new TextEncoder().encode(secret));
|
||||
}
|
||||
|
||||
setCloseFn(fn: () => Promise<void>) {
|
||||
|
|
|
|||
|
|
@ -7,7 +7,7 @@ import { BaseService } from 'src/services/base.service';
|
|||
*/
|
||||
@Injectable()
|
||||
export class MaintenanceService extends BaseService {
|
||||
async startMaintenance(): Promise<{ secret: Uint8Array }> {
|
||||
async startMaintenance(): Promise<{ secret: string }> {
|
||||
const { isMaintenanceMode } = await this.maintenanceRepository.getMaintenanceMode();
|
||||
if (isMaintenanceMode) {
|
||||
throw new BadRequestException('Already in maintenance mode');
|
||||
|
|
|
|||
|
|
@ -469,7 +469,7 @@ export interface MemoryData {
|
|||
|
||||
export type VersionCheckMetadata = { checkedAt: string; releaseVersion: string };
|
||||
export type SystemFlags = { mountChecks: Record<StorageFolder, boolean> };
|
||||
export type MaintenanceModeState<S> = { isMaintenanceMode: true; secret: S } | { isMaintenanceMode: false };
|
||||
export type MaintenanceModeState = { isMaintenanceMode: true; secret: string } | { isMaintenanceMode: false };
|
||||
export type MemoriesState = {
|
||||
/** memories have already been created through this date */
|
||||
lastOnThisDayDate: string;
|
||||
|
|
@ -480,7 +480,7 @@ export interface SystemMetadata extends Record<SystemMetadataKey, Record<string,
|
|||
[SystemMetadataKey.AdminOnboarding]: { isOnboarded: boolean };
|
||||
[SystemMetadataKey.FacialRecognitionState]: { lastRun?: string };
|
||||
[SystemMetadataKey.License]: { licenseKey: string; activationKey: string; activatedAt: Date };
|
||||
[SystemMetadataKey.MaintenanceMode]: MaintenanceModeState<string>;
|
||||
[SystemMetadataKey.MaintenanceMode]: MaintenanceModeState;
|
||||
[SystemMetadataKey.MediaLocation]: MediaLocation;
|
||||
[SystemMetadataKey.ReverseGeocodingState]: { lastUpdate?: string; lastImportFileName?: string };
|
||||
[SystemMetadataKey.SystemConfig]: DeepPartial<SystemConfig>;
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue