Skip to content

Commit

Permalink
HPCC-30220 ECL Watch fix authentication & ESP session lock issues
Browse files Browse the repository at this point in the history
Signed-off-by: Jeremy Clements <[email protected]>
  • Loading branch information
jeclrsg committed Sep 28, 2023
1 parent 1621648 commit 999c658
Show file tree
Hide file tree
Showing 7 changed files with 49 additions and 12 deletions.
6 changes: 3 additions & 3 deletions esp/src/eclwatch/stub.js
Original file line number Diff line number Diff line change
Expand Up @@ -35,13 +35,13 @@ define([
if (modernMode === String(true) && hpccWidget !== "IFrameWidget") {
switch (hpccWidget) {
case "WUDetailsWidget":
window.location.replace(`/esp/files/index.html#/workunits/${params.Wuid}`);
window.location.replace(`/#/workunits/${params.Wuid}`);
break;
case "GraphsWUWidget":
window.location.replace(`/esp/files/index.html#/workunits/${params.Wuid}/metrics`);
window.location.replace(`/#/workunits/${params.Wuid}/metrics`);
break;
default:
window.location.replace("/esp/files/index.html");
window.location.replace("/");
}
} else {
ready(function () {
Expand Down
26 changes: 24 additions & 2 deletions esp/src/src-react/components/Frame.tsx
Original file line number Diff line number Diff line change
@@ -1,17 +1,20 @@
import * as React from "react";
import * as topic from "dojo/topic";
import { ThemeProvider } from "@fluentui/react";
import { FluentProvider } from "@fluentui/react-components";
import { select as d3Select } from "@hpcc-js/common";
import { scopedLogger } from "@hpcc-js/util";
import { useUserTheme } from "../hooks/theme";
import { HolyGrail } from "../layouts/HolyGrail";
import { hashHistory } from "../util/history";
import { router } from "../routes";
import { DevTitle } from "./Title";
import { MainNavigation, SubNavigation } from "./Menu";
import { CookieConsent } from "./forms/CookieConsent";
import { userKeyValStore } from "../../src/KeyValStore";
import { userKeyValStore } from "src/KeyValStore";
import { fireIdle, initSession, lock, unlock } from "src/Session";
import { useGlobalStore } from "../hooks/store";
import { useUserTheme } from "../hooks/theme";
import { useUserSession } from "../hooks/user";

const logger = scopedLogger("../components/Frame.tsx");

Expand All @@ -21,6 +24,7 @@ interface FrameProps {
export const Frame: React.FunctionComponent<FrameProps> = () => {

const [showCookieConsent, setShowCookieConsent] = React.useState(false);
const { userSession, setUserSession } = useUserSession();
const [locationPathname, setLocationPathname] = React.useState<string>(window.location.hash.split("#").join(""));
const [body, setBody] = React.useState(<h1>...loading...</h1>);
const { theme, themeV9, isDark } = useUserTheme();
Expand All @@ -46,6 +50,24 @@ export const Frame: React.FunctionComponent<FrameProps> = () => {
return () => unlisten();
}, []);

React.useEffect(() => {
initSession();

topic.subscribe("hpcc/session_management_status", function (publishedMessage) {
if (publishedMessage.status === "Unlocked") {
unlock();
} else if (publishedMessage.status === "Locked") {
lock();
} else if (publishedMessage.status === "DoIdle") {
fireIdle();
} else if (publishedMessage.status === "Idle") {
window.localStorage.setItem("pageOnLock", window.location.hash.substring(1));
setUserSession({ ...userSession, Status: "Locked" });
window.location.reload();
}
});
}, [setUserSession, userSession]);

React.useEffect(() => {
document.title = `${showEnvironmentTitle && environmentTitle.length ? environmentTitle : "ECL Watch v9"}${locationPathname.split("/").join(" | ")}`;
}, [environmentTitle, locationPathname, showEnvironmentTitle]);
Expand Down
11 changes: 11 additions & 0 deletions esp/src/src-react/components/forms/Login.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,15 @@ export const Login: React.FunctionComponent<LoginProps> = ({
const [showError, setShowError] = React.useState(false);
const [errorMessage, setErrorMessage] = React.useState("");

React.useEffect(() => {
const cookies = Utility.parseCookies();
if (cookies["ESPSessionState"] === "true") {
const lastUrl = window.localStorage.getItem("pageOnLock") ?? "/";
window.localStorage.removeItem("pageOnLock");
replaceUrl(lastUrl);
}
}, []);

const loginStyles = React.useMemo(() => mergeStyleSets({
root: {
height: "100%",
Expand Down Expand Up @@ -107,6 +116,8 @@ export const Login: React.FunctionComponent<LoginProps> = ({
setErrorMessage(cookies.ESPAuthenticationMSG);
setShowError(true);
} else {
cookies["Status"] = "Unlocked";
cookies["ESPAuthenticated"] = "true";
createUserSession(cookies).then(() => {
setErrorMessage("");
replaceUrl("/", null, true);
Expand Down
7 changes: 5 additions & 2 deletions esp/src/src-react/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import { scopedLogger } from "@hpcc-js/util";
import { cookieKeyValStore, userKeyValStore } from "src/KeyValStore";
import { containerized, ModernMode } from "src/BuildInfo";
import { ECLWatchLogger } from "./hooks/logging";
import { replaceUrl } from "./util/history";

import "css!dijit-themes/flat/flat.css";
import "css!hpcc/css/ecl.css";
Expand Down Expand Up @@ -40,8 +41,10 @@ store.getEx(ModernMode, { defaultValue: String(containerized) }).then(async mode
const authType = await authTypeResp?.text() ?? "None";
const userStore = cookieKeyValStore();
const userSession = await userStore.getAll();
if (authType.indexOf("None") < 0 && (!userSession["ESPAuthenticated"] && (!userSession["ECLWatchUser"] || !userSession["Status"] || userSession["Status"] === "Locked"))) {
window.location.replace("#/login");
if (authType.indexOf("None") < 0 && (userSession["ESPSessionState"] === "false" || userSession["ECLWatchUser"] === "false" || (!userSession["Status"] || userSession["Status"] === "Locked"))) {
if (window.location.hash.indexOf("login") < 0) {
replaceUrl("/login");
}
import("./components/forms/Login").then(_ => {
try {
ReactDOM.render(
Expand Down
4 changes: 2 additions & 2 deletions esp/src/src/ESPUtil.ts
Original file line number Diff line number Diff line change
Expand Up @@ -314,10 +314,10 @@ export function goToPageUserPreference(gridName, key) {

export const MonitorLockClick = dojo.declare([Evented], {
unlocked() {
this.emit("unlocked", {});
this.emit("Unlocked", {});
},
locked() {
this.emit("locked", {});
this.emit("Locked", {});
}
});

Expand Down
2 changes: 1 addition & 1 deletion esp/src/src/KeyValStore.ts
Original file line number Diff line number Diff line change
Expand Up @@ -212,7 +212,7 @@ class CookieStorage implements IKeyValStore {
set(key: string, value: string, broadcast?: boolean): Promise<void> {
const cookies = Utility.parseCookies();
const oldValue = cookies[key];
document.cookie = `${key}=${value}`;
document.cookie = `${key}=${value};path=/`;
return Promise.resolve().then(() => {
if (broadcast) {
this._dispatch.post(new ValueChangedMessage(key, value, oldValue));
Expand Down
5 changes: 3 additions & 2 deletions esp/src/src/Session.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,6 @@ const espTimeoutSeconds = cookie("ESPSessionTimeoutSeconds") || 600; // 10 minun
const IDLE_TIMEOUT = espTimeoutSeconds * 1000;
const SESSION_RESET_FREQ = 30 * 1000;
const idleWatcher = new ESPUtil.IdleWatcher(IDLE_TIMEOUT);
const monitorLockClick = new ESPUtil.MonitorLockClick();
const sessionIsActive = espTimeoutSeconds;

let _prevReset = Date.now();
Expand Down Expand Up @@ -73,7 +72,9 @@ export function initSession() {
});

idleWatcher.start();
monitorLockClick.unlocked();
if (!cookie("Status")) {
document.cookie = "Status=Unlocked;Path=/";
}
} else if (cookie("ECLWatchUser")) {
window.location.replace(dojoConfig.urlInfo.basePath + "/Login.html");
}
Expand Down

0 comments on commit 999c658

Please sign in to comment.