diff --git a/app/assets/javascripts/admin/addon/controllers/admin-user-index.js b/app/assets/javascripts/admin/addon/controllers/admin-user-index.js index c11df41a5f9..807bb399325 100644 --- a/app/assets/javascripts/admin/addon/controllers/admin-user-index.js +++ b/app/assets/javascripts/admin/addon/controllers/admin-user-index.js @@ -222,11 +222,6 @@ export default Controller.extend(CanCheckEmails, { .then((result) => { if (result.email_confirmation_required) { bootbox.alert(I18n.t("admin.user.grant_admin_confirm")); - } else { - const controller = showModal("grant-admin-second-factor", { - model: this.model, - }); - controller.setResult(result); } }) .catch((error) => { diff --git a/app/assets/javascripts/discourse/app/controllers/grant-admin-second-factor.js b/app/assets/javascripts/discourse/app/controllers/grant-admin-second-factor.js deleted file mode 100644 index 62c000b4731..00000000000 --- a/app/assets/javascripts/discourse/app/controllers/grant-admin-second-factor.js +++ /dev/null @@ -1,84 +0,0 @@ -import Controller from "@ember/controller"; -import { action } from "@ember/object"; -import discourseComputed from "discourse-common/utils/decorators"; -import { getWebauthnCredential } from "discourse/lib/webauthn"; -import ModalFunctionality from "discourse/mixins/modal-functionality"; -import { SECOND_FACTOR_METHODS } from "discourse/models/user"; -import I18n from "I18n"; -import bootbox from "bootbox"; - -export default Controller.extend(ModalFunctionality, { - showSecondFactor: false, - secondFactorMethod: SECOND_FACTOR_METHODS.TOTP, - secondFactorToken: null, - securityKeyCredential: null, - - inProgress: false, - - onShow() { - this.setProperties({ - showSecondFactor: false, - secondFactorMethod: SECOND_FACTOR_METHODS.TOTP, - secondFactorToken: null, - securityKeyCredential: null, - }); - }, - - @discourseComputed("inProgress", "securityKeyCredential", "secondFactorToken") - disabled(inProgress, securityKeyCredential, secondFactorToken) { - return inProgress || (!securityKeyCredential && !secondFactorToken); - }, - - setResult(result) { - this.setProperties({ - otherMethodAllowed: result.multiple_second_factor_methods, - secondFactorRequired: true, - showLoginButtons: false, - backupEnabled: result.backup_enabled, - showSecondFactor: result.totp_enabled, - showSecurityKey: result.security_key_enabled, - secondFactorMethod: result.security_key_enabled - ? SECOND_FACTOR_METHODS.SECURITY_KEY - : SECOND_FACTOR_METHODS.TOTP, - securityKeyChallenge: result.challenge, - securityKeyAllowedCredentialIds: result.allowed_credential_ids, - }); - }, - - @action - authenticateSecurityKey() { - getWebauthnCredential( - this.securityKeyChallenge, - this.securityKeyAllowedCredentialIds, - (credentialData) => { - this.set("securityKeyCredential", credentialData); - this.send("authenticate"); - }, - (errorMessage) => { - this.flash(errorMessage, "error"); - } - ); - }, - - @action - authenticate() { - this.set("inProgress", true); - this.model - .grantAdmin({ - second_factor_token: - this.securityKeyCredential || this.secondFactorToken, - second_factor_method: this.secondFactorMethod, - timezone: moment.tz.guess(), - }) - .then((result) => { - if (result.success) { - this.send("closeModal"); - bootbox.alert(I18n.t("admin.user.grant_admin_success")); - } else { - this.flash(result.error, "error"); - this.setResult(result); - } - }) - .finally(() => this.set("inProgress", false)); - }, -}); diff --git a/app/assets/javascripts/discourse/app/templates/modal/grant-admin-second-factor.hbs b/app/assets/javascripts/discourse/app/templates/modal/grant-admin-second-factor.hbs deleted file mode 100644 index 3c49f73034c..00000000000 --- a/app/assets/javascripts/discourse/app/templates/modal/grant-admin-second-factor.hbs +++ /dev/null @@ -1,33 +0,0 @@ -{{#d-modal-body title="admin.user.grant_admin"}} - {{#second-factor-form - secondFactorMethod=secondFactorMethod - secondFactorToken=secondFactorToken - class=secondFactorClass - backupEnabled=backupEnabled - }} - {{#if showSecurityKey}} - {{#security-key-form - allowedCredentialIds=securityKeyAllowedCredentialIds - challenge=securityKeyChallenge - showSecurityKey=showSecurityKey - showSecondFactor=showSecondFactor - secondFactorMethod=secondFactorMethod - otherMethodAllowed=otherMethodAllowed - action=(action "authenticateSecurityKey")}} - {{/security-key-form}} - {{else}} - {{second-factor-input value=secondFactorToken inputId="second-factor-confirmation" secondFactorMethod=secondFactorMethod backupEnabled=backupEnabled}} - {{/if}} - {{/second-factor-form}} - - {{#unless showSecurityKey}} - - {{/unless}} -{{/d-modal-body}} diff --git a/app/assets/javascripts/discourse/tests/acceptance/admin-user-index-test.js b/app/assets/javascripts/discourse/tests/acceptance/admin-user-index-test.js index bb766e5ca80..e355b3c17f4 100644 --- a/app/assets/javascripts/discourse/tests/acceptance/admin-user-index-test.js +++ b/app/assets/javascripts/discourse/tests/acceptance/admin-user-index-test.js @@ -8,7 +8,9 @@ import { click, currentURL, fillIn, visit } from "@ember/test-helpers"; import selectKit from "discourse/tests/helpers/select-kit-helper"; import { test } from "qunit"; import I18n from "I18n"; +import { SECOND_FACTOR_METHODS } from "discourse/models/user"; +const { TOTP, BACKUP_CODE, SECURITY_KEY } = SECOND_FACTOR_METHODS; acceptance("Admin - User Index", function (needs) { needs.user(); needs.pretender((server, helper) => { @@ -83,17 +85,17 @@ acceptance("Admin - User Index", function (needs) { }); server.put("/admin/users/4/grant_admin", () => { - return helper.response({ - failed: "FAILED", - ok: false, - error: "The selected two-factor method is invalid.", - reason: "invalid_second_factor_method", - backup_enabled: true, - security_key_enabled: true, + return helper.response(403, { + second_factor_challenge_nonce: "somenonce", + }); + }); + + server.get("/session/2fa.json", () => { + return helper.response(200, { totp_enabled: true, - multiple_second_factor_methods: true, - allowed_credential_ids: ["allowed_credential_ids"], - challenge: "challenge", + backup_enabled: true, + security_keys_enabled: true, + allowed_methods: [TOTP, BACKUP_CODE, SECURITY_KEY], }); }); }); @@ -202,9 +204,13 @@ acceptance("Admin - User Index", function (needs) { await click(".bootbox .btn-primary"); }); - test("grant admin - shows the second factor modal", async function (assert) { + test("grant admin - redirects to the 2fa page", async function (assert) { await visit("/admin/users/4/user2"); await click(".grant-admin"); - assert.ok(exists(".grant-admin-second-factor-modal")); + assert.equal( + currentURL(), + "/session/2fa?nonce=somenonce", + "user is redirected to the 2FA page" + ); }); });