diff --git a/.env.template b/.env.template index e7cdffbc..5328fe08 100644 --- a/.env.template +++ b/.env.template @@ -23,7 +23,8 @@ OPID_CLIENT_ID= OPID_CLIENT_SECRET= OPID_CLIENT_ISSUER= OPID_CLIENT_REDIREC_URL= -OPID_LOGIN_SCREEN_PROVIDER= +OPID_LOGIN_SCREEN_PROVIDER=http://pusher.workadventure.localhost/login-screen +OPID_PROFILE_SCREEN_PROVIDER= DISABLE_ANONYMOUS= # If you want to have a contact page in your menu, you MUST set CONTACT_URL to the URL of the page that you want diff --git a/docker-compose.single-domain.yaml b/docker-compose.single-domain.yaml index 4522cbe9..e241c108 100644 --- a/docker-compose.single-domain.yaml +++ b/docker-compose.single-domain.yaml @@ -72,6 +72,7 @@ services: OPID_CLIENT_SECRET: $OPID_CLIENT_SECRET OPID_CLIENT_ISSUER: $OPID_CLIENT_ISSUER OPID_CLIENT_REDIREC_URL: $OPID_CLIENT_REDIREC_URL + OPID_PROFILE_SCREEN_PROVIDER: $OPID_PROFILE_SCREEN_PROVIDER DISABLE_ANONYMOUS: $DISABLE_ANONYMOUS volumes: - ./pusher:/usr/src/app diff --git a/docker-compose.yaml b/docker-compose.yaml index cc27a78a..03395f22 100644 --- a/docker-compose.yaml +++ b/docker-compose.yaml @@ -74,6 +74,7 @@ services: OPID_CLIENT_SECRET: $OPID_CLIENT_SECRET OPID_CLIENT_ISSUER: $OPID_CLIENT_ISSUER OPID_CLIENT_REDIREC_URL: $OPID_CLIENT_REDIREC_URL + OPID_PROFILE_SCREEN_PROVIDER: $OPID_PROFILE_SCREEN_PROVIDER DISABLE_ANONYMOUS: $DISABLE_ANONYMOUS volumes: - ./pusher:/usr/src/app diff --git a/pusher/src/App.ts b/pusher/src/App.ts index 81aed045..327d493c 100644 --- a/pusher/src/App.ts +++ b/pusher/src/App.ts @@ -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); } } diff --git a/pusher/src/Controller/OpenIdProfileController.ts b/pusher/src/Controller/OpenIdProfileController.ts new file mode 100644 index 00000000..372b603b --- /dev/null +++ b/pusher/src/Controller/OpenIdProfileController.ts @@ -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 ( + "" + + ` +
+ +
+ +
+
+ +
+
+ Profile validated by domain: ${domain} +
+
+ Your email: ${email} +
+
+ + ` + ); + } +} diff --git a/pusher/src/Enum/EnvironmentVariable.ts b/pusher/src/Enum/EnvironmentVariable.ts index 43bfc7bf..52382266 100644 --- a/pusher/src/Enum/EnvironmentVariable.ts +++ b/pusher/src/Enum/EnvironmentVariable.ts @@ -16,6 +16,7 @@ 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_REDIREC_URL = process.env.OPID_CLIENT_REDIREC_URL || FRONT_URL + "/jwt"; +export const OPID_PROFILE_SCREEN_PROVIDER = process.env.OPID_PROFILE_SCREEN_PROVIDER || ADMIN_URL + "/profile"; export const DISABLE_ANONYMOUS = process.env.DISABLE_ANONYMOUS || false; export { diff --git a/pusher/src/Services/AdminApi.ts b/pusher/src/Services/AdminApi.ts index d002ff8b..6e1848eb 100644 --- a/pusher/src/Services/AdminApi.ts +++ b/pusher/src/Services/AdminApi.ts @@ -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"; @@ -142,13 +142,15 @@ 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 ADMIN_URL + `/profile?token=${accessToken}`; + return `${OPID_PROFILE_SCREEN_PROVIDER}?accessToken=${accessToken}`; } async logoutOauth(token: string) {