add OIDC username + locale

This commit is contained in:
Lurkars 2022-02-16 09:11:08 +01:00
parent 8af7166c47
commit 2816946c94
7 changed files with 72 additions and 10 deletions

View File

@ -76,6 +76,9 @@ services:
OPID_CLIENT_ISSUER: $OPID_CLIENT_ISSUER OPID_CLIENT_ISSUER: $OPID_CLIENT_ISSUER
OPID_CLIENT_REDIRECT_URL: $OPID_CLIENT_REDIRECT_URL OPID_CLIENT_REDIRECT_URL: $OPID_CLIENT_REDIRECT_URL
OPID_PROFILE_SCREEN_PROVIDER: $OPID_PROFILE_SCREEN_PROVIDER OPID_PROFILE_SCREEN_PROVIDER: $OPID_PROFILE_SCREEN_PROVIDER
OPID_ADDITIONAL_SCOPES: $OPID_ADDITIONAL_SCOPES
OPID_USERNAME_CLAIM: $OPID_USERNAME_CLAIM
OPID_LOCALE_CLAIM: $OPID_LOCALE_CLAIM
DISABLE_ANONYMOUS: $DISABLE_ANONYMOUS DISABLE_ANONYMOUS: $DISABLE_ANONYMOUS
volumes: volumes:
- ./pusher:/usr/src/app - ./pusher:/usr/src/app

View File

@ -86,6 +86,9 @@ services:
OPID_CLIENT_ISSUER: $OPID_CLIENT_ISSUER OPID_CLIENT_ISSUER: $OPID_CLIENT_ISSUER
OPID_CLIENT_REDIRECT_URL: $OPID_CLIENT_REDIRECT_URL OPID_CLIENT_REDIRECT_URL: $OPID_CLIENT_REDIRECT_URL
OPID_PROFILE_SCREEN_PROVIDER: $OPID_PROFILE_SCREEN_PROVIDER OPID_PROFILE_SCREEN_PROVIDER: $OPID_PROFILE_SCREEN_PROVIDER
OPID_ADDITIONAL_SCOPES: $OPID_ADDITIONAL_SCOPES
OPID_USERNAME_CLAIM: $OPID_USERNAME_CLAIM
OPID_LOCALE_CLAIM: $OPID_LOCALE_CLAIM
DISABLE_ANONYMOUS: $DISABLE_ANONYMOUS DISABLE_ANONYMOUS: $DISABLE_ANONYMOUS
volumes: volumes:
- ./pusher:/usr/src/app - ./pusher:/usr/src/app

View File

@ -16,6 +16,10 @@ import { isRegisterData } from "../Messages/JsonMessages/RegisterData";
import { isAdminApiData } from "../Messages/JsonMessages/AdminApiData"; import { isAdminApiData } from "../Messages/JsonMessages/AdminApiData";
import { limitMapStore } from "../Stores/GameStore"; import { limitMapStore } from "../Stores/GameStore";
import { showLimitRoomModalStore } from "../Stores/ModalStore"; import { showLimitRoomModalStore } from "../Stores/ModalStore";
import { gameManager } from "../Phaser/Game/GameManager";
import { locales } from "../i18n/i18n-util";
import type { Locales } from "../i18n/i18n-types";
import { setCurrentLocale } from "../i18n/locales";
class ConnectionManager { class ConnectionManager {
private localUser!: LocalUser; private localUser!: LocalUser;
@ -342,9 +346,12 @@ class ConnectionManager {
throw new Error("No Auth code provided"); throw new Error("No Auth code provided");
} }
} }
const { authToken, userUuid, textures, email } = await Axios.get(`${PUSHER_URL}/login-callback`, { const { authToken, userUuid, textures, email, username, locale } = await Axios.get(
params: { code, nonce, token, playUri: this.currentRoom?.key }, `${PUSHER_URL}/login-callback`,
}).then((res) => { {
params: { code, nonce, token, playUri: this.currentRoom?.key },
}
).then((res) => {
return res.data; return res.data;
}); });
localUserStore.setAuthToken(authToken); localUserStore.setAuthToken(authToken);
@ -352,6 +359,27 @@ class ConnectionManager {
localUserStore.saveUser(this.localUser); localUserStore.saveUser(this.localUser);
this.authToken = authToken; this.authToken = authToken;
if (username) {
gameManager.setPlayerName(username);
}
if (locale) {
try {
if (locales.indexOf(locale) == -1) {
locales.forEach((l) => {
if (l.startsWith(locale.split("-")[0])) {
setCurrentLocale(l);
return;
}
});
} else {
setCurrentLocale(locale as Locales);
}
} catch (err) {
console.warn("Could not set locale", err);
}
}
//user connected, set connected store for menu at true //user connected, set connected store for menu at true
userIsConnected.set(true); userIsConnected.set(true);
} }

View File

@ -93,7 +93,15 @@ export class AuthenticateController extends BaseController {
res.writeStatus("200"); res.writeStatus("200");
this.addCorsHeaders(res); this.addCorsHeaders(res);
res.writeHeader("Content-Type", "application/json"); res.writeHeader("Content-Type", "application/json");
return res.end(JSON.stringify({ ...resCheckTokenAuth, ...resUserData, authToken: token })); return res.end(
JSON.stringify({
...resCheckTokenAuth,
...resUserData,
authToken: token,
username: authTokenData?.username,
locale: authTokenData?.locale,
})
);
} catch (err) { } catch (err) {
console.info("User was not connected", err); console.info("User was not connected", err);
} }
@ -115,7 +123,12 @@ export class AuthenticateController extends BaseController {
if (!email) { if (!email) {
throw new Error("No email in the response"); throw new Error("No email in the response");
} }
const authToken = jwtTokenManager.createAuthToken(email, userInfo?.access_token); const authToken = jwtTokenManager.createAuthToken(
email,
userInfo?.access_token,
userInfo?.username,
userInfo?.locale
);
//Get user data from Admin Back Office //Get user data from Admin Back Office
//This is very important to create User Local in LocalStorage in WorkAdventure //This is very important to create User Local in LocalStorage in WorkAdventure
@ -124,7 +137,9 @@ export class AuthenticateController extends BaseController {
res.writeStatus("200"); res.writeStatus("200");
this.addCorsHeaders(res); this.addCorsHeaders(res);
res.writeHeader("Content-Type", "application/json"); res.writeHeader("Content-Type", "application/json");
return res.end(JSON.stringify({ ...data, authToken })); return res.end(
JSON.stringify({ ...data, authToken, username: userInfo?.username, locale: userInfo?.locale })
);
} catch (e) { } catch (e) {
console.error("openIDCallback => ERROR", e); console.error("openIDCallback => ERROR", e);
return this.errorToResponse(e, res); return this.errorToResponse(e, res);

View File

@ -18,6 +18,9 @@ export const OPID_CLIENT_SECRET = process.env.OPID_CLIENT_SECRET || "";
export const OPID_CLIENT_ISSUER = process.env.OPID_CLIENT_ISSUER || ""; 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_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 OPID_PROFILE_SCREEN_PROVIDER = process.env.OPID_PROFILE_SCREEN_PROVIDER || ADMIN_URL + "/profile";
export const OPID_ADDITIONAL_SCOPES = process.env.OPID_ADDITIONAL_SCOPES || "";
export const OPID_USERNAME_CLAIM = process.env.OPID_USERNAME_CLAIM || "username";
export const OPID_LOCALE_CLAIM = process.env.OPID_LOCALE_CLAIM || "locale";
export const DISABLE_ANONYMOUS: boolean = process.env.DISABLE_ANONYMOUS === "true"; export const DISABLE_ANONYMOUS: boolean = process.env.DISABLE_ANONYMOUS === "true";
export { export {

View File

@ -5,6 +5,8 @@ import { InvalidTokenError } from "../Controller/InvalidTokenError";
export interface AuthTokenData { export interface AuthTokenData {
identifier: string; //will be a email if logged in or an uuid if anonymous identifier: string; //will be a email if logged in or an uuid if anonymous
accessToken?: string; accessToken?: string;
username?: string;
locale?: string;
} }
export interface AdminSocketTokenData { export interface AdminSocketTokenData {
authorizedRoomIds: string[]; //the list of rooms the client is authorized to read from. authorizedRoomIds: string[]; //the list of rooms the client is authorized to read from.
@ -16,8 +18,8 @@ class JWTTokenManager {
return Jwt.verify(token, ADMIN_SOCKETS_TOKEN) as AdminSocketTokenData; return Jwt.verify(token, ADMIN_SOCKETS_TOKEN) as AdminSocketTokenData;
} }
public createAuthToken(identifier: string, accessToken?: string) { public createAuthToken(identifier: string, accessToken?: string, username?: string, locale?: string) {
return Jwt.sign({ identifier, accessToken }, SECRET_KEY, { expiresIn: "30d" }); return Jwt.sign({ identifier, accessToken, username, locale }, SECRET_KEY, { expiresIn: "30d" });
} }
public verifyJWTToken(token: string, ignoreExpiration: boolean = false): AuthTokenData { public verifyJWTToken(token: string, ignoreExpiration: boolean = false): AuthTokenData {

View File

@ -4,6 +4,9 @@ import {
OPID_CLIENT_SECRET, OPID_CLIENT_SECRET,
OPID_CLIENT_ISSUER, OPID_CLIENT_ISSUER,
OPID_CLIENT_REDIRECT_URL, OPID_CLIENT_REDIRECT_URL,
OPID_USERNAME_CLAIM,
OPID_LOCALE_CLAIM,
OPID_ADDITIONAL_SCOPES,
} from "../Enum/EnvironmentVariable"; } from "../Enum/EnvironmentVariable";
class OpenIDClient { class OpenIDClient {
@ -26,7 +29,7 @@ class OpenIDClient {
public authorizationUrl(state: string, nonce: string, playUri?: string, redirect?: string) { public authorizationUrl(state: string, nonce: string, playUri?: string, redirect?: string) {
return this.initClient().then((client) => { return this.initClient().then((client) => {
return client.authorizationUrl({ return client.authorizationUrl({
scope: "openid email", scope: "openid email " + OPID_ADDITIONAL_SCOPES,
prompt: "login", prompt: "login",
state: state, state: state,
nonce: nonce, nonce: nonce,
@ -36,7 +39,10 @@ class OpenIDClient {
}); });
} }
public getUserInfo(code: string, nonce: string): Promise<{ email: string; sub: string; access_token: string }> { public getUserInfo(
code: string,
nonce: string
): Promise<{ email: string; sub: string; access_token: string; username: string; locale: string }> {
return this.initClient().then((client) => { return this.initClient().then((client) => {
return client.callback(OPID_CLIENT_REDIRECT_URL, { code }, { nonce }).then((tokenSet) => { return client.callback(OPID_CLIENT_REDIRECT_URL, { code }, { nonce }).then((tokenSet) => {
return client.userinfo(tokenSet).then((res) => { return client.userinfo(tokenSet).then((res) => {
@ -45,6 +51,8 @@ class OpenIDClient {
email: res.email as string, email: res.email as string,
sub: res.sub, sub: res.sub,
access_token: tokenSet.access_token as string, access_token: tokenSet.access_token as string,
username: res[OPID_USERNAME_CLAIM] as string,
locale: res[OPID_LOCALE_CLAIM] as string,
}; };
}); });
}); });