Working on integration of the woka-list with the new admin endpoint.

This commit is contained in:
David Négrier 2022-02-24 21:09:19 +01:00
parent 0543232bc3
commit da469b64d2
14 changed files with 79 additions and 68 deletions

View File

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

View File

@ -27,7 +27,7 @@ import { ProtobufUtils } from "../Model/Websocket/ProtobufUtils";
import { RoomSocket, ZoneSocket } from "src/RoomManager";
import { Admin } from "../Model/Admin";
import { adminApi } from "../Services/AdminApi";
import { isMapDetailsData, MapDetailsData } from "../Services/AdminApi/MapDetailsData";
import { isMapDetailsData, MapDetailsData } from "../Messages/JsonMessages/MapDetailsData";
import { ITiledMap } from "@workadventure/tiled-map-type-guard/dist";
import { mapFetcher } from "../Services/MapFetcher";
import { VariablesManager } from "../Services/VariablesManager";
@ -35,7 +35,7 @@ import { ADMIN_API_URL } from "../Enum/EnvironmentVariable";
import { LocalUrlError } from "../Services/LocalUrlError";
import { emitErrorOnRoomSocket } from "../Services/MessageHelpers";
import { VariableError } from "../Services/VariableError";
import { isRoomRedirect } from "../Services/AdminApi/RoomRedirect";
import { isRoomRedirect } from "../Messages/JsonMessages/RoomRedirect";
export type ConnectCallback = (user: User, group: Group) => void;
export type DisconnectCallback = (user: User, group: Group) => void;
@ -571,8 +571,11 @@ export class GameRoom {
return {
mapUrl,
policy_type: 1,
textures: [],
tags: [],
authenticationMandatory: null,
roomSlug: null,
contactPage: null,
group: null,
};
}

View File

@ -1,7 +1,7 @@
import { ADMIN_API_TOKEN, ADMIN_API_URL } from "../Enum/EnvironmentVariable";
import Axios from "axios";
import { isMapDetailsData, MapDetailsData } from "./AdminApi/MapDetailsData";
import { isRoomRedirect, RoomRedirect } from "./AdminApi/RoomRedirect";
import { isMapDetailsData, MapDetailsData } from "../Messages/JsonMessages/MapDetailsData";
import { isRoomRedirect, RoomRedirect } from "../Messages/JsonMessages/RoomRedirect";
class AdminApi {
async fetchMapDetails(playUri: string): Promise<MapDetailsData | RoomRedirect> {

View File

@ -1,11 +0,0 @@
import * as tg from "generic-type-guard";
export const isCharacterTexture = new tg.IsInterface()
.withProperties({
id: tg.isNumber,
level: tg.isNumber,
url: tg.isString,
rights: tg.isString,
})
.get();
export type CharacterTexture = tg.GuardedType<typeof isCharacterTexture>;

View File

@ -1,21 +0,0 @@
import * as tg from "generic-type-guard";
import { isCharacterTexture } from "./CharacterTexture";
import { isAny, isNumber } from "generic-type-guard";
/*const isNumericEnum =
<T extends { [n: number]: string }>(vs: T) =>
(v: any): v is T =>
typeof v === "number" && v in vs;*/
export const isMapDetailsData = new tg.IsInterface()
.withProperties({
mapUrl: tg.isString,
policy_type: isNumber, //isNumericEnum(GameRoomPolicyTypes),
tags: tg.isArray(tg.isString),
textures: tg.isArray(isCharacterTexture),
})
.withOptionalProperties({
roomSlug: tg.isUnion(tg.isString, tg.isNull), // deprecated
})
.get();
export type MapDetailsData = tg.GuardedType<typeof isMapDetailsData>;

View File

@ -1,8 +0,0 @@
import * as tg from "generic-type-guard";
export const isRoomRedirect = new tg.IsInterface()
.withProperties({
redirectUrl: tg.isString,
})
.get();
export type RoomRedirect = tg.GuardedType<typeof isRoomRedirect>;

View File

@ -340,8 +340,21 @@ export class RoomConnection implements RoomConnection {
this.userId = roomJoinedMessage.currentUserId;
this.tags = roomJoinedMessage.tag;
this._userRoomToken = roomJoinedMessage.userRoomToken;
// If one of the URLs sent to us does not exist, let's go to the Woka selection screen.
for (const characterLayer of roomJoinedMessage.characterLayer) {
if (!characterLayer.url) {
this.goToSelectYourWokaScene();
this.closed = true;
break;
}
}
if (this.closed) {
break;
}
const characterLayers = roomJoinedMessage.characterLayer.map(
this.mapCharactgerLayerToBodyResourceDescription.bind(this)
this.mapCharacterLayerToBodyResourceDescription.bind(this)
);
this._roomJoinedMessageStream.next({
@ -360,10 +373,7 @@ export class RoomConnection implements RoomConnection {
break;
}
case "invalidTextureMessage": {
menuVisiblilityStore.set(false);
menuIconVisiblilityStore.set(false);
selectCharacterSceneVisibleStore.set(true);
gameManager.leaveGame(SelectCharacterSceneName, new SelectCharacterScene());
this.goToSelectYourWokaScene();
this.closed = true;
break;
@ -608,7 +618,7 @@ export class RoomConnection implements RoomConnection {
});
}*/
private mapCharactgerLayerToBodyResourceDescription(
private mapCharacterLayerToBodyResourceDescription(
characterLayer: CharacterLayerMessage
): BodyResourceDescriptionInterface {
return {
@ -624,9 +634,7 @@ export class RoomConnection implements RoomConnection {
throw new Error("Invalid JOIN_ROOM message");
}
const characterLayers = message.characterLayers.map(
this.mapCharactgerLayerToBodyResourceDescription.bind(this)
);
const characterLayers = message.characterLayers.map(this.mapCharacterLayerToBodyResourceDescription.bind(this));
const companion = message.companion;
@ -886,4 +894,11 @@ export class RoomConnection implements RoomConnection {
public get userRoomToken(): string | undefined {
return this._userRoomToken;
}
private goToSelectYourWokaScene(): void {
menuVisiblilityStore.set(false);
menuIconVisiblilityStore.set(false);
selectCharacterSceneVisibleStore.set(true);
gameManager.leaveGame(SelectCharacterSceneName, new SelectCharacterScene());
}
}

View File

@ -1535,7 +1535,7 @@ ${escapedMessage}
this.messageSubscription?.unsubscribe();
this.userInputManager.destroy();
this.pinchManager?.destroy();
this.emoteManager.destroy();
this.emoteManager?.destroy();
this.cameraManager.destroy();
this.peerStoreUnsubscribe();
this.emoteUnsubscribe();

View File

@ -43,9 +43,22 @@ export class SelectCharacterScene extends AbstractCharacterScene {
}
preload() {
const wokaMetadataKey = "woka-list";
const wokaMetadataKey = "woka/list";
this.cache.json.remove(wokaMetadataKey);
this.load.json(wokaMetadataKey, `${PUSHER_URL}/${wokaMetadataKey}`);
// FIXME: window.location.href is wrong. We need the URL of the main room (so we need to apply any redirect before!)
this.load.json(
wokaMetadataKey,
`${PUSHER_URL}/${wokaMetadataKey}/` + encodeURIComponent(window.location.href),
undefined,
{
responseType: "text",
headers: {
Authorization: localUserStore.getAuthToken() ?? "",
},
withCredentials: true,
}
);
this.load.once(`filecomplete-json-${wokaMetadataKey}`, () => {
this.playerTextures.loadPlayerTexturesMetadata(this.cache.json.get(wokaMetadataKey));
this.loadSelectSceneCharacters()

View File

@ -9,9 +9,10 @@
"copy-to-front-ts-proto": "sed 's/import { Observable } from \"rxjs\";/import type { Observable } from \"rxjs\";/g' ts-proto-generated/protos/messages.ts > ../front/src/Messages/ts-proto-generated/messages.ts",
"copy-to-pusher": "rm -rf ../pusher/src/Messages/generated && cp -rf generated/ ../pusher/src/Messages/generated",
"json-copy-to-pusher": "rm -rf ../pusher/src/Messages/JsonMessages/* && cp -rf JsonMessages/* ../pusher/src/Messages/JsonMessages/",
"json-copy-to-back": "rm -rf ../back/src/Messages/JsonMessages/* && cp -rf JsonMessages/* ../back/src/Messages/JsonMessages/",
"json-copy-to-front": "rm -rf ../front/src/Messages/JsonMessages/* && cp -rf JsonMessages/* ../front/src/Messages/JsonMessages/",
"precommit": "lint-staged",
"proto-all": "yarn run proto && yarn run ts-proto && yarn run copy-to-back && yarn run copy-to-front-ts-proto && yarn run copy-to-pusher && yarn run json-copy-to-pusher && yarn run json-copy-to-front",
"proto-all": "yarn run proto && yarn run ts-proto && yarn run copy-to-back && yarn run copy-to-front-ts-proto && yarn run copy-to-pusher && yarn run json-copy-to-pusher && yarn run json-copy-to-back && 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",
"pretty": "yarn prettier --write 'JsonMessages/**/*.ts'",
"pretty-check": "yarn prettier --check 'JsonMessages/**/*.ts'"

View File

@ -68,7 +68,7 @@ export class AuthenticateController extends BaseHttpController {
);
res.status(302);
res.setHeader("Location", loginUri);
return res;
return res.send("");
} catch (e) {
console.error("openIDLogin => e", e);
this.castErrorToResponse(e, res);

View File

@ -1,11 +1,16 @@
import { BaseHttpController } from "./BaseHttpController";
import { wokaService } from "../Services/WokaService";
import * as tg from "generic-type-guard";
import { jwtTokenManager } from "../Services/JWTTokenManager";
export class WokaListController extends BaseHttpController {
routes() {
this.app.options("/woka/list/:roomUrl", {}, async (req, res) => {
res.status(200).send("");
});
// eslint-disable-next-line @typescript-eslint/no-misused-promises
this.app.get("/woka/list/:roomId", {}, async (req, res) => {
this.app.get("/woka/list/:roomUrl", {}, async (req, res) => {
const token = req.header("Authorization");
if (!token) {
@ -13,12 +18,19 @@ export class WokaListController extends BaseHttpController {
return;
}
try {
const jwtData = jwtTokenManager.verifyJWTToken(token);
// Let's set the "uuid" param
req.params["uuid"] = jwtData.identifier;
} catch (e) {
console.error("Connection refused for token: " + token, e);
res.status(401).send("Invalid token sent");
return;
}
const isParameters = new tg.IsInterface()
.withProperties({
roomId: tg.isString,
})
.withOptionalProperties({
messages: tg.isArray(tg.isUnknown),
roomUrl: tg.isString,
})
.get();
@ -26,8 +38,8 @@ export class WokaListController extends BaseHttpController {
return res.status(400).send("Unknown parameters");
}
const roomId = req.path_parameters.roomId;
const wokaList = await wokaService.getWokaList(roomId, token);
const roomUrl = decodeURIComponent(req.path_parameters.roomUrl);
const wokaList = await wokaService.getWokaList(roomUrl, req.params["uuid"]);
if (!wokaList) {
return res.status(500).send("Error on getting woka list");

View File

@ -10,6 +10,7 @@ export function cors(req: Request, res: Response, next?: MiddlewareNext): Middle
);
res.setHeader("access-control-allow-methods", "GET, POST, OPTIONS, PUT, PATCH, DELETE");
res.setHeader("access-control-allow-origin", FRONT_URL);
res.setHeader("access-control-allow-credentials", "true");
if (next) {
next();

View File

@ -7,10 +7,14 @@ class AdminWokaService implements WokaServiceInterface {
/**
* Returns the list of all available Wokas for the current user.
*/
getWokaList(roomId: string, token: string): Promise<WokaList | undefined> {
getWokaList(roomUrl: string, token: string): Promise<WokaList | undefined> {
return axios
.get(`${ADMIN_API_URL}/api/woka/list/${roomId}/${token}`, {
.get(`${ADMIN_API_URL}/api/woka/list`, {
headers: { Authorization: `${ADMIN_API_TOKEN}` },
params: {
roomUrl,
uuid: token,
},
})
.then((res) => {
if (isWokaList(res.data)) {