diff --git a/app/.env.example b/app/.env.example index 86b6c55..44588bc 100644 --- a/app/.env.example +++ b/app/.env.example @@ -33,3 +33,4 @@ BCEID_SERVICE_ID= BCEID_SERVICE_BASIC_AUTH= IDIR_JWKS_URI= IDIR_ISSUER= +NEXTAUTH_URL=http://localhost:3000 diff --git a/app/controllers/realm.ts b/app/controllers/realm.ts index 5618a0f..bf01d21 100644 --- a/app/controllers/realm.ts +++ b/app/controllers/realm.ts @@ -2,8 +2,8 @@ import { runQuery } from 'utils/db'; import KeycloakCore from 'utils/keycloak-core'; export async function getAllowedRealms(session: any) { - const username = session?.idir_username || ''; - const roles = session?.client_roles || []; + const username = session?.user?.idir_username || ''; + const roles = session?.user?.client_roles || []; const isAdmin = roles.includes('sso-admin'); let result: any = null; @@ -54,8 +54,8 @@ export async function getAllowedRealms(session: any) { } export async function getAllowedRealmNames(session: any) { - const username = session?.idir_username || ''; - const roles = session?.client_roles || []; + const username = session?.user?.idir_username || ''; + const roles = session?.user?.client_roles || []; const isAdmin = roles.includes('sso-admin'); let result: any = null; diff --git a/app/layout/Layout.tsx b/app/layout/Layout.tsx index a413f2a..3206ea3 100644 --- a/app/layout/Layout.tsx +++ b/app/layout/Layout.tsx @@ -10,6 +10,9 @@ import { startCase } from 'lodash'; import BCSans from './BCSans'; import Navigation from './Navigation'; import BottomAlertProvider from './BottomAlert'; +import { useSession } from 'next-auth/react'; +import { useEffect } from 'react'; +import { User } from 'next-auth'; const headerPlusFooterHeight = '152px'; @@ -106,11 +109,11 @@ const routes: Route[] = [ { path: '/realm', label: 'Realm Profile', roles: ['user'], hide: true }, ]; -const LeftMenuItems = ({ currentUser, currentPath }: { currentUser: any; currentPath: string }) => { - let roles = ['guest']; +const LeftMenuItems = ({ currentUser, currentPath }: { currentUser: Partial; currentPath: string }) => { + let roles: string[] = ['guest']; if (currentUser) { - roles = currentUser?.client_roles?.length > 0 ? currentUser.client_roles : ['user']; + roles = currentUser?.client_roles?.length! > 0 ? currentUser.client_roles! : ['user']; } const isCurrent = (path: string) => currentPath === path || currentPath.startsWith(`${path}/`); @@ -136,7 +139,7 @@ const RightMenuItems = () => ( <>
  • Need help?
  • - + @@ -146,20 +149,22 @@ const RightMenuItems = () => ( - + ); // identity_provider, idir_userid, client_roles, family_name, given_name -function Layout({ children, currentUser, onLoginClick, onLogoutClick }: any) { +function Layout({ children, onLoginClick, onLogoutClick }: any) { const router = useRouter(); + const { data } = useSession(); + const currentUser: Partial = data?.user!; const pathname = router.pathname; const rightSide = currentUser ? ( -
    Welcome {`${currentUser.given_name} ${currentUser.family_name}`}
    +
    Welcome {`${currentUser?.given_name} ${currentUser?.family_name}`}
       @@ -79,9 +78,7 @@ const Home = ({ currentUser }: Props) => { )} - - Hero image - + {IntroRealms} diff --git a/app/pages/my-dashboard.tsx b/app/pages/my-dashboard.tsx index f5fe733..26958d6 100644 --- a/app/pages/my-dashboard.tsx +++ b/app/pages/my-dashboard.tsx @@ -1,22 +1,20 @@ import React, { useState, useEffect } from 'react'; -import { useRouter } from 'next/router'; import Head from 'next/head'; import { Grid as SpinnerGrid } from 'react-loader-spinner'; import styled from 'styled-components'; -import Button from '@button-inc/bcgov-theme/Button'; -import Modal from '@button-inc/bcgov-theme/Modal'; import Grid from '@button-inc/bcgov-theme/Grid'; import Alert from '@button-inc/bcgov-theme/Alert'; import StyledLink from '@button-inc/bcgov-theme/Link'; import { RealmProfile } from 'types/realm-profile'; -import { UserSession } from 'types/user-session'; import RealmLeftPanel from 'page-partials/my-dashboard/RealmLeftPanel'; import RealmRightPanel from 'page-partials/my-dashboard/RealmRightPanel'; import PopupModal from 'page-partials/my-dashboard/PopupModal'; import TopAlertWrapper from 'components/TopAlertWrapper'; import ResponsiveContainer, { MediaRule } from 'components/ResponsiveContainer'; import { getRealmProfiles } from 'services/realm'; -import { getSurvey, answerSurvey } from 'services/survey'; +import { getSurvey } from 'services/survey'; +import { useSession } from 'next-auth/react'; +import { User } from 'next-auth'; const AlignCenter = styled.div` text-align: center; @@ -40,12 +38,9 @@ const mediaRules: MediaRule[] = [ }, ]; -interface Props { - currentUser: UserSession; -} - -function MyDashboard({ currentUser }: Props) { - const router = useRouter(); +function MyDashboard() { + const { data } = useSession(); + const currentUser: Partial = data?.user!; const [loading, setLoading] = useState(false); const [answered, setAnswered] = useState(true); const [selectedId, setSelectedId] = useState(null); diff --git a/app/pages/realm/[rid].tsx b/app/pages/realm/[rid].tsx index 9250afb..c765a4c 100644 --- a/app/pages/realm/[rid].tsx +++ b/app/pages/realm/[rid].tsx @@ -60,10 +60,9 @@ const mediaRules: MediaRule[] = [ interface Props { alert: BottomAlert; - currentUser: UserSession; } -function EditRealm({ alert, currentUser }: Props) { +function EditRealm({ alert }: Props) { const router = useRouter(); const { rid } = router.query; diff --git a/app/services/axios.ts b/app/services/axios.ts index cfcc07d..b3785b4 100644 --- a/app/services/axios.ts +++ b/app/services/axios.ts @@ -9,8 +9,7 @@ const instance = axios.create({ instance?.interceptors.request.use( async function (config) { - const appToken = store2.session.get('app-token'); - return { ...config, headers: { ...config.headers, Authorization: `Bearer ${appToken}` } }; + return { ...config, headers: { ...config.headers } }; }, function (error) { return Promise.reject(error); diff --git a/app/svg/IntroRealms.svg b/app/svg/IntroRealms.svg new file mode 100644 index 0000000..6484e43 --- /dev/null +++ b/app/svg/IntroRealms.svg @@ -0,0 +1,95 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/app/svg/IntroRealms.tsx b/app/svg/IntroRealms.tsx new file mode 100644 index 0000000..ee5fa81 --- /dev/null +++ b/app/svg/IntroRealms.tsx @@ -0,0 +1,324 @@ +import React from 'react'; + +export default ( + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +); diff --git a/app/types/next-auth.d.ts b/app/types/next-auth.d.ts new file mode 100644 index 0000000..5d3c26b --- /dev/null +++ b/app/types/next-auth.d.ts @@ -0,0 +1,24 @@ +import NextAuth, { DefaultSession } from 'next-auth'; + +declare module 'next-auth' { + /** + * Returned by `useSession`, `getSession` and received as a prop on the `SessionProvider` React Context + */ + interface Session { + accessToken: string; + user: User & DefaultSession['user']; + } + + interface User { + id: string; + name?: string | null; + email?: string | null; + image?: string | null; + client_roles: string[]; + given_name: string | null; + family_name: string | null; + preferred_username: string | null; + email: string | null; + idir_username: string | null; + } +} diff --git a/app/yarn.lock b/app/yarn.lock index c3ab39a..30221e4 100644 --- a/app/yarn.lock +++ b/app/yarn.lock @@ -113,7 +113,7 @@ dependencies: regenerator-runtime "^0.13.4" -"@babel/runtime@^7.12.0", "@babel/runtime@^7.18.3": +"@babel/runtime@^7.12.0", "@babel/runtime@^7.18.3", "@babel/runtime@^7.20.13": version "7.22.15" resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.22.15.tgz#38f46494ccf6cf020bd4eed7124b425e83e523b8" integrity sha512-T0O+aa+4w0u06iNmapipJXMV4HoUir03hpx3/YqXXhu9xim3w+dVphjFWl1OH8NbZHw5Lbm9k45drDkgq2VNNA== @@ -601,6 +601,11 @@ "@nodelib/fs.scandir" "2.1.5" fastq "^1.6.0" +"@panva/hkdf@^1.0.2": + version "1.1.1" + resolved "https://registry.yarnpkg.com/@panva/hkdf/-/hkdf-1.1.1.tgz#ab9cd8755d1976e72fc77a00f7655a64efe6cd5d" + integrity sha512-dhPeilub1NuIG0X5Kvhh9lH4iW3ZsHlnzwgwbOlgwQ2wG1IqFzsgHqmKPk3WzsdWAeaxKJxgM0+W433RmN45GA== + "@popperjs/core@^2.10.1": version "2.11.0" resolved "https://registry.yarnpkg.com/@popperjs/core/-/core-2.11.0.tgz#6734f8ebc106a0860dff7f92bf90df193f0935d7" @@ -1564,6 +1569,11 @@ convert-source-map@^1.5.0: dependencies: safe-buffer "~5.1.1" +cookie@^0.5.0: + version "0.5.0" + resolved "https://registry.yarnpkg.com/cookie/-/cookie-0.5.0.tgz#d1f5d71adec6558c58f389987c366aa47e994f8b" + integrity sha512-YZ3GUyn/o8gfKJlnlX7g7xq4gyO6OSuhGPKaaGssGB2qgDUS0gPgtTvoyZLTt9Ab6dC4hfc9dV5arkvc/OCmrw== + core-js-pure@^3.16.0: version "3.18.3" resolved "https://registry.yarnpkg.com/core-js-pure/-/core-js-pure-3.18.3.tgz#7eed77dcce1445ab68fd68715856633e2fb3b90c" @@ -2737,6 +2747,11 @@ isobject@^4.0.0: resolved "https://registry.yarnpkg.com/isobject/-/isobject-4.0.0.tgz#3f1c9155e73b192022a80819bacd0343711697b0" integrity sha512-S/2fF5wH8SJA/kmwr6HYhK/RI/OkhD84k8ntalo0iJjZikgq1XFvR5M8NPT1x5F7fBwCG3qHfnzeP/Vh/ZxCUA== +jose@^4.11.4, jose@^4.14.4: + version "4.14.6" + resolved "https://registry.yarnpkg.com/jose/-/jose-4.14.6.tgz#94dca1d04a0ad8c6bff0998cdb51220d473cc3af" + integrity sha512-EqJPEUlZD0/CSUMubKtMaYUOtWe91tZXTWMJZoKSbLk+KtdhNdcvppH8lA9XwVu2V4Ailvsj0GBZJ2ZwDjfesQ== + js-sha256@0.9.0: version "0.9.0" resolved "https://registry.yarnpkg.com/js-sha256/-/js-sha256-0.9.0.tgz#0b89ac166583e91ef9123644bd3c5334ce9d0966" @@ -3110,6 +3125,21 @@ natural-compare@^1.4.0: resolved "https://registry.yarnpkg.com/natural-compare/-/natural-compare-1.4.0.tgz#4abebfeed7541f2c27acfb29bdbbd15c8d5ba4f7" integrity sha1-Sr6/7tdUHywnrPspvbvRXI1bpPc= +next-auth@^4.23.1: + version "4.23.1" + resolved "https://registry.yarnpkg.com/next-auth/-/next-auth-4.23.1.tgz#7a82f5327cf4c7e32819da4eb977f2251a23c3cf" + integrity sha512-mL083z8KgRtlrIV6CDca2H1kduWJuK/3pTS0Fe2og15KOm4v2kkLGdSDfc2g+019aEBrJUT0pPW2Xx42ImN1WA== + dependencies: + "@babel/runtime" "^7.20.13" + "@panva/hkdf" "^1.0.2" + cookie "^0.5.0" + jose "^4.11.4" + oauth "^0.9.15" + openid-client "^5.4.0" + preact "^10.6.3" + preact-render-to-string "^5.1.19" + uuid "^8.3.2" + next@12.1.6: version "12.1.6" resolved "https://registry.yarnpkg.com/next/-/next-12.1.6.tgz#eb205e64af1998651f96f9df44556d47d8bbc533" @@ -3140,11 +3170,21 @@ node-cron@^3.0.2: dependencies: uuid "8.3.2" +oauth@^0.9.15: + version "0.9.15" + resolved "https://registry.yarnpkg.com/oauth/-/oauth-0.9.15.tgz#bd1fefaf686c96b75475aed5196412ff60cfb9c1" + integrity sha512-a5ERWK1kh38ExDEfoO6qUHJb32rd7aYmPHuyCu3Fta/cnICvYmgd2uhuKXvPD+PXB+gCEYYEaQdIRAjCOwAKNA== + object-assign@^4.1.0, object-assign@^4.1.1: version "4.1.1" resolved "https://registry.yarnpkg.com/object-assign/-/object-assign-4.1.1.tgz#2109adc7965887cfc05cbbd442cac8bfbb360863" integrity sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM= +object-hash@^2.2.0: + version "2.2.0" + resolved "https://registry.yarnpkg.com/object-hash/-/object-hash-2.2.0.tgz#5ad518581eefc443bd763472b8ff2e9c2c0d54a5" + integrity sha512-gScRMn0bS5fH+IuwyIFgnh9zBdo4DV+6GhygmWM9HyNJSgS0hScp1f5vjtm7oIIOiT9trXrShAkLFSc2IqKNgw== + object-inspect@^1.11.0, object-inspect@^1.9.0: version "1.11.0" resolved "https://registry.yarnpkg.com/object-inspect/-/object-inspect-1.11.0.tgz#9dceb146cedd4148a0d9e51ab88d34cf509922b1" @@ -3205,6 +3245,11 @@ object.values@^1.1.5: define-properties "^1.1.3" es-abstract "^1.19.1" +oidc-token-hash@^5.0.3: + version "5.0.3" + resolved "https://registry.yarnpkg.com/oidc-token-hash/-/oidc-token-hash-5.0.3.tgz#9a229f0a1ce9d4fc89bcaee5478c97a889e7b7b6" + integrity sha512-IF4PcGgzAr6XXSff26Sk/+P4KZFJVuHAJZj3wgO3vX2bMdNVp/QXTP3P7CEm9V1IdG8lDLY3HhiqpsE/nOwpPw== + once@^1.3.0: version "1.4.0" resolved "https://registry.yarnpkg.com/once/-/once-1.4.0.tgz#583b1aa775961d4b113ac17d9c50baef9dd76bd1" @@ -3212,6 +3257,16 @@ once@^1.3.0: dependencies: wrappy "1" +openid-client@^5.4.0: + version "5.5.0" + resolved "https://registry.yarnpkg.com/openid-client/-/openid-client-5.5.0.tgz#0c631b33c6a2c3e01197506978d6bff70e75c858" + integrity sha512-Y7Xl8BgsrkzWLHkVDYuroM67hi96xITyEDSkmWaGUiNX6CkcXC3XyQGdv5aWZ6dukVKBFVQCADi9gCavOmU14w== + dependencies: + jose "^4.14.4" + lru-cache "^6.0.0" + object-hash "^2.2.0" + oidc-token-hash "^5.0.3" + optionator@^0.9.1: version "0.9.1" resolved "https://registry.yarnpkg.com/optionator/-/optionator-0.9.1.tgz#4f236a6373dae0566a6d43e1326674f50c291499" @@ -3445,11 +3500,28 @@ postgres-interval@^1.1.0: dependencies: xtend "^4.0.0" +preact-render-to-string@^5.1.19: + version "5.2.6" + resolved "https://registry.yarnpkg.com/preact-render-to-string/-/preact-render-to-string-5.2.6.tgz#0ff0c86cd118d30affb825193f18e92bd59d0604" + integrity sha512-JyhErpYOvBV1hEPwIxc/fHWXPfnEGdRKxc8gFdAZ7XV4tlzyzG847XAyEZqoDnynP88akM4eaHcSOzNcLWFguw== + dependencies: + pretty-format "^3.8.0" + +preact@^10.6.3: + version "10.17.1" + resolved "https://registry.yarnpkg.com/preact/-/preact-10.17.1.tgz#0a1b3c658c019e759326b9648c62912cf5c2dde1" + integrity sha512-X9BODrvQ4Ekwv9GURm9AKAGaomqXmip7NQTZgY7gcNmr7XE83adOMJvd3N42id1tMFU7ojiynRsYnY6/BRFxLA== + prelude-ls@^1.2.1: version "1.2.1" resolved "https://registry.yarnpkg.com/prelude-ls/-/prelude-ls-1.2.1.tgz#debc6489d7a6e6b0e7611888cec880337d316396" integrity sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g== +pretty-format@^3.8.0: + version "3.8.0" + resolved "https://registry.yarnpkg.com/pretty-format/-/pretty-format-3.8.0.tgz#bfbed56d5e9a776645f4b1ff7aa1a3ac4fa3c385" + integrity sha512-WuxUnVtlWL1OfZFQFuqvnvs6MiAGk9UNsBostyBOB0Is9wb5uRESevA6rnl/rkksXaGX3GzZhPup5d6Vp1nFew== + prismjs@1.27.0, prismjs@^1.21.0, prismjs@^1.22.0, prismjs@~1.25.0: version "1.27.0" resolved "https://registry.yarnpkg.com/prismjs/-/prismjs-1.27.0.tgz#bb6ee3138a0b438a3653dd4d6ce0cc6510a45057" @@ -4299,7 +4371,7 @@ util-deprecate@^1.0.1, util-deprecate@^1.0.2: resolved "https://registry.yarnpkg.com/util-deprecate/-/util-deprecate-1.0.2.tgz#450d4dc9fa70de732762fbd2d4a28981419a0ccf" integrity sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8= -uuid@8.3.2: +uuid@8.3.2, uuid@^8.3.2: version "8.3.2" resolved "https://registry.yarnpkg.com/uuid/-/uuid-8.3.2.tgz#80d5b5ced271bb9af6c445f21a1a04c606cefbe2" integrity sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg== diff --git a/helm/webapp/Chart.yaml b/helm/webapp/Chart.yaml index 4f09c8f..17fcb1e 100644 --- a/helm/webapp/Chart.yaml +++ b/helm/webapp/Chart.yaml @@ -1,6 +1,6 @@ apiVersion: v1 name: realm-registry -version: 0.2.0 +version: 0.2.1 appVersion: 0.1.0 description: Nextjs application to manage SSO keycloak custom realm profiles dependencies: diff --git a/helm/webapp/values-c6af30-dev.yaml b/helm/webapp/values-c6af30-dev.yaml index 9bb69da..6ba5d2d 100644 --- a/helm/webapp/values-c6af30-dev.yaml +++ b/helm/webapp/values-c6af30-dev.yaml @@ -16,6 +16,7 @@ env: IDIR_ISSUER: https://dev.loginproxy.gov.bc.ca/auth/realms/standard IDIR_AUDIENCE: css-app-in-gold-4128 CHES_API_ENDPOINT: https://ches.api.gov.bc.ca/api/v1/email + NEXTAUTH_URL: http://realm-registry-sandbox.apps.gold.devops.gov.bc.ca vault: vaultSecretEngine: c6af30-nonprod diff --git a/helm/webapp/values-c6af30-prod.yaml b/helm/webapp/values-c6af30-prod.yaml index abeb7b9..8295cff 100644 --- a/helm/webapp/values-c6af30-prod.yaml +++ b/helm/webapp/values-c6af30-prod.yaml @@ -16,6 +16,7 @@ env: IDIR_ISSUER: https://loginproxy.gov.bc.ca/auth/realms/standard IDIR_AUDIENCE: css-app-in-gold-4128 CHES_API_ENDPOINT: https://ches.api.gov.bc.ca/api/v1/email + NEXTAUTH_URL: http://realm-registry.apps.gold.devops.gov.bc.ca vault: vaultSecretEngine: c6af30-prod