mirror of
https://github.com/Kingsrook/qqq-frontend-material-dashboard.git
synced 2025-07-18 13:20:43 +00:00
CE-609 - staged-rollout-ready - keeping the auth header, but also setting sessionUUID cookie; placeholder for quick-rollback; added todo#authHeader comments to mark where follow-up needs to happen after happy with new code
This commit is contained in:
@ -6,7 +6,7 @@
|
|||||||
"@auth0/auth0-react": "1.10.2",
|
"@auth0/auth0-react": "1.10.2",
|
||||||
"@emotion/react": "11.7.1",
|
"@emotion/react": "11.7.1",
|
||||||
"@emotion/styled": "11.6.0",
|
"@emotion/styled": "11.6.0",
|
||||||
"@kingsrook/qqq-frontend-core": "1.0.79",
|
"@kingsrook/qqq-frontend-core": "1.0.81",
|
||||||
"@mui/icons-material": "5.4.1",
|
"@mui/icons-material": "5.4.1",
|
||||||
"@mui/material": "5.11.1",
|
"@mui/material": "5.11.1",
|
||||||
"@mui/styles": "5.11.1",
|
"@mui/styles": "5.11.1",
|
||||||
|
31
src/App.tsx
31
src/App.tsx
@ -38,6 +38,7 @@ import {useCookies} from "react-cookie";
|
|||||||
import {Navigate, Route, Routes, useLocation,} from "react-router-dom";
|
import {Navigate, Route, Routes, useLocation,} from "react-router-dom";
|
||||||
import {Md5} from "ts-md5/dist/md5";
|
import {Md5} from "ts-md5/dist/md5";
|
||||||
import CommandMenu from "CommandMenu";
|
import CommandMenu from "CommandMenu";
|
||||||
|
import DNDTest from "DNDTest";
|
||||||
import QContext from "QContext";
|
import QContext from "QContext";
|
||||||
import Sidenav from "qqq/components/horseshoe/sidenav/SideNav";
|
import Sidenav from "qqq/components/horseshoe/sidenav/SideNav";
|
||||||
import theme from "qqq/components/legacy/Theme";
|
import theme from "qqq/components/legacy/Theme";
|
||||||
@ -102,6 +103,7 @@ export default function App()
|
|||||||
const oldExp = oldJSON["exp"];
|
const oldExp = oldJSON["exp"];
|
||||||
if(oldExp * 1000 < (new Date().getTime()))
|
if(oldExp * 1000 < (new Date().getTime()))
|
||||||
{
|
{
|
||||||
|
console.log("Access token in local storage was expired.");
|
||||||
return (true);
|
return (true);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -115,6 +117,10 @@ export default function App()
|
|||||||
delete oldJSON["iat"]
|
delete oldJSON["iat"]
|
||||||
|
|
||||||
const different = JSON.stringify(newJSON) !== JSON.stringify(oldJSON);
|
const different = JSON.stringify(newJSON) !== JSON.stringify(oldJSON);
|
||||||
|
if(different)
|
||||||
|
{
|
||||||
|
console.log("Latest access token from auth0 has changed vs localStorage.");
|
||||||
|
}
|
||||||
return (different);
|
return (different);
|
||||||
}
|
}
|
||||||
catch(e)
|
catch(e)
|
||||||
@ -146,18 +152,28 @@ export default function App()
|
|||||||
{
|
{
|
||||||
console.log("Loading token from auth0...");
|
console.log("Loading token from auth0...");
|
||||||
const accessToken = await getAccessTokenSilently();
|
const accessToken = await getAccessTokenSilently();
|
||||||
// qController.setAuthorizationHeaderValue("Bearer " + accessToken);
|
|
||||||
|
|
||||||
const lsAccessToken = localStorage.getItem("accessToken");
|
const lsAccessToken = localStorage.getItem("accessToken");
|
||||||
if (shouldStoreNewToken(accessToken, lsAccessToken))
|
if (shouldStoreNewToken(accessToken, lsAccessToken))
|
||||||
{
|
{
|
||||||
|
console.log("Sending accessToken to backend, requesting a sessionUUID...");
|
||||||
const newSessionUuid = await qController.manageSession(accessToken, null);
|
const newSessionUuid = await qController.manageSession(accessToken, null);
|
||||||
setCookie(SESSION_UUID_COOKIE_NAME, newSessionUuid, {path: "/"});
|
setCookie(SESSION_UUID_COOKIE_NAME, newSessionUuid, {path: "/"});
|
||||||
localStorage.setItem("accessToken", accessToken);
|
localStorage.setItem("accessToken", accessToken);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
// todo#authHeader - this is our quick rollback plan - if we feel the need to stop using the cookie approach. //
|
||||||
|
// we turn off the shouldStoreNewToken block above, and turn on these 2 lines. //
|
||||||
|
////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
removeCookie(SESSION_UUID_COOKIE_NAME, {path: "/"});
|
||||||
|
localStorage.removeItem("accessToken");
|
||||||
|
*/
|
||||||
|
|
||||||
setIsFullyAuthenticated(true);
|
setIsFullyAuthenticated(true);
|
||||||
qController.setGotAuthentication();
|
qController.setGotAuthentication();
|
||||||
|
qController.setAuthorizationHeaderValue("Bearer " + accessToken);
|
||||||
|
|
||||||
setLoggedInUser(user);
|
setLoggedInUser(user);
|
||||||
console.log("Token load complete.");
|
console.log("Token load complete.");
|
||||||
@ -165,7 +181,7 @@ export default function App()
|
|||||||
catch (e)
|
catch (e)
|
||||||
{
|
{
|
||||||
console.log(`Error loading token: ${JSON.stringify(e)}`);
|
console.log(`Error loading token: ${JSON.stringify(e)}`);
|
||||||
// qController.clearAuthenticationMetaDataLocalStorage();
|
qController.clearAuthenticationMetaDataLocalStorage();
|
||||||
localStorage.removeItem("accessToken")
|
localStorage.removeItem("accessToken")
|
||||||
removeCookie(SESSION_UUID_COOKIE_NAME, {path: "/"});
|
removeCookie(SESSION_UUID_COOKIE_NAME, {path: "/"});
|
||||||
logout();
|
logout();
|
||||||
@ -178,7 +194,7 @@ export default function App()
|
|||||||
// use a random token if anonymous or mock //
|
// use a random token if anonymous or mock //
|
||||||
/////////////////////////////////////////////
|
/////////////////////////////////////////////
|
||||||
console.log("Generating random token...");
|
console.log("Generating random token...");
|
||||||
// qController.setAuthorizationHeaderValue(null);
|
qController.setAuthorizationHeaderValue(Md5.hashStr(`${new Date()}`));
|
||||||
setIsFullyAuthenticated(true);
|
setIsFullyAuthenticated(true);
|
||||||
setCookie(SESSION_UUID_COOKIE_NAME, Md5.hashStr(`${new Date()}`), {path: "/"});
|
setCookie(SESSION_UUID_COOKIE_NAME, Md5.hashStr(`${new Date()}`), {path: "/"});
|
||||||
console.log("Token generation complete.");
|
console.log("Token generation complete.");
|
||||||
@ -531,7 +547,7 @@ export default function App()
|
|||||||
}
|
}
|
||||||
|
|
||||||
const pathToLabelMap: {[path: string]: string} = {}
|
const pathToLabelMap: {[path: string]: string} = {}
|
||||||
for(let i =0; i<appRoutesList.length; i++)
|
for (let i = 0; i < appRoutesList.length; i++)
|
||||||
{
|
{
|
||||||
const route = appRoutesList[i];
|
const route = appRoutesList[i];
|
||||||
pathToLabelMap[route.route] = route.name;
|
pathToLabelMap[route.route] = route.name;
|
||||||
@ -557,13 +573,14 @@ export default function App()
|
|||||||
{
|
{
|
||||||
if ((e as QException).status === "401")
|
if ((e as QException).status === "401")
|
||||||
{
|
{
|
||||||
// todo revisit qController.clearAuthenticationMetaDataLocalStorage();
|
console.log("Exception is a QException with status = 401. Clearing some of localStorage & cookies");
|
||||||
|
qController.clearAuthenticationMetaDataLocalStorage();
|
||||||
|
localStorage.removeItem("accessToken")
|
||||||
|
removeCookie(SESSION_UUID_COOKIE_NAME, {path: "/"});
|
||||||
|
|
||||||
//////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////
|
||||||
// todo - this is auth0 logout... make more generic //
|
// todo - this is auth0 logout... make more generic //
|
||||||
//////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////
|
||||||
localStorage.removeItem("accessToken")
|
|
||||||
removeCookie(SESSION_UUID_COOKIE_NAME, {path: "/"});
|
|
||||||
logout();
|
logout();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -221,12 +221,19 @@ function ProcessRun({process, table, defaultProcessValues, isModal, isWidget, is
|
|||||||
|
|
||||||
const download = (url: string, fileName: string) =>
|
const download = (url: string, fileName: string) =>
|
||||||
{
|
{
|
||||||
const qController = Client.getInstance();
|
/////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
// todo - this could be simplified. //
|
||||||
|
// it was originally built like this when we had to submit full access token to backend... //
|
||||||
|
/////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
let xhr = new XMLHttpRequest();
|
let xhr = new XMLHttpRequest();
|
||||||
xhr.open("POST", url);
|
xhr.open("POST", url);
|
||||||
xhr.responseType = "blob";
|
xhr.responseType = "blob";
|
||||||
let formData = new FormData();
|
let formData = new FormData();
|
||||||
|
|
||||||
|
////////////////////////////////////
|
||||||
|
// todo#authHeader - delete this. //
|
||||||
|
////////////////////////////////////
|
||||||
|
const qController = Client.getInstance();
|
||||||
formData.append("Authorization", qController.getAuthorizationHeaderValue());
|
formData.append("Authorization", qController.getAuthorizationHeaderValue());
|
||||||
|
|
||||||
// @ts-ignore
|
// @ts-ignore
|
||||||
|
@ -1145,6 +1145,7 @@ function RecordQuery({table, launchProcess}: Props): JSX.Element
|
|||||||
<body>
|
<body>
|
||||||
Generating file <u>${filename}</u>${totalRecords ? " with " + totalRecords.toLocaleString() + " record" + (totalRecords == 1 ? "" : "s") : ""}...
|
Generating file <u>${filename}</u>${totalRecords ? " with " + totalRecords.toLocaleString() + " record" + (totalRecords == 1 ? "" : "s") : ""}...
|
||||||
<form id="exportForm" method="post" action="${url}" >
|
<form id="exportForm" method="post" action="${url}" >
|
||||||
|
<!-- todo#authHeader - remove this. -->
|
||||||
<input type="hidden" name="Authorization" value="${qController.getAuthorizationHeaderValue()}">
|
<input type="hidden" name="Authorization" value="${qController.getAuthorizationHeaderValue()}">
|
||||||
<input type="hidden" name="fields" value="${visibleFields.join(",")}">
|
<input type="hidden" name="fields" value="${visibleFields.join(",")}">
|
||||||
<input type="hidden" name="filter" id="filter">
|
<input type="hidden" name="filter" id="filter">
|
||||||
|
@ -95,6 +95,11 @@ export default class HtmlUtils
|
|||||||
form.setAttribute("target", "downloadIframe");
|
form.setAttribute("target", "downloadIframe");
|
||||||
iframe.appendChild(form);
|
iframe.appendChild(form);
|
||||||
|
|
||||||
|
/////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
// todo#authHeader - remove after comfortable with sessionUUID //
|
||||||
|
// todo - this could be simplified (i think?) //
|
||||||
|
// it was originally built like this when we had to submit full access token to backend... //
|
||||||
|
/////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
const authorizationInput = document.createElement("input");
|
const authorizationInput = document.createElement("input");
|
||||||
authorizationInput.setAttribute("type", "hidden");
|
authorizationInput.setAttribute("type", "hidden");
|
||||||
authorizationInput.setAttribute("id", "authorizationInput");
|
authorizationInput.setAttribute("id", "authorizationInput");
|
||||||
@ -118,6 +123,11 @@ export default class HtmlUtils
|
|||||||
{
|
{
|
||||||
if(url.startsWith("data:"))
|
if(url.startsWith("data:"))
|
||||||
{
|
{
|
||||||
|
/////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
// todo#authHeader - remove the Authorization input after comfortable with sessionUUID //
|
||||||
|
// todo - this could be simplified (i think?) //
|
||||||
|
// it was originally built like this when we had to submit full access token to backend... //
|
||||||
|
/////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
const openInWindow = window.open("", "_blank");
|
const openInWindow = window.open("", "_blank");
|
||||||
openInWindow.document.write(`<html lang="en">
|
openInWindow.document.write(`<html lang="en">
|
||||||
<body style="margin: 0">
|
<body style="margin: 0">
|
||||||
|
Reference in New Issue
Block a user