Zod EVERYWHERE (#2027)
* Zod EVERYWHERE * Add no-unused-vars rule to eslint in front * Add no-unused-vars rule to eslint in pusher * Add no-unused-vars rule to eslint in back * Remove unused PlayerTexture guards * Fix data providing on room connection Co-authored-by: Alexis Faizeau <a.faizeau@workadventu.re>
This commit is contained in:
@@ -1,10 +1,9 @@
|
||||
import { ADMIN_API_TOKEN, ADMIN_API_URL, ADMIN_URL, OPID_PROFILE_SCREEN_PROVIDER } from "../Enum/EnvironmentVariable";
|
||||
import { ADMIN_API_TOKEN, ADMIN_API_URL, OPID_PROFILE_SCREEN_PROVIDER } from "../Enum/EnvironmentVariable";
|
||||
import Axios, { AxiosResponse } from "axios";
|
||||
import { isMapDetailsData, MapDetailsData } from "../Messages/JsonMessages/MapDetailsData";
|
||||
import { isRoomRedirect, RoomRedirect } from "../Messages/JsonMessages/RoomRedirect";
|
||||
import { AdminApiData, isAdminApiData } from "../Messages/JsonMessages/AdminApiData";
|
||||
import * as tg from "generic-type-guard";
|
||||
import { isNumber } from "generic-type-guard";
|
||||
import { z } from "zod";
|
||||
import { isWokaDetail } from "../Messages/JsonMessages/PlayerTextures";
|
||||
import qs from "qs";
|
||||
|
||||
@@ -13,22 +12,18 @@ export interface AdminBannedData {
|
||||
message: string;
|
||||
}
|
||||
|
||||
const isFetchMemberDataByUuidResponse = new tg.IsInterface()
|
||||
.withProperties({
|
||||
email: tg.isString,
|
||||
userUuid: tg.isString,
|
||||
tags: tg.isArray(tg.isString),
|
||||
visitCardUrl: tg.isNullable(tg.isString),
|
||||
textures: tg.isArray(isWokaDetail),
|
||||
messages: tg.isArray(tg.isUnknown),
|
||||
})
|
||||
.withOptionalProperties({
|
||||
anonymous: tg.isBoolean,
|
||||
userRoomToken: tg.isString,
|
||||
})
|
||||
.get();
|
||||
export const isFetchMemberDataByUuidResponse = z.object({
|
||||
email: z.string(),
|
||||
userUuid: z.string(),
|
||||
tags: z.array(z.string()),
|
||||
visitCardUrl: z.nullable(z.string()),
|
||||
textures: z.array(isWokaDetail),
|
||||
messages: z.array(z.unknown()),
|
||||
anonymous: z.optional(z.boolean()),
|
||||
userRoomToken: z.optional(z.string()),
|
||||
});
|
||||
|
||||
export type FetchMemberDataByUuidResponse = tg.GuardedType<typeof isFetchMemberDataByUuidResponse>;
|
||||
export type FetchMemberDataByUuidResponse = z.infer<typeof isFetchMemberDataByUuidResponse>;
|
||||
|
||||
class AdminApi {
|
||||
/**
|
||||
@@ -50,13 +45,23 @@ class AdminApi {
|
||||
headers: { Authorization: `${ADMIN_API_TOKEN}` },
|
||||
params,
|
||||
});
|
||||
if (!isMapDetailsData(res.data) && !isRoomRedirect(res.data)) {
|
||||
throw new Error(
|
||||
"Invalid answer received from the admin for the /api/map endpoint. Received: " +
|
||||
JSON.stringify(res.data)
|
||||
);
|
||||
|
||||
const mapDetailData = isMapDetailsData.safeParse(res.data);
|
||||
const roomRedirect = isRoomRedirect.safeParse(res.data);
|
||||
|
||||
if (mapDetailData.success) {
|
||||
return mapDetailData.data;
|
||||
}
|
||||
return res.data;
|
||||
|
||||
if (roomRedirect.success) {
|
||||
return roomRedirect.data;
|
||||
}
|
||||
|
||||
console.error(mapDetailData.error.issues);
|
||||
console.error(roomRedirect.error.issues);
|
||||
throw new Error(
|
||||
"Invalid answer received from the admin for the /api/map endpoint. Received: " + JSON.stringify(res.data)
|
||||
);
|
||||
}
|
||||
|
||||
async fetchMemberDataByUuid(
|
||||
@@ -80,13 +85,18 @@ class AdminApi {
|
||||
return qs.stringify(p, { arrayFormat: "brackets" });
|
||||
},
|
||||
});
|
||||
if (!isFetchMemberDataByUuidResponse(res.data)) {
|
||||
throw new Error(
|
||||
"Invalid answer received from the admin for the /api/room/access endpoint. Received: " +
|
||||
JSON.stringify(res.data)
|
||||
);
|
||||
|
||||
const fetchMemberDataByUuidResponse = isFetchMemberDataByUuidResponse.safeParse(res.data);
|
||||
|
||||
if (fetchMemberDataByUuidResponse.success) {
|
||||
return fetchMemberDataByUuidResponse.data;
|
||||
}
|
||||
return res.data;
|
||||
|
||||
console.error(fetchMemberDataByUuidResponse.error.issues);
|
||||
throw new Error(
|
||||
"Invalid answer received from the admin for the /api/room/access endpoint. Received: " +
|
||||
JSON.stringify(res.data)
|
||||
);
|
||||
}
|
||||
|
||||
async fetchMemberDataByToken(organizationMemberToken: string, playUri: string | null): Promise<AdminApiData> {
|
||||
@@ -98,11 +108,16 @@ class AdminApi {
|
||||
params: { playUri },
|
||||
headers: { Authorization: `${ADMIN_API_TOKEN}` },
|
||||
});
|
||||
if (!isAdminApiData(res.data)) {
|
||||
console.error("Message received from /api/login-url is not in the expected format. Message: ", res.data);
|
||||
throw new Error("Message received from /api/login-url is not in the expected format.");
|
||||
|
||||
const adminApiData = isAdminApiData.safeParse(res.data);
|
||||
|
||||
if (adminApiData.success) {
|
||||
return adminApiData.data;
|
||||
}
|
||||
return res.data;
|
||||
|
||||
console.error(adminApiData.error.issues);
|
||||
console.error("Message received from /api/login-url is not in the expected format. Message: ", res.data);
|
||||
throw new Error("Message received from /api/login-url is not in the expected format.");
|
||||
}
|
||||
|
||||
reportPlayer(
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { ExSocketInterface } from "_Model/Websocket/ExSocketInterface";
|
||||
import { ExSocketInterface } from "../Model/Websocket/ExSocketInterface";
|
||||
import { BatchMessage, ErrorMessage, ServerToClientMessage, SubMessage } from "../Messages/generated/messages_pb";
|
||||
import { WebSocket } from "uWebSockets.js";
|
||||
|
||||
|
||||
@@ -1,10 +1,11 @@
|
||||
import { WokaDetail, WokaDetailsResult, WokaList, wokaPartNames } from "../Messages/JsonMessages/PlayerTextures";
|
||||
import { WokaDetail, WokaList, wokaPartNames } from "../Messages/JsonMessages/PlayerTextures";
|
||||
import { WokaServiceInterface } from "./WokaServiceInterface";
|
||||
|
||||
class LocalWokaService implements WokaServiceInterface {
|
||||
/**
|
||||
* Returns the list of all available Wokas & Woka Parts for the current user.
|
||||
*/
|
||||
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
||||
async getWokaList(roomId: string, token: string): Promise<WokaList | undefined> {
|
||||
const wokaData: WokaList = await require("../../data/woka.json");
|
||||
if (!wokaData) {
|
||||
@@ -21,7 +22,7 @@ class LocalWokaService implements WokaServiceInterface {
|
||||
*
|
||||
* If one of the textures cannot be found, undefined is returned (and the user should be redirected to Woka choice page!)
|
||||
*/
|
||||
async fetchWokaDetails(textureIds: string[]): Promise<WokaDetailsResult | undefined> {
|
||||
async fetchWokaDetails(textureIds: string[]): Promise<WokaDetail[] | undefined> {
|
||||
const wokaData: WokaList = await require("../../data/woka.json");
|
||||
const textures = new Map<
|
||||
string,
|
||||
|
||||
@@ -49,13 +49,11 @@ import Jwt from "jsonwebtoken";
|
||||
import { clientEventsEmitter } from "./ClientEventsEmitter";
|
||||
import { gaugeManager } from "./GaugeManager";
|
||||
import { apiClientRepository } from "./ApiClientRepository";
|
||||
import { GroupDescriptor, UserDescriptor, ZoneEventListener } from "_Model/Zone";
|
||||
import { GroupDescriptor, UserDescriptor, ZoneEventListener } from "../Model/Zone";
|
||||
import Debug from "debug";
|
||||
import { ExAdminSocketInterface } from "_Model/Websocket/ExAdminSocketInterface";
|
||||
import { WebSocket } from "uWebSockets.js";
|
||||
import { isRoomRedirect } from "../Messages/JsonMessages/RoomRedirect";
|
||||
//import { CharacterTexture } from "../Messages/JsonMessages/CharacterTexture";
|
||||
import { ExAdminSocketInterface } from "../Model/Websocket/ExAdminSocketInterface";
|
||||
import { compressors } from "hyper-express";
|
||||
import { isMapDetailsData } from "../Messages/JsonMessages/MapDetailsData";
|
||||
|
||||
const debug = Debug("socket");
|
||||
|
||||
@@ -446,13 +444,14 @@ export class SocketManager implements ZoneEventListener {
|
||||
|
||||
public async updateRoomWithAdminData(room: PusherRoom): Promise<void> {
|
||||
const data = await adminApi.fetchMapDetails(room.roomUrl);
|
||||
const mapDetailsData = isMapDetailsData.safeParse(data);
|
||||
|
||||
if (isRoomRedirect(data)) {
|
||||
if (mapDetailsData.success) {
|
||||
room.tags = mapDetailsData.data.tags;
|
||||
room.policyType = Number(mapDetailsData.data.policy_type);
|
||||
} else {
|
||||
// TODO: if the updated room data is actually a redirect, we need to take everybody on the map
|
||||
// and redirect everybody to the new location (so we need to close the connection for everybody)
|
||||
} else {
|
||||
room.tags = data.tags;
|
||||
room.policyType = Number(data.policy_type);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -683,7 +682,7 @@ export class SocketManager implements ZoneEventListener {
|
||||
for (const roomUrl of tabUrlRooms) {
|
||||
const apiRoom = await apiClientRepository.getClient(roomUrl);
|
||||
roomMessage.setRoomid(roomUrl);
|
||||
apiRoom.sendAdminMessageToRoom(roomMessage, (response) => {
|
||||
apiRoom.sendAdminMessageToRoom(roomMessage, () => {
|
||||
return;
|
||||
});
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user