Files
P42_UI/app/libs/myUser.js
T
2025-08-27 21:13:25 +00:00

266 lines
8.6 KiB
JavaScript
Executable File

'use strict'
/**
__ __
( )( ) ___ ____ ____
)( )( / __)( ___)( _ \
)(__)( \__ \ )__) ) /
(______)(___/(____)(_)\_)
By Nike
This file is part of P42 implementation of SPARC.
* @category MyEic
* @subcategory Libraries
* @extends User
*/
class myUser extends app.LoadedClasses.User {
authUrl = '';
preferences = {}
/**
*
*/
constructor() { super(); }
/**
* Checks if user belongs to a role
* @param {string} role
* @returns {boolean}
*/
hasRole(role) { return(this.roles.indexOf(role)>-1); }
/**
*
* @returns {Array<string>}
*/
getRoles() { return(app.User.roles); }
/**
* @async
* @returns {string}
*
*/
fetchServices() {
let host = new URL(app.config.userLib.apiDiscoveryEndpoint).host
let stage = (host.split('.')[1] != 'eismea') ? '.'+host.split('.')[1] : ''
return(fetch('/app/assets/json/global/services.json?'+crypto.randomUUID(), {
method: 'GET'
})
.then(response=>response.text())
.then(response=>JSON.parse(response.replace(/__host__/g, host).replace(/__stage__/g, stage)))
)
}
/**
* Candidate for deprecation
* @returns {Promise}
*/
getApiServices() {
return(
this.fetchServices()
.then(response => {
if(response.success) {
// Was to much to ask to respect existing code & existing contract, so do the cleanup here
let api = {};
for(let entry of response.payload){
api[entry.resource] = entry.actions.reduce( (acc, v)=>{
acc[v.action]=v.availableMethod;
return(acc); }, {}
);
}
// Now override with exceptions from config. (also creates from exceptions)
for(let resource in app.config.userLib.apiStageExceptions){
if(!api.hasOwnProperty(resource)) api[resource] = [];
for(let action in app.config.userLib.apiStageExceptions[resource]) {
api[resource][action] = app.config.userLib.apiStageExceptions[resource][action];
console.warn(`Replacing / adding existing API with exception for resource: ${resource} action: ${action}`)
}
}
app.config.api = api;
}
}
)
)
}
/**
*
* @param {*} callBack
*/
checkAuthenticated(callBack){
let headers = {};
if(app.config.userLib.authForwardDomain) {
let url = new URL(document.location.href);
headers = { 'x-requested-path': url.pathname };
}
this.identity = {
uuid: 'nike',
email: 'info@nicsys.eu'
};
this.roles = ['admin']
this.isAuthenticated = true
console.log('Will call callback...', callBack)
callBack();
/*
fetch(app.config.userLib.authEndpoint+'?'+crypto.randomUUID(),{
headers: headers,
method: 'GET',
credentials: 'include'
})
.then(response => response.json())
.then(async resp => {
if(resp.success){
this.authenticationDone = true
this.isAuthenticated = resp.payload.isAuthenticated;
if(resp.payload.isAuthenticated) {
if((!this.identity) || (!this.identity.uuid)) {
this.logoutUrl = resp.payload.logoutUri;
this.parseUserInfo(resp.payload.userInfo);
}
this.platformRestrictions = resp.payload.platformRestrictions || null
if((this.platformRestrictions) && (!this.isVIP())){
this.ShowCurtain()
this.stopKeepAlive()
return // not triggering callback avoids any further ctrl loading by the router
}
if(!app.config.api) await this.getApiServices()
if(app.config.userLib.keepAliveSeconds && (app.config.userLib.keepAliveSeconds>0)) this.startKeepAlive()
callBack();
} else {
console.warn('Authorizer said User was not authenticated !');
this.authUrl = resp.payload.authUrl;
this.logoutUrl = resp.payload.logoutUri;
callBack();
}
} else {
console.error('Server error calling authorizer checkAuthenticated (success not true)');
this.stopKeepAlive() // Just in case KAL is active, because we arrive here from KAL itself
document.location.href = '/eulogin-error.html';
}
})
.catch((err) => {
console.error('Server error calling authorizer checkAuthenticated (Network error)',err);
document.location.href = '/eulogin-error.html';
});
*/
}
/**
*
* @returns {string}
*/
getMessageBusUserInfo() { return(this.identity.uuid) }
/**
*
* @param {string} jumpTo
*/
logout(jumpTo='') {
jumpTo = jumpTo ? jumpTo : this.logoutUrl
fetch(app.config.userLib.logoutEndpoint+'?'+crypto.randomUUID(),{
method: 'GET',
credentials: 'include'
}).then((resp) =>{
window.onbeforeunload = null // If user confirmed to logout, not need to have him confirm he's leaving the app !
document.location.href = jumpTo;
});
}
/**
* This is separated, so that upper layer has a chance to use a login button, or avoid redirection loops.
*/
gotoLogin() {
window.onbeforeunload = null // If user asks to relogin, not need to have him confirm he's leaving the app !
document.location.href = this.authUrl;
}
/**
*
* @param {*} info
*/
async parseUserInfo(info) {
this.identity = {
uuid: info.euLoginId,
firstname: info.family_name,
lastname: info.given_name,
email: info.email
};
this.roles = info.userRoles || []
}
loadPreferences() {
if(app.MessageBus) {
app.MessageBus.requestWssGwAction('GET', { key: `${this.identity.uuid}:userPrefs`})
.then(settings => {
this.preferences = settings.value;
})
}
}
savePreferences() {
if(app.MessageBus) {
app.MessageBus.requestWssGwAction('SET', {
key: `${this.identity.uuid}:userPrefs`,
value: this.preferences
})
}
}
getPreference(path) {
let value = null;
if(app.MessageBus) {
let segments = path.split('.');
let pointer = this.preferences;
if(pointer) {
for(let segment of segments) {
if(pointer[segment]) {
if(typeof pointer[segment] == 'object') {
pointer = pointer[segment];
} else {
value = pointer[segment];
}
} else {
break;
}
}
}
}
return value;
}
setPreference(path, value) {
if(app.MessageBus) {
let segments = path.split('.');
let pointer = this.preferences;
for(let i = 0; i < segments.length - 1; i++) {
let segment = segments[i];
if(!pointer[segment]) {
pointer[segment] = {};
}
pointer = pointer[segment];
}
pointer[segments[segments.length - 1]] = value;
}
this.savePreferences();
}
}
app.registerClass('User', myUser, true); // for Sparc to use
app.registerClass('myUser', myUser, true); // Just to avoid double-loading if squeezed