Merge branch 'develop' of github.com:thecodingmachine/workadventure into improve_logging
This commit is contained in:
commit
a1107bd20e
71 changed files with 10373 additions and 520 deletions
|
@ -6,6 +6,7 @@ import { PrometheusController } from "./Controller/PrometheusController";
|
|||
import { DebugController } from "./Controller/DebugController";
|
||||
import { App as uwsApp } from "./Server/sifrr.server";
|
||||
import { AdminController } from "./Controller/AdminController";
|
||||
import { OpenIdProfileController } from "./Controller/OpenIdProfileController";
|
||||
|
||||
class App {
|
||||
public app: uwsApp;
|
||||
|
@ -15,6 +16,7 @@ class App {
|
|||
public prometheusController: PrometheusController;
|
||||
private debugController: DebugController;
|
||||
private adminController: AdminController;
|
||||
private openIdProfileController: OpenIdProfileController;
|
||||
|
||||
constructor() {
|
||||
this.app = new uwsApp();
|
||||
|
@ -26,6 +28,7 @@ class App {
|
|||
this.prometheusController = new PrometheusController(this.app);
|
||||
this.debugController = new DebugController(this.app);
|
||||
this.adminController = new AdminController(this.app);
|
||||
this.openIdProfileController = new OpenIdProfileController(this.app);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -1,10 +1,11 @@
|
|||
import { v4 } from "uuid";
|
||||
import { HttpRequest, HttpResponse, TemplatedApp } from "uWebSockets.js";
|
||||
import { BaseController } from "./BaseController";
|
||||
import { adminApi } from "../Services/AdminApi";
|
||||
import { adminApi, FetchMemberDataByUuidResponse } from "../Services/AdminApi";
|
||||
import { AuthTokenData, jwtTokenManager } from "../Services/JWTTokenManager";
|
||||
import { parse } from "query-string";
|
||||
import { openIDClient } from "../Services/OpenIDClient";
|
||||
import { DISABLE_ANONYMOUS } from "../Enum/EnvironmentVariable";
|
||||
import log from "../Services/Logger";
|
||||
|
||||
export interface TokenInterface {
|
||||
|
@ -56,19 +57,37 @@ export class AuthenticateController extends BaseController {
|
|||
res.onAborted(() => {
|
||||
log.warn("/message request was aborted");
|
||||
});
|
||||
const { code, nonce, token } = parse(req.getQuery());
|
||||
const IPAddress = req.getHeader("x-forwarded-for");
|
||||
const { code, nonce, token, playUri } = parse(req.getQuery());
|
||||
try {
|
||||
//verify connected by token
|
||||
if (token != undefined) {
|
||||
try {
|
||||
const authTokenData: AuthTokenData = jwtTokenManager.verifyJWTToken(token as string, false);
|
||||
if (authTokenData.hydraAccessToken == undefined) {
|
||||
|
||||
//Get user data from Admin Back Office
|
||||
//This is very important to create User Local in LocalStorage in WorkAdventure
|
||||
const resUserData = await this.getUserByUserIdentifier(
|
||||
authTokenData.identifier,
|
||||
playUri as string,
|
||||
IPAddress
|
||||
);
|
||||
|
||||
if (authTokenData.accessToken == undefined) {
|
||||
//if not nonce and code, user connected in anonymous
|
||||
//get data with identifier and return token
|
||||
if (!code && !nonce) {
|
||||
res.writeStatus("200");
|
||||
this.addCorsHeaders(res);
|
||||
return res.end(JSON.stringify({ ...resUserData, authToken: token }));
|
||||
}
|
||||
throw Error("Token cannot to be check on Hydra");
|
||||
}
|
||||
await openIDClient.checkTokenAuth(authTokenData.hydraAccessToken);
|
||||
|
||||
const resCheckTokenAuth = await openIDClient.checkTokenAuth(authTokenData.accessToken);
|
||||
res.writeStatus("200");
|
||||
this.addCorsHeaders(res);
|
||||
return res.end(JSON.stringify({ authToken: token }));
|
||||
return res.end(JSON.stringify({ ...resCheckTokenAuth, ...resUserData, authToken: token }));
|
||||
} catch (err) {
|
||||
log.info("User was not connected", err);
|
||||
}
|
||||
|
@ -80,10 +99,15 @@ export class AuthenticateController extends BaseController {
|
|||
if (!email) {
|
||||
throw new Error("No email in the response");
|
||||
}
|
||||
const authToken = jwtTokenManager.createAuthToken(email, userInfo.access_token);
|
||||
const authToken = jwtTokenManager.createAuthToken(email, userInfo?.access_token);
|
||||
|
||||
//Get user data from Admin Back Office
|
||||
//This is very important to create User Local in LocalStorage in WorkAdventure
|
||||
const data = await this.getUserByUserIdentifier(email, playUri as string, IPAddress);
|
||||
|
||||
res.writeStatus("200");
|
||||
this.addCorsHeaders(res);
|
||||
return res.end(JSON.stringify({ authToken }));
|
||||
return res.end(JSON.stringify({ ...data, authToken }));
|
||||
} catch (e) {
|
||||
log.error("openIDCallback => ERROR", e);
|
||||
return this.errorToResponse(e, res);
|
||||
|
@ -100,10 +124,10 @@ export class AuthenticateController extends BaseController {
|
|||
|
||||
try {
|
||||
const authTokenData: AuthTokenData = jwtTokenManager.verifyJWTToken(token as string, false);
|
||||
if (authTokenData.hydraAccessToken == undefined) {
|
||||
if (authTokenData.accessToken == undefined) {
|
||||
throw Error("Token cannot to be logout on Hydra");
|
||||
}
|
||||
await openIDClient.logoutUser(authTokenData.hydraAccessToken);
|
||||
await openIDClient.logoutUser(authTokenData.accessToken);
|
||||
} catch (error) {
|
||||
log.error("openIDCallback => logout-callback", error);
|
||||
} finally {
|
||||
|
@ -176,16 +200,21 @@ export class AuthenticateController extends BaseController {
|
|||
log.warn("Login request was aborted");
|
||||
});
|
||||
|
||||
const userUuid = v4();
|
||||
const authToken = jwtTokenManager.createAuthToken(userUuid);
|
||||
res.writeStatus("200 OK");
|
||||
this.addCorsHeaders(res);
|
||||
res.end(
|
||||
JSON.stringify({
|
||||
authToken,
|
||||
userUuid,
|
||||
})
|
||||
);
|
||||
if (DISABLE_ANONYMOUS) {
|
||||
res.writeStatus("403 FORBIDDEN");
|
||||
res.end();
|
||||
} else {
|
||||
const userUuid = v4();
|
||||
const authToken = jwtTokenManager.createAuthToken(userUuid);
|
||||
res.writeStatus("200 OK");
|
||||
this.addCorsHeaders(res);
|
||||
res.end(
|
||||
JSON.stringify({
|
||||
authToken,
|
||||
userUuid,
|
||||
})
|
||||
);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -197,20 +226,20 @@ export class AuthenticateController extends BaseController {
|
|||
res.onAborted(() => {
|
||||
log.warn("/message request was aborted");
|
||||
});
|
||||
const { userIdentify, token } = parse(req.getQuery());
|
||||
const { token } = parse(req.getQuery());
|
||||
try {
|
||||
//verify connected by token
|
||||
if (token != undefined) {
|
||||
try {
|
||||
const authTokenData: AuthTokenData = jwtTokenManager.verifyJWTToken(token as string, false);
|
||||
if (authTokenData.hydraAccessToken == undefined) {
|
||||
if (authTokenData.accessToken == undefined) {
|
||||
throw Error("Token cannot to be check on Hydra");
|
||||
}
|
||||
await openIDClient.checkTokenAuth(authTokenData.hydraAccessToken);
|
||||
await openIDClient.checkTokenAuth(authTokenData.accessToken);
|
||||
|
||||
//get login profile
|
||||
res.writeStatus("302");
|
||||
res.writeHeader("Location", adminApi.getProfileUrl(authTokenData.hydraAccessToken));
|
||||
res.writeHeader("Location", adminApi.getProfileUrl(authTokenData.accessToken));
|
||||
this.addCorsHeaders(res);
|
||||
// eslint-disable-next-line no-unsafe-finally
|
||||
return res.end();
|
||||
|
@ -224,4 +253,33 @@ export class AuthenticateController extends BaseController {
|
|||
}
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param email
|
||||
* @param playUri
|
||||
* @param IPAddress
|
||||
* @return FetchMemberDataByUuidResponse|object
|
||||
* @private
|
||||
*/
|
||||
private async getUserByUserIdentifier(
|
||||
email: string,
|
||||
playUri: string,
|
||||
IPAddress: string
|
||||
): Promise<FetchMemberDataByUuidResponse | object> {
|
||||
let data: FetchMemberDataByUuidResponse = {
|
||||
email: email,
|
||||
userUuid: email,
|
||||
tags: [],
|
||||
messages: [],
|
||||
visitCardUrl: null,
|
||||
textures: [],
|
||||
};
|
||||
try {
|
||||
data = await adminApi.fetchMemberDataByUuid(email, playUri, IPAddress);
|
||||
} catch (err) {
|
||||
console.error("openIDCallback => fetchMemberDataByUuid", err);
|
||||
}
|
||||
return data;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,11 +1,12 @@
|
|||
import { HttpResponse } from "uWebSockets.js";
|
||||
import { FRONT_URL } from "../Enum/EnvironmentVariable";
|
||||
import log from "../Services/Logger";
|
||||
|
||||
export class BaseController {
|
||||
protected addCorsHeaders(res: HttpResponse): void {
|
||||
res.writeHeader("access-control-allow-headers", "Origin, X-Requested-With, Content-Type, Accept");
|
||||
res.writeHeader("access-control-allow-methods", "GET, POST, OPTIONS, PUT, PATCH, DELETE");
|
||||
res.writeHeader("access-control-allow-origin", "*");
|
||||
res.writeHeader("access-control-allow-origin", FRONT_URL);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -26,10 +26,9 @@ import { jwtTokenManager, tokenInvalidException } from "../Services/JWTTokenMana
|
|||
import { adminApi, FetchMemberDataByUuidResponse } from "../Services/AdminApi";
|
||||
import { SocketManager, socketManager } from "../Services/SocketManager";
|
||||
import { emitInBatch } from "../Services/IoSocketHelpers";
|
||||
import { ADMIN_API_TOKEN, ADMIN_API_URL, SOCKET_IDLE_TIMER } from "../Enum/EnvironmentVariable";
|
||||
import { ADMIN_SOCKETS_TOKEN, ADMIN_API_URL, DISABLE_ANONYMOUS, SOCKET_IDLE_TIMER } from "../Enum/EnvironmentVariable";
|
||||
import { Zone } from "_Model/Zone";
|
||||
import { ExAdminSocketInterface } from "_Model/Websocket/ExAdminSocketInterface";
|
||||
import { v4 } from "uuid";
|
||||
import { CharacterTexture } from "../Services/AdminApi/CharacterTexture";
|
||||
import log from "../Services/Logger";
|
||||
|
||||
|
@ -49,15 +48,19 @@ export class IoSocketController {
|
|||
const websocketProtocol = req.getHeader("sec-websocket-protocol");
|
||||
const websocketExtensions = req.getHeader("sec-websocket-extensions");
|
||||
const token = query.token;
|
||||
if (token !== ADMIN_API_TOKEN) {
|
||||
let authorizedRoomIds: string[];
|
||||
try {
|
||||
const data = jwtTokenManager.verifyAdminSocketToken(token as string);
|
||||
authorizedRoomIds = data.authorizedRoomIds;
|
||||
} catch (e) {
|
||||
log.info("Admin access refused for token: " + token);
|
||||
res.writeStatus("401 Unauthorized").end("Incorrect token");
|
||||
return;
|
||||
}
|
||||
const roomId = query.roomId;
|
||||
if (typeof roomId !== "string") {
|
||||
log.error("Received");
|
||||
res.writeStatus("400 Bad Request").end("Missing room id");
|
||||
if (typeof roomId !== "string" || !authorizedRoomIds.includes(roomId)) {
|
||||
log.error("Invalid room id");
|
||||
res.writeStatus("403 Bad Request").end("Invalid room id");
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -71,8 +74,6 @@ export class IoSocketController {
|
|||
},
|
||||
message: (ws, arrayBuffer, isBinary): void => {
|
||||
try {
|
||||
const roomId = ws.roomId as string;
|
||||
|
||||
//TODO refactor message type and data
|
||||
const message: { event: string; message: { type: string; message: unknown; userUuid: string } } =
|
||||
JSON.parse(new TextDecoder("utf-8").decode(new Uint8Array(arrayBuffer)));
|
||||
|
@ -176,6 +177,11 @@ export class IoSocketController {
|
|||
|
||||
const tokenData =
|
||||
token && typeof token === "string" ? jwtTokenManager.verifyJWTToken(token) : null;
|
||||
|
||||
if (DISABLE_ANONYMOUS && !tokenData) {
|
||||
throw new Error("Expecting token");
|
||||
}
|
||||
|
||||
const userIdentifier = tokenData ? tokenData.identifier : "";
|
||||
|
||||
let memberTags: string[] = [];
|
||||
|
@ -184,6 +190,7 @@ export class IoSocketController {
|
|||
let memberTextures: CharacterTexture[] = [];
|
||||
const room = await socketManager.getOrCreateRoom(roomId);
|
||||
let userData: FetchMemberDataByUuidResponse = {
|
||||
email: userIdentifier,
|
||||
userUuid: userIdentifier,
|
||||
tags: [],
|
||||
visitCardUrl: null,
|
||||
|
|
|
@ -2,9 +2,9 @@ import { HttpRequest, HttpResponse, TemplatedApp } from "uWebSockets.js";
|
|||
import { BaseController } from "./BaseController";
|
||||
import { parse } from "query-string";
|
||||
import { adminApi } from "../Services/AdminApi";
|
||||
import { ADMIN_API_URL } from "../Enum/EnvironmentVariable";
|
||||
import { ADMIN_API_URL, DISABLE_ANONYMOUS, FRONT_URL } from "../Enum/EnvironmentVariable";
|
||||
import { GameRoomPolicyTypes } from "../Model/PusherRoom";
|
||||
import { MapDetailsData } from "../Services/AdminApi/MapDetailsData";
|
||||
import { isMapDetailsData, MapDetailsData } from "../Services/AdminApi/MapDetailsData";
|
||||
import { socketManager } from "../Services/SocketManager";
|
||||
import { AuthTokenData, jwtTokenManager } from "../Services/JWTTokenManager";
|
||||
import { v4 } from "uuid";
|
||||
|
@ -21,7 +21,6 @@ export class MapController extends BaseController {
|
|||
getMapUrl() {
|
||||
this.App.options("/map", (res: HttpResponse, req: HttpRequest) => {
|
||||
this.addCorsHeaders(res);
|
||||
|
||||
res.end();
|
||||
});
|
||||
|
||||
|
@ -65,6 +64,7 @@ export class MapController extends BaseController {
|
|||
tags: [],
|
||||
textures: [],
|
||||
contactPage: undefined,
|
||||
authenticationMandatory: DISABLE_ANONYMOUS,
|
||||
} as MapDetailsData)
|
||||
);
|
||||
|
||||
|
@ -80,14 +80,26 @@ export class MapController extends BaseController {
|
|||
authTokenData = jwtTokenManager.verifyJWTToken(query.authToken as string);
|
||||
userId = authTokenData.identifier;
|
||||
} catch (e) {
|
||||
// Decode token, in this case we don't need to create new token.
|
||||
authTokenData = jwtTokenManager.verifyJWTToken(query.authToken as string, true);
|
||||
userId = authTokenData.identifier;
|
||||
log.info("JWT expire, but decoded", userId);
|
||||
try {
|
||||
// Decode token, in this case we don't need to create new token.
|
||||
authTokenData = jwtTokenManager.verifyJWTToken(query.authToken as string, true);
|
||||
userId = authTokenData.identifier;
|
||||
log.info("JWT expire, but decoded", userId);
|
||||
} catch (e) {
|
||||
// The token was not good, redirect user on login page
|
||||
res.writeStatus("500");
|
||||
res.writeHeader("Access-Control-Allow-Origin", FRONT_URL);
|
||||
res.end("Token decrypted error");
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
const mapDetails = await adminApi.fetchMapDetails(query.playUri as string, userId);
|
||||
|
||||
if (isMapDetailsData(mapDetails) && DISABLE_ANONYMOUS) {
|
||||
mapDetails.authenticationMandatory = true;
|
||||
}
|
||||
|
||||
res.writeStatus("200 OK");
|
||||
this.addCorsHeaders(res);
|
||||
res.end(JSON.stringify(mapDetails));
|
||||
|
|
80
pusher/src/Controller/OpenIdProfileController.ts
Normal file
80
pusher/src/Controller/OpenIdProfileController.ts
Normal file
|
@ -0,0 +1,80 @@
|
|||
import { BaseController } from "./BaseController";
|
||||
import { HttpRequest, HttpResponse, TemplatedApp } from "uWebSockets.js";
|
||||
import { parse } from "query-string";
|
||||
import { openIDClient } from "../Services/OpenIDClient";
|
||||
import { AuthTokenData, jwtTokenManager } from "../Services/JWTTokenManager";
|
||||
import { adminApi } from "../Services/AdminApi";
|
||||
import { OPID_CLIENT_ISSUER } from "../Enum/EnvironmentVariable";
|
||||
import { IntrospectionResponse } from "openid-client";
|
||||
|
||||
export class OpenIdProfileController extends BaseController {
|
||||
constructor(private App: TemplatedApp) {
|
||||
super();
|
||||
this.profileOpenId();
|
||||
}
|
||||
|
||||
profileOpenId() {
|
||||
//eslint-disable-next-line @typescript-eslint/no-misused-promises
|
||||
this.App.get("/profile", async (res: HttpResponse, req: HttpRequest) => {
|
||||
res.onAborted(() => {
|
||||
console.warn("/message request was aborted");
|
||||
});
|
||||
|
||||
const { accessToken } = parse(req.getQuery());
|
||||
if (!accessToken) {
|
||||
throw Error("Access token expected cannot to be check on Hydra");
|
||||
}
|
||||
try {
|
||||
const resCheckTokenAuth = await openIDClient.checkTokenAuth(accessToken as string);
|
||||
if (!resCheckTokenAuth.email) {
|
||||
throw "Email was not found";
|
||||
}
|
||||
res.end(
|
||||
this.buildHtml(
|
||||
OPID_CLIENT_ISSUER,
|
||||
resCheckTokenAuth.email as string,
|
||||
resCheckTokenAuth.picture as string | undefined
|
||||
)
|
||||
);
|
||||
} catch (error) {
|
||||
console.error("profileCallback => ERROR", error);
|
||||
this.errorToResponse(error, res);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
buildHtml(domain: string, email: string, pictureUrl?: string) {
|
||||
return `
|
||||
<!DOCTYPE>
|
||||
<html>
|
||||
<head>
|
||||
<style>
|
||||
*{
|
||||
font-family: PixelFont-7, monospace;
|
||||
}
|
||||
body{
|
||||
text-align: center;
|
||||
color: white;
|
||||
}
|
||||
section{
|
||||
margin: 20px;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<div class="container">
|
||||
<section>
|
||||
<img src="${pictureUrl ? pictureUrl : "/images/profile"}">
|
||||
</section>
|
||||
<section>
|
||||
Profile validated by domain: <span style="font-weight: bold">${domain}</span>
|
||||
</section>
|
||||
<section>
|
||||
Your email: <span style="font-weight: bold">${email}</span>
|
||||
</section>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
`;
|
||||
}
|
||||
}
|
|
@ -4,6 +4,7 @@ const API_URL = process.env.API_URL || "";
|
|||
const ADMIN_API_URL = process.env.ADMIN_API_URL || "";
|
||||
const ADMIN_URL = process.env.ADMIN_URL || "";
|
||||
const ADMIN_API_TOKEN = process.env.ADMIN_API_TOKEN || "myapitoken";
|
||||
export const ADMIN_SOCKETS_TOKEN = process.env.ADMIN_SOCKETS_TOKEN || "myapitoken";
|
||||
const CPU_OVERHEAT_THRESHOLD = Number(process.env.CPU_OVERHEAT_THRESHOLD) || 80;
|
||||
const JITSI_URL: string | undefined = process.env.JITSI_URL === "" ? undefined : process.env.JITSI_URL;
|
||||
const JITSI_ISS = process.env.JITSI_ISS || "";
|
||||
|
@ -15,6 +16,9 @@ export const FRONT_URL = process.env.FRONT_URL || "http://localhost";
|
|||
export const OPID_CLIENT_ID = process.env.OPID_CLIENT_ID || "";
|
||||
export const OPID_CLIENT_SECRET = process.env.OPID_CLIENT_SECRET || "";
|
||||
export const OPID_CLIENT_ISSUER = process.env.OPID_CLIENT_ISSUER || "";
|
||||
export const OPID_CLIENT_REDIRECT_URL = process.env.OPID_CLIENT_REDIRECT_URL || FRONT_URL + "/jwt";
|
||||
export const OPID_PROFILE_SCREEN_PROVIDER = process.env.OPID_PROFILE_SCREEN_PROVIDER || ADMIN_URL + "/profile";
|
||||
export const DISABLE_ANONYMOUS: boolean = process.env.DISABLE_ANONYMOUS === "true";
|
||||
|
||||
export {
|
||||
SECRET_KEY,
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
import { ADMIN_API_TOKEN, ADMIN_API_URL, ADMIN_URL } from "../Enum/EnvironmentVariable";
|
||||
import { ADMIN_API_TOKEN, ADMIN_API_URL, ADMIN_URL, OPID_PROFILE_SCREEN_PROVIDER } from "../Enum/EnvironmentVariable";
|
||||
import Axios from "axios";
|
||||
import { GameRoomPolicyTypes } from "_Model/PusherRoom";
|
||||
import { CharacterTexture } from "./AdminApi/CharacterTexture";
|
||||
|
@ -22,6 +22,7 @@ export interface AdminBannedData {
|
|||
}
|
||||
|
||||
export interface FetchMemberDataByUuidResponse {
|
||||
email: string;
|
||||
userUuid: string;
|
||||
tags: string[];
|
||||
visitCardUrl: string | null;
|
||||
|
@ -142,13 +143,19 @@ class AdminApi {
|
|||
});
|
||||
}
|
||||
|
||||
/*TODO add constant to use profile companny*/
|
||||
/**
|
||||
*
|
||||
* @param accessToken
|
||||
*/
|
||||
getProfileUrl(accessToken: string): string {
|
||||
if (!ADMIN_URL) {
|
||||
if (!OPID_PROFILE_SCREEN_PROVIDER) {
|
||||
throw new Error("No admin backoffice set!");
|
||||
}
|
||||
return `${OPID_PROFILE_SCREEN_PROVIDER}?accessToken=${accessToken}`;
|
||||
}
|
||||
|
||||
return ADMIN_URL + `/profile?token=${accessToken}`;
|
||||
async logoutOauth(token: string) {
|
||||
await Axios.get(ADMIN_API_URL + `/oauth/logout?token=${token}`);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -16,6 +16,7 @@ export const isMapDetailsData = new tg.IsInterface()
|
|||
tags: tg.isArray(tg.isString),
|
||||
textures: tg.isArray(isCharacterTexture),
|
||||
contactPage: tg.isUnion(tg.isString, tg.isUndefined),
|
||||
authenticationMandatory: tg.isUnion(tg.isBoolean, tg.isUndefined),
|
||||
})
|
||||
.get();
|
||||
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
import { ADMIN_API_URL, ALLOW_ARTILLERY, SECRET_KEY } from "../Enum/EnvironmentVariable";
|
||||
import { ADMIN_API_URL, ADMIN_SOCKETS_TOKEN, ALLOW_ARTILLERY, SECRET_KEY } from "../Enum/EnvironmentVariable";
|
||||
import { uuid } from "uuidv4";
|
||||
import Jwt, { verify } from "jsonwebtoken";
|
||||
import { TokenInterface } from "../Controller/AuthenticateController";
|
||||
|
@ -6,13 +6,20 @@ import { adminApi, AdminBannedData } from "../Services/AdminApi";
|
|||
|
||||
export interface AuthTokenData {
|
||||
identifier: string; //will be a email if logged in or an uuid if anonymous
|
||||
hydraAccessToken?: string;
|
||||
accessToken?: string;
|
||||
}
|
||||
export interface AdminSocketTokenData {
|
||||
authorizedRoomIds: string[]; //the list of rooms the client is authorized to read from.
|
||||
}
|
||||
export const tokenInvalidException = "tokenInvalid";
|
||||
|
||||
class JWTTokenManager {
|
||||
public createAuthToken(identifier: string, hydraAccessToken?: string) {
|
||||
return Jwt.sign({ identifier, hydraAccessToken }, SECRET_KEY, { expiresIn: "30d" });
|
||||
public verifyAdminSocketToken(token: string): AdminSocketTokenData {
|
||||
return Jwt.verify(token, ADMIN_SOCKETS_TOKEN) as AdminSocketTokenData;
|
||||
}
|
||||
|
||||
public createAuthToken(identifier: string, accessToken?: string) {
|
||||
return Jwt.sign({ identifier, accessToken }, SECRET_KEY, { expiresIn: "30d" });
|
||||
}
|
||||
|
||||
public verifyJWTToken(token: string, ignoreExpiration: boolean = false): AuthTokenData {
|
||||
|
|
|
@ -1,7 +1,10 @@
|
|||
import { Issuer, Client, IntrospectionResponse } from "openid-client";
|
||||
import { OPID_CLIENT_ID, OPID_CLIENT_SECRET, OPID_CLIENT_ISSUER, FRONT_URL } from "../Enum/EnvironmentVariable";
|
||||
|
||||
const opidRedirectUri = FRONT_URL + "/jwt";
|
||||
import {
|
||||
OPID_CLIENT_ID,
|
||||
OPID_CLIENT_SECRET,
|
||||
OPID_CLIENT_ISSUER,
|
||||
OPID_CLIENT_REDIRECT_URL,
|
||||
} from "../Enum/EnvironmentVariable";
|
||||
|
||||
class OpenIDClient {
|
||||
private issuerPromise: Promise<Client> | null = null;
|
||||
|
@ -12,7 +15,7 @@ class OpenIDClient {
|
|||
return new issuer.Client({
|
||||
client_id: OPID_CLIENT_ID,
|
||||
client_secret: OPID_CLIENT_SECRET,
|
||||
redirect_uris: [opidRedirectUri],
|
||||
redirect_uris: [OPID_CLIENT_REDIRECT_URL],
|
||||
response_types: ["code"],
|
||||
});
|
||||
});
|
||||
|
@ -35,7 +38,7 @@ class OpenIDClient {
|
|||
|
||||
public getUserInfo(code: string, nonce: string): Promise<{ email: string; sub: string; access_token: string }> {
|
||||
return this.initClient().then((client) => {
|
||||
return client.callback(opidRedirectUri, { code }, { nonce }).then((tokenSet) => {
|
||||
return client.callback(OPID_CLIENT_REDIRECT_URL, { code }, { nonce }).then((tokenSet) => {
|
||||
return client.userinfo(tokenSet).then((res) => {
|
||||
return {
|
||||
...res,
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue