From d582ec02b1b763b3de64deaaa26ac8529f976713 Mon Sep 17 00:00:00 2001
From: Michel Heusschen <59014050+michelheusschen@users.noreply.github.com>
Date: Sun, 7 Jul 2024 13:20:28 +0200
Subject: [PATCH] fix(server): reset-admin-password command (#10939)

* fix(server): reset-admin-password command

* fix immichCli
---
 .../specs/immich-admin.e2e-spec.ts            | 21 ++++++++++++++++++-
 e2e/src/utils.ts                              |  6 +++---
 server/src/dtos/user.dto.ts                   |  2 +-
 3 files changed, 24 insertions(+), 5 deletions(-)

diff --git a/e2e/src/immich-admin/specs/immich-admin.e2e-spec.ts b/e2e/src/immich-admin/specs/immich-admin.e2e-spec.ts
index 707093ab25..d025b7a338 100644
--- a/e2e/src/immich-admin/specs/immich-admin.e2e-spec.ts
+++ b/e2e/src/immich-admin/specs/immich-admin.e2e-spec.ts
@@ -9,11 +9,30 @@ describe(`immich-admin`, () => {
 
   describe('list-users', () => {
     it('should list the admin user', async () => {
-      const { stdout, stderr, exitCode } = await immichAdmin(['list-users']);
+      const { stdout, stderr, exitCode } = await immichAdmin(['list-users']).promise;
       expect(exitCode).toBe(0);
       expect(stderr).toBe('');
       expect(stdout).toContain("email: 'admin@immich.cloud'");
       expect(stdout).toContain("name: 'Immich Admin'");
     });
   });
+
+  describe('reset-admin-password', () => {
+    it('should reset admin password', async () => {
+      const { child, promise } = immichAdmin(['reset-admin-password']);
+
+      let data = '';
+      child.stdout.on('data', (chunk) => {
+        data += chunk;
+        if (data.includes('Please choose a new password (optional)')) {
+          child.stdin.end('\n');
+        }
+      });
+
+      const { stderr, stdout, exitCode } = await promise;
+      expect(exitCode).toBe(0);
+      expect(stderr).toBe('');
+      expect(stdout).toContain('The admin password has been updated to:');
+    });
+  });
 });
diff --git a/e2e/src/utils.ts b/e2e/src/utils.ts
index e018e87b59..d58fbe0b69 100644
--- a/e2e/src/utils.ts
+++ b/e2e/src/utils.ts
@@ -64,13 +64,13 @@ export const tempDir = tmpdir();
 export const asBearerAuth = (accessToken: string) => ({ Authorization: `Bearer ${accessToken}` });
 export const asKeyAuth = (key: string) => ({ 'x-api-key': key });
 export const immichCli = (args: string[]) =>
-  executeCommand('node', ['node_modules/.bin/immich', '-d', `/${tempDir}/immich/`, ...args]);
+  executeCommand('node', ['node_modules/.bin/immich', '-d', `/${tempDir}/immich/`, ...args]).promise;
 export const immichAdmin = (args: string[]) =>
   executeCommand('docker', ['exec', '-i', 'immich-e2e-server', '/bin/bash', '-c', `immich-admin ${args.join(' ')}`]);
 
 const executeCommand = (command: string, args: string[]) => {
   let _resolve: (value: CommandResponse) => void;
-  const deferred = new Promise<CommandResponse>((resolve) => (_resolve = resolve));
+  const promise = new Promise<CommandResponse>((resolve) => (_resolve = resolve));
   const child = spawn(command, args, { stdio: 'pipe' });
 
   let stdout = '';
@@ -86,7 +86,7 @@ const executeCommand = (command: string, args: string[]) => {
     });
   });
 
-  return deferred;
+  return { promise, child };
 };
 
 let client: pg.Client | null = null;
diff --git a/server/src/dtos/user.dto.ts b/server/src/dtos/user.dto.ts
index ce9ff5c99f..54020a7397 100644
--- a/server/src/dtos/user.dto.ts
+++ b/server/src/dtos/user.dto.ts
@@ -140,7 +140,7 @@ export class UserAdminResponseDto extends UserResponseDto {
 }
 
 export function mapUserAdmin(entity: UserEntity): UserAdminResponseDto {
-  const license = entity.metadata.find(
+  const license = entity.metadata?.find(
     (item): item is UserMetadataEntity<UserMetadataKey.LICENSE> => item.key === UserMetadataKey.LICENSE,
   )?.value;
   return {