Skip to content

Commit ef202fd

Browse files
ocshawncmlsnsnyk-botShawn O'Connorcraigrbarnes
authored
Chore/sync upstreem gen3 to 0.12.10 (#75)
* fix: package.json & package-lock.json to reduce vulnerabilities (#82) The following vulnerabilities are fixed with an upgrade: - https://snyk.io/vuln/SNYK-JS-NEXT-9508709 Co-authored-by: snyk-bot <snyk-bot@snyk.io> * update next dependencies to 15.2.4 * Update README.md (#84) * update to @gen3/ff 0.10.85 (#85) * Update README.md (#86) add unrelated-histories information * Fix docker start (#88) * fix Docker not starting * fix Docker not starting * update env files (#89) * Release 0.10.89 (#91) * update to 0.10.89 * update to 0.10.89 * remove old config files/images * update ContentDatabase * update ContentDatabase paths (#93) * update apps config path (uc-cdis#94) * add theme colors into safelist (uc-cdis#95) * update to 0.10.91 (uc-cdis#96) * fix version to 0.10.91 (uc-cdis#97) * update to 0.10.92 (uc-cdis#104) * update to node 22.11, gen3FF 0.10.94 (uc-cdis#107) * update git node version * update gen3 to 0.11.11 * add favicon (uc-cdis#109) * add favicon * add favicon --------- Co-authored-by: Shawn O'Connor <shawnoconnor@uchicago.edu> * Add Datadog/remove faro (uc-cdis#105) * add Datadog/remove faro * remove Grafana * update gen3 to 0.11.18 * update gen3 to 0.11.19 and add footer links * update to Gen3 FEF 0.11.43 (uc-cdis#127) * add GradioApp support (uc-cdis#128) * add GradioApp support * fix default * update dependencies * update more dependencies * update more dependencies * add the hugging face apps (uc-cdis#129) * update tailwind paths for Gen3/frontend (uc-cdis#136) * fix default * update package-lock * fix build error * remove gradio * remove older tailwind path * update gen3 version and package lock * update gen3 to 0.11.47 * update gen3 to 0.11.48 remove unneeded cookies-next * Feat/footer (uc-cdis#139) * add the hugging face apps * Update README for clarity on Gen3 Data Commons * update development configuration * darken footer * partially revert footer changed (uc-cdis#140) * update docker image for faster builds (uc-cdis#141) * Changes to landingPage (uc-cdis#142) * Revert landingPage change (uc-cdis#143) * Update from old Gen3 Docs to new Gen3 Docs link (uc-cdis#146) * Update Gen3 docs link Update the default Documentation link from the old Gen3 docs site (https://gen3.org/resources/user/) to the new Gen3 docs site (https://docs.gen3.org/) * Update to new docs link Change the workspace docs reference from the old docs (https://gen3.org/resources/user/analyze-data/) to the new docs (https://docs.gen3.org/gen3-resources/user-guide/analyze-data/) * Update to v0.11.58 (uc-cdis#147) * add height to tailwind config * add package * add height to tailwind config * update to 0.11.55 * update deps * update to v0.11.58 * update to 0.11.59 (uc-cdis#148) * update node version in ci * update to nextjs 15.5.7 (uc-cdis#153) * Add Authz Middleware (uc-cdis#156) * update to new auth model * update to 0.12.0 * Setup for data dog * Add missing icons and update tailwind config (uc-cdis#158) * add missing icons * update app with dataDog * update tailwind config * update tailwind config * refactor data dog * update to NextJS 15.5.9 (uc-cdis#162) * Add linkWithIconAndTooltip custom cell renderer (uc-cdis#166) * fix a bug when app page is not found react expecting null * Update middleware to use code generation (uc-cdis#167) * update to NextJS 15.5.9 * fix fetchArboristResources to use the correct endpoint * get working scanPaths and update middleware * set NODE_ENV for dev and prod builds * update to 0.12.5 * update to 0.12.5 * new package-lock.json * add package lock * new package-lock.json part 2 * update dependencies * update dependencies (uc-cdis#169) * update dependencies (uc-cdis#171) * update gen3 to 12.10 * fix storybook --------- Co-authored-by: cmlsn <100160785+cmlsn@users.noreply.github.com> Co-authored-by: snyk-bot <snyk-bot@snyk.io> Co-authored-by: Shawn O'Connor <shawnoconnor@uchicago.edu> Co-authored-by: Craig Barnes <craig.barnes@intelligentlight.com> Co-authored-by: Krishna Agarwal <159047652+krishnaa05@users.noreply.github.com> Co-authored-by: smvgarcia <111767892+smvgarcia@users.noreply.github.com> Co-authored-by: Pauline Ribeyre <4224001+paulineribeyre@users.noreply.github.com>
1 parent 917e8cf commit ef202fd

File tree

14 files changed

+1691
-5630
lines changed

14 files changed

+1691
-5630
lines changed

.storybook/main.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,5 +33,9 @@ const config: StorybookConfig = {
3333

3434
return config;
3535
},
36+
env: (config) => ({
37+
...config,
38+
NEXT_PUBLIC_GEN3_COMMONS_NAME: 'vpodcprod',
39+
}),
3640
};
3741
export default config;

config/vpodcprod/navigation.json

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,11 @@
11
{
22
"navigation": {
3+
"hideUnauthorizedLinks": false,
34
"classNames": {
4-
"root": "pl-1 mr-6 bg-base-max text-primary opacity-100 hover:opacity-100",
5+
"root": "pl-1 mr-6 bg-base-max text-primary opacity-100 hover:opacity-100 data-disabled:opacity-35 data-disabled:hover:text-primary data-disabled:hover:opacity-35",
56
"item": "py-2 px-4 hover:bg-base-lightest hover:text-base-contrast",
6-
"navigationPanel": "bg-base-max text-primary"
7+
"navigationPanel": "bg-base-max text-primary",
8+
"icon": "data-disabled:opacity-50"
79
},
810
"logo": {
911
"src": "/images/vpodc-logo.png",

package-lock.json

Lines changed: 1497 additions & 5477 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 17 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "@gen3/vpodc-data-commons",
3-
"version": "0.12.2",
3+
"version": "0.12.10",
44
"private": "true",
55
"engines": {
66
"npm": ">=10.9.2",
@@ -9,12 +9,15 @@
99
"scripts": {
1010
"lint": "next lint",
1111
"lint-fix": "next lint --fix",
12+
"predev": " NODE_ENV=development npm run build:middlewarePaths",
1213
"dev": "next dev",
14+
"prebuild": "NODE_ENV=production npm run build:middlewarePaths",
1315
"build": "next build",
1416
"start": "next start",
15-
"setupCommons": "npm run buildColors && npm run getSchema && npm run getDRSToHostname",
17+
"setupCommons": "npm run buildColors && npm run getSchema && npm run getDRSToHostname && npm run buildIcons && npm run build:middlewarePaths",
1618
"build:colors": "node ./node_modules/@gen3/toolsff/dist/buildColors.esm.js --themeFile=config/$npm_config_commons/colors.json --out=config/$npm_config_commons",
1719
"build:icons": "node ./node_modules/@gen3/toolsff/dist/bundleIcons.esm.js --inpath=config/icons --outpath=config/icons",
20+
"build:middlewarePaths": "node ./node_modules/@gen3/toolsff/dist/scanSitePaths.esm.js",
1821
"getSchema": "node ./node_modules/@gen3/toolsff/dist/getSchema.esm.js --out=config/",
1922
"getDRSToHostname": "node ./node_modules/@gen3/toolsff/dist/getDRSToHostname.esm.js --out=config/",
2023
"storybook": "storybook dev -p 6006",
@@ -26,8 +29,8 @@
2629
"@fontsource/montserrat": "^5.2.8",
2730
"@fontsource/poppins": "^5.2.7",
2831
"@fontsource/source-sans-pro": "^5.2.5",
29-
"@gen3/core": "0.12.2",
30-
"@gen3/frontend": "0.12.2",
32+
"@gen3/core": "0.12.10",
33+
"@gen3/frontend": "0.12.10",
3134
"@grafana/faro-react": "^1.9.1",
3235
"@grafana/faro-web-sdk": "^1.9.1",
3336
"@grafana/faro-web-tracing": "^1.9.1",
@@ -47,12 +50,20 @@
4750
"jsonpath-plus": "^10.3.0",
4851
"mantine-react-table": "^2.0.0-beta.9",
4952
"react": "^18.3.1",
50-
"react-dom": "18.3.1"
53+
"react-dom": "18.3.1",
54+
"react-icons": "^5.5.0",
55+
"use-deep-compare": "^1.3.0",
56+
"lodash": "^4.14.202",
57+
"tailwind-styled-components": "^2.2.0",
58+
"remark-gfm": "^4.0.1",
59+
"react-markdown": "^10.1.0",
60+
"validator": "13.15.23",
61+
"victory": "^37.3.6"
5162
},
5263
"devDependencies": {
5364
"@axe-core/react": "^4.10.2",
5465
"@chromatic-com/storybook": "^4.1.1",
55-
"@gen3/toolsff": "0.12.2",
66+
"@gen3/toolsff": "0.12.10",
5667
"@jest/globals": "^29.7.0",
5768
"@next/eslint-plugin-next": "^15.5.9",
5869
"@storybook/addon-a11y": "^9.1.10",

public/images/createdby.png

19.5 KB
Loading

public/mockServiceWorker.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
* - Please do NOT modify this file.
88
*/
99

10-
const PACKAGE_VERSION = '2.12.4'
10+
const PACKAGE_VERSION = '2.12.7'
1111
const INTEGRITY_CHECKSUM = '4db4a41e972cec1b64cc569c66952d82'
1212
const IS_MOCKED_RESPONSE = Symbol('isMockedResponse')
1313
const activeClientIds = new Set()

src/lib/CohortBuilder/CustomCellRenderers.tsx

Lines changed: 58 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ import {
33
ExplorerTableCellRendererFactory,
44
type CellRendererFunctionProps,
55
} from '@gen3/frontend';
6-
import { ActionIcon, Text } from '@mantine/core';
6+
import { ActionIcon, Text, Tooltip } from '@mantine/core';
77
import { FaExternalLinkAlt } from 'react-icons/fa';
88

99
const RenderDicomLink = ({ cell }: CellRendererFunctionProps) => {
@@ -51,6 +51,58 @@ const RenderLinkCell = ({ cell }: CellRendererFunctionProps) => {
5151
);
5252
};
5353

54+
interface LinkCellOptions {
55+
icon: string;
56+
color: string;
57+
variant: string;
58+
size: string;
59+
tooltip: boolean;
60+
}
61+
62+
const RenderLinkIconDefaultParameters : LinkCellOptions = {
63+
icon: 'gen3:external-link', // TODO
64+
color: 'accent.5',
65+
variant: 'filled',
66+
size: 'md',
67+
tooltip: false,
68+
}
69+
70+
/**
71+
* RenderLinkWithIcon is a functional component that renders a hyperlink with an associated icon inside a tooltip.
72+
*
73+
* This component primarily checks if a value exists in the `cell` object provided as a property. If there is no
74+
* value or the value is an empty string, it returns an empty span. Otherwise, a link is rendered with customizable
75+
* icon appearance and tooltip functionality.
76+
*
77+
* Parameters for styling and behavior can be passed through `params`, which override the default configurations.
78+
*
79+
* @param {Object} props - The component props.
80+
* @param {CellRendererFunctionProps} props.cell - Contains the value for the hyperlink.
81+
* @param {...Array<Record<string, unknown>>} params - Additional configuration parameters for the rendered link and its icon. Defaults are defined in `RenderLinkIconDefaultParameters`.
82+
* @returns {React.ReactNode} A React element representing a tooltip-wrapped link with an icon, or an empty span if no value is present in `cell`.
83+
*/
84+
const RenderLinkWithIcon = ({ cell }: CellRendererFunctionProps,
85+
...params: Array<Record<string, unknown>>) => {
86+
if (!cell?.getValue() || cell?.getValue() === '') {
87+
return <span></span>;
88+
} else {
89+
const mergedParams = { ...RenderLinkIconDefaultParameters, ...(params ? params[0] : {}) };
90+
const { variant, color, size, tooltip } = mergedParams;
91+
return (
92+
<Tooltip label={cell.getValue() as string} disabled={tooltip ? !tooltip : true} >
93+
<a href={`${cell.getValue()}`} target="_blank" rel="noreferrer">
94+
95+
<ActionIcon size={size} variant={variant} color={color}>
96+
<FaExternalLinkAlt />
97+
</ActionIcon>
98+
99+
</a>
100+
</Tooltip>
101+
);
102+
}
103+
};
104+
105+
54106
export const registerCohortTableCustomCellRenderers = () => {
55107
ExplorerTableCellRendererFactory().registerRenderer(
56108
'link',
@@ -67,4 +119,9 @@ export const registerCohortTableCustomCellRenderers = () => {
67119
'linkURL',
68120
RenderLinkCell,
69121
);
122+
ExplorerTableCellRendererFactory().registerRenderer(
123+
'link',
124+
'linkWithIconAndTooltip',
125+
RenderLinkWithIcon,
126+
);
70127
};

src/lib/auth/fetchAuthz.ts

Lines changed: 6 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -12,21 +12,19 @@ const DEFAULT_TTL_SECONDS = 360;
1212
* to a simple string[] of resource paths.
1313
*/
1414
export async function fetchArboristResources(
15-
cookies?: string,
15+
accessToken: string | null,
1616
useService: boolean = false,
1717
revalidate: number = DEFAULT_TTL_SECONDS,
1818
): Promise<string[]> {
19-
const headers: Record<string, string> = {};
20-
21-
if (cookies) {
22-
headers.Cookie = cookies;
23-
}
19+
const headers: Record<string, string> = {
20+
...(accessToken ? { Authorization: `Bearer ${accessToken}` } : {}),
21+
credentials: 'include',
22+
};
2423

2524
const url = useService
26-
? `${GEN3_AUTHZ_SERVICE}/resource`
25+
? `${GEN3_AUTHZ_SERVICE}/auth/resources`
2726
: `${GEN3_AUTHZ_API}/resources`;
2827
const res = await fetch(url, { headers, next: { revalidate: revalidate } });
29-
3028
if (!res.ok) {
3129
console.error(
3230
'commons:fetchArboristResources Arborist /resource failed:',
@@ -35,7 +33,6 @@ export async function fetchArboristResources(
3533
);
3634
return [];
3735
}
38-
3936
const data = (await res.json()) as AuthzResourceResponse;
4037
return data.resources ?? [];
4138
}

src/middleware-impl.ts

Lines changed: 81 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,81 @@
1+
import { NextRequest, NextResponse } from 'next/server';
2+
import { getRouteConfig } from './lib/auth/arboristConfig';
3+
import {
4+
getAccessToken,
5+
getLoginStatus,
6+
type LoginStatus,
7+
} from './lib/auth/getLoginStatus';
8+
import { fetchArboristResources } from './lib/auth/fetchAuthz';
9+
import { RouteConfig } from '@gen3/frontend/server';
10+
11+
const WILDCARD_ROUTE_KEY = '*';
12+
13+
function getRouteRuleForPath(pathname: string, routeConfig: RouteConfig) {
14+
return routeConfig?.[pathname] ?? routeConfig?.[WILDCARD_ROUTE_KEY];
15+
}
16+
17+
function isLoggedIn(loginStatus: LoginStatus) {
18+
return loginStatus.status === 'issued';
19+
}
20+
21+
export async function middleware(req: NextRequest) {
22+
const pathname = req.nextUrl.pathname;
23+
const { routes: routeConfig } = await getRouteConfig();
24+
let rule = getRouteRuleForPath(pathname, routeConfig);
25+
26+
// check if there is a wildcard route
27+
if (!rule) {
28+
rule = getRouteRuleForPath('*', routeConfig);
29+
}
30+
31+
// Public route: not listed in Arborist config
32+
if (!rule) {
33+
return NextResponse.next();
34+
}
35+
36+
const loginRequired = rule.loginRequired ?? true;
37+
const needsAuthz = Array.isArray(rule?.authz) && rule?.authz.length > 0;
38+
39+
// Gen3 login check
40+
const loginStatus = await getLoginStatus(req.headers.get('Cookie') || '');
41+
const loggedIn = await isLoggedIn(loginStatus);
42+
43+
// Enforce login if required
44+
if (loginRequired && !loggedIn) {
45+
const loginUrl = new URL('/Login', req.url);
46+
loginUrl.searchParams.set('referer', pathname);
47+
return NextResponse.redirect(loginUrl);
48+
}
49+
50+
// If no authz resources configured, login is enough
51+
if (!needsAuthz) {
52+
return NextResponse.next();
53+
}
54+
55+
// if authz is required but we somehow aren't logged in,
56+
// send to login (even though in practice loginRequired will almost
57+
// always be true when authz is configured).
58+
if (!loggedIn) {
59+
const loginUrl = new URL('/Login', req.url);
60+
loginUrl.searchParams.set('referer', pathname);
61+
return NextResponse.redirect(loginUrl);
62+
}
63+
64+
// Authz is enabled AND route has authzResources → check Arborist resources
65+
const tokenFromCookie =
66+
getAccessToken(req.headers.get('Cookie') || '') ?? null;
67+
68+
// Let the server-side helper resolve resources using the active Gen3 session.
69+
const resources = await fetchArboristResources(
70+
tokenFromCookie,
71+
process.env.NODE_ENV === 'production',
72+
);
73+
74+
const allowed = rule?.authz!.some((needed) => resources.includes(needed));
75+
if (!allowed) {
76+
// Already logged in if required; they just lack authz for this resource
77+
return NextResponse.redirect(new URL('/403', req.url));
78+
}
79+
80+
return NextResponse.next();
81+
}

0 commit comments

Comments
 (0)