Improving code security by adding stricter typings

This commit is contained in:
David Négrier 2021-12-14 18:55:41 +01:00
parent bbef3b3eaf
commit 2fff6ae41e
12 changed files with 45 additions and 23 deletions

View file

@ -11,6 +11,7 @@ import { loginSceneVisibleIframeStore } from "../Stores/LoginSceneStore";
import { userIsConnected } from "../Stores/MenuStore"; import { userIsConnected } from "../Stores/MenuStore";
import { analyticsClient } from "../Administration/AnalyticsClient"; import { analyticsClient } from "../Administration/AnalyticsClient";
import { axiosWithRetry } from "./AxiosUtils"; import { axiosWithRetry } from "./AxiosUtils";
import axios from "axios";
class ConnectionManager { class ConnectionManager {
private localUser!: LocalUser; private localUser!: LocalUser;
@ -192,11 +193,11 @@ class ConnectionManager {
analyticsClient.loggedWithSso(); analyticsClient.loggedWithSso();
} catch (err) { } catch (err) {
console.error(err); console.error(err);
//if user must to be connect in current room or pusher error is not openid provier access error // if the user must be connected in the current room or if the pusher error is not openid provider access error
//try to connected with function loadOpenIDScreen // try to connect with function loadOpenIDScreen
if ( if (
this._currentRoom.authenticationMandatory || this._currentRoom.authenticationMandatory ||
(err.response?.data && err.response.data !== "User cannot to be connected on openid provier") (axios.isAxiosError(err) && err.response?.data && err.response.data !== "User cannot to be connected on openid provider")
) { ) {
this.loadOpenIDScreen(); this.loadOpenIDScreen();
return Promise.reject(new Error("You will be redirect on login page")); return Promise.reject(new Error("You will be redirect on login page"));

View file

@ -5,6 +5,8 @@ import type { CharacterTexture } from "./LocalUser";
import { localUserStore } from "./LocalUserStore"; import { localUserStore } from "./LocalUserStore";
import axios from "axios"; import axios from "axios";
import { axiosWithRetry } from "./AxiosUtils"; import { axiosWithRetry } from "./AxiosUtils";
import {isMapDetailsData} from "../../../pusher/src/Messages/JsonMessages/MapDetailsData";
import {isRoomRedirect} from "../Messages/JsonMessages/RoomRedirect";
export class MapDetail { export class MapDetail {
constructor(public readonly mapUrl: string, public readonly textures: CharacterTexture[] | undefined) {} constructor(public readonly mapUrl: string, public readonly textures: CharacterTexture[] | undefined) {}
@ -101,27 +103,34 @@ export class Room {
}); });
const data = result.data; const data = result.data;
if (data.redirectUrl) {
if (isRoomRedirect(data.redirectUrl)) {
return { return {
redirectUrl: data.redirectUrl as string, redirectUrl: data.redirectUrl as string,
}; };
} else if (isMapDetailsData(data)) {
console.log("Map ", this.id, " resolves to URL ", data.mapUrl);
this._mapUrl = data.mapUrl;
this._textures = data.textures;
this._group = data.group;
this._authenticationMandatory =
data.authenticationMandatory != null ? data.authenticationMandatory : DISABLE_ANONYMOUS;
this._iframeAuthentication = data.iframeAuthentication || OPID_LOGIN_SCREEN_PROVIDER;
this._contactPage = data.contactPage || CONTACT_URL;
return new MapDetail(data.mapUrl, data.textures);
} else {
throw new Error('Data received by the /map endpoint of the Pusher is not in a valid format.');
} }
console.log("Map ", this.id, " resolves to URL ", data.mapUrl);
this._mapUrl = data.mapUrl;
this._textures = data.textures;
this._group = data.group;
this._authenticationMandatory =
data.authenticationMandatory != null ? data.authenticationMandatory : DISABLE_ANONYMOUS;
this._iframeAuthentication = data.iframeAuthentication || OPID_LOGIN_SCREEN_PROVIDER;
this._contactPage = data.contactPage || CONTACT_URL;
return new MapDetail(data.mapUrl, data.textures);
} catch (e) { } catch (e) {
if (axios.isAxiosError(e) && e.response?.status == 401 && e.response?.data === "Token decrypted error") { if (axios.isAxiosError(e) && e.response?.status == 401 && e.response?.data === "Token decrypted error") {
console.warn("JWT token sent could not be decrypted. Maybe it expired?"); console.warn("JWT token sent could not be decrypted. Maybe it expired?");
localUserStore.setAuthToken(null); localUserStore.setAuthToken(null);
window.location.assign("/login"); window.location.assign("/login");
} else { } else if (axios.isAxiosError(e)) {
console.error("Error => getMapDetail", e, e.response); console.error("Error => getMapDetail", e, e.response);
} else {
console.error("Error => getMapDetail", e);
} }
throw e; throw e;
} }

View file

@ -0,0 +1,2 @@
*
!.gitignore

View file

@ -1,7 +1,6 @@
import * as tg from "generic-type-guard"; import * as tg from "generic-type-guard";
import { GameRoomPolicyTypes } from "_Model/PusherRoom";
import { isCharacterTexture } from "./CharacterTexture"; import { isCharacterTexture } from "./CharacterTexture";
import { isAny, isNumber } from "generic-type-guard"; import { isNumber } from "generic-type-guard";
/*const isNumericEnum = /*const isNumericEnum =
<T extends { [n: number]: string }>(vs: T) => <T extends { [n: number]: string }>(vs: T) =>
@ -17,6 +16,7 @@ export const isMapDetailsData = new tg.IsInterface()
textures: tg.isArray(isCharacterTexture), textures: tg.isArray(isCharacterTexture),
contactPage: tg.isUnion(tg.isString, tg.isUndefined), contactPage: tg.isUnion(tg.isString, tg.isUndefined),
authenticationMandatory: tg.isUnion(tg.isBoolean, tg.isUndefined), authenticationMandatory: tg.isUnion(tg.isBoolean, tg.isUndefined),
group: tg.isString,
}) })
.get(); .get();

View file

@ -7,10 +7,13 @@
"copy-to-back": "rm -rf ../back/src/Messages/generated && cp -rf generated/ ../back/src/Messages/generated", "copy-to-back": "rm -rf ../back/src/Messages/generated && cp -rf generated/ ../back/src/Messages/generated",
"copy-to-front": "rm -rf ../front/src/Messages/generated && cp -rf generated/ ../front/src/Messages/generated", "copy-to-front": "rm -rf ../front/src/Messages/generated && cp -rf generated/ ../front/src/Messages/generated",
"copy-to-pusher": "rm -rf ../pusher/src/Messages/generated && cp -rf generated/ ../pusher/src/Messages/generated", "copy-to-pusher": "rm -rf ../pusher/src/Messages/generated && cp -rf generated/ ../pusher/src/Messages/generated",
"proto-all": "yarn run proto && yarn run copy-to-back && yarn run copy-to-front && yarn run copy-to-pusher", "json-copy-to-pusher": "rm -rf ../pusher/src/Messages/JsonMessages/* && cp -rf JsonMessages/* ../pusher/src/Messages/JsonMessages/",
"proto:watch": "yarn run proto-all; inotifywait -q -m -e close_write protos/messages.proto | while read -r filename event; do yarn run proto-all; done" "json-copy-to-front": "rm -rf ../front/src/Messages/JsonMessages/* && cp -rf JsonMessages/* ../front/src/Messages/JsonMessages/",
"proto-all": "yarn run proto && yarn run copy-to-back && yarn run copy-to-front && yarn run copy-to-pusher && yarn run json-copy-to-pusher && yarn run json-copy-to-front",
"proto:watch": "yarn run proto-all; inotifywait -q -m -e close_write protos/messages.proto JsonMessages/ | while read -r filename event; do yarn run proto-all; done"
}, },
"dependencies": { "dependencies": {
"generic-type-guard": "^3.5.0",
"google-protobuf": "^3.13.0", "google-protobuf": "^3.13.0",
"grpc": "^1.24.4" "grpc": "^1.24.4"
}, },

View file

@ -1788,6 +1788,11 @@ gauge@~2.7.3:
strip-ansi "^3.0.1" strip-ansi "^3.0.1"
wide-align "^1.1.0" wide-align "^1.1.0"
generic-type-guard@^3.5.0:
version "3.5.0"
resolved "https://registry.yarnpkg.com/generic-type-guard/-/generic-type-guard-3.5.0.tgz#39de9f8fceee65d79e7540959f0e7b23210c07b6"
integrity sha512-OpgXv/sbRobhFboaSyN/Tsh97Sxt5pcfLLxCiYZgYIIWFFp+kn2EzAXiaQZKEVRlq1rOE/zh8cYhJXEwplbJiQ==
get-caller-file@^2.0.1: get-caller-file@^2.0.1:
version "2.0.5" version "2.0.5"
resolved "https://registry.yarnpkg.com/get-caller-file/-/get-caller-file-2.0.5.tgz#4f94412a82db32f36e3b0b9741f8a97feb031f7e" resolved "https://registry.yarnpkg.com/get-caller-file/-/get-caller-file-2.0.5.tgz#4f94412a82db32f36e3b0b9741f8a97feb031f7e"

View file

@ -83,7 +83,7 @@ export class AuthenticateController extends BaseController {
console.error("Token cannot to be check on OpenId provider"); console.error("Token cannot to be check on OpenId provider");
res.writeStatus("500"); res.writeStatus("500");
res.writeHeader("Access-Control-Allow-Origin", FRONT_URL); res.writeHeader("Access-Control-Allow-Origin", FRONT_URL);
res.end("User cannot to be connected on openid provier"); res.end("User cannot to be connected on openid provider");
return; return;
} }
@ -105,7 +105,7 @@ export class AuthenticateController extends BaseController {
console.error("User cannot to be connected on OpenId provider => ", err); console.error("User cannot to be connected on OpenId provider => ", err);
res.writeStatus("500"); res.writeStatus("500");
res.writeHeader("Access-Control-Allow-Origin", FRONT_URL); res.writeHeader("Access-Control-Allow-Origin", FRONT_URL);
res.end("User cannot to be connected on openid provier"); res.end("User cannot to be connected on openid provider");
return; return;
} }
const email = userInfo.email || userInfo.sub; const email = userInfo.email || userInfo.sub;

View file

@ -4,7 +4,7 @@ import { parse } from "query-string";
import { adminApi } from "../Services/AdminApi"; import { adminApi } from "../Services/AdminApi";
import { ADMIN_API_URL, DISABLE_ANONYMOUS, FRONT_URL } from "../Enum/EnvironmentVariable"; import { ADMIN_API_URL, DISABLE_ANONYMOUS, FRONT_URL } from "../Enum/EnvironmentVariable";
import { GameRoomPolicyTypes } from "../Model/PusherRoom"; import { GameRoomPolicyTypes } from "../Model/PusherRoom";
import { isMapDetailsData, MapDetailsData } from "../Services/AdminApi/MapDetailsData"; import { isMapDetailsData, MapDetailsData } from "../Messages/JsonMessages/MapDetailsData";
import { socketManager } from "../Services/SocketManager"; import { socketManager } from "../Services/SocketManager";
import { AuthTokenData, jwtTokenManager } from "../Services/JWTTokenManager"; import { AuthTokenData, jwtTokenManager } from "../Services/JWTTokenManager";
import { v4 } from "uuid"; import { v4 } from "uuid";

View file

@ -0,0 +1,2 @@
*
!.gitignore

View file

@ -47,8 +47,8 @@ import { GroupDescriptor, UserDescriptor, ZoneEventListener } from "_Model/Zone"
import Debug from "debug"; import Debug from "debug";
import { ExAdminSocketInterface } from "_Model/Websocket/ExAdminSocketInterface"; import { ExAdminSocketInterface } from "_Model/Websocket/ExAdminSocketInterface";
import { WebSocket } from "uWebSockets.js"; import { WebSocket } from "uWebSockets.js";
import { isRoomRedirect } from "./AdminApi/RoomRedirect"; import { isRoomRedirect } from "../Messages/JsonMessages/RoomRedirect";
import { CharacterTexture } from "./AdminApi/CharacterTexture"; import { CharacterTexture } from "../Messages/JsonMessages/CharacterTexture";
const debug = Debug("socket"); const debug = Debug("socket");