FIX: Deleting security keys was not working (#20427)

Bug was introduced in e313190fdb. There is
a workaround, using the trash icon in the edit modal, but that UI is
quite confusing to users.
This commit is contained in:
Penar Musaraj 2023-03-06 10:51:39 -05:00 committed by GitHub
parent b5e736504a
commit 420214fc82
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 68 additions and 58 deletions

View File

@ -166,40 +166,61 @@ export default Controller.extend(CanCheckEmails, {
confirmButtonIcon: "ban", confirmButtonIcon: "ban",
cancelButtonClass: "btn-flat", cancelButtonClass: "btn-flat",
didConfirm: () => { didConfirm: () => {
this.currentUser if (this.totps.includes(secondFactorMethod)) {
.updateSecondFactor( this.currentUser
secondFactorMethod.id, .updateSecondFactor(
secondFactorMethod.name, secondFactorMethod.id,
true, secondFactorMethod.name,
secondFactorMethod.method true,
) secondFactorMethod.method
.then((response) => { )
if (response.error) { .then((response) => {
return; if (response.error) {
} return;
this.markDirty(); }
}) this.markDirty();
.catch((e) => this.handleError(e)) this.set(
.finally(() => { "totps",
this.setProperties({ this.totps.filter(
totps: this.totps.filter( (totp) =>
(totp) => totp.id !== secondFactorMethod.id ||
totp.id !== secondFactorMethod.id || totp.method !== secondFactorMethod.method
totp.method !== secondFactorMethod.method )
), );
security_keys: this.security_keys.filter( })
(key) => .catch((e) => this.handleError(e))
key.id !== secondFactorMethod.id || .finally(() => {
key.method !== secondFactorMethod.method this.set("loading", false);
),
}); });
}
this.set("loading", false); if (this.security_keys.includes(secondFactorMethod)) {
}); this.currentUser
.updateSecurityKey(
secondFactorMethod.id,
secondFactorMethod.name,
true
)
.then((response) => {
if (response.error) {
return;
}
this.markDirty();
this.set(
"security_keys",
this.security_keys.filter(
(securityKey) => securityKey.id !== secondFactorMethod.id
)
);
})
.catch((e) => this.handleError(e))
.finally(() => {
this.set("loading", false);
});
}
}, },
}); });
}, },
disableSecondFactorBackup() { disableSecondFactorBackup() {
this.dialog.deleteConfirm({ this.dialog.deleteConfirm({
title: I18n.t("user.second_factor.delete_backup_codes_confirm_title"), title: I18n.t("user.second_factor.delete_backup_codes_confirm_title"),

View File

@ -3,25 +3,6 @@ import ModalFunctionality from "discourse/mixins/modal-functionality";
export default Controller.extend(ModalFunctionality, { export default Controller.extend(ModalFunctionality, {
actions: { actions: {
disableSecurityKey() {
this.user
.updateSecurityKey(this.model.id, this.model.name, true)
.then((response) => {
if (response.error) {
return;
}
this.markDirty();
})
.catch((error) => {
this.send("closeModal");
this.onError(error);
})
.finally(() => {
this.set("loading", false);
this.send("closeModal");
});
},
editSecurityKey() { editSecurityKey() {
this.user this.user
.updateSecurityKey(this.model.id, this.model.name, false) .updateSecurityKey(this.model.id, this.model.name, false)

View File

@ -15,11 +15,4 @@
@class="btn-primary" @class="btn-primary"
@label="user.second_factor.security_key.save" @label="user.second_factor.security_key.save"
/> />
<DButton
@action={{action "disableSecurityKey"}}
@class="btn-danger no-text"
@icon="trash-alt"
@aria-label="user.second_factor.disable"
@title="user.second_factor.disable"
/>
</div> </div>

View File

@ -169,7 +169,7 @@
{{#if this.model.second_factor_enabled}} {{#if this.model.second_factor_enabled}}
{{#unless this.showEnforcedNotice}} {{#unless this.showEnforcedNotice}}
<div class="control-group"> <div class="control-group pref-second-factor-disable-all">
<div class="controls"> <div class="controls">
<DButton <DButton
@class="btn-danger" @class="btn-danger"

View File

@ -41,6 +41,12 @@ acceptance("User Preferences - Second Factor", function (needs) {
}); });
}); });
server.put("/u/security_key.json", () => {
return helper.response({
success: "OK",
});
});
server.put("/u/second_factors_backup.json", () => { server.put("/u/second_factors_backup.json", () => {
return helper.response({ return helper.response({
backup_codes: ["dsffdsd", "fdfdfdsf", "fddsds"], backup_codes: ["dsffdsd", "fdfdfdsf", "fddsds"],
@ -109,14 +115,23 @@ acceptance("User Preferences - Second Factor", function (needs) {
); );
await click(".dialog-close"); await click(".dialog-close");
assert.ok(
exists(".security-key .second-factor-item"),
"User has a physical security key"
);
await click(".security-key .btn-danger"); await click(".security-key .btn-danger");
assert.strictEqual( assert.strictEqual(
query("#dialog-title").innerText.trim(), query("#dialog-title").innerText.trim(),
"Deleting an authenticator" "Deleting an authenticator"
); );
await click(".dialog-close"); await click(".dialog-footer .btn-danger");
assert.notOk(
exists(".security-key .second-factor-item"),
"security key row is removed after a successful delete"
);
await click(".btn-danger.btn-icon-text"); await click(".pref-second-factor-disable-all .btn-danger");
assert.strictEqual( assert.strictEqual(
query("#dialog-title").innerText.trim(), query("#dialog-title").innerText.trim(),
"Are you sure you want to disable two-factor authentication?" "Are you sure you want to disable two-factor authentication?"