Skip to content

Commit

Permalink
Merge pull request #2135 from bcgov/feat/kc-gold-integration
Browse files Browse the repository at this point in the history
Feat: kc gold integration
  • Loading branch information
dleard authored Jan 19, 2023
2 parents e33097d + 8769427 commit aef6348
Show file tree
Hide file tree
Showing 77 changed files with 1,535 additions and 1,066 deletions.
1 change: 0 additions & 1 deletion .circleci/config.yml
Original file line number Diff line number Diff line change
Expand Up @@ -215,7 +215,6 @@ jobs:
source ~/.bashrc
pushd schema
./data/deploy-data.sh -prod
sqitch verify
popd
- run:
name: regenerate schema via introspection
Expand Down
2 changes: 1 addition & 1 deletion .tool-versions
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
nodejs 14.17.5
nodejs 14.21.1
yarn 1.22.19
postgres 14.0
python 3.9.2
2 changes: 2 additions & 0 deletions app/.env.example
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@ HOST=<host address>
GGIRCS_HOST=<ggircs URL>
METABASE_HOST=<metabase URL>

KC_CLIENT_SECRET=<keycloak client secret> #pragma: allowlist secret

# true if we want the mocks database schema to be deployed, false otherwise
ENABLE_DB_MOCKS=<true or false>
ENABLE_DB_MOCKS_COOKIES_ONLY=<true or false>
Expand Down
7 changes: 1 addition & 6 deletions app/components/Layout/Header.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -120,15 +120,10 @@ const HeaderLayout: React.FunctionComponent<Props> = ({
isRegistered && userProfileDropdown
) : (
<>
<li>
<Link href="/register">
<a className="nav-button">Register</a>
</Link>
</li>
<li>
<LoginButton>
<button className="nav-button" type="submit">
Login
Login (IDIR)
</button>
</LoginButton>
</li>
Expand Down
4 changes: 2 additions & 2 deletions app/components/LoginButton.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,10 @@ import { Form } from "react-bootstrap";

const LoginForm: React.FunctionComponent = ({ children }) => {
const router = useRouter();
let loginURI = "/login";
let loginURI = "/login?kc_idp_hint=idir";

if (router.query.redirectTo)
loginURI += `?redirectTo=${encodeURIComponent(
loginURI += `&redirectTo=${encodeURIComponent(
router.query.redirectTo as string
)}`;

Expand Down
16 changes: 2 additions & 14 deletions app/containers/RegistrationLoginButtons.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
import React from "react";
import { Col, Card, Button } from "react-bootstrap";
import LoginButton from "../components/LoginButton";
import { Col, Card } from "react-bootstrap";
import { createFragmentContainer, graphql } from "react-relay";
import { RegistrationLoginButtons_query } from "RegistrationLoginButtons_query.graphql";
import { dateTimeFormat } from "functions/formatDates";
Expand Down Expand Up @@ -46,20 +45,9 @@ export const RegistrationLoginButtonsComponent: React.FunctionComponent<Props> =
Apply for the CleanBC Industrial Incentive Program (CIIP)
</Card.Title>
{cardText}
<a
href="/register"
style={{ padding: "15px", display: "block" }}
className="btn btn-primary btn-lg"
>
Register and Apply
</a>
</Card.Body>
</Card>
<LoginButton>
<Button className="login-link" type="submit" variant="outline-dark">
Already have an account? Click here to login.
</Button>
</LoginButton>

<style jsx global>{`
.login-link {
padding: 20px;
Expand Down
103 changes: 50 additions & 53 deletions app/containers/User/UserForm.tsx
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
import React, { useState } from "react";
import React, { useMemo } from "react";
import { createFragmentContainer, graphql, RelayProp } from "react-relay";
import JsonSchemaForm, { IChangeEvent, AjvError } from "@rjsf/core";
import { JSONSchema7 } from "json-schema";
import { UserForm_user } from "UserForm_user.graphql";
import createUserMutation from "mutations/user/createUserMutation";
import createOrUpdateUserMutation from "mutations/user/createOrUpdateUserMutation";
import updateUserMutation from "mutations/user/updateUserMutation";
import FormArrayFieldTemplate from "containers/Forms/FormArrayFieldTemplate";
import FormFieldTemplate from "containers/Forms/FormFieldTemplate";
Expand All @@ -13,7 +13,6 @@ import { customTransformErrors } from "functions/customTransformErrors";
interface Props {
user?: UserForm_user;
relay: RelayProp;
uuid?: string;
defaultGivenName?: string;
defaultFamilyName?: string;
defaultEmail?: string;
Expand All @@ -37,7 +36,6 @@ const transformErrors = (errors: AjvError[]) => {

const UserForm: React.FunctionComponent<Props> = ({
user,
uuid,
defaultGivenName,
defaultFamilyName,
defaultEmail,
Expand All @@ -46,20 +44,13 @@ const UserForm: React.FunctionComponent<Props> = ({
}) => {
const handleChange = async (e: IChangeEvent<UserForm_user>) => {
if (user) {
const {
firstName,
lastName,
emailAddress,
phoneNumber,
occupation,
} = e.formData;
const { firstName, lastName, phoneNumber, occupation } = e.formData;
await updateUserMutation(relay.environment, {
input: {
id: user.id,
ciipUserPatch: {
firstName,
lastName,
emailAddress,
phoneNumber,
occupation,
},
Expand All @@ -70,62 +61,68 @@ const UserForm: React.FunctionComponent<Props> = ({

const handleSubmit = async (e: IChangeEvent<UserForm_user>) => {
if (user) await handleChange(e);
else
await createUserMutation(relay.environment, {
else {
const { firstName, lastName, phoneNumber, occupation } = e.formData;
await createOrUpdateUserMutation(relay.environment, {
input: {
ciipUser: {
...e.formData,
uuid,
},
firstName,
lastName,
phoneNumber,
occupation,
},
});
}
onSubmit();
};

const [userSchema] = useState<JSONSchema7>({
type: "object",
properties: {
firstName: {
type: "string",
title: "First Name",
default: defaultGivenName,
},
lastName: {
type: "string",
title: "Last Name",
default: defaultFamilyName,
},
emailAddress: {
type: "string",
title: "Email Address",
default: defaultEmail,
format: "email",
},
phoneNumber: {
type: "string",
title: "Phone Number",
format: "phoneNumber",
},
occupation: {
type: "string",
title: "Occupation",
const userSchema: JSONSchema7 = useMemo(
() => ({
type: "object",
properties: {
firstName: {
type: "string",
title: "First Name",
default: defaultGivenName,
},
lastName: {
type: "string",
title: "Last Name",
default: defaultFamilyName,
},
emailAddress: {
type: "string",
title: "Email Address",
default: defaultEmail,
format: "email",
},
phoneNumber: {
type: "string",
title: "Phone Number",
format: "phoneNumber",
},
occupation: {
type: "string",
title: "Occupation",
},
},
required: ["firstName", "lastName", "phoneNumber", "occupation"],
}),
[defaultGivenName, defaultFamilyName, defaultEmail]
);

const uiSchema = {
emailAddress: {
"ui:disabled": true,
},
required: [
"firstName",
"lastName",
"emailAddress",
"phoneNumber",
"occupation",
],
});
};

return (
<JsonSchemaForm
omitExtraData
liveOmit
liveValidate
schema={userSchema}
uiSchema={uiSchema}
customFormats={customFormats}
transformErrors={transformErrors}
formData={user}
Expand Down
12 changes: 6 additions & 6 deletions app/cypress/integration/index.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,14 +5,14 @@ describe("The index page", () => {

cy.visit("/");
cy.get("#page-content");
cy.get("header").contains("Register");
cy.get("header").contains("Login");
cy.get("header").contains("Register").should("not.exist");
cy.get("header").contains("Login (IDIR)");
cy.get("header").happoScreenshot({ component: "Header" });
cy.get("footer").happoScreenshot({ component: "Footer" });
cy.get("#page-content").contains("Register and Apply");
cy.get("#page-content").contains(
"Already have an account? Click here to login."
);
cy.get("#page-content").contains("Register and Apply").should("not.exist");
cy.get("#page-content")
.contains("Already have an account? Click here to login.")
.should("not.exist");

cy.contains("Jan 23, 1991");
cy.get("body").happoScreenshot({ component: "Index Page" });
Expand Down
12 changes: 1 addition & 11 deletions app/cypress/integration/login-redirects.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -43,9 +43,7 @@ function testRedirectsForScopedPages(scope, pages) {

cy.mockLogin(scope);

// As the SSO login page won't open in a frame in Cypress, the final redirect must be
// tested indirectly as though we're following the auth callback:
cy.visit(`/login?redirectTo=${encodeURIComponent(url)}`);
cy.visit(url);
cy.url().should("include", url);
});
});
Expand All @@ -62,11 +60,3 @@ describe("Successful redirection of authenticated pages through login", () => {
testRedirectsForScopedPages(scope, AUTHENTICATED_PAGES[scope])
);
});

describe("When failing the keycloak authorization", () => {
it("should redirect to the 403 page", () => {
// Any request with the auth_callback=1 query param will be routed through the keycloak middleware
cy.visit("/login?auth_callback=1");
cy.url().should("include", "/403");
});
});
5 changes: 0 additions & 5 deletions app/data/kc-namespace-map.json

This file was deleted.

32 changes: 32 additions & 0 deletions app/mutations/user/createOrUpdateUserMutation.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
import { graphql } from "react-relay";
import {
createOrUpdateUserMutation as createOrUpdateUserMutationType,
createOrUpdateUserMutationVariables,
} from "__generated__/createOrUpdateUserMutation.graphql";
import RelayModernEnvironment from "relay-runtime/lib/store/RelayModernEnvironment";
import BaseMutation from "mutations/BaseMutation";

const mutation = graphql`
mutation createOrUpdateUserMutation($input: CreateOrUpdateCiipUserInput!) {
createOrUpdateCiipUser(input: $input) {
ciipUser {
firstName
lastName
emailAddress
occupation
phoneNumber
}
}
}
`;

const createOrUpdateUserMutation = async (
environment: RelayModernEnvironment,
variables: createOrUpdateUserMutationVariables
) => {
return new BaseMutation<createOrUpdateUserMutationType>(
"create-or-update-ciip-user-mutation"
).performMutation(environment, mutation, variables);
};

export default createOrUpdateUserMutation;
32 changes: 0 additions & 32 deletions app/mutations/user/createUserMutation.ts

This file was deleted.

5 changes: 3 additions & 2 deletions app/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -27,12 +27,13 @@
"lint": "eslint --ext .js,.jsx,.ts,.tsx ."
},
"engines": {
"node": "14.17.5",
"node": "14.21.1",
"yarn": "1.22.19"
},
"author": "",
"license": "ISC",
"dependencies": {
"@bcgov-cas/sso-express": "^3.2.0",
"@fortawesome/fontawesome-svg-core": "^1.2.31",
"@fortawesome/free-solid-svg-icons": "^5.15.3",
"@fortawesome/react-fontawesome": "^0.1.16",
Expand Down Expand Up @@ -61,13 +62,13 @@
"isomorphic-fetch": "^3.0.0",
"js-file-download": "^0.4.12",
"json-schema": "^0.4.0",
"keycloak-connect": "^10.0.0",
"lightship": "^6.7.2",
"lodash.throttle": "^4.1.1",
"moment-timezone": "^0.5.35",
"morgan": "^1.10.0",
"next": "^12.1.0",
"nodemailer": "^6.6.1",
"openid-client": "5",
"pg": "^8.2.0",
"postgraphile": "^4.11.0",
"postgraphile-log-consola": "^1.0.1",
Expand Down
Loading

0 comments on commit aef6348

Please sign in to comment.