|
@@ -11,7 +11,10 @@ import { User } from '../../User/User'
|
|
import { UserRepositoryInterface } from '../../User/UserRepositoryInterface'
|
|
import { UserRepositoryInterface } from '../../User/UserRepositoryInterface'
|
|
|
|
|
|
import { ChangeCredentials } from './ChangeCredentials'
|
|
import { ChangeCredentials } from './ChangeCredentials'
|
|
-import { Username } from '@standardnotes/domain-core'
|
|
|
|
|
|
+import { Result, Username } from '@standardnotes/domain-core'
|
|
|
|
+import { DeleteOtherSessionsForUser } from '../DeleteOtherSessionsForUser'
|
|
|
|
+import { ApiVersion } from '../../Api/ApiVersion'
|
|
|
|
+import { Session } from '../../Session/Session'
|
|
|
|
|
|
describe('ChangeCredentials', () => {
|
|
describe('ChangeCredentials', () => {
|
|
let userRepository: UserRepositoryInterface
|
|
let userRepository: UserRepositoryInterface
|
|
@@ -21,13 +24,23 @@ describe('ChangeCredentials', () => {
|
|
let domainEventFactory: DomainEventFactoryInterface
|
|
let domainEventFactory: DomainEventFactoryInterface
|
|
let timer: TimerInterface
|
|
let timer: TimerInterface
|
|
let user: User
|
|
let user: User
|
|
|
|
+ let deleteOtherSessionsForUser: DeleteOtherSessionsForUser
|
|
|
|
|
|
const createUseCase = () =>
|
|
const createUseCase = () =>
|
|
- new ChangeCredentials(userRepository, authResponseFactoryResolver, domainEventPublisher, domainEventFactory, timer)
|
|
|
|
|
|
+ new ChangeCredentials(
|
|
|
|
+ userRepository,
|
|
|
|
+ authResponseFactoryResolver,
|
|
|
|
+ domainEventPublisher,
|
|
|
|
+ domainEventFactory,
|
|
|
|
+ timer,
|
|
|
|
+ deleteOtherSessionsForUser,
|
|
|
|
+ )
|
|
|
|
|
|
beforeEach(() => {
|
|
beforeEach(() => {
|
|
authResponseFactory = {} as jest.Mocked<AuthResponseFactoryInterface>
|
|
authResponseFactory = {} as jest.Mocked<AuthResponseFactoryInterface>
|
|
- authResponseFactory.createResponse = jest.fn().mockReturnValue({ foo: 'bar' })
|
|
|
|
|
|
+ authResponseFactory.createResponse = jest
|
|
|
|
+ .fn()
|
|
|
|
+ .mockReturnValue({ response: { foo: 'bar' }, session: { uuid: '1-2-3' } as jest.Mocked<Session> })
|
|
|
|
|
|
authResponseFactoryResolver = {} as jest.Mocked<AuthResponseFactoryResolverInterface>
|
|
authResponseFactoryResolver = {} as jest.Mocked<AuthResponseFactoryResolverInterface>
|
|
authResponseFactoryResolver.resolveAuthResponseFactoryVersion = jest.fn().mockReturnValue(authResponseFactory)
|
|
authResponseFactoryResolver.resolveAuthResponseFactoryVersion = jest.fn().mockReturnValue(authResponseFactory)
|
|
@@ -49,27 +62,25 @@ describe('ChangeCredentials', () => {
|
|
|
|
|
|
timer = {} as jest.Mocked<TimerInterface>
|
|
timer = {} as jest.Mocked<TimerInterface>
|
|
timer.getUTCDate = jest.fn().mockReturnValue(new Date(1))
|
|
timer.getUTCDate = jest.fn().mockReturnValue(new Date(1))
|
|
|
|
+
|
|
|
|
+ deleteOtherSessionsForUser = {} as jest.Mocked<DeleteOtherSessionsForUser>
|
|
|
|
+ deleteOtherSessionsForUser.execute = jest.fn().mockReturnValue(Result.ok())
|
|
})
|
|
})
|
|
|
|
|
|
it('should change password', async () => {
|
|
it('should change password', async () => {
|
|
- expect(
|
|
|
|
- await createUseCase().execute({
|
|
|
|
- username: Username.create('test@test.te').getValue(),
|
|
|
|
- apiVersion: '20190520',
|
|
|
|
- currentPassword: 'qweqwe123123',
|
|
|
|
- newPassword: 'test234',
|
|
|
|
- pwNonce: 'asdzxc',
|
|
|
|
- updatedWithUserAgent: 'Google Chrome',
|
|
|
|
- kpCreated: '123',
|
|
|
|
- kpOrigination: 'password-change',
|
|
|
|
- }),
|
|
|
|
- ).toEqual({
|
|
|
|
- success: true,
|
|
|
|
- authResponse: {
|
|
|
|
- foo: 'bar',
|
|
|
|
- },
|
|
|
|
|
|
+ const result = await createUseCase().execute({
|
|
|
|
+ username: Username.create('test@test.te').getValue(),
|
|
|
|
+ apiVersion: ApiVersion.v20200115,
|
|
|
|
+ currentPassword: 'qweqwe123123',
|
|
|
|
+ newPassword: 'test234',
|
|
|
|
+ pwNonce: 'asdzxc',
|
|
|
|
+ updatedWithUserAgent: 'Google Chrome',
|
|
|
|
+ kpCreated: '123',
|
|
|
|
+ kpOrigination: 'password-change',
|
|
})
|
|
})
|
|
|
|
|
|
|
|
+ expect(result.isFailed()).toBeFalsy()
|
|
|
|
+
|
|
expect(userRepository.save).toHaveBeenCalledWith({
|
|
expect(userRepository.save).toHaveBeenCalledWith({
|
|
encryptedPassword: expect.any(String),
|
|
encryptedPassword: expect.any(String),
|
|
pwNonce: 'asdzxc',
|
|
pwNonce: 'asdzxc',
|
|
@@ -81,29 +92,24 @@ describe('ChangeCredentials', () => {
|
|
})
|
|
})
|
|
expect(domainEventPublisher.publish).not.toHaveBeenCalled()
|
|
expect(domainEventPublisher.publish).not.toHaveBeenCalled()
|
|
expect(domainEventFactory.createUserEmailChangedEvent).not.toHaveBeenCalled()
|
|
expect(domainEventFactory.createUserEmailChangedEvent).not.toHaveBeenCalled()
|
|
|
|
+ expect(deleteOtherSessionsForUser.execute).toHaveBeenCalled()
|
|
})
|
|
})
|
|
|
|
|
|
it('should change email', async () => {
|
|
it('should change email', async () => {
|
|
userRepository.findOneByUsernameOrEmail = jest.fn().mockReturnValueOnce(user).mockReturnValueOnce(null)
|
|
userRepository.findOneByUsernameOrEmail = jest.fn().mockReturnValueOnce(user).mockReturnValueOnce(null)
|
|
|
|
|
|
- expect(
|
|
|
|
- await createUseCase().execute({
|
|
|
|
- username: Username.create('test@test.te').getValue(),
|
|
|
|
- apiVersion: '20190520',
|
|
|
|
- currentPassword: 'qweqwe123123',
|
|
|
|
- newPassword: 'test234',
|
|
|
|
- newEmail: 'new@test.te',
|
|
|
|
- pwNonce: 'asdzxc',
|
|
|
|
- updatedWithUserAgent: 'Google Chrome',
|
|
|
|
- kpCreated: '123',
|
|
|
|
- kpOrigination: 'password-change',
|
|
|
|
- }),
|
|
|
|
- ).toEqual({
|
|
|
|
- success: true,
|
|
|
|
- authResponse: {
|
|
|
|
- foo: 'bar',
|
|
|
|
- },
|
|
|
|
|
|
+ const result = await createUseCase().execute({
|
|
|
|
+ username: Username.create('test@test.te').getValue(),
|
|
|
|
+ apiVersion: ApiVersion.v20200115,
|
|
|
|
+ currentPassword: 'qweqwe123123',
|
|
|
|
+ newPassword: 'test234',
|
|
|
|
+ newEmail: 'new@test.te',
|
|
|
|
+ pwNonce: 'asdzxc',
|
|
|
|
+ updatedWithUserAgent: 'Google Chrome',
|
|
|
|
+ kpCreated: '123',
|
|
|
|
+ kpOrigination: 'password-change',
|
|
})
|
|
})
|
|
|
|
+ expect(result.isFailed()).toBeFalsy()
|
|
|
|
|
|
expect(userRepository.save).toHaveBeenCalledWith({
|
|
expect(userRepository.save).toHaveBeenCalledWith({
|
|
encryptedPassword: expect.any(String),
|
|
encryptedPassword: expect.any(String),
|
|
@@ -116,6 +122,7 @@ describe('ChangeCredentials', () => {
|
|
})
|
|
})
|
|
expect(domainEventFactory.createUserEmailChangedEvent).toHaveBeenCalledWith('1-2-3', 'test@test.te', 'new@test.te')
|
|
expect(domainEventFactory.createUserEmailChangedEvent).toHaveBeenCalledWith('1-2-3', 'test@test.te', 'new@test.te')
|
|
expect(domainEventPublisher.publish).toHaveBeenCalled()
|
|
expect(domainEventPublisher.publish).toHaveBeenCalled()
|
|
|
|
+ expect(deleteOtherSessionsForUser.execute).toHaveBeenCalled()
|
|
})
|
|
})
|
|
|
|
|
|
it('should not change email if already taken', async () => {
|
|
it('should not change email if already taken', async () => {
|
|
@@ -124,22 +131,19 @@ describe('ChangeCredentials', () => {
|
|
.mockReturnValueOnce(user)
|
|
.mockReturnValueOnce(user)
|
|
.mockReturnValueOnce({} as jest.Mocked<User>)
|
|
.mockReturnValueOnce({} as jest.Mocked<User>)
|
|
|
|
|
|
- expect(
|
|
|
|
- await createUseCase().execute({
|
|
|
|
- username: Username.create('test@test.te').getValue(),
|
|
|
|
- apiVersion: '20190520',
|
|
|
|
- currentPassword: 'qweqwe123123',
|
|
|
|
- newPassword: 'test234',
|
|
|
|
- newEmail: 'new@test.te',
|
|
|
|
- pwNonce: 'asdzxc',
|
|
|
|
- updatedWithUserAgent: 'Google Chrome',
|
|
|
|
- kpCreated: '123',
|
|
|
|
- kpOrigination: 'password-change',
|
|
|
|
- }),
|
|
|
|
- ).toEqual({
|
|
|
|
- success: false,
|
|
|
|
- errorMessage: 'The email you entered is already taken. Please try again.',
|
|
|
|
|
|
+ const result = await createUseCase().execute({
|
|
|
|
+ username: Username.create('test@test.te').getValue(),
|
|
|
|
+ apiVersion: ApiVersion.v20200115,
|
|
|
|
+ currentPassword: 'qweqwe123123',
|
|
|
|
+ newPassword: 'test234',
|
|
|
|
+ newEmail: 'new@test.te',
|
|
|
|
+ pwNonce: 'asdzxc',
|
|
|
|
+ updatedWithUserAgent: 'Google Chrome',
|
|
|
|
+ kpCreated: '123',
|
|
|
|
+ kpOrigination: 'password-change',
|
|
})
|
|
})
|
|
|
|
+ expect(result.isFailed()).toBeTruthy()
|
|
|
|
+ expect(result.getError()).toEqual('The email you entered is already taken. Please try again.')
|
|
|
|
|
|
expect(userRepository.save).not.toHaveBeenCalled()
|
|
expect(userRepository.save).not.toHaveBeenCalled()
|
|
expect(domainEventFactory.createUserEmailChangedEvent).not.toHaveBeenCalled()
|
|
expect(domainEventFactory.createUserEmailChangedEvent).not.toHaveBeenCalled()
|
|
@@ -147,22 +151,19 @@ describe('ChangeCredentials', () => {
|
|
})
|
|
})
|
|
|
|
|
|
it('should not change email if the new email is invalid', async () => {
|
|
it('should not change email if the new email is invalid', async () => {
|
|
- expect(
|
|
|
|
- await createUseCase().execute({
|
|
|
|
- username: Username.create('test@test.te').getValue(),
|
|
|
|
- apiVersion: '20190520',
|
|
|
|
- currentPassword: 'qweqwe123123',
|
|
|
|
- newPassword: 'test234',
|
|
|
|
- newEmail: '',
|
|
|
|
- pwNonce: 'asdzxc',
|
|
|
|
- updatedWithUserAgent: 'Google Chrome',
|
|
|
|
- kpCreated: '123',
|
|
|
|
- kpOrigination: 'password-change',
|
|
|
|
- }),
|
|
|
|
- ).toEqual({
|
|
|
|
- success: false,
|
|
|
|
- errorMessage: 'Username cannot be empty',
|
|
|
|
|
|
+ const result = await createUseCase().execute({
|
|
|
|
+ username: Username.create('test@test.te').getValue(),
|
|
|
|
+ apiVersion: ApiVersion.v20200115,
|
|
|
|
+ currentPassword: 'qweqwe123123',
|
|
|
|
+ newPassword: 'test234',
|
|
|
|
+ newEmail: '',
|
|
|
|
+ pwNonce: 'asdzxc',
|
|
|
|
+ updatedWithUserAgent: 'Google Chrome',
|
|
|
|
+ kpCreated: '123',
|
|
|
|
+ kpOrigination: 'password-change',
|
|
})
|
|
})
|
|
|
|
+ expect(result.isFailed()).toBeTruthy()
|
|
|
|
+ expect(result.getError()).toEqual('Username cannot be empty')
|
|
|
|
|
|
expect(userRepository.save).not.toHaveBeenCalled()
|
|
expect(userRepository.save).not.toHaveBeenCalled()
|
|
expect(domainEventFactory.createUserEmailChangedEvent).not.toHaveBeenCalled()
|
|
expect(domainEventFactory.createUserEmailChangedEvent).not.toHaveBeenCalled()
|
|
@@ -172,63 +173,52 @@ describe('ChangeCredentials', () => {
|
|
it('should not change email if the user is not found', async () => {
|
|
it('should not change email if the user is not found', async () => {
|
|
userRepository.findOneByUsernameOrEmail = jest.fn().mockReturnValue(null)
|
|
userRepository.findOneByUsernameOrEmail = jest.fn().mockReturnValue(null)
|
|
|
|
|
|
- expect(
|
|
|
|
- await createUseCase().execute({
|
|
|
|
- username: Username.create('test@test.te').getValue(),
|
|
|
|
- apiVersion: '20190520',
|
|
|
|
- currentPassword: 'qweqwe123123',
|
|
|
|
- newPassword: 'test234',
|
|
|
|
- newEmail: '',
|
|
|
|
- pwNonce: 'asdzxc',
|
|
|
|
- updatedWithUserAgent: 'Google Chrome',
|
|
|
|
- kpCreated: '123',
|
|
|
|
- kpOrigination: 'password-change',
|
|
|
|
- }),
|
|
|
|
- ).toEqual({
|
|
|
|
- success: false,
|
|
|
|
- errorMessage: 'User not found.',
|
|
|
|
|
|
+ const result = await createUseCase().execute({
|
|
|
|
+ username: Username.create('test@test.te').getValue(),
|
|
|
|
+ apiVersion: ApiVersion.v20200115,
|
|
|
|
+ currentPassword: 'qweqwe123123',
|
|
|
|
+ newPassword: 'test234',
|
|
|
|
+ newEmail: '',
|
|
|
|
+ pwNonce: 'asdzxc',
|
|
|
|
+ updatedWithUserAgent: 'Google Chrome',
|
|
|
|
+ kpCreated: '123',
|
|
|
|
+ kpOrigination: 'password-change',
|
|
})
|
|
})
|
|
|
|
|
|
|
|
+ expect(result.isFailed()).toBeTruthy()
|
|
|
|
+ expect(result.getError()).toEqual('User not found.')
|
|
|
|
+
|
|
expect(userRepository.save).not.toHaveBeenCalled()
|
|
expect(userRepository.save).not.toHaveBeenCalled()
|
|
expect(domainEventFactory.createUserEmailChangedEvent).not.toHaveBeenCalled()
|
|
expect(domainEventFactory.createUserEmailChangedEvent).not.toHaveBeenCalled()
|
|
expect(domainEventPublisher.publish).not.toHaveBeenCalled()
|
|
expect(domainEventPublisher.publish).not.toHaveBeenCalled()
|
|
})
|
|
})
|
|
|
|
|
|
it('should not change password if current password is incorrect', async () => {
|
|
it('should not change password if current password is incorrect', async () => {
|
|
- expect(
|
|
|
|
- await createUseCase().execute({
|
|
|
|
- username: Username.create('test@test.te').getValue(),
|
|
|
|
- apiVersion: '20190520',
|
|
|
|
- currentPassword: 'test123',
|
|
|
|
- newPassword: 'test234',
|
|
|
|
- pwNonce: 'asdzxc',
|
|
|
|
- updatedWithUserAgent: 'Google Chrome',
|
|
|
|
- }),
|
|
|
|
- ).toEqual({
|
|
|
|
- success: false,
|
|
|
|
- errorMessage: 'The current password you entered is incorrect. Please try again.',
|
|
|
|
|
|
+ const result = await createUseCase().execute({
|
|
|
|
+ username: Username.create('test@test.te').getValue(),
|
|
|
|
+ apiVersion: ApiVersion.v20200115,
|
|
|
|
+ currentPassword: 'test123',
|
|
|
|
+ newPassword: 'test234',
|
|
|
|
+ pwNonce: 'asdzxc',
|
|
|
|
+ updatedWithUserAgent: 'Google Chrome',
|
|
})
|
|
})
|
|
|
|
+ expect(result.isFailed()).toBeTruthy()
|
|
|
|
+ expect(result.getError()).toEqual('The current password you entered is incorrect. Please try again.')
|
|
|
|
|
|
expect(userRepository.save).not.toHaveBeenCalled()
|
|
expect(userRepository.save).not.toHaveBeenCalled()
|
|
})
|
|
})
|
|
|
|
|
|
it('should update protocol version while changing password', async () => {
|
|
it('should update protocol version while changing password', async () => {
|
|
- expect(
|
|
|
|
- await createUseCase().execute({
|
|
|
|
- username: Username.create('test@test.te').getValue(),
|
|
|
|
- apiVersion: '20190520',
|
|
|
|
- currentPassword: 'qweqwe123123',
|
|
|
|
- newPassword: 'test234',
|
|
|
|
- pwNonce: 'asdzxc',
|
|
|
|
- updatedWithUserAgent: 'Google Chrome',
|
|
|
|
- protocolVersion: '004',
|
|
|
|
- }),
|
|
|
|
- ).toEqual({
|
|
|
|
- success: true,
|
|
|
|
- authResponse: {
|
|
|
|
- foo: 'bar',
|
|
|
|
- },
|
|
|
|
|
|
+ const result = await createUseCase().execute({
|
|
|
|
+ username: Username.create('test@test.te').getValue(),
|
|
|
|
+ apiVersion: ApiVersion.v20200115,
|
|
|
|
+ currentPassword: 'qweqwe123123',
|
|
|
|
+ newPassword: 'test234',
|
|
|
|
+ pwNonce: 'asdzxc',
|
|
|
|
+ updatedWithUserAgent: 'Google Chrome',
|
|
|
|
+ protocolVersion: '004',
|
|
})
|
|
})
|
|
|
|
+ expect(result.isFailed()).toBeFalsy()
|
|
|
|
|
|
expect(userRepository.save).toHaveBeenCalledWith({
|
|
expect(userRepository.save).toHaveBeenCalledWith({
|
|
encryptedPassword: expect.any(String),
|
|
encryptedPassword: expect.any(String),
|
|
@@ -239,4 +229,63 @@ describe('ChangeCredentials', () => {
|
|
updatedAt: new Date(1),
|
|
updatedAt: new Date(1),
|
|
})
|
|
})
|
|
})
|
|
})
|
|
|
|
+
|
|
|
|
+ it('should not delete other sessions for user if neither passoword nor email are changed', async () => {
|
|
|
|
+ userRepository.findOneByUsernameOrEmail = jest.fn().mockReturnValueOnce(user)
|
|
|
|
+
|
|
|
|
+ const result = await createUseCase().execute({
|
|
|
|
+ username: Username.create('test@test.te').getValue(),
|
|
|
|
+ apiVersion: ApiVersion.v20200115,
|
|
|
|
+ currentPassword: 'qweqwe123123',
|
|
|
|
+ newPassword: 'qweqwe123123',
|
|
|
|
+ newEmail: undefined,
|
|
|
|
+ pwNonce: 'asdzxc',
|
|
|
|
+ updatedWithUserAgent: 'Google Chrome',
|
|
|
|
+ kpCreated: '123',
|
|
|
|
+ kpOrigination: 'password-change',
|
|
|
|
+ })
|
|
|
|
+ expect(result.isFailed()).toBeFalsy()
|
|
|
|
+
|
|
|
|
+ expect(userRepository.save).toHaveBeenCalledWith({
|
|
|
|
+ encryptedPassword: expect.any(String),
|
|
|
|
+ email: 'test@test.te',
|
|
|
|
+ uuid: '1-2-3',
|
|
|
|
+ pwNonce: 'asdzxc',
|
|
|
|
+ kpCreated: '123',
|
|
|
|
+ kpOrigination: 'password-change',
|
|
|
|
+ updatedAt: new Date(1),
|
|
|
|
+ })
|
|
|
|
+ expect(domainEventFactory.createUserEmailChangedEvent).not.toHaveBeenCalled()
|
|
|
|
+ expect(domainEventPublisher.publish).not.toHaveBeenCalled()
|
|
|
|
+ expect(deleteOtherSessionsForUser.execute).not.toHaveBeenCalled()
|
|
|
|
+ })
|
|
|
|
+
|
|
|
|
+ it('should not delete other sessions for user if the caller does not support sessions', async () => {
|
|
|
|
+ authResponseFactory.createResponse = jest.fn().mockReturnValue({ response: { foo: 'bar' } })
|
|
|
|
+
|
|
|
|
+ const result = await createUseCase().execute({
|
|
|
|
+ username: Username.create('test@test.te').getValue(),
|
|
|
|
+ apiVersion: ApiVersion.v20200115,
|
|
|
|
+ currentPassword: 'qweqwe123123',
|
|
|
|
+ newPassword: 'test234',
|
|
|
|
+ pwNonce: 'asdzxc',
|
|
|
|
+ updatedWithUserAgent: 'Google Chrome',
|
|
|
|
+ kpCreated: '123',
|
|
|
|
+ kpOrigination: 'password-change',
|
|
|
|
+ })
|
|
|
|
+
|
|
|
|
+ expect(result.isFailed()).toBeFalsy()
|
|
|
|
+
|
|
|
|
+ expect(userRepository.save).toHaveBeenCalledWith({
|
|
|
|
+ encryptedPassword: expect.any(String),
|
|
|
|
+ pwNonce: 'asdzxc',
|
|
|
|
+ kpCreated: '123',
|
|
|
|
+ email: 'test@test.te',
|
|
|
|
+ uuid: '1-2-3',
|
|
|
|
+ kpOrigination: 'password-change',
|
|
|
|
+ updatedAt: new Date(1),
|
|
|
|
+ })
|
|
|
|
+
|
|
|
|
+ expect(deleteOtherSessionsForUser.execute).not.toHaveBeenCalled()
|
|
|
|
+ })
|
|
})
|
|
})
|