'use strict'; import Secure from './secure.js'; import App from './app.js'; import RequestToDomain from './requests-to-domain.js'; // import * as jose from 'jose'; // per la gestione del token import { getKeycloakRealm, getKeycloakURL, getMyURL } from './configuration.js'; const mySecure = new Secure(); let token = null; let expirationTime = null; // momento a partire dal quale il token non sarà più valido let alreadyRefreshed = false; // true se ho appena fatto la richiesta del token usando il refresh token let oldTimeout = null; const uri = window.location.toString(); if(!uri.includes(`#`) && !uri.includes("/secured/home/")) { const a = document.getElementById("my-link"); a.href = a.href.replace("$MY_CODE_CHALLENGE", mySecure.codeChallenge).replace("$MY_STATE", mySecure.state); sessionStorage.setItem("stateSent", mySecure.state); // state inviato durante la richiesta dell`authcode sessionStorage.setItem("codeVerifier", mySecure.codeVerifier); //automatically redirect to the login page window.location.href = a.href; } else if(uri.includes("#")){ // l`uri e` del tipo localhost:3000/secured# seguito da parametri const uriSplit = uri.split(`#`); const params = uriSplit[1].split(`&`); const uriState = queryStringGetValue(params[0]); const uriAuthCode = queryStringGetValue(params[2]); if(!sessionStorage.stateSent || sessionStorage.stateSent !== uriState) { // get the body element const body = document.getElementsByTagName(`body`)[0]; body.innerHTML = `Errors in the request!`; } else { await requestFirstToken(uriAuthCode); // post per la richiesta del token if(token !== null) { expirationTime = moment().add(token.expires_in,`s`); sessionStorage.setItem("expirationTime", expirationTime.toJSON()); const myDomains = await RequestToDomain.getMyDomains(); // const myDomains = [{nome: "casa1", stato:"on", admin: true}, // {nome: "casa2", stato:"off", admin: false}, // {nome: "casa3", stato:"off", admin: true}, // {nome: "casa4", stato:"on", admin: false}, // {nome: "casa4", stato:"on", admin: false}, // {nome: "casa4", stato:"on", admin: false}, // {nome: "casa4", stato:"on", admin: true}, // {nome: "casa4", stato:"on", admin: false} // ]; const app = new App(myDomains); } } } else if(uri.includes(`/secured/home/`)) { token = JSON.parse(sessionStorage.getItem(`token`)); expirationTime = moment(sessionStorage.getItem(`expirationTime`)); oldTimeout = timeoutRefresh(); } /** * Ottengo il valore associato al parametro. * @param {*} queryString query string del tipo parametro=valore. * @returns il valore associato al parametro. */ function queryStringGetValue(queryString) { const arr = queryString.split(`=`); return arr[1]; } /** * Post per la richiesta del token; * imposta il token ottenuto */ async function requestFirstToken(uriAuthCode) { const url = `${getKeycloakURL()}realms/${getKeycloakRealm()}/protocol/openid-connect/token`; const response = await fetch(url, { method: `POST`, headers: { 'Content-type':`application/x-www-form-urlencoded` }, body: new URLSearchParams({ grant_type: `authorization_code`, client_id: `myclient`, code_verifier: sessionStorage.getItem("codeVerifier"), code: uriAuthCode, redirect_uri: `${getMyURL()}secured` }) }); token = await response.json(); if(response.ok) { sessionStorage.setItem("token", JSON.stringify(token)); oldTimeout = timeoutRefresh(); } else token = null; } async function getToken() { const now = moment(); if(now - expirationTime < 1) { //this token has expired, so request new token await requestUsingRefreshToken(); } return token.access_token; } /** * Post per la richiesta del token usando il refresh token. */ async function requestUsingRefreshToken() { const url = `${getKeycloakURL()}realms/${getKeycloakRealm()}/protocol/openid-connect/token`; const response = await fetch(url, { method: `POST`, headers: { 'Content-type':`application/x-www-form-urlencoded` }, body: new URLSearchParams({ grant_type: `refresh_token`, client_id: `myclient`, refresh_token: `${token.refresh_token}` }) }); token = await response.json(); if(response.ok) { alreadyRefreshed = true; sessionStorage.setItem("token", JSON.stringify(token)); expirationTime = moment().add(token.expires_in,`s`); sessionStorage.setItem("expirationTime", expirationTime.toJSON()); oldTimeout = timeoutRefresh(); } else token = null; } /** * Prima che scada il refresh token, richiedo nuovamente il token * (usando il refresh token). * @returns id di setTimeout() */ function timeoutRefresh() { if(oldTimeout !== null) clearTimeout(oldTimeout); return setTimeout(async () => { if(!alreadyRefreshed) { await requestUsingRefreshToken(); alreadyRefreshed = false; } }, 10000);//(token.refresh_expires_in*1000)-5000); } /** * Effettua il logout. */ async function logoutKeycloak() { if(token == null) return; clearTimeout(oldTimeout); // DA FARE: funziona, ma vedere se fare il redirect alla pagina iniziale. window.location.href = `${getKeycloakURL()}realms/${getKeycloakRealm()}/protocol/openid-connect/logout?id_token_hint=${await getIdToken()}`; } async function getIdToken() { const now = moment(); if(now - expirationTime < 1) { //this token has expired, so request new token await requestUsingRefreshToken(); } return token.id_token; } export {getToken, logoutKeycloak};