Administrative MFA TOTP reset feature
See original GitHub issueBefore opening, please confirm:
- I have searched for duplicate or closed issues and discussions.
- I have read the guide for submitting bug reports.
- I have done my best to include a minimal, self-contained set of instructions for consistently reproducing the issue.
JavaScript Framework
Angular
Amplify APIs
Authentication
Amplify Categories
auth
Environment information
# Put output below this line
System:
OS: macOS 11.6
CPU: (12) x64 Intel(R) Core(TM) i9-8950HK CPU @ 2.90GHz
Memory: 112.69 MB / 32.00 GB
Shell: 3.2.57 - /bin/bash
Binaries:
Node: 14.17.5 - ~/.nvm/versions/node/v14.17.5/bin/node
Yarn: 1.22.10 - /usr/local/bin/yarn
npm: 6.14.14 - ~/.nvm/versions/node/v14.17.5/bin/npm
Browsers:
Chrome: 94.0.4606.81
Firefox: 92.0.1
Safari: 15.0
npmPackages:
<%= name %>: <%= version %>
@angular-devkit/build-angular: 0.1102.14 => 0.1102.14
@angular-eslint/builder: ^0.0.1-alpha.32 => 0.0.1-alpha.32
@angular-eslint/eslint-plugin: ~1.0.0 => 1.0.0
@angular-eslint/eslint-plugin-template: ~1.0.0 => 1.0.0
@angular-eslint/template-parser: ~1.0.0 => 1.0.0
@angular-material-components/datetime-picker: 5.1.1 => 5.1.1
@angular/animations: 11.2.14 => 11.2.14
@angular/animations/browser: undefined ()
@angular/animations/browser/testing: undefined ()
@angular/cdk: 11.2.13 => 11.2.13
@angular/cdk/a11y: undefined ()
@angular/cdk/accordion: undefined ()
@angular/cdk/bidi: undefined ()
@angular/cdk/clipboard: undefined ()
@angular/cdk/coercion: undefined ()
@angular/cdk/collections: undefined ()
@angular/cdk/drag-drop: undefined ()
@angular/cdk/keycodes: undefined ()
@angular/cdk/layout: undefined ()
@angular/cdk/observers: undefined ()
@angular/cdk/overlay: undefined ()
@angular/cdk/platform: undefined ()
@angular/cdk/portal: undefined ()
@angular/cdk/scrolling: undefined ()
@angular/cdk/stepper: undefined ()
@angular/cdk/table: undefined ()
@angular/cdk/testing: undefined ()
@angular/cdk/testing/protractor: undefined ()
@angular/cdk/testing/testbed: undefined ()
@angular/cdk/text-field: undefined ()
@angular/cdk/tree: undefined ()
@angular/cli: 11.2.14 => 11.2.14
@angular/common: 11.2.14 => 11.2.14
@angular/common/http: undefined ()
@angular/common/http/testing: undefined ()
@angular/common/testing: undefined ()
@angular/common/upgrade: undefined ()
@angular/compiler: 11.2.14 => 11.2.14
@angular/compiler-cli: 11.2.14 => 11.2.14
@angular/compiler/testing: undefined ()
@angular/core: 11.2.14 => 11.2.14
@angular/core/testing: undefined ()
@angular/flex-layout: 11.0.0-beta.33 => 11.0.0-beta.33
@angular/flex-layout/core: undefined ()
@angular/flex-layout/extended: undefined ()
@angular/flex-layout/flex: undefined ()
@angular/flex-layout/grid: undefined ()
@angular/flex-layout/server: undefined ()
@angular/forms: 11.2.14 => 11.2.14
@angular/language-service: 11.2.14 => 11.2.14
@angular/material: 11.2.13 => 11.2.13
@angular/material/autocomplete: undefined ()
@angular/material/autocomplete/testing: undefined ()
@angular/material/badge: undefined ()
@angular/material/badge/testing: undefined ()
@angular/material/bottom-sheet: undefined ()
@angular/material/bottom-sheet/testing: undefined ()
@angular/material/button: undefined ()
@angular/material/button-toggle: undefined ()
@angular/material/button-toggle/testing: undefined ()
@angular/material/button/testing: undefined ()
@angular/material/card: undefined ()
@angular/material/card/testing: undefined ()
@angular/material/checkbox: undefined ()
@angular/material/checkbox/testing: undefined ()
@angular/material/chips: undefined ()
@angular/material/chips/testing: undefined ()
@angular/material/core: undefined ()
@angular/material/core/testing: undefined ()
@angular/material/datepicker: undefined ()
@angular/material/datepicker/testing: undefined ()
@angular/material/dialog: undefined ()
@angular/material/dialog/testing: undefined ()
@angular/material/divider: undefined ()
@angular/material/divider/testing: undefined ()
@angular/material/expansion: undefined ()
@angular/material/expansion/testing: undefined ()
@angular/material/form-field: undefined ()
@angular/material/form-field/testing: undefined ()
@angular/material/form-field/testing/control: undefined ()
@angular/material/grid-list: undefined ()
@angular/material/grid-list/testing: undefined ()
@angular/material/icon: undefined ()
@angular/material/icon/testing: undefined ()
@angular/material/input: undefined ()
@angular/material/input/testing: undefined ()
@angular/material/list: undefined ()
@angular/material/list/testing: undefined ()
@angular/material/menu: undefined ()
@angular/material/menu/testing: undefined ()
@angular/material/paginator: undefined ()
@angular/material/paginator/testing: undefined ()
@angular/material/progress-bar: undefined ()
@angular/material/progress-bar/testing: undefined ()
@angular/material/progress-spinner: undefined ()
@angular/material/progress-spinner/testing: undefined ()
@angular/material/radio: undefined ()
@angular/material/radio/testing: undefined ()
@angular/material/select: undefined ()
@angular/material/select/testing: undefined ()
@angular/material/sidenav: undefined ()
@angular/material/sidenav/testing: undefined ()
@angular/material/slide-toggle: undefined ()
@angular/material/slide-toggle/testing: undefined ()
@angular/material/slider: undefined ()
@angular/material/slider/testing: undefined ()
@angular/material/snack-bar: undefined ()
@angular/material/snack-bar/testing: undefined ()
@angular/material/sort: undefined ()
@angular/material/sort/testing: undefined ()
@angular/material/stepper: undefined ()
@angular/material/stepper/testing: undefined ()
@angular/material/table: undefined ()
@angular/material/table/testing: undefined ()
@angular/material/tabs: undefined ()
@angular/material/tabs/testing: undefined ()
@angular/material/toolbar: undefined ()
@angular/material/toolbar/testing: undefined ()
@angular/material/tooltip: undefined ()
@angular/material/tooltip/testing: undefined ()
@angular/material/tree: undefined ()
@angular/material/tree/testing: undefined ()
@angular/platform-browser: 11.2.14 => 11.2.14
@angular/platform-browser-dynamic: 11.2.14 => 11.2.14
@angular/platform-browser-dynamic/testing: undefined ()
@angular/platform-browser/animations: undefined ()
@angular/platform-browser/testing: undefined ()
@angular/router: 11.2.14 => 11.2.14
@angular/router/testing: undefined ()
@angular/router/upgrade: undefined ()
@apollo/client: ^3.0.0 => 3.2.2
@apollo/client/cache: undefined ()
@apollo/client/core: undefined ()
@apollo/client/errors: undefined ()
@apollo/client/link/batch: undefined ()
@apollo/client/link/batch-http: undefined ()
@apollo/client/link/context: undefined ()
@apollo/client/link/core: undefined ()
@apollo/client/link/error: undefined ()
@apollo/client/link/http: undefined ()
@apollo/client/link/persisted-queries: undefined ()
@apollo/client/link/retry: undefined ()
@apollo/client/link/schema: undefined ()
@apollo/client/link/utils: undefined ()
@apollo/client/link/ws: undefined ()
@apollo/client/react: undefined ()
@apollo/client/react/components: undefined ()
@apollo/client/react/context: undefined ()
@apollo/client/react/data: undefined ()
@apollo/client/react/hoc: undefined ()
@apollo/client/react/hooks: undefined ()
@apollo/client/react/parser: undefined ()
@apollo/client/react/ssr: undefined ()
@apollo/client/testing: undefined ()
@apollo/client/utilities: undefined ()
@aws-amplify/ui-angular: ^1.0.3 => 1.0.3
@casl/ability: ^5.2.2 => 5.2.2
@casl/ability/extra: undefined ()
@casl/angular: ^5.1.0 => 5.1.0
@datorama/akita: ^4.23.2 => 4.23.2
@graphql-codegen/cli: ^1.13.3 => 1.14.0
@graphql-codegen/introspection: ^1.18.0 => 1.18.0
@graphql-codegen/typescript-apollo-angular: ^1.13.3 => 1.14.0
@graphql-codegen/typescript-document-nodes: ^1.13.3 => 1.14.0
@graphql-codegen/typescript-operations: ^1.13.3 => 1.14.0
@nestjs/common: 7.6.18 => 7.6.18 (7.4.2)
@nestjs/core: 7.6.18 => 7.6.18
@nestjs/graphql: ^7.6.0 => 7.7.0
@nestjs/platform-express: 7.6.18 => 7.6.18
@nestjs/schematics: 7.3.1 => 7.3.1
@nestjs/testing: 7.6.18 => 7.6.18
@nestjs/typeorm: ^7.1.0 => 7.1.0
@ngx-formly/core: ^5.9.3 => 5.9.3
@ngx-formly/core/json-schema: undefined ()
@ngx-formly/core/select: undefined ()
@nrwl/angular: 11.6.3 => 11.6.3
@nrwl/angular/testing: undefined ()
@nrwl/cli: 11.6.3 => 11.6.3
@nrwl/cypress: 11.6.3 => 11.6.3
@nrwl/eslint-plugin-nx: 11.6.3 => 11.6.3
@nrwl/jest: 11.6.3 => 11.6.3
@nrwl/linter: 11.6.3 => 11.6.3
@nrwl/nest: 11.6.3 => 11.6.3
@nrwl/node: 11.6.3 => 11.6.3
@nrwl/nx-cloud: ^12.2.7 => 12.2.7
@nrwl/tao: 11.6.3 => 11.6.3
@nrwl/workspace: 11.6.3 => 11.6.3
@synap/nest-aws-kms: ^0.0.2 => 0.0.2
@synap/ngx-subscription-helpers: ^0.0.1 => 0.0.1
@types/config: ^0.0.36 => 0.0.36
@types/jest: 26.0.8 => 26.0.8 (26.0.23)
@types/lodash-es: ^4.17.3 => 4.17.3
@types/node: 14.14.33 => 14.14.33 (14.0.5, 10.17.24, 14.6.4)
@typescript-eslint/eslint-plugin: 4.3.0 => 4.3.0
@typescript-eslint/parser: 4.3.0 => 4.3.0
apollo-angular: ^2.0.4 => 2.0.4
apollo-angular/headers: undefined ()
apollo-angular/http: undefined ()
apollo-angular/testing: undefined ()
apollo-link-scalars: ^2.0.1 => 2.0.1
apollo-server-express: ^2.12.0 => 2.13.1
aws-amplify: ^3.3.22 => 3.3.22
aws-sdk: ^2.730.0 => 2.730.0 (2.738.0)
casual: ^1.6.2 => 1.6.2
chart.js: ^2.9.4 => 2.9.4
chartjs-node-canvas: ^3.0.6 => 3.0.6
class-transformer: ^0.3.1 => 0.3.1
class-validator: ^0.12.2 => 0.12.2
config: ^3.3.1 => 3.3.1
core-js: ^2.5.4 => 2.6.11 (3.8.3, 3.6.5)
cypress: ^4.1.0 => 4.6.0
deep-object-diff: ^1.1.0 => 1.1.0
dotenv: 8.2.0 => 8.2.0 (4.0.0, 6.2.0)
eslint: 7.10.0 => 7.10.0
eslint-config-prettier: 8.1.0 => 8.1.0
eslint-plugin-cypress: ^2.10.3 => 2.11.3
eslint-plugin-no-null: ^1.0.2 => 1.0.2
eslint-plugin-prettier: ^3.1.4 => 3.1.4
exceljs: ^4.1.1 => 4.1.1
graphql: ^15.0.0 => 15.3.0 (14.0.0, 14.6.0)
graphql-tools: ^5.0.0 => 5.0.0 (4.0.8)
jest: 26.2.2 => 26.2.2
jest-preset-angular: 8.3.2 => 8.3.2
jsonwebtoken: ^8.5.1 => 8.5.1
jwk-to-pem: ^2.0.4 => 2.0.4
lib: 0.0.1
lodash-es: ^4.17.15 => 4.17.15
moment: ^2.27.0 => 2.27.0 (2.29.1, 2.26.0, 2.24.0)
moment-timezone: ^0.5.31 => 0.5.31
morgan: ^1.10.0 => 1.10.0
mysql: ^2.18.1 => 2.18.1
nest-aws-sdk: ^1.1.1 => 1.1.1
ng2-charts: ^2.4.2 => 2.4.2
ngx-dropzone: ^2.2.2 => 2.2.2
ngx-markdown: 11.0.0 => 11.0.0
nodemailer: ^6.4.16 => 6.4.16
pdf-lib: ^1.11.2 => 1.11.2
prettier: 2.2.1 => 2.2.1
reflect-metadata: ^0.1.13 => 0.1.13
rxjs: 6.5.5 => 6.5.5 (6.6.3, 6.6.7, 6.3.3)
rxjs/ajax: undefined ()
rxjs/fetch: undefined ()
rxjs/internal-compatibility: undefined ()
rxjs/operators: undefined ()
rxjs/testing: undefined ()
rxjs/webSocket: undefined ()
ts-jest: 26.4.0 => 26.4.0 (26.5.6)
ts-node: 9.1.1 => 9.1.1
tslib: ^2.0.0 => 2.0.0 (1.13.0, 2.1.0, 1.14.1, 2.0.1, 1.11.2, 2.2.0)
typeorm: ^0.2.25 => 0.2.25
typeorm-seeding: ^1.6.1 => 1.6.1
typescript: 4.0.8 => 4.0.8 (4.1.5, 4.0.3, 3.9.3)
zone.js: ^0.10.2 => 0.10.3
npmGlobalPackages:
@angular/cli: 12.2.2
npm: 6.14.14
Describe the bug
When a user’s MFA preference is removed, that user can no longer log in and is stuck with a spinner in the login button.
Expected behavior
From the AdminSetUserMFAPreference docs the expected behavior is:
If multiple options are enabled and no preference is set, a challenge to choose an MFA option will be returned during sign in.
Reproduction steps
Begin with a user in an MFA-required pool with software token MFA enabled and preferred:
{
"Username": "...",
"UserAttributes": ["..."],
"Enabled": true,
"UserStatus": "CONFIRMED",
"MFAOptions": [
{
"DeliveryMedium": "SMS",
"AttributeName": "phone_number"
}
],
"PreferredMfaSetting": "SOFTWARE_TOKEN_MFA",
"UserMFASettingList": [
"SOFTWARE_TOKEN_MFA"
]
}
Use the AdminSetUserMFAPreference action to remove the preferred MFA, putting the user in this state:
{
"Username": "...",
"UserAttributes": ["..."],
"Enabled": true,
"UserStatus": "CONFIRMED",
"MFAOptions": [
{
"DeliveryMedium": "SMS",
"AttributeName": "phone_number"
}
],
"UserMFASettingList": [
"SOFTWARE_TOKEN_MFA"
]
}
Now when the user tries to log in they receive this console error: “Unhandled Promise rejection: Local storage is missing an ID Token, Please authenticate”.
Code Snippet
// Put your code below this line.
Log output
// Put your logs below this line
zone-evergreen.js:659 Unhandled Promise rejection: Local storage is missing an ID Token, Please authenticate ; Zone: <root> ; Task: Promise.then ; Value: Error: Local storage is missing an ID Token, Please authenticate
at CognitoUser.getSession (CognitoUser.js:1324)
at Auth.js:1305
at new ZoneAwarePromise (zone-evergreen.js:960)
at AuthClass.push.v4IS.AuthClass.userSession (Auth.js:1303)
at Auth.js:1030
at new ZoneAwarePromise (zone-evergreen.js:960)
at AuthClass.push.v4IS.AuthClass.userAttributes (Auth.js:1029)
at AuthClass.push.v4IS.AuthClass.verifiedContact (Auth.js:1044)
at checkContact (auth-helpers-bd096ca7.js:20)
at handleSignIn (auth-helpers-bd096ca7.js:59) Error: Local storage is missing an ID Token, Please authenticate
at CognitoUser.getSession (https://staging.iask.works/vendor.js:68019:16)
at https://staging.iask.works/vendor.js:198008:18
at new ZoneAwarePromise (https://staging.iask.works/polyfills.js:1058:33)
at AuthClass.push.v4IS.AuthClass.userSession (https://staging.iask.works/vendor.js:198006:16)
at https://staging.iask.works/vendor.js:197733:19
at new ZoneAwarePromise (https://staging.iask.works/polyfills.js:1058:33)
at AuthClass.push.v4IS.AuthClass.userAttributes (https://staging.iask.works/vendor.js:197732:16)
at AuthClass.push.v4IS.AuthClass.verifiedContact (https://staging.iask.works/vendor.js:197747:21)
at checkContact (https://staging.iask.works/common.js:60:83)
at handleSignIn (https://staging.iask.works/common.js:99:19)
aws-exports.js
No response
Manual configuration
Auth: {
userPoolId: 'us-west-1_Zj5xZfsJI',
userPoolWebClientId: '5gs4rr5nlstvb2qaegunfejhtf',
region: 'us-west-1',
}
Additional configuration
No response
Mobile Device
No response
Mobile Operating System
No response
Mobile Browser
No response
Mobile Browser Version
No response
Additional information and screenshots
Issue Analytics
- State:
- Created 2 years ago
- Comments:10 (6 by maintainers)
@synapdk are you using Amplify at all? the doc you have mentioned links to Cognito docs. If you are using Amplify, I think you might still need to use
setPreferedMFA
method since that is where we persist the data in localStorage in our code. If you are doing a combination of Cognito API calls and Amplify, I think you might have to replicate what we have done in our code to set the localStorage.Could you share a minimal code so we can see your usage? Also, after you have called the API, can you do
getCurrentAuthenticatedUser
to see if the challengeName and mfaPreference have updated?To reach out to cognito forum - https://forums.aws.amazon.com/forum.jspa?forumID=173.
I am moving this to discussion since this is more of a question than issue or bug.