Skip to content

Commit

Permalink
Merge branch 'main' into ORV2-2161
Browse files Browse the repository at this point in the history
  • Loading branch information
cberg-aot authored Apr 25, 2024
2 parents 30bbb61 + c23898b commit ae4ebe3
Show file tree
Hide file tree
Showing 27 changed files with 671 additions and 143 deletions.
2 changes: 1 addition & 1 deletion .github/CODEOWNERS
Validating CODEOWNERS rules …
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
* @john-fletcher-aot @gchauhan-aot @praju-aot @krishnan-aot @zgong-gov

# Frontend:
/frontend/** @krishnan-aot @erikataot @zgong-gov
/frontend/** @krishnan-aot @zgong-gov

# Vehicles:
/vehicles/** @gchauhan-aot @praju-aot
Expand Down
3 changes: 0 additions & 3 deletions docker-compose.yml
Original file line number Diff line number Diff line change
@@ -1,6 +1,3 @@
---
version: "3.8"

services:
sql-server-db:
container_name: sql-server-db
Expand Down
31 changes: 15 additions & 16 deletions dops/package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion dops/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -110,7 +110,7 @@
"prettier": "^3.2.5",
"rimraf": "^5.0.5",
"source-map-support": "^0.5.21",
"supertest": "^6.3.4",
"supertest": "^7.0.0",
"ts-jest": "^29.1.2",
"ts-loader": "^9.5.1",
"ts-node": "^10.9.2",
Expand Down
2 changes: 1 addition & 1 deletion frontend/Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ USER app
EXPOSE 3000

# Have only the compiled app, ready for production with Nginx
FROM nginx:1.25.4-alpine as production-stage
FROM nginx:1.26-alpine as production-stage
RUN mkdir /app
COPY --from=builder /app/build /usr/share/nginx/html
COPY nginx.conf /etc/nginx/nginx.conf
Expand Down
2 changes: 1 addition & 1 deletion frontend/src/common/apiManager/httpRequestHandler.ts
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ const getUserStorageKey = () =>
*
* @returns JSON parsed object, or undefined if item not found in sessionStorage.
*/
const getUserStorage = () => {
export const getUserStorage = () => {
const storageKey = getDefaultRequiredVal("", getUserStorageKey());
return applyWhenNotNullable(JSON.parse, sessionStorage.getItem(storageKey));
};
Expand Down
53 changes: 44 additions & 9 deletions frontend/src/common/authentication/auth-walls/BCeIDAuthWall.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ import { IDIRUserAuthGroupType, UserRolesType } from "../types";
import { DoesUserHaveRole } from "../util";
import { IDIRAuthWall } from "./IDIRAuthWall";
import { setRedirectInSession } from "../../helpers/util";
import { getUserStorage } from "../../apiManager/httpRequestHandler";

export const isIDIR = (identityProvider: string) =>
identityProvider === IDPS.IDIR;
Expand All @@ -38,6 +39,7 @@ export const BCeIDAuthWall = ({
isAuthenticated,
isLoading: isAuthLoading,
user: userFromToken,
signinSilent,
} = useAuth();

const { userRoles, companyId, isNewBCeIDUser } = useContext(OnRouteBCContext);
Expand All @@ -47,18 +49,51 @@ export const BCeIDAuthWall = ({
const navigate = useNavigate();

/**
* Redirect the user back to login page if they are trying to directly access
* a protected page but are unauthenticated.
* Redirects the user to the login page.
* This function captures the current URL and passes it as a redirect parameter
* to the login page so that after successful authentication, the user can be
* redirected back to the page they initially requested.
*/
const redirectToLoginPage = () => {
setRedirectInSession(window.location.href);
navigate({
pathname: HOME,
search: createSearchParams({
r: window.location.href,
}).toString(),
});
};

/**
* Try refreshing the access token,
* if still logged out redirect the user back to login page if
* they are trying to directly access a protected page but are unauthenticated.
*/
useEffect(() => {
if (!isAuthLoading && !isAuthenticated) {
setRedirectInSession(window.location.href);
navigate({
pathname: HOME,
search: createSearchParams({
r: window.location.href,
}).toString(),
});
try {
const userSessionJSON = getUserStorage();
if (userSessionJSON?.refresh_token) {
signinSilent()
.then((value) => {
if (!value?.access_token) {
// If sign in is unsuccessful, redirect to home page.
redirectToLoginPage();
}
// else, silent sign in is complete and token is refreshed.
// AuthContext will be updated and the component rerenders which
// takes care of directing the user as appropriate.
})
.catch(() => {
redirectToLoginPage();
});
} else {
redirectToLoginPage();
}
} catch (e) {
console.error("Unable to process token refresh; redirecting to login");
redirectToLoginPage();
}
}
}, [isAuthLoading, isAuthenticated]);

Expand Down
5 changes: 1 addition & 4 deletions frontend/src/common/components/header/Header.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -154,10 +154,7 @@ export const Header = () => {
</div>
</header>
{shouldDisplayNavBar && (
<Navbar
isAuthenticated={isAuthenticated}
userRoles={userRoles}
/>
<Navbar isAuthenticated={isAuthenticated} userRoles={userRoles} />
)}
{shouldDisplayNavBar && menuOpen ? (
<Navbar
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { useState } from "react";
import { useContext, useState } from "react";
import { useNavigate, useSearchParams } from "react-router-dom";
import {
RadioGroup,
Expand Down Expand Up @@ -29,6 +29,7 @@ import {
SearchFields,
} from "../../../../features/idir/search/types/types";
import { useFeatureFlagsQuery } from "../../../hooks/hooks";
import OnRouteBCContext from "../../../authentication/OnRouteBCContext";

const SEARCH_BY_PERMIT_OPTIONS = [
{ label: "Permit Number", value: "permitNumber" },
Expand Down Expand Up @@ -90,6 +91,7 @@ export const SearchFilter = ({
*/
closeFilter: () => void;
}) => {
const { clearCompanyContext } = useContext(OnRouteBCContext);
const [searchParams] = useSearchParams();
const { data: featureFlags } = useFeatureFlagsQuery();
const navigate = useNavigate();
Expand Down Expand Up @@ -147,6 +149,7 @@ export const SearchFilter = ({

if (data?.searchString?.trim()?.length < 1) return;

clearCompanyContext?.();
closeFilter();

navigate(`${IDIR_ROUTES.SEARCH_RESULTS}?${searchFields}`);
Expand Down
12 changes: 10 additions & 2 deletions frontend/src/common/components/links/CustomExternalLink.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import { ExternalLinkProps } from "./types/LinkProps";
import { CustomLinkContent } from "./CustomLinkContent";

export const CustomExternalLink = (props: ExternalLinkProps) => {
const { withLinkIcon, ...linkProps } = props;
const { withLinkIcon, openInNewTab, ...linkProps } = props;

const className = () => {
const baseClassName = "custom-link";
Expand All @@ -12,8 +12,16 @@ export const CustomExternalLink = (props: ExternalLinkProps) => {
: baseClassName;
};

const linkTarget = openInNewTab ? {
target: "_blank",
} : {};

return (
<a {...linkProps} className={className()}>
<a
{...linkProps}
{...linkTarget}
className={className()}
>
<CustomLinkContent withLinkIcon={withLinkIcon}>
{linkProps.children}
</CustomLinkContent>
Expand Down
5 changes: 4 additions & 1 deletion frontend/src/common/components/links/types/LinkProps.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,9 @@ type Props<TExternal = boolean> = TExternal extends true
? CustomLinkProps & LinkHTMLAttributes<HTMLAnchorElement>
: CustomLinkProps & LinkProps;

export type ExternalLinkProps = Props<true>;
export type ExternalLinkProps = Props<true> & {
openInNewTab?: boolean;
};

export type InternalLinkProps = Props<false>;
export type CustomActionLinkProps = MuiLinkProps;
3 changes: 3 additions & 0 deletions frontend/src/common/constants/validation_messages.json
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,9 @@
"messageTemplate": ":fieldName is required",
"placeholders": [":fieldName"]
},
"selectionRequired": {
"defaultMessage": "Select at least one item"
},
"NaN": {
"defaultMessage": "Must be a number"
},
Expand Down
1 change: 1 addition & 0 deletions frontend/src/common/helpers/validationMessages.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ const replacePlaceholders = (
};

export const requiredMessage = () => validationMessages.required.defaultMessage;
export const selectionRequired = () => validationMessages.selectionRequired.defaultMessage;
export const invalidNumber = () => validationMessages.NaN.defaultMessage;
export const invalidCountryCode = () =>
validationMessages.country.defaultMessage;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,9 @@ import PermitResendDialog from "./PermitResendDialog";
import { viewReceiptPdf } from "../../../permits/helpers/permitPDFHelper";
import * as routes from "../../../../routes/constants";
import { USER_AUTH_GROUP } from "../../../../common/authentication/types";
import { Nullable } from "../../../../common/types/common";
import { useResendPermit } from "../../../permits/hooks/hooks";
import { SnackBarContext } from "../../../../App";
import { EmailNotificationType } from "../../../permits/types/EmailNotificationType";

const PERMIT_ACTION_TYPES = {
RESEND: "resend",
Expand Down Expand Up @@ -90,7 +90,6 @@ export const IDIRPermitSearchRowActions = ({
isPermitInactive,
permitNumber,
email,
fax,
userAuthGroup,
companyId,
}: {
Expand All @@ -110,10 +109,6 @@ export const IDIRPermitSearchRowActions = ({
* The email address (for use in resend dialog)
*/
email?: string;
/**
* The fax number (for use in resend dialog)
*/
fax?: string;
/**
* The auth group for the current user (eg. PPCCLERK or EOFFICER)
*/
Expand Down Expand Up @@ -145,12 +140,12 @@ export const IDIRPermitSearchRowActions = ({
const handleResend = async (
permitId: string,
email: string,
fax?: Nullable<string>,
notificationTypes: EmailNotificationType[],
) => {
const response = await resendPermitMutation.mutateAsync({
permitId,
email,
fax,
notificationTypes,
});

setOpenResendDialog(false);
Expand All @@ -173,13 +168,13 @@ export const IDIRPermitSearchRowActions = ({
options={getOptions(isPermitInactive, userAuthGroup)}
key={`idir-search-row-${permitNumber}`}
/>

<PermitResendDialog
shouldOpen={openResendDialog}
onCancel={() => setOpenResendDialog(false)}
onResend={handleResend}
permitId={permitId}
email={email}
fax={fax}
permitNumber={permitNumber}
/>
</>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -70,4 +70,35 @@
margin-bottom: 0;
margin-top: 1.5rem;
}

& &__notification-types {
display: block;
margin-top: 1.5rem;

.notification-type {
display: flex;
align-items: center;

&__checkbox {
padding: 0;

&--invalid {
color: $bc-red;
}
}

&__label {
margin-left: 0.5rem;
}

&--receipt {
margin-top: 1.5rem;
}
}
}

& &__error-msg {
color: $bc-red;
margin-top: 0.5rem;
}
}
Loading

0 comments on commit ae4ebe3

Please sign in to comment.