mirror of
https://github.com/discourse/discourse.git
synced 2025-03-19 23:37:25 +08:00
FIX: Regression when enforced 2FA is enabled (#24415)
This commit is contained in:
parent
f19fd75af9
commit
bcfb1a423d
@ -45,7 +45,7 @@ export default class ConfirmSession extends Component {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
const result = await ajax("/u/confirm-session", {
|
const result = await ajax("/u/confirm-session.json", {
|
||||||
type: "POST",
|
type: "POST",
|
||||||
data: { publicKeyCredential },
|
data: { publicKeyCredential },
|
||||||
});
|
});
|
||||||
@ -67,7 +67,7 @@ export default class ConfirmSession extends Component {
|
|||||||
? null
|
? null
|
||||||
: I18n.t("user.confirm_access.incorrect_password");
|
: I18n.t("user.confirm_access.incorrect_password");
|
||||||
|
|
||||||
const result = await ajax("/u/confirm-session", {
|
const result = await ajax("/u/confirm-session.json", {
|
||||||
type: "POST",
|
type: "POST",
|
||||||
data: {
|
data: {
|
||||||
password: this.password,
|
password: this.password,
|
||||||
|
@ -2,6 +2,7 @@ import Controller from "@ember/controller";
|
|||||||
import { action } from "@ember/object";
|
import { action } from "@ember/object";
|
||||||
import { alias } from "@ember/object/computed";
|
import { alias } from "@ember/object/computed";
|
||||||
import { inject as service } from "@ember/service";
|
import { inject as service } from "@ember/service";
|
||||||
|
import ConfirmSession from "discourse/components/dialog-messages/confirm-session";
|
||||||
import SecondFactorConfirmPhrase from "discourse/components/dialog-messages/second-factor-confirm-phrase";
|
import SecondFactorConfirmPhrase from "discourse/components/dialog-messages/second-factor-confirm-phrase";
|
||||||
import SecondFactorAddSecurityKey from "discourse/components/modal/second-factor-add-security-key";
|
import SecondFactorAddSecurityKey from "discourse/components/modal/second-factor-add-security-key";
|
||||||
import SecondFactorAddTotp from "discourse/components/modal/second-factor-add-totp";
|
import SecondFactorAddTotp from "discourse/components/modal/second-factor-add-totp";
|
||||||
@ -25,11 +26,11 @@ export default Controller.extend(CanCheckEmails, {
|
|||||||
newUsername: null,
|
newUsername: null,
|
||||||
backupEnabled: alias("model.second_factor_backup_enabled"),
|
backupEnabled: alias("model.second_factor_backup_enabled"),
|
||||||
secondFactorMethod: SECOND_FACTOR_METHODS.TOTP,
|
secondFactorMethod: SECOND_FACTOR_METHODS.TOTP,
|
||||||
totps: null,
|
totps: [],
|
||||||
|
security_keys: [],
|
||||||
|
|
||||||
init() {
|
init() {
|
||||||
this._super(...arguments);
|
this._super(...arguments);
|
||||||
this.set("totps", []);
|
|
||||||
},
|
},
|
||||||
|
|
||||||
@discourseComputed
|
@discourseComputed
|
||||||
@ -47,6 +48,36 @@ export default Controller.extend(CanCheckEmails, {
|
|||||||
return totps.length > 0 || security_keys.length > 0;
|
return totps.length > 0 || security_keys.length > 0;
|
||||||
},
|
},
|
||||||
|
|
||||||
|
async createToTpModal() {
|
||||||
|
try {
|
||||||
|
await this.modal.show(SecondFactorAddTotp, {
|
||||||
|
model: {
|
||||||
|
secondFactor: this.model,
|
||||||
|
markDirty: () => this.markDirty(),
|
||||||
|
onError: (e) => this.handleError(e),
|
||||||
|
},
|
||||||
|
});
|
||||||
|
this.loadSecondFactors();
|
||||||
|
} catch (error) {
|
||||||
|
popupAjaxError(error);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
async createSecurityKeyModal() {
|
||||||
|
try {
|
||||||
|
await this.modal.show(SecondFactorAddSecurityKey, {
|
||||||
|
model: {
|
||||||
|
secondFactor: this.model,
|
||||||
|
markDirty: this.markDirty,
|
||||||
|
onError: this.handleError,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
this.loadSecondFactors();
|
||||||
|
} catch (error) {
|
||||||
|
popupAjaxError(error);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
@action
|
@action
|
||||||
handleError(error) {
|
handleError(error) {
|
||||||
if (error.jqXHR) {
|
if (error.jqXHR) {
|
||||||
@ -104,6 +135,46 @@ export default Controller.extend(CanCheckEmails, {
|
|||||||
this.set("dirty", true);
|
this.set("dirty", true);
|
||||||
},
|
},
|
||||||
|
|
||||||
|
@action
|
||||||
|
async createTotp() {
|
||||||
|
try {
|
||||||
|
const trustedSession = await this.model.trustedSession();
|
||||||
|
|
||||||
|
if (!trustedSession.success) {
|
||||||
|
this.dialog.dialog({
|
||||||
|
title: I18n.t("user.confirm_access.title"),
|
||||||
|
type: "notice",
|
||||||
|
bodyComponent: ConfirmSession,
|
||||||
|
didConfirm: () => this.createToTpModal(),
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
await this.createToTpModal();
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
popupAjaxError(error);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
@action
|
||||||
|
async createSecurityKey() {
|
||||||
|
try {
|
||||||
|
const trustedSession = await this.model.trustedSession();
|
||||||
|
|
||||||
|
if (!trustedSession.success) {
|
||||||
|
this.dialog.dialog({
|
||||||
|
title: I18n.t("user.confirm_access.title"),
|
||||||
|
type: "notice",
|
||||||
|
bodyComponent: ConfirmSession,
|
||||||
|
didConfirm: () => this.createSecurityKeyModal(),
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
await this.createSecurityKeyModal();
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
popupAjaxError(error);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
actions: {
|
actions: {
|
||||||
disableAllSecondFactors() {
|
disableAllSecondFactors() {
|
||||||
if (this.loading) {
|
if (this.loading) {
|
||||||
@ -237,28 +308,6 @@ export default Controller.extend(CanCheckEmails, {
|
|||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
|
||||||
async createTotp() {
|
|
||||||
await this.modal.show(SecondFactorAddTotp, {
|
|
||||||
model: {
|
|
||||||
secondFactor: this.model,
|
|
||||||
markDirty: () => this.markDirty(),
|
|
||||||
onError: (e) => this.handleError(e),
|
|
||||||
},
|
|
||||||
});
|
|
||||||
this.loadSecondFactors();
|
|
||||||
},
|
|
||||||
|
|
||||||
async createSecurityKey() {
|
|
||||||
await this.modal.show(SecondFactorAddSecurityKey, {
|
|
||||||
model: {
|
|
||||||
secondFactor: this.model,
|
|
||||||
markDirty: this.markDirty,
|
|
||||||
onError: this.handleError,
|
|
||||||
},
|
|
||||||
});
|
|
||||||
this.loadSecondFactors();
|
|
||||||
},
|
|
||||||
|
|
||||||
async editSecurityKey(security_key) {
|
async editSecurityKey(security_key) {
|
||||||
await this.modal.show(SecondFactorEditSecurityKey, {
|
await this.modal.show(SecondFactorEditSecurityKey, {
|
||||||
model: {
|
model: {
|
||||||
|
@ -51,6 +51,10 @@ acceptance("User Preferences - Second Factor", function (needs) {
|
|||||||
backup_codes: ["dsffdsd", "fdfdfdsf", "fddsds"],
|
backup_codes: ["dsffdsd", "fdfdfdsf", "fddsds"],
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
server.get("/u/trusted-session.json", () => {
|
||||||
|
return helper.response({ success: "OK" });
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
test("second factor totp", async function (assert) {
|
test("second factor totp", async function (assert) {
|
||||||
|
@ -109,13 +109,38 @@ describe "User preferences for Security", type: :system do
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
shared_examples "enforced second factor" do
|
||||||
|
it "allows user to add 2FA" do
|
||||||
|
SiteSetting.enforce_second_factor = "all"
|
||||||
|
|
||||||
|
visit("/")
|
||||||
|
|
||||||
|
expect(page).to have_selector(
|
||||||
|
".alert-error",
|
||||||
|
text: "You are required to enable two-factor authentication before accessing this site.",
|
||||||
|
)
|
||||||
|
|
||||||
|
expect(page).to have_css(".user-preferences .totp")
|
||||||
|
expect(page).to have_css(".user-preferences .security-key")
|
||||||
|
|
||||||
|
find(".user-preferences .totp .btn.new-totp").click
|
||||||
|
|
||||||
|
find(".dialog-body input#password").fill_in(with: password)
|
||||||
|
find(".confirm-session .btn-primary").click
|
||||||
|
|
||||||
|
expect(page).to have_css(".qr-code")
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
context "when desktop" do
|
context "when desktop" do
|
||||||
include_examples "security keys"
|
include_examples "security keys"
|
||||||
include_examples "passkeys"
|
include_examples "passkeys"
|
||||||
|
include_examples "enforced second factor"
|
||||||
end
|
end
|
||||||
|
|
||||||
context "when mobile", mobile: true do
|
context "when mobile", mobile: true do
|
||||||
include_examples "security keys"
|
include_examples "security keys"
|
||||||
include_examples "passkeys"
|
include_examples "passkeys"
|
||||||
|
include_examples "enforced second factor"
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
Loading…
x
Reference in New Issue
Block a user