DEV: Redirect to actionable page if routing is restricted (#28002)

If a user has a required action, e.g. adding a 2FA method or filling in new required fields, we disable client-side routing except to allowed pages.

This led to a situation where a user might navigate away from e.g. the profile page to look at the new ToS, and then being "stuck" due to not knowing how to get back to accept the new terms.

This PR makes it so that if you click any restricted link, instead of doing nothing we transition the user back to the page where they can take the required action.
This commit is contained in:
Ted Johansson 2024-07-22 12:24:05 +08:00 committed by GitHub
parent 352d6f9dfb
commit 23d7800ff1
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
3 changed files with 31 additions and 1 deletions

View File

@ -76,6 +76,11 @@ const ApplicationRoute = DiscourseRoute.extend({
!this.restrictedRouting.isAllowedRoute(transition.to.name)
) {
transition.abort();
this.router.replaceWith(
this.restrictedRouting.redirectRoute,
this.currentUser
);
return false;
}

View File

@ -38,6 +38,16 @@ export default class RestrictedRouting extends Service {
return true;
}
get redirectRoute() {
if (this._needs2fa) {
return "preferences.second-factor";
}
if (this._needsRequiredFields) {
return "preferences.profile";
}
}
get _needs2fa() {
// NOTE: Matches the should_enforce_2fa? and disqualified_from_2fa_enforcement
// methods in ApplicationController.

View File

@ -31,7 +31,7 @@ describe "User preferences | Profile", type: :system do
)
end
it "redirects to the profile page to fill up required fields" do
it "server-side redirects to the profile page to fill up required fields" do
visit("/")
expect(page).to have_current_path("/u/#{user.username}/preferences/profile")
@ -42,6 +42,21 @@ describe "User preferences | Profile", type: :system do
)
end
it "client-side redirects to the profile page to fill up required fields" do
visit("/faq")
expect(page).to have_current_path("/faq")
find("#site-logo").click
expect(page).to have_current_path("/u/#{user.username}/preferences/profile")
expect(page).to have_selector(
".alert-error",
text: I18n.t("js.user.preferences.profile.enforced_required_fields"),
)
end
it "disables client-side routing while missing required fields" do
user_preferences_profile_page.visit(user)