Skip to content
This repository was archived by the owner on Jan 24, 2024. It is now read-only.

Commit e7f202b

Browse files
author
Francesco Novy
committed
feat: Handle resetting password for inactive user
This now throws an PasswordCannotBeResetError. This commit also adds tests for the error dispatching.
1 parent 3f56ebc commit e7f202b

2 files changed

Lines changed: 170 additions & 3 deletions

File tree

‎addon/errors/cognito.ts‎

Lines changed: 29 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -10,13 +10,20 @@ export class CognitoError extends Error {
1010
name: string;
1111
_error: AmazonCognitoIdentityJsError;
1212

13-
constructor(error: string | AmazonCognitoIdentityJsError, message?: string) {
13+
constructor(
14+
error: string | AmazonCognitoIdentityJsError | null,
15+
message?: string
16+
) {
1417
if (typeof error === 'string') {
1518
message = error;
1619
error = { message, name: 'CognitoError' };
1720
}
1821

19-
let humanMessage = message || error.message;
22+
if (!error || typeof error !== 'object') {
23+
error = { message: 'An error has occurred.', name: 'CognitoError' };
24+
}
25+
26+
let humanMessage = message || error.message || 'An error has occurred.';
2027

2128
super(humanMessage);
2229

@@ -27,6 +34,7 @@ export class CognitoError extends Error {
2734
}
2835
}
2936

37+
// Note: This error is never thrown by dispatchError, but only manually in cognito._authenticate()
3038
export class NewPasswordRequiredError extends CognitoError {
3139
userAttributes: Object;
3240
requiredAttributes: Object;
@@ -82,6 +90,16 @@ export class InvalidPasswordError extends CognitoError {
8290
}
8391
}
8492

93+
export class PasswordCannotBeResetError extends CognitoError {
94+
constructor(error: AmazonCognitoIdentityJsError) {
95+
super(
96+
error,
97+
'The user you are trying to reset the password for is not active.'
98+
);
99+
this.name = 'PasswordCannotBeResetError';
100+
}
101+
}
102+
85103
export function dispatchError(error: AmazonCognitoIdentityJsError) {
86104
let errorMap = {
87105
PasswordResetRequiredException: PasswordResetRequiredError,
@@ -94,7 +112,7 @@ export function dispatchError(error: AmazonCognitoIdentityJsError) {
94112
};
95113

96114
if (!error || typeof error !== 'object') {
97-
return error;
115+
return new CognitoError(error);
98116
}
99117

100118
// @ts-ignore
@@ -108,5 +126,13 @@ export function dispatchError(error: AmazonCognitoIdentityJsError) {
108126
ErrorType = CognitoError;
109127
}
110128

129+
// Special case: When requesting password reset, this can be thrown
130+
if (
131+
ErrorType === InvalidAuthorizationError &&
132+
error.message === 'User password cannot be reset in the current state.'
133+
) {
134+
ErrorType = PasswordCannotBeResetError;
135+
}
136+
111137
return ErrorType ? new ErrorType(error) : new CognitoError(error);
112138
}

‎tests/unit/errors/cognito-test.ts‎

Lines changed: 141 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,141 @@
1+
import {
2+
CognitoError,
3+
InvalidAuthorizationError,
4+
UserNotFoundError,
5+
PasswordResetRequiredError,
6+
VerificationCodeMismatchError,
7+
VerificationCodeExpiredError,
8+
InvalidPasswordError,
9+
PasswordCannotBeResetError,
10+
dispatchError,
11+
} from 'ember-cognito-identity/errors/cognito';
12+
import { module, test } from 'qunit';
13+
14+
module('Unit | Utility | errors/cognito', function () {
15+
test('it works for a string', function (assert) {
16+
// @ts-ignore
17+
let result = dispatchError('test error');
18+
assert.ok(result instanceof CognitoError);
19+
assert.equal(result.message, 'test error');
20+
});
21+
22+
test('it works with null', function (assert) {
23+
// @ts-ignore
24+
let result = dispatchError(null);
25+
assert.ok(result instanceof CognitoError);
26+
assert.equal(result.message, 'An error has occurred.');
27+
});
28+
29+
test('it works for PasswordResetRequiredException', function (assert) {
30+
let result = dispatchError({
31+
code: 'PasswordResetRequiredException',
32+
name: 'PasswordResetRequiredException',
33+
message: 'test message',
34+
});
35+
36+
assert.ok(result instanceof PasswordResetRequiredError);
37+
assert.equal(result.message, 'Password reset required for the user.');
38+
});
39+
40+
test('it works for NotAuthorizedException', function (assert) {
41+
let result = dispatchError({
42+
code: 'NotAuthorizedException',
43+
name: 'NotAuthorizedException',
44+
message: 'test message',
45+
});
46+
47+
assert.ok(result instanceof InvalidAuthorizationError);
48+
assert.equal(result.message, 'The password you provided is incorrect.');
49+
});
50+
51+
test('it works for CodeMismatchException', function (assert) {
52+
let result = dispatchError({
53+
code: 'CodeMismatchException',
54+
name: 'CodeMismatchException',
55+
message: 'test message',
56+
});
57+
58+
assert.ok(result instanceof VerificationCodeMismatchError);
59+
assert.equal(
60+
result.message,
61+
'Invalid verification code provided, please try again.'
62+
);
63+
});
64+
65+
test('it works for InvalidPasswordException', function (assert) {
66+
let result = dispatchError({
67+
code: 'InvalidPasswordException',
68+
name: 'InvalidPasswordException',
69+
message: 'test message',
70+
});
71+
72+
assert.ok(result instanceof InvalidPasswordError);
73+
assert.equal(result.message, 'test message');
74+
});
75+
76+
test('it works for InvalidParameterException', function (assert) {
77+
let result = dispatchError({
78+
code: 'InvalidParameterException',
79+
name: 'InvalidParameterException',
80+
message: 'test message',
81+
});
82+
83+
assert.ok(result instanceof InvalidPasswordError);
84+
assert.equal(result.message, 'test message');
85+
});
86+
87+
test('it works for UserNotFoundException', function (assert) {
88+
let result = dispatchError({
89+
code: 'UserNotFoundException',
90+
name: 'UserNotFoundException',
91+
message: 'test message',
92+
});
93+
94+
assert.ok(result instanceof UserNotFoundError);
95+
assert.equal(result.message, 'This user does not exist.');
96+
});
97+
98+
test('it works for ExpiredCodeException', function (assert) {
99+
let result = dispatchError({
100+
code: 'ExpiredCodeException',
101+
name: 'ExpiredCodeException',
102+
message: 'test message',
103+
});
104+
105+
assert.ok(result instanceof VerificationCodeExpiredError);
106+
assert.equal(
107+
result.message,
108+
'The verification code is expired, please request a new one.'
109+
);
110+
});
111+
112+
module('special cases', function () {
113+
test('it handles updating invalid attributes', function (assert) {
114+
let result = dispatchError({
115+
name: 'NotAuthorizedException',
116+
code: 'NotAuthorizedException',
117+
message: 'A client attempted to write unauthorized attribute',
118+
});
119+
120+
assert.ok(result instanceof CognitoError);
121+
assert.equal(
122+
result.message,
123+
'A client attempted to write unauthorized attribute'
124+
);
125+
});
126+
127+
test('it handles requesting a password reset for an inactive user', function (assert) {
128+
let result = dispatchError({
129+
name: 'NotAuthorizedException',
130+
code: 'NotAuthorizedException',
131+
message: 'User password cannot be reset in the current state.',
132+
});
133+
134+
assert.ok(result instanceof PasswordCannotBeResetError);
135+
assert.equal(
136+
result.message,
137+
'The user you are trying to reset the password for is not active.'
138+
);
139+
});
140+
});
141+
});

0 commit comments

Comments
 (0)