[Bug] Unauthorized 401 error fix (#2315)

* reset scene on 401

* fix: Reset scene and clear session ID on 401 error

* Added explanation to clientSessionId
This commit is contained in:
Frederico Santos 2024-06-17 02:44:07 +01:00 committed by GitHub
parent de51c5b7a5
commit 1efb7c5847
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
4 changed files with 27 additions and 4 deletions

View File

@ -7,6 +7,7 @@ export interface UserInfo {
} }
export let loggedInUser: UserInfo = null; export let loggedInUser: UserInfo = null;
// This is a random string that is used to identify the client session - unique per session (tab or window) so that the game will only save on the one that the server is expecting
export const clientSessionId = Utils.randomString(32); export const clientSessionId = Utils.randomString(32);
export function initLoggedInUser(): void { export function initLoggedInUser(): void {

View File

@ -94,7 +94,14 @@ export class LoginPhase extends Phase {
this.scene.playSound("menu_open"); this.scene.playSound("menu_open");
const loadData = () => { const loadData = () => {
updateUserInfo().then(() => this.scene.gameData.loadSystem().then(() => this.end())); updateUserInfo().then(success => {
if (!success[0]) {
Utils.setCookie(Utils.sessionIdKey, "");
this.scene.reset(true, true);
return;
}
this.scene.gameData.loadSystem().then(() => this.end());
});
}; };
this.scene.ui.setMode(Mode.LOGIN_FORM, { this.scene.ui.setMode(Mode.LOGIN_FORM, {
@ -108,7 +115,14 @@ export class LoginPhase extends Phase {
buttonActions: [ buttonActions: [
() => { () => {
this.scene.ui.playSelect(); this.scene.ui.playSelect();
updateUserInfo().then(() => this.end()); updateUserInfo().then(success => {
if (!success[0]) {
Utils.setCookie(Utils.sessionIdKey, "");
this.scene.reset(true, true);
return;
}
this.end();
} );
}, () => { }, () => {
this.scene.unshiftPhase(new LoginPhase(this.scene, false)); this.scene.unshiftPhase(new LoginPhase(this.scene, false));
this.end(); this.end();
@ -118,6 +132,9 @@ export class LoginPhase extends Phase {
} }
] ]
}); });
} else if (statusCode === 401) {
Utils.setCookie(Utils.sessionIdKey, "");
this.scene.reset(true, true);
} else { } else {
this.scene.unshiftPhase(new UnavailablePhase(this.scene)); this.scene.unshiftPhase(new UnavailablePhase(this.scene));
super.end(); super.end();
@ -4198,7 +4215,8 @@ export class GameOverPhase extends BattlePhase {
If Offline, execute offlineNewClear(), a localStorage implementation of newClear daily run checks */ If Offline, execute offlineNewClear(), a localStorage implementation of newClear daily run checks */
if (this.victory) { if (this.victory) {
if (!Utils.isLocal) { if (!Utils.isLocal) {
Utils.apiFetch(`savedata/session/newclear?slot=${this.scene.sessionSlotId}&clientSessionId=${clientSessionId}`, true) .then(response => response.json()) Utils.apiFetch(`savedata/session/newclear?slot=${this.scene.sessionSlotId}&clientSessionId=${clientSessionId}`, true)
.then(response => response.json())
.then(newClear => doGameOver(newClear)); .then(newClear => doGameOver(newClear));
} else { } else {
this.scene.gameData.offlineNewClear(this.scene).then(result => { this.scene.gameData.offlineNewClear(this.scene).then(result => {

View File

@ -1261,7 +1261,7 @@ export class GameData {
if (!bypassLogin && dataType < GameDataType.SETTINGS) { if (!bypassLogin && dataType < GameDataType.SETTINGS) {
updateUserInfo().then(success => { updateUserInfo().then(success => {
if (!success) { if (!success[0]) {
return displayError(`Could not contact the server. Your ${dataName} data could not be imported.`); return displayError(`Could not contact the server. Your ${dataName} data could not be imported.`);
} }
let url: string; let url: string;

View File

@ -3,6 +3,7 @@ import { ModalConfig, ModalUiHandler } from "./modal-ui-handler";
import { addTextObject, TextStyle } from "./text"; import { addTextObject, TextStyle } from "./text";
import { Mode } from "./ui"; import { Mode } from "./ui";
import { updateUserInfo } from "#app/account"; import { updateUserInfo } from "#app/account";
import * as Utils from "#app/utils";
export default class UnavailableModalUiHandler extends ModalUiHandler { export default class UnavailableModalUiHandler extends ModalUiHandler {
private reconnectTimer: NodeJS.Timeout; private reconnectTimer: NodeJS.Timeout;
@ -55,6 +56,9 @@ export default class UnavailableModalUiHandler extends ModalUiHandler {
this.reconnectDuration = this.minTime; this.reconnectDuration = this.minTime;
this.scene.playSound("pb_bounce_1"); this.scene.playSound("pb_bounce_1");
this.reconnectCallback(); this.reconnectCallback();
} else if (response[1] === 401) {
Utils.setCookie(Utils.sessionIdKey, "");
this.scene.reset(true, true);
} else { } else {
this.reconnectDuration = Math.min(this.reconnectDuration * 2, this.maxTime); // Set a max delay so it isn't infinite this.reconnectDuration = Math.min(this.reconnectDuration * 2, this.maxTime); // Set a max delay so it isn't infinite
this.reconnectTimer = this.reconnectTimer =