Skip to content

Commit

Permalink
chore: remove vulnerable dependencies from Slack app (#9057)
Browse files Browse the repository at this point in the history
* chore: remove vulnerable dependencies from Slack app

* adding env example back

* change prefix to use REACT_APP and update typing of import.meta

---------

Co-authored-by: Sarah Lessner <sarah.lessner@contentful.com>
  • Loading branch information
david-shibley-contentful and sarahlessner authored Dec 20, 2024
1 parent e05757a commit 4effad3
Show file tree
Hide file tree
Showing 8 changed files with 11,870 additions and 35,995 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
<body>
<noscript>You need to enable JavaScript to run this app.</noscript>
<div id="root"></div>
<script type="module" src="./src/index.tsx"></script>
<!--
This HTML file is a template.
If you open it directly in the browser, you will see an empty page.
Expand Down
47,772 changes: 11,810 additions & 35,962 deletions apps/slack/frontend/package-lock.json

Large diffs are not rendered by default.

15 changes: 8 additions & 7 deletions apps/slack/frontend/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -8,18 +8,20 @@
"@contentful/f36-tokens": "^4.0.0",
"@contentful/f36-workbench": "^4.21.0",
"@contentful/react-apps-toolkit": "^1.2.13",
"@emotion/css": "^11.13.4",
"contentful-management": "^10.26.0",
"emotion": "^10.0.27",
"react": "^17.0.2",
"react-dom": "^17.0.2",
"uuid": "^9.0.0",
"vite": "^5.4.8",
"vitest": "^2.1.2",
"zustand": "^4.2.0"
},
"scripts": {
"start": "PORT=1234 cross-env BROWSER=none react-scripts start",
"build": "react-scripts build",
"test": "SKIP_PREFLIGHT_CHECK=true react-scripts test",
"eject": "react-scripts eject",
"start": "vite",
"build": "vite build",
"test": "vitest",
"eject": "vite eject",
"lint": "eslint --ext .ts,.tsx,.js,.jsx,.svg ./",
"upload": "contentful-app-scripts upload --bundle-dir ./build",
"deploy": "aws s3 sync ./build ${STATIC_S3_BASE}/slack --acl public-read",
Expand All @@ -43,7 +45,6 @@
"@testing-library/jest-dom": "^5.16.5",
"@testing-library/react": "^12.1.4",
"@types/jest": "^29.2.5",
"@types/node": "^14.18.36",
"@types/react": "^17.0.43",
"@types/react-dom": "^18.0.3",
"@types/uuid": "^9.0.1",
Expand All @@ -52,7 +53,7 @@
"eslint-config-prettier": "^9.0.0",
"eslint-plugin-react": "^7.33.1",
"eslint-plugin-react-hooks": "^4.6.0",
"react-scripts": "^5.0.1",
"jsdom": "^25.0.1",
"typescript": "4.9.5"
},
"homepage": "."
Expand Down
48 changes: 25 additions & 23 deletions apps/slack/frontend/src/components/ConfigScreen.spec.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,23 +4,27 @@ import { act, render, screen, waitFor } from '@testing-library/react';
import { authStore } from '../auth.store';
import { makeMockSdk } from '../../test/mocks/mockSdk';
import { useSDK } from '@contentful/react-apps-toolkit';
import { Mock, vi } from 'vitest';
import { apiClient } from '../requests';

jest.mock('../requests', () => {
const realRequests = jest.requireActual('../requests');
vi.mock('../requests', () => {
const realRequests = vi.importActual('../requests');
return {
...realRequests,
apiClient: {
getChannels: jest.fn(),
getWorkspace: jest.fn(),
createAuthToken: jest.fn(),
getChannels: vi.fn(),
getWorkspace: vi.fn(),
createAuthToken: vi.fn(),
},
};
});

jest.mock('@contentful/react-apps-toolkit', () => {
vi.mock(import('@contentful/react-apps-toolkit'), async (importOriginal) => {
const actual = await importOriginal();
return {
useSDK: jest.fn(),
useCMA: jest.fn(),
...actual,
useSDK: vi.fn(),
useCMA: vi.fn(),
};
});

Expand All @@ -29,68 +33,66 @@ let useContextMock: any;

beforeEach(() => {
realUseContext = React.useContext;
useContextMock = React.useContext = jest.fn();
useContextMock = React.useContext = vi.fn();
});

afterEach(() => {
React.useContext = realUseContext;
vi.resetAllMocks();
});

describe('Config Screen component', () => {
let callbacks: any;
beforeEach(() => {
const result = makeMockSdk();
useContextMock.mockReturnValue({ api: { install: jest.fn() } });
(useSDK as jest.Mock).mockReturnValue(result.sdk);
useContextMock.mockReturnValue({ api: { install: vi.fn() } });
(useSDK as Mock).mockReturnValue(result.sdk);
callbacks = result.callbacks;
});
it('Component text exists', async () => {
const { getByText } = render(<ConfigScreen />);

await act(callbacks.onConfigure);

expect(getByText('Connect to Slack')).toBeInTheDocument();
expect(getByText('Connect to Slack')).toBeDefined();
});
it('Shows the connected workspace if installation parameters are set', async () => {
const { sdk } = makeMockSdk();
const { apiClient } = jest.requireMock('../requests');
sdk.app.getParameters = () => ({ workspaces: ['whatever'], notifications: [] });
(useSDK as jest.Mock).mockReturnValue(sdk);
apiClient.getWorkspace.mockResolvedValueOnce({
(useSDK as Mock).mockReturnValue(sdk);
(apiClient.getWorkspace as Mock).mockResolvedValueOnce({
id: 'so-unique',
name: 'nice workspace',
icon: { image_68: 'whatever' },
});
apiClient.getWorkspace.mockResolvedValueOnce([]);
(apiClient.getWorkspace as Mock).mockResolvedValueOnce([]);

const { getByText } = render(<ConfigScreen />);
await waitFor(() => screen.findByText('Slack workspace'));

await waitFor(() => screen.findByText('nice workspace'));

expect(getByText('nice workspace')).toBeInTheDocument();
expect(getByText('nice workspace')).toBeDefined();
});
it('Shows an error message if fetching the workspace failed', async () => {
const { sdk } = makeMockSdk();
const { apiClient } = jest.requireMock('../requests');

apiClient.getWorkspace.mockRejectedValueOnce(new Error());
(apiClient.getWorkspace as Mock).mockRejectedValueOnce(new Error());
sdk.app.getParameters = () => ({ workspaces: ['whatever'], notifications: [] });
(useSDK as jest.Mock).mockReturnValue(sdk);
(useSDK as Mock).mockReturnValue(sdk);

const { getByText } = render(<ConfigScreen />);

await waitFor(() => screen.findByText('Failed to fetch workspace'));

expect(getByText('Failed to fetch workspace')).toBeInTheDocument();
expect(getByText('Failed to fetch workspace')).toBeDefined();
});
it('Saves the token after first installation', async () => {
const UUID = '1234';
const { sdk, callbacks } = makeMockSdk();
sdk.app.isInstalled = () => Promise.resolve(false);
(useSDK as jest.Mock).mockReturnValue(sdk);
(useSDK as Mock).mockReturnValue(sdk);

const { apiClient } = jest.requireMock('../requests');
authStore.getState().setTemporaryRefreshToken('not-empty');
authStore.getState().setInstallationUuid(UUID);
render(<ConfigScreen />);
Expand Down
4 changes: 2 additions & 2 deletions apps/slack/frontend/src/constants.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
export const CLIENT_ID = process.env.REACT_APP_SLACK_CLIENT_ID;
export const BACKEND_BASE_URL = process.env.REACT_APP_BACKEND_BASE_URL;
export const CLIENT_ID = import.meta.env.REACT_APP_SLACK_CLIENT_ID;
export const BACKEND_BASE_URL = import.meta.env.REACT_APP_BACKEND_BASE_URL;

export const makeOAuthURL = (spaceId: string, environmentId: string) => {
const redirectUri = encodeURIComponent(
Expand Down
3 changes: 2 additions & 1 deletion apps/slack/frontend/tsconfig.json
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,8 @@
"resolveJsonModule": true,
"isolatedModules": true,
"noEmit": true,
"jsx": "react-jsx"
"jsx": "react-jsx",
"types": ["vite/client"]
},
"include": [
"src",
Expand Down
12 changes: 12 additions & 0 deletions apps/slack/frontend/vite.config.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
import { defineConfig } from 'vite';

export default defineConfig({
server: {
port: 1234,
},
base: './',
envPrefix: 'REACT_APP',
build: {
outDir: 'build',
},
});
10 changes: 10 additions & 0 deletions apps/slack/frontend/vitest.config.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
import { defineConfig } from 'vite';
import { configDefaults } from 'vitest/config';

export default defineConfig({
test: {
environment: 'jsdom', // Ensure jsdom is still set for browser-like environment
globals: true, // Enable global usage of describe, test, etc.
exclude: [...configDefaults.exclude, 'node_modules'],
},
});

0 comments on commit 4effad3

Please sign in to comment.