diff --git a/packages/cli/src/services/user.service.ts b/packages/cli/src/services/user.service.ts index 2500d9cfe5..c19e98eb0c 100644 --- a/packages/cli/src/services/user.service.ts +++ b/packages/cli/src/services/user.service.ts @@ -125,7 +125,8 @@ export class UserService { user: User, options?: { withInviteUrl?: boolean; posthog?: PostHogClient; withScopes?: boolean }, ) { - const { password, updatedAt, apiKey, authIdentities, ...rest } = user; + const { password, updatedAt, apiKey, authIdentities, mfaRecoveryCodes, mfaSecret, ...rest } = + user; const ldapIdentity = authIdentities?.find((i) => i.providerType === 'ldap'); diff --git a/packages/cli/test/integration/auth.api.test.ts b/packages/cli/test/integration/auth.api.test.ts index 4044482be6..ab3f3a8dd3 100644 --- a/packages/cli/test/integration/auth.api.test.ts +++ b/packages/cli/test/integration/auth.api.test.ts @@ -12,6 +12,7 @@ import * as utils from './shared/utils/'; import { getGlobalMemberRole, getGlobalOwnerRole } from './shared/db/roles'; import { createUser, createUserShell } from './shared/db/users'; import { UserRepository } from '@db/repositories/user.repository'; +import { MfaService } from '@/Mfa/mfa.service'; let globalOwnerRole: Role; let globalMemberRole: Role; @@ -22,9 +23,12 @@ const ownerPassword = randomValidPassword(); const testServer = utils.setupTestServer({ endpointGroups: ['auth'] }); const license = testServer.license; +let mfaService: MfaService; + beforeAll(async () => { globalOwnerRole = await getGlobalOwnerRole(); globalMemberRole = await getGlobalMemberRole(); + mfaService = Container.get(MfaService); }); beforeEach(async () => { @@ -59,6 +63,8 @@ describe('POST /login', () => { globalRole, apiKey, globalScopes, + mfaSecret, + mfaRecoveryCodes, } = response.body.data; expect(validator.isUUID(id)).toBe(true); @@ -73,6 +79,53 @@ describe('POST /login', () => { expect(globalRole.scope).toBe('global'); expect(apiKey).toBeUndefined(); expect(globalScopes).toBeDefined(); + expect(mfaRecoveryCodes).toBeUndefined(); + expect(mfaSecret).toBeUndefined(); + + const authToken = utils.getAuthToken(response); + expect(authToken).toBeDefined(); + }); + + test('should log user with MFA enabled', async () => { + const secret = 'test'; + const recoveryCodes = ['1']; + await mfaService.saveSecretAndRecoveryCodes(owner.id, secret, recoveryCodes); + await mfaService.enableMfa(owner.id); + + const response = await testServer.authlessAgent.post('/login').send({ + email: owner.email, + password: ownerPassword, + mfaToken: mfaService.totp.generateTOTP(secret), + }); + + expect(response.statusCode).toBe(200); + + const { + id, + email, + firstName, + lastName, + password, + personalizationAnswers, + globalRole, + apiKey, + mfaRecoveryCodes, + mfaSecret, + } = response.body.data; + + expect(validator.isUUID(id)).toBe(true); + expect(email).toBe(owner.email); + expect(firstName).toBe(owner.firstName); + expect(lastName).toBe(owner.lastName); + expect(password).toBeUndefined(); + expect(personalizationAnswers).toBeNull(); + expect(password).toBeUndefined(); + expect(globalRole).toBeDefined(); + expect(globalRole.name).toBe('owner'); + expect(globalRole.scope).toBe('global'); + expect(apiKey).toBeUndefined(); + expect(mfaRecoveryCodes).toBeUndefined(); + expect(mfaSecret).toBeUndefined(); const authToken = utils.getAuthToken(response); expect(authToken).toBeDefined();