Working on integration of the woka-list with the new admin endpoint.
This commit is contained in:
parent
0543232bc3
commit
da469b64d2
2
back/src/Messages/JsonMessages/.gitignore
vendored
Normal file
2
back/src/Messages/JsonMessages/.gitignore
vendored
Normal file
@ -0,0 +1,2 @@
|
|||||||
|
*
|
||||||
|
!.gitignore
|
@ -27,7 +27,7 @@ import { ProtobufUtils } from "../Model/Websocket/ProtobufUtils";
|
|||||||
import { RoomSocket, ZoneSocket } from "src/RoomManager";
|
import { RoomSocket, ZoneSocket } from "src/RoomManager";
|
||||||
import { Admin } from "../Model/Admin";
|
import { Admin } from "../Model/Admin";
|
||||||
import { adminApi } from "../Services/AdminApi";
|
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 { ITiledMap } from "@workadventure/tiled-map-type-guard/dist";
|
||||||
import { mapFetcher } from "../Services/MapFetcher";
|
import { mapFetcher } from "../Services/MapFetcher";
|
||||||
import { VariablesManager } from "../Services/VariablesManager";
|
import { VariablesManager } from "../Services/VariablesManager";
|
||||||
@ -35,7 +35,7 @@ import { ADMIN_API_URL } from "../Enum/EnvironmentVariable";
|
|||||||
import { LocalUrlError } from "../Services/LocalUrlError";
|
import { LocalUrlError } from "../Services/LocalUrlError";
|
||||||
import { emitErrorOnRoomSocket } from "../Services/MessageHelpers";
|
import { emitErrorOnRoomSocket } from "../Services/MessageHelpers";
|
||||||
import { VariableError } from "../Services/VariableError";
|
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 ConnectCallback = (user: User, group: Group) => void;
|
||||||
export type DisconnectCallback = (user: User, group: Group) => void;
|
export type DisconnectCallback = (user: User, group: Group) => void;
|
||||||
@ -571,8 +571,11 @@ export class GameRoom {
|
|||||||
return {
|
return {
|
||||||
mapUrl,
|
mapUrl,
|
||||||
policy_type: 1,
|
policy_type: 1,
|
||||||
textures: [],
|
|
||||||
tags: [],
|
tags: [],
|
||||||
|
authenticationMandatory: null,
|
||||||
|
roomSlug: null,
|
||||||
|
contactPage: null,
|
||||||
|
group: null,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
import { ADMIN_API_TOKEN, ADMIN_API_URL } from "../Enum/EnvironmentVariable";
|
import { ADMIN_API_TOKEN, ADMIN_API_URL } from "../Enum/EnvironmentVariable";
|
||||||
import Axios from "axios";
|
import Axios from "axios";
|
||||||
import { isMapDetailsData, MapDetailsData } from "./AdminApi/MapDetailsData";
|
import { isMapDetailsData, MapDetailsData } from "../Messages/JsonMessages/MapDetailsData";
|
||||||
import { isRoomRedirect, RoomRedirect } from "./AdminApi/RoomRedirect";
|
import { isRoomRedirect, RoomRedirect } from "../Messages/JsonMessages/RoomRedirect";
|
||||||
|
|
||||||
class AdminApi {
|
class AdminApi {
|
||||||
async fetchMapDetails(playUri: string): Promise<MapDetailsData | RoomRedirect> {
|
async fetchMapDetails(playUri: string): Promise<MapDetailsData | RoomRedirect> {
|
||||||
|
@ -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>;
|
|
@ -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>;
|
|
@ -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>;
|
|
@ -340,8 +340,21 @@ export class RoomConnection implements RoomConnection {
|
|||||||
this.userId = roomJoinedMessage.currentUserId;
|
this.userId = roomJoinedMessage.currentUserId;
|
||||||
this.tags = roomJoinedMessage.tag;
|
this.tags = roomJoinedMessage.tag;
|
||||||
this._userRoomToken = roomJoinedMessage.userRoomToken;
|
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(
|
const characterLayers = roomJoinedMessage.characterLayer.map(
|
||||||
this.mapCharactgerLayerToBodyResourceDescription.bind(this)
|
this.mapCharacterLayerToBodyResourceDescription.bind(this)
|
||||||
);
|
);
|
||||||
|
|
||||||
this._roomJoinedMessageStream.next({
|
this._roomJoinedMessageStream.next({
|
||||||
@ -360,10 +373,7 @@ export class RoomConnection implements RoomConnection {
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case "invalidTextureMessage": {
|
case "invalidTextureMessage": {
|
||||||
menuVisiblilityStore.set(false);
|
this.goToSelectYourWokaScene();
|
||||||
menuIconVisiblilityStore.set(false);
|
|
||||||
selectCharacterSceneVisibleStore.set(true);
|
|
||||||
gameManager.leaveGame(SelectCharacterSceneName, new SelectCharacterScene());
|
|
||||||
|
|
||||||
this.closed = true;
|
this.closed = true;
|
||||||
break;
|
break;
|
||||||
@ -608,7 +618,7 @@ export class RoomConnection implements RoomConnection {
|
|||||||
});
|
});
|
||||||
}*/
|
}*/
|
||||||
|
|
||||||
private mapCharactgerLayerToBodyResourceDescription(
|
private mapCharacterLayerToBodyResourceDescription(
|
||||||
characterLayer: CharacterLayerMessage
|
characterLayer: CharacterLayerMessage
|
||||||
): BodyResourceDescriptionInterface {
|
): BodyResourceDescriptionInterface {
|
||||||
return {
|
return {
|
||||||
@ -624,9 +634,7 @@ export class RoomConnection implements RoomConnection {
|
|||||||
throw new Error("Invalid JOIN_ROOM message");
|
throw new Error("Invalid JOIN_ROOM message");
|
||||||
}
|
}
|
||||||
|
|
||||||
const characterLayers = message.characterLayers.map(
|
const characterLayers = message.characterLayers.map(this.mapCharacterLayerToBodyResourceDescription.bind(this));
|
||||||
this.mapCharactgerLayerToBodyResourceDescription.bind(this)
|
|
||||||
);
|
|
||||||
|
|
||||||
const companion = message.companion;
|
const companion = message.companion;
|
||||||
|
|
||||||
@ -886,4 +894,11 @@ export class RoomConnection implements RoomConnection {
|
|||||||
public get userRoomToken(): string | undefined {
|
public get userRoomToken(): string | undefined {
|
||||||
return this._userRoomToken;
|
return this._userRoomToken;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private goToSelectYourWokaScene(): void {
|
||||||
|
menuVisiblilityStore.set(false);
|
||||||
|
menuIconVisiblilityStore.set(false);
|
||||||
|
selectCharacterSceneVisibleStore.set(true);
|
||||||
|
gameManager.leaveGame(SelectCharacterSceneName, new SelectCharacterScene());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -1535,7 +1535,7 @@ ${escapedMessage}
|
|||||||
this.messageSubscription?.unsubscribe();
|
this.messageSubscription?.unsubscribe();
|
||||||
this.userInputManager.destroy();
|
this.userInputManager.destroy();
|
||||||
this.pinchManager?.destroy();
|
this.pinchManager?.destroy();
|
||||||
this.emoteManager.destroy();
|
this.emoteManager?.destroy();
|
||||||
this.cameraManager.destroy();
|
this.cameraManager.destroy();
|
||||||
this.peerStoreUnsubscribe();
|
this.peerStoreUnsubscribe();
|
||||||
this.emoteUnsubscribe();
|
this.emoteUnsubscribe();
|
||||||
|
@ -43,9 +43,22 @@ export class SelectCharacterScene extends AbstractCharacterScene {
|
|||||||
}
|
}
|
||||||
|
|
||||||
preload() {
|
preload() {
|
||||||
const wokaMetadataKey = "woka-list";
|
const wokaMetadataKey = "woka/list";
|
||||||
this.cache.json.remove(wokaMetadataKey);
|
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.load.once(`filecomplete-json-${wokaMetadataKey}`, () => {
|
||||||
this.playerTextures.loadPlayerTexturesMetadata(this.cache.json.get(wokaMetadataKey));
|
this.playerTextures.loadPlayerTexturesMetadata(this.cache.json.get(wokaMetadataKey));
|
||||||
this.loadSelectSceneCharacters()
|
this.loadSelectSceneCharacters()
|
||||||
|
@ -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-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",
|
"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-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/",
|
"json-copy-to-front": "rm -rf ../front/src/Messages/JsonMessages/* && cp -rf JsonMessages/* ../front/src/Messages/JsonMessages/",
|
||||||
"precommit": "lint-staged",
|
"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",
|
"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": "yarn prettier --write 'JsonMessages/**/*.ts'",
|
||||||
"pretty-check": "yarn prettier --check 'JsonMessages/**/*.ts'"
|
"pretty-check": "yarn prettier --check 'JsonMessages/**/*.ts'"
|
||||||
|
@ -68,7 +68,7 @@ export class AuthenticateController extends BaseHttpController {
|
|||||||
);
|
);
|
||||||
res.status(302);
|
res.status(302);
|
||||||
res.setHeader("Location", loginUri);
|
res.setHeader("Location", loginUri);
|
||||||
return res;
|
return res.send("");
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
console.error("openIDLogin => e", e);
|
console.error("openIDLogin => e", e);
|
||||||
this.castErrorToResponse(e, res);
|
this.castErrorToResponse(e, res);
|
||||||
|
@ -1,11 +1,16 @@
|
|||||||
import { BaseHttpController } from "./BaseHttpController";
|
import { BaseHttpController } from "./BaseHttpController";
|
||||||
import { wokaService } from "../Services/WokaService";
|
import { wokaService } from "../Services/WokaService";
|
||||||
import * as tg from "generic-type-guard";
|
import * as tg from "generic-type-guard";
|
||||||
|
import { jwtTokenManager } from "../Services/JWTTokenManager";
|
||||||
|
|
||||||
export class WokaListController extends BaseHttpController {
|
export class WokaListController extends BaseHttpController {
|
||||||
routes() {
|
routes() {
|
||||||
|
this.app.options("/woka/list/:roomUrl", {}, async (req, res) => {
|
||||||
|
res.status(200).send("");
|
||||||
|
});
|
||||||
|
|
||||||
// eslint-disable-next-line @typescript-eslint/no-misused-promises
|
// 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");
|
const token = req.header("Authorization");
|
||||||
|
|
||||||
if (!token) {
|
if (!token) {
|
||||||
@ -13,12 +18,19 @@ export class WokaListController extends BaseHttpController {
|
|||||||
return;
|
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()
|
const isParameters = new tg.IsInterface()
|
||||||
.withProperties({
|
.withProperties({
|
||||||
roomId: tg.isString,
|
roomUrl: tg.isString,
|
||||||
})
|
|
||||||
.withOptionalProperties({
|
|
||||||
messages: tg.isArray(tg.isUnknown),
|
|
||||||
})
|
})
|
||||||
.get();
|
.get();
|
||||||
|
|
||||||
@ -26,8 +38,8 @@ export class WokaListController extends BaseHttpController {
|
|||||||
return res.status(400).send("Unknown parameters");
|
return res.status(400).send("Unknown parameters");
|
||||||
}
|
}
|
||||||
|
|
||||||
const roomId = req.path_parameters.roomId;
|
const roomUrl = decodeURIComponent(req.path_parameters.roomUrl);
|
||||||
const wokaList = await wokaService.getWokaList(roomId, token);
|
const wokaList = await wokaService.getWokaList(roomUrl, req.params["uuid"]);
|
||||||
|
|
||||||
if (!wokaList) {
|
if (!wokaList) {
|
||||||
return res.status(500).send("Error on getting woka list");
|
return res.status(500).send("Error on getting woka list");
|
||||||
|
@ -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-methods", "GET, POST, OPTIONS, PUT, PATCH, DELETE");
|
||||||
res.setHeader("access-control-allow-origin", FRONT_URL);
|
res.setHeader("access-control-allow-origin", FRONT_URL);
|
||||||
|
res.setHeader("access-control-allow-credentials", "true");
|
||||||
|
|
||||||
if (next) {
|
if (next) {
|
||||||
next();
|
next();
|
||||||
|
@ -7,10 +7,14 @@ class AdminWokaService implements WokaServiceInterface {
|
|||||||
/**
|
/**
|
||||||
* Returns the list of all available Wokas for the current user.
|
* 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
|
return axios
|
||||||
.get(`${ADMIN_API_URL}/api/woka/list/${roomId}/${token}`, {
|
.get(`${ADMIN_API_URL}/api/woka/list`, {
|
||||||
headers: { Authorization: `${ADMIN_API_TOKEN}` },
|
headers: { Authorization: `${ADMIN_API_TOKEN}` },
|
||||||
|
params: {
|
||||||
|
roomUrl,
|
||||||
|
uuid: token,
|
||||||
|
},
|
||||||
})
|
})
|
||||||
.then((res) => {
|
.then((res) => {
|
||||||
if (isWokaList(res.data)) {
|
if (isWokaList(res.data)) {
|
||||||
|
Loading…
Reference in New Issue
Block a user