Merged PR 770: Remove Basic Auth and add inactivity timeout to logged in pages

Related work items: #7331, #7332
This commit is contained in:
Robert Bond
2022-01-26 10:40:34 +00:00
13 changed files with 184 additions and 55 deletions
+1 -1
View File
@@ -45,7 +45,7 @@ RELAYPATH = "test-pedw-hc"
GOOGLE_TAG_MANAGER = GTM-T78CBC3 GOOGLE_TAG_MANAGER = GTM-T78CBC3
SHOWLOGIN = "true" SHOWLOGIN = "true"
SHOWREPRESENTATIONS = "false" SHOWREPRESENTATIONS = "false"
BASIC_AUTH_CREDENTIALS = pinswg:password|pinswg2:password2 //BASIC_AUTH_CREDENTIALS = pinswg:password|pinswg2:password2
PORT= "3000" PORT= "3000"
+34 -38
View File
@@ -12,48 +12,50 @@ import YourAccount from "./myportal/youraccount";
import { parseCookies, setCookie, destroyCookie } from "nookies"; import { parseCookies, setCookie, destroyCookie } from "nookies";
import IdleTimer from "react-idle-timer"; import IdleTimer from "react-idle-timer";
import TimeoutModal from "../components/timeoutmodal"; import TimeoutModal from "./timeout/timeoutmodal";
import { useState } from "react"; import { useState } from "react";
import TimeOut from "../components/timeout";
const MyPortal = (props) => { const MyPortal = (props) => {
let { t } = useTranslation(); let { t } = useTranslation();
const router = useRouter(); const router = useRouter();
const { locale } = router; const { locale } = router;
const [showModal, setShowModal] = useState(false); // const [showModal, setShowModal] = useState(false);
const inactiveTimeOut = 12000; // in seconds // const inactiveTimeOut = 1200; // in seconds
const reminderTimeout = 60; // in seconds // const reminderTimeout = 60; // in seconds
let idleTimer = null; // let idleTimer = null;
let logoutTimer = null; // let logoutTimer = null;
let onIdle = () => { // let onIdle = () => {
togglePopup(); // togglePopup();
logoutTimer = setTimeout(() => { // logoutTimer = setTimeout(() => {
handleLogout(); // handleLogout();
}, 1000 * reminderTimeout * 1); // }, 1000 * reminderTimeout * 1);
}; // };
let togglePopup = () => { // let togglePopup = () => {
showModal == true ? setShowModal(false) : setShowModal(true); // showModal == true ? setShowModal(false) : setShowModal(true);
}; // };
let handleStayLoggedIn = () => { // let handleStayLoggedIn = () => {
if (logoutTimer) { // if (logoutTimer) {
clearTimeout(logoutTimer); // clearTimeout(logoutTimer);
logoutTimer = null; // logoutTimer = null;
} // }
idleTimer.reset(); // idleTimer.reset();
togglePopup(); // togglePopup();
}; // };
const handleLogout = () => { // const handleLogout = () => {
console.log("////////////", "\n", "logout", "\n", "//////////"); // console.log("////////////", "\n", "logout", "\n", "//////////");
destroyCookie({}, "pinsUser"), // destroyCookie({}, "pinsUser"),
window.localStorage.clear(), // window.localStorage.clear(),
router.replace(props.ggLogout); // router.replace(props.ggLogout);
}; // };
return ( return (
<> <>
@@ -124,7 +126,7 @@ const MyPortal = (props) => {
</div> </div>
</div> </div>
</main> </main>
<IdleTimer {/* <IdleTimer
ref={(ref) => { ref={(ref) => {
idleTimer = ref; idleTimer = ref;
}} }}
@@ -133,14 +135,8 @@ const MyPortal = (props) => {
onActive={console.log(" bbis active", idleTimer)} onActive={console.log(" bbis active", idleTimer)}
onIdle={onIdle} onIdle={onIdle}
timeout={1000 * inactiveTimeOut * 1} timeout={1000 * inactiveTimeOut * 1}
/> /> */}
<TimeOut ggLogout={props.ggLogout} />
<TimeoutModal
remainingCountdown={reminderTimeout}
showModal={showModal}
togglePopup={togglePopup}
handleStayLoggedIn={handleStayLoggedIn}
/>
</> </>
); );
}; };
+2 -2
View File
@@ -10,6 +10,7 @@ import {
setAppealTypeTitle, setAppealTypeTitle,
} from "../../store/appealType/action"; } from "../../store/appealType/action";
import { getFormCollectionByID } from "../utils"; import { getFormCollectionByID } from "../utils";
import FileUpload from "./fileupload";
let CreateCase = (props) => { let CreateCase = (props) => {
// useEffect(() => { // useEffect(() => {
@@ -238,7 +239,6 @@ let CreateCase = (props) => {
label={t("newappeal:select-lpa-label")} label={t("newappeal:select-lpa-label")}
errorMsg={t("newappeal:select-lpa-label-error-msg")} errorMsg={t("newappeal:select-lpa-label-error-msg")}
/> />
<Field <Field
name="appealTypes" name="appealTypes"
component={RenderAppealTypeList} component={RenderAppealTypeList}
@@ -247,7 +247,7 @@ let CreateCase = (props) => {
label={t("newappeal:select-appeal-type-label")} label={t("newappeal:select-appeal-type-label")}
errorMsg={t("newappeal:select-appeal-type-label-error-msg")} errorMsg={t("newappeal:select-appeal-type-label-error-msg")}
/> />
<FileUpload />
<button <button
type="submit" type="submit"
className="govuk-button" className="govuk-button"
+42
View File
@@ -0,0 +1,42 @@
import { useDropzone } from "react-dropzone";
import Link from "next/link";
import { useState, useEffect } from "react";
import { useRouter } from "next/router";
import useTranslation from "next-translate/useTranslation";
import jsonpath from "jsonpath";
import _ from "lodash";
const FileUpload = () => {
const { acceptedFiles, getRootProps, getInputProps } = useDropzone();
const files = acceptedFiles.map((file) => (
<li key={file.path}>
{file.path} - {file.size} bytes
</li>
));
return (
<div className="govuk-grid-column-full">
<div className="govuk-grid-row">
<div className="govuk-form-group">
<section className="container">
<div
{...getRootProps({
className: "dropzone",
})}
>
<input {...getInputProps()} />
<p>
Drag and drop files here or click to select
files
</p>
</div>
<aside>
<h4>Files</h4>
<ul>{files}</ul>
</aside>
</section>
</div>
</div>
</div>
);
};
export default FileUpload;
+69
View File
@@ -0,0 +1,69 @@
import useTranslation from "next-translate/useTranslation";
import { useRouter } from "next/router";
import { destroyCookie } from "nookies";
import { useState } from "react";
import IdleTimer from "react-idle-timer";
import TimeoutModal from "./timeoutmodal";
const TimeOut = (props) => {
let { t } = useTranslation();
const router = useRouter();
const { locale } = router;
const [showModal, setShowModal] = useState(false);
const inactiveTimeOut = 1200; // in seconds
const reminderTimeout = 60; // in seconds
let idleTimer = null;
let logoutTimer = null;
let onIdle = () => {
togglePopup();
logoutTimer = setTimeout(() => {
handleLogout();
}, 1000 * reminderTimeout * 1);
};
let togglePopup = () => {
showModal == true ? setShowModal(false) : setShowModal(true);
};
let handleStayLoggedIn = () => {
if (logoutTimer) {
clearTimeout(logoutTimer);
logoutTimer = null;
}
idleTimer.reset();
togglePopup();
};
const handleLogout = () => {
console.log("////////////", "\n", "logout", "\n", "//////////");
destroyCookie({}, "pinsUser"),
window.localStorage.clear(),
router.replace(props.ggLogout);
};
return (
<>
<IdleTimer
ref={(ref) => {
idleTimer = ref;
}}
element={document}
stopOnIdle={true}
onActive={console.log(" bbis active", idleTimer)}
onIdle={onIdle}
timeout={1000 * inactiveTimeOut * 1}
/>
<TimeoutModal
remainingCountdown={reminderTimeout}
showModal={showModal}
togglePopup={togglePopup}
handleStayLoggedIn={handleStayLoggedIn}
/>
</>
);
};
export default TimeOut;
+9 -9
View File
@@ -11,17 +11,17 @@ class MyDocument extends Document {
let useGATracking = false; let useGATracking = false;
//remove this block when not need after softlaunch //remove this block when not need after softlaunch
let hasBasicAuth = // let hasBasicAuth =
typeof process.env.BASIC_AUTH_CREDENTIALS != "undefined"; // typeof process.env.BASIC_AUTH_CREDENTIALS != "undefined";
console.log("hasbasicAuth:", hasBasicAuth); // console.log("hasbasicAuth:", hasBasicAuth);
if (ctx.req && ctx.res) { // if (ctx.req && ctx.res) {
hasBasicAuth && // hasBasicAuth &&
(await basicAuthMiddleware(ctx.req, ctx.res, { // (await basicAuthMiddleware(ctx.req, ctx.res, {
users: process.env.BASIC_AUTH_CREDENTIALS, // users: process.env.BASIC_AUTH_CREDENTIALS,
})); // }));
} // }
if (ctx.req && ctx.req.headers.cookie) { if (ctx.req && ctx.req.headers.cookie) {
typeof ctx.req.cookies.CookiePolicy != "undefined" typeof ctx.req.cookies.CookiePolicy != "undefined"
@@ -26,8 +26,6 @@ export default async function ApiProxy(req, res) {
loggedInUserId + loggedInUserId +
" and servicestage eq 1 and pinswg_appealcasetype ne null&$orderby=createdon desc&$count=true"; " and servicestage eq 1 and pinswg_appealcasetype ne null&$orderby=createdon desc&$count=true";
console.log(queryUrl);
return axios return axios
.get( .get(
WEBAPI_URL + queryUrl + hashAPIPath(queryUrl), WEBAPI_URL + queryUrl + hashAPIPath(queryUrl),
+7 -1
View File
@@ -4,13 +4,16 @@ import Head from "next/head";
import { useRouter } from "next/router"; import { useRouter } from "next/router";
import { connect } from "react-redux"; import { connect } from "react-redux";
import { getAppealsTypes, getLPA } from "../../actions"; import { getAppealsTypes, getLPA } from "../../actions";
import { getProviderConfig } from "../../actions/govgateway";
import Breadcrumbs from "../../components/breadcrumbs"; import Breadcrumbs from "../../components/breadcrumbs";
import CookieBanner from "../../components/cookieBanner"; import CookieBanner from "../../components/cookieBanner";
import CRMError from "../../components/crmError"; import CRMError from "../../components/crmError";
import Footer from "../../components/footer"; import Footer from "../../components/footer";
import Header from "../../components/header"; import Header from "../../components/header";
import Search from "../../components/search"; import Search from "../../components/search";
import TimeOut from "../../components/timeout";
import { setAppealType } from "../../store/appealType/action"; import { setAppealType } from "../../store/appealType/action";
import { getGovGatewayConfig } from "../../store/govgateway/action";
import { setLPA } from "../../store/lpa/action"; import { setLPA } from "../../store/lpa/action";
import { wrapper } from "../../store/store"; import { wrapper } from "../../store/store";
@@ -51,6 +54,7 @@ const Home = (props) => {
</div> </div>
<Footer footerLinks={footerLinks} /> <Footer footerLinks={footerLinks} />
</div> </div>
<TimeOut ggLogout={props.govGateway.config.end_session_endpoint} />
</div> </div>
); );
}; };
@@ -62,7 +66,8 @@ export const getServerSideProps = wrapper.getServerSideProps(
await getAppealsTypes(), await getAppealsTypes(),
await getLPA(), await getLPA(),
]); ]);
const providerConfig = await getProviderConfig();
store.dispatch(getGovGatewayConfig(providerConfig));
store.dispatch(setAppealType(appealTypeData)); store.dispatch(setAppealType(appealTypeData));
store.dispatch(setLPA(lpaData)); store.dispatch(setLPA(lpaData));
} }
@@ -77,6 +82,7 @@ const mapStateToProps = (state) => {
LPAData: state.LPAData, LPAData: state.LPAData,
//form: state.form, //form: state.form,
accountDetails: state.accountDetails, accountDetails: state.accountDetails,
govGateway: state.govGateway,
}; };
}; };
+7 -1
View File
@@ -25,6 +25,9 @@ import {
setWatchedCases, setWatchedCases,
setWatchedCasesDetails, setWatchedCasesDetails,
} from "../../store/watchedCases/action"; } from "../../store/watchedCases/action";
import TimeOut from "../../components/timeout";
import { getGovGatewayConfig } from "../../store/govgateway/action";
import { getProviderConfig } from "../../actions/govgateway";
const Home = (props) => { const Home = (props) => {
const { footerLinks, pages, watchedCases } = props; const { footerLinks, pages, watchedCases } = props;
@@ -56,6 +59,7 @@ const Home = (props) => {
</div> </div>
<Footer footerLinks={footerLinks} /> <Footer footerLinks={footerLinks} />
</div> </div>
<TimeOut ggLogout={props.govGateway.config.end_session_endpoint} />
</div> </div>
); );
}; };
@@ -78,7 +82,8 @@ export const getServerSideProps = wrapper.getServerSideProps(
await getSearchDetails(searchResultsObj), await getSearchDetails(searchResultsObj),
await getDetails(watchedCases, "myWatchedCases"), await getDetails(watchedCases, "myWatchedCases"),
]); ]);
const providerConfig = await getProviderConfig();
store.dispatch(getGovGatewayConfig(providerConfig));
store.dispatch(setSearchResults(searchResultsObj)); store.dispatch(setSearchResults(searchResultsObj));
store.dispatch(setSearchDetails(searchDetailsObj)); store.dispatch(setSearchDetails(searchDetailsObj));
store.dispatch(setWatchedCases(watchedCases)); store.dispatch(setWatchedCases(watchedCases));
@@ -129,6 +134,7 @@ const mapStateToProps = (state) => {
watchedCases: state.watchedCases, watchedCases: state.watchedCases,
myRepresentations: state.myRepresentations, myRepresentations: state.myRepresentations,
awaitingSubmission: state.awaitingSubmission, awaitingSubmission: state.awaitingSubmission,
govGateway: state.govGateway,
}; };
}; };
+3
View File
@@ -7,6 +7,7 @@ import Case from "../../components/case";
import CookieBanner from "../../components/cookieBanner"; import CookieBanner from "../../components/cookieBanner";
import Footer from "../../components/footer"; import Footer from "../../components/footer";
import Header from "../../components/header"; import Header from "../../components/header";
import TimeOut from "../../components/timeout";
const Home = (props) => { const Home = (props) => {
const { footerLinks, pages, showRepresentations } = props; const { footerLinks, pages, showRepresentations } = props;
@@ -74,6 +75,7 @@ const Home = (props) => {
</div> </div>
<Footer footerLinks={footerLinks} /> <Footer footerLinks={footerLinks} />
</div> </div>
<TimeOut ggLogout={props.govGateway.config.end_session_endpoint} />
</div> </div>
); );
}; };
@@ -92,6 +94,7 @@ const mapStateToProps = (state) => {
watchedCases: state.watchedCases, watchedCases: state.watchedCases,
myRepresentations: state.myRepresentations, myRepresentations: state.myRepresentations,
awaitingSubmission: state.awaitingSubmission, awaitingSubmission: state.awaitingSubmission,
govGateway: state.govGateway,
}; };
}; };
+7 -1
View File
@@ -26,6 +26,9 @@ import {
setWatchedCases, setWatchedCases,
setWatchedCasesDetails, setWatchedCasesDetails,
} from "../../store/watchedCases/action"; } from "../../store/watchedCases/action";
import TimeOut from "../../components/timeout";
import { getGovGatewayConfig } from "../../store/govgateway/action";
import { getProviderConfig } from "../../actions/govgateway";
const Home = (props) => { const Home = (props) => {
const { footerLinks, pages, watchedCases } = props; const { footerLinks, pages, watchedCases } = props;
@@ -56,6 +59,7 @@ const Home = (props) => {
</div> </div>
<Footer footerLinks={footerLinks} /> <Footer footerLinks={footerLinks} />
</div> </div>
<TimeOut ggLogout={props.govGateway.config.end_session_endpoint} />
</div> </div>
); );
}; };
@@ -89,7 +93,8 @@ export const getServerSideProps = wrapper.getServerSideProps(
await getSearchDetails(searchResultsObj), await getSearchDetails(searchResultsObj),
await getDetails(watchedCases, "myWatchedCases"), await getDetails(watchedCases, "myWatchedCases"),
]); ]);
const providerConfig = await getProviderConfig();
store.dispatch(getGovGatewayConfig(providerConfig));
store.dispatch(setSearchResults(searchResultsObj)); store.dispatch(setSearchResults(searchResultsObj));
store.dispatch(setSearchDetails(searchDetailsObj)); store.dispatch(setSearchDetails(searchDetailsObj));
store.dispatch(setSearch(query.q)); store.dispatch(setSearch(query.q));
@@ -142,6 +147,7 @@ const mapStateToProps = (state) => {
myRepresentations: state.myRepresentations, myRepresentations: state.myRepresentations,
awaitingSubmission: state.awaitingSubmission, awaitingSubmission: state.awaitingSubmission,
accountDetails: state.accountDetails, accountDetails: state.accountDetails,
govGateway: state.govGateway,
}; };
}; };
+3
View File
@@ -7,6 +7,7 @@ import CookieBanner from "../../components/cookieBanner";
import Footer from "../../components/footer"; import Footer from "../../components/footer";
import Header from "../../components/header"; import Header from "../../components/header";
import ViewAll from "../../components/myportal/viewall"; import ViewAll from "../../components/myportal/viewall";
import TimeOut from "../../components/timeout";
const Home = (props) => { const Home = (props) => {
const { footerLinks, pages } = props; const { footerLinks, pages } = props;
@@ -44,6 +45,7 @@ const Home = (props) => {
</div> </div>
<Footer footerLinks={footerLinks} /> <Footer footerLinks={footerLinks} />
</div> </div>
<TimeOut ggLogout={props.govGateway.config.end_session_endpoint} />
</div> </div>
); );
}; };
@@ -70,6 +72,7 @@ const mapStateToProps = (state) => {
myRepresentations: state.myRepresentations, myRepresentations: state.myRepresentations,
awaitingSubmission: state.awaitingSubmission, awaitingSubmission: state.awaitingSubmission,
currentView: state.currentView, currentView: state.currentView,
govGateway: state.govGateway,
}; };
}; };