Files
zulip/static/js/setup.js
Riken Shah bfc1e45a91 password_change: Avoid unnecessary redirect to the login page.
This commits adds on to 9884226f, which was added to
handle a rare race condition that occurs when the
session hash is not updated by the backend during the
password change process.

It handles a variant race situation where the request was initiated
before/during the password change event and completed after it was
completed. Hence, forcing the page to redirect to the login page.
2021-03-31 11:03:09 -07:00

91 lines
3.2 KiB
JavaScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
import $ from "jquery";
import * as blueslip from "./blueslip";
import * as loading from "./loading";
import {page_params} from "./page_params";
import * as util from "./util";
// Miscellaneous early setup.
export let password_change_in_progress = false;
export let last_password_change_start_time = null;
export function set_password_change_in_progress(value) {
password_change_in_progress = value;
if (value) {
last_password_change_start_time = new Date();
}
}
$(() => {
if (util.is_mobile()) {
// Disable the tutorial; it's ugly on mobile.
page_params.needs_tutorial = false;
}
page_params.page_load_time = Date.now();
// Display loading indicator. This disappears after the first
// get_events completes.
if (!page_params.needs_tutorial) {
loading.make_indicator($("#page_loading_indicator"), {
text: "Loading...",
abs_positioned: true,
});
}
// This is an issue fix where in jQuery v3 the result of outerHeight on a node
// that doesnt exist is now “undefined” rather than “null”, which means it
// will no longer cast to a Number but rather NaN. For this, we create the
// `safeOuterHeight` and `safeOuterWidth` functions to safely return a result
// (or 0).
$.fn.safeOuterHeight = function (...args) {
return this.outerHeight(...args) || 0;
};
$.fn.safeOuterWidth = function (...args) {
return this.outerWidth(...args) || 0;
};
// Attach the time when the request was initiated to its XHR
// object. This allows us to detect race situations where a
// password change completed before we got a response that failed
// due to the ongoing password change.
$(document).ajaxSend((event, xhr) => {
xhr.initiatedTime = new Date();
});
// For some reason, jQuery wants this to be attached to an element.
$(document).ajaxError((event, xhr) => {
if (
password_change_in_progress ||
(last_password_change_start_time &&
xhr.initiatedTime <= last_password_change_start_time)
) {
// The backend for handling password change API requests
// will replace the user's session; this results in a
// brief race where any API request will fail with a 401
// error after the old session is deactivated but before
// the new one has been propagated to the browser. So we
// skip our normal HTTP 401 error handling if we're in the
// process of executing a password change.
return;
}
if (xhr.status === 401) {
// We got logged out somehow, perhaps from another window
// changing the user's password, or a session timeout. We
// could display an error message, but jumping right to
// the login page conveys the same information with a
// smoother re-login experience.
window.location.replace(page_params.login_page);
}
});
$.fn.expectOne = function () {
if (blueslip && this.length !== 1) {
blueslip.error("Expected one element in jQuery set, " + this.length + " found");
}
return this;
};
});