From f37a9a09fa788bd2022341c5ce000419ed32516b Mon Sep 17 00:00:00 2001 From: Darran Boyd Date: Mon, 25 Nov 2024 17:14:40 +1100 Subject: [PATCH] feat(browser-extension): Improve support for custom domains for various integration --- .../src/entrypoints/content-script.ts | 71 +++---- .../src/entrypoints/popup/App.tsx | 24 +-- .../entrypoints/popup/ConfigDetailView.tsx | 60 ++++++ .../src/entrypoints/popup/ConfigView.tsx | 195 +++++++++++------- .../popup/ExtensionConfigProvider.tsx | 46 +++++ .../src/entrypoints/popup/RegexArrayForm.tsx | 65 ++++++ .../src/entrypoints/popup/config.ts | 75 ++++--- .../src/entrypoints/popup/main.tsx | 9 +- 8 files changed, 386 insertions(+), 159 deletions(-) create mode 100644 packages/threat-composer-app-browser-extension/src/entrypoints/popup/ConfigDetailView.tsx create mode 100644 packages/threat-composer-app-browser-extension/src/entrypoints/popup/ExtensionConfigProvider.tsx create mode 100644 packages/threat-composer-app-browser-extension/src/entrypoints/popup/RegexArrayForm.tsx diff --git a/packages/threat-composer-app-browser-extension/src/entrypoints/content-script.ts b/packages/threat-composer-app-browser-extension/src/entrypoints/content-script.ts index ef4b98b6..0385cdff 100644 --- a/packages/threat-composer-app-browser-extension/src/entrypoints/content-script.ts +++ b/packages/threat-composer-app-browser-extension/src/entrypoints/content-script.ts @@ -14,7 +14,7 @@ limitations under the License. ******************************************************************************************************************** */ -import { getExtensionConfig, TCConfig } from './popup/config'; +import { getExtensionConfig, TCConfig, IntegrationTypes } from './popup/config'; import { logDebugMessage } from '../debugLogger'; const tcButtonText = 'View in Threat Composer'; @@ -93,6 +93,7 @@ async function getTCJSONCandidate(url: string, element: HTMLElement, config: TCC } }) .catch(function (error) { + console.log(error); logDebugMessage(config, 'Error during fetch: ' + error.message); }); }; @@ -113,25 +114,12 @@ async function handleRawFile(config: TCConfig) { }; function isRawSite(tcConfig: TCConfig) { - if (matchesAnyRegex(window.location.href, tcConfig.integrationRawUrlRegexes)) {return true;} + if (matchesAnyRegex(window.location.href, tcConfig.integrations[IntegrationTypes.RAW].urlRegexes)) {return true;} return false; } function isGitLabSite(tcConfig: TCConfig) { - if (matchesAnyRegex(window.location.href, tcConfig.integrationGitLabCodeBrowserUrlRegexes)) {return true;} - - // Check for the presence of the GitLab logo or branding - const gitlabLogo = document.querySelector('img[src*="gitlab.com/assets/logo"]'); - if (gitlabLogo) { - return true; - } - - // Check for the presence of specific GitLab UI elements - const gitlabLayout = document.querySelector('.layout-page'); - const gitlabHeader = document.querySelector('.navbar-gitlab'); - if (gitlabLayout && gitlabHeader) { - return true; - } + if (matchesAnyRegex(window.location.href, tcConfig.integrations[IntegrationTypes.GITLAB].urlRegexes)) {return true;} // Check for the presence of GitLab-specific classes or IDs const gitlabElements = document.querySelectorAll('[class*="gl-"], [id*="gl-"]'); @@ -144,26 +132,26 @@ function isGitLabSite(tcConfig: TCConfig) { } function isGitHubSite(tcConfig: TCConfig) { - if (matchesAnyRegex(window.location.href, tcConfig.integrationGitHubCodeBrowserUrlRegexes)) {return true;} + if (matchesAnyRegex(window.location.href, tcConfig.integrations[IntegrationTypes.GITHUB].urlRegexes)) {return true;} return false; } function isCodeCatalystSite(tcConfig: TCConfig) { - if (matchesAnyRegex(window.location.href, tcConfig.integrationCodeCatalystCodeBrowserUrlRegexes)) {return true;} + if (matchesAnyRegex(window.location.href, tcConfig.integrations[IntegrationTypes.CODECATALYST].urlRegexes)) {return true;} return false; } function isAmazonCodeBrowser(tcConfig: TCConfig) { - if (matchesAnyRegex(window.location.href, tcConfig.integrationAmazonCodeBrowserUrlRegexes)) {return true;} + if (matchesAnyRegex(window.location.href, tcConfig.integrations[IntegrationTypes.CODEAMAZON].urlRegexes)) {return true;} return false; } function isBitbucketSite(tcConfig: TCConfig) { - if (matchesAnyRegex(window.location.href, tcConfig.integrationBitBucketCodeBrowserUrlRegexes)) {return true;} + if (matchesAnyRegex(window.location.href, tcConfig.integrations[IntegrationTypes.BITBUCKET].urlRegexes)) {return true;} // Check for the presence of Bitbucket-specific elements const bitbucketMeta = document.querySelectorAll('meta[name="application-name"][content="Bitbucket"]'); - if (bitbucketMeta) { + if (bitbucketMeta.length > 0) { return true; } @@ -356,38 +344,38 @@ async function handleCodeCatalystCodeViewer(codeCatalystState: TCCodeCatalystSta async function ContentScriptInScope(tcConfig: TCConfig) { let inScopeRegexes = [tcConfig.baseUrlRegex]; - if (tcConfig.integrationRaw) { - tcConfig.integrationRawUrlRegexes.forEach(entry => { + if (tcConfig.integrations[IntegrationTypes.RAW].enabled) { + tcConfig.integrations[IntegrationTypes.RAW].urlRegexes.forEach(entry => { inScopeRegexes.push(entry); }); } - if (tcConfig.integrationAmazonCodeBrowser) { - tcConfig.integrationAmazonCodeBrowserUrlRegexes.forEach(entry => { + if (tcConfig.integrations[IntegrationTypes.CODEAMAZON].enabled) { + tcConfig.integrations[IntegrationTypes.CODEAMAZON].urlRegexes.forEach(entry => { inScopeRegexes.push(entry); }); } - if (tcConfig.integrationBitBucketCodeBrowser) { - tcConfig.integrationBitBucketCodeBrowserUrlRegexes.forEach(entry => { + if (tcConfig.integrations[IntegrationTypes.BITBUCKET].enabled) { + tcConfig.integrations[IntegrationTypes.BITBUCKET].urlRegexes.forEach(entry => { inScopeRegexes.push(entry); }); } - if (tcConfig.integrationCodeCatalystCodeBrowser) { - tcConfig.integrationCodeCatalystCodeBrowserUrlRegexes.forEach(entry => { + if (tcConfig.integrations[IntegrationTypes.CODECATALYST].enabled) { + tcConfig.integrations[IntegrationTypes.CODECATALYST].urlRegexes.forEach(entry => { inScopeRegexes.push(entry); }); } - if (tcConfig.integrationGitHubCodeBrowser) { - tcConfig.integrationGitHubCodeBrowserUrlRegexes.forEach(entry => { + if (tcConfig.integrations[IntegrationTypes.GITHUB].enabled) { + tcConfig.integrations[IntegrationTypes.GITHUB].urlRegexes.forEach(entry => { inScopeRegexes.push(entry); }); } - if (tcConfig.integrationGitLabCodeBrowser) { - tcConfig.integrationGitLabCodeBrowserUrlRegexes.forEach(entry => { + if (tcConfig.integrations[IntegrationTypes.GITLAB].enabled) { + tcConfig.integrations[IntegrationTypes.GITLAB].urlRegexes.forEach(entry => { inScopeRegexes.push(entry); }); } @@ -403,8 +391,8 @@ async function ContentScriptInScope(tcConfig: TCConfig) { return match; } -function matchesAnyRegex(url: string, regexArray: RegExp[]) { - return regexArray.some(regex => regex.test(url)); +function matchesAnyRegex(url: string, regexArray: string[]) { + return regexArray.some(regex => new RegExp(regex).test(url)); } export default defineContentScript({ @@ -448,10 +436,10 @@ export default defineContentScript({ } if ( - tcConfig.integrationRaw && isRawSite(tcConfig)) { + tcConfig.integrations[IntegrationTypes.RAW].enabled && isRawSite(tcConfig)) { logDebugMessage(tcConfig, 'Assuming raw file view'); await handleRawFile(tcConfig); - } else if (tcConfig.integrationGitLabCodeBrowser && isGitLabSite(tcConfig)) { + } else if (tcConfig.integrations[IntegrationTypes.GITLAB].enabled && isGitLabSite(tcConfig)) { logDebugMessage(tcConfig, 'Assuming GitLab code browser'); await handleGitLabBrowser(gitLabState, tcConfig); let observerForGitLabCodeBrowser = new MutationObserver( @@ -459,7 +447,7 @@ export default defineContentScript({ ); observerForGitLabCodeBrowser.observe(document, config); //Scope is `document` as GitLab is a SPA } else if ( - tcConfig.integrationGitHubCodeBrowser && isGitHubSite(tcConfig) + tcConfig.integrations[IntegrationTypes.GITHUB].enabled && isGitHubSite(tcConfig) ) { logDebugMessage(tcConfig, 'Assuming GitHub code browser', @@ -470,7 +458,7 @@ export default defineContentScript({ ); observerForGitHubCodeViewer.observe(document, config); //Scope is `document` as GitHub is a SPA } else if ( - tcConfig.integrationCodeCatalystCodeBrowser && isCodeCatalystSite(tcConfig) + tcConfig.integrations[IntegrationTypes.CODECATALYST].enabled && isCodeCatalystSite(tcConfig) ) { logDebugMessage(tcConfig, 'Assuming Code Catalyst code browser'); //Inject script @@ -485,7 +473,7 @@ export default defineContentScript({ ); observerForCodeCatalystCodeViewer.observe(document.body, config); } else if ( - tcConfig.integrationAmazonCodeBrowser && isAmazonCodeBrowser(tcConfig) + tcConfig.integrations[IntegrationTypes.CODEAMAZON].enabled && isAmazonCodeBrowser(tcConfig) ) { logDebugMessage(tcConfig, 'Assuming Amazon code browser'); await handleAmazonCodeBrowser(codeBrowserState, tcConfig); @@ -494,9 +482,10 @@ export default defineContentScript({ ); observerForAmazonCodeBrowser.observe(document.body, config); } else if ( - tcConfig.integrationBitBucketCodeBrowser && + tcConfig.integrations[IntegrationTypes.BITBUCKET].enabled && isBitbucketSite(tcConfig) ) { + console.log(tcConfig); logDebugMessage(tcConfig, 'URL is bitbucket.org - Assuming Bitbucket code browser'); await handleBitbucketCodeBrowser(codeBrowserState, tcConfig); let observerForBitbucketCodeBrowser = new MutationObserver( diff --git a/packages/threat-composer-app-browser-extension/src/entrypoints/popup/App.tsx b/packages/threat-composer-app-browser-extension/src/entrypoints/popup/App.tsx index 0dffb55a..b7871c63 100644 --- a/packages/threat-composer-app-browser-extension/src/entrypoints/popup/App.tsx +++ b/packages/threat-composer-app-browser-extension/src/entrypoints/popup/App.tsx @@ -14,24 +14,18 @@ limitations under the License. ******************************************************************************************************************** */ -import { Spinner } from '@cloudscape-design/components'; -import { FC, useState, useEffect } from 'react'; -import { TCConfig, getExtensionConfig } from './config'; +import { FC } from 'react'; +import { Route, Routes } from 'react-router-dom'; +import { ConfigDetailView } from './ConfigDetailView'; import Config from './ConfigView'; -import { logDebugMessage } from '../../debugLogger'; const App: FC = () => { - const [config, setConfig] = useState(); - - useEffect(() => { - getExtensionConfig() - .then((loadedConfig) => setConfig(loadedConfig)) - .catch((error) => { - logDebugMessage({ debug: true } as any, error); - }); - }, []); - - return config ? : ; + return ( + + }/> + }/> + + ); }; export default App; diff --git a/packages/threat-composer-app-browser-extension/src/entrypoints/popup/ConfigDetailView.tsx b/packages/threat-composer-app-browser-extension/src/entrypoints/popup/ConfigDetailView.tsx new file mode 100644 index 00000000..e3c06c9c --- /dev/null +++ b/packages/threat-composer-app-browser-extension/src/entrypoints/popup/ConfigDetailView.tsx @@ -0,0 +1,60 @@ +/** ******************************************************************************************************************* + Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. + + Licensed under the Apache License, Version 2.0 (the "License"). + You may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + ******************************************************************************************************************** */ +import { Button, SpaceBetween } from '@cloudscape-design/components'; +import Form from '@cloudscape-design/components/form'; +import { FC, useCallback, useContext, useMemo } from 'react'; +import { Navigate, useNavigate, useParams } from 'react-router-dom'; +import { IntegrationConfig } from './config'; +import { ExtensionConfigContext } from './ExtensionConfigProvider'; +import { RegexArrayForm } from './RegexArrayForm'; + +export interface ConfigDetailViewProps { + +} + +export const ConfigDetailView: FC = () => { + const navigate = useNavigate(); + const { integrationType } = useParams<{ integrationType: string }>(); + const { config, setConfig } = useContext(ExtensionConfigContext); + const integrationConfig = useMemo(() => config.integrations[integrationType!], [integrationType, config]); + const setIntegrationConfig = useCallback((newIntegrationConfig: Partial) => { + setConfig((prev) => { + return { + ...prev, integrations: { + ...prev.integrations, + [integrationType!]: + { ...prev.integrations[integrationType!], ...newIntegrationConfig } + } + }; + }); + }, [integrationType, setConfig]); + return ( +
+ + + )}> + { setIntegrationConfig({ urlRegexes: newRegexes }); }}> + + + + +
+ + ); +}; \ No newline at end of file diff --git a/packages/threat-composer-app-browser-extension/src/entrypoints/popup/ConfigView.tsx b/packages/threat-composer-app-browser-extension/src/entrypoints/popup/ConfigView.tsx index 42be6101..6ccaa4fe 100644 --- a/packages/threat-composer-app-browser-extension/src/entrypoints/popup/ConfigView.tsx +++ b/packages/threat-composer-app-browser-extension/src/entrypoints/popup/ConfigView.tsx @@ -17,22 +17,21 @@ import Box from '@cloudscape-design/components/box'; import Button from '@cloudscape-design/components/button'; import ColumnLayout from '@cloudscape-design/components/column-layout'; import Container from '@cloudscape-design/components/container'; -import FormField from '@cloudscape-design/components/form-field'; import Header from '@cloudscape-design/components/header'; -import Input from '@cloudscape-design/components/input'; -import Select from '@cloudscape-design/components/select'; import SpaceBetween from '@cloudscape-design/components/space-between'; import Toggle from '@cloudscape-design/components/toggle'; -import { FC } from 'react'; +import { FC, useContext } from 'react'; +import { useNavigate } from 'react-router-dom'; import { TCConfig, useExtensionConfig, ThreatComposerTarget, DefaultConfig, + IntegrationTypes, } from './config'; +import { ExtensionConfigContext } from './ExtensionConfigProvider'; interface ConfigProps { - readonly initialConfig: TCConfig; } // function createTargetOption(target: ThreatComposerTarget) { @@ -56,8 +55,9 @@ interface ConfigProps { // } // } -const Config: FC = ({ initialConfig }) => { - const [config, setConfig] = useExtensionConfig(initialConfig); +const Config: FC = ({ }) => { + const navigate = useNavigate(); + const { config, setConfig } = useContext(ExtensionConfigContext); return ( @@ -76,17 +76,26 @@ const Config: FC = ({ initialConfig }) => {
- - setConfig((prev) => ({ - ...prev, - integrationRaw: detail.checked, - })) - } - checked={config.integrationRaw} - > + + + setConfig((prev) => ({ + ...prev, + integrations: { + ...prev.integrations, + [IntegrationTypes.RAW]: { + ...prev.integrations[IntegrationTypes.RAW], + enabled: detail.checked, + }, + }, + })) + } + checked={config.integrations[IntegrationTypes.RAW].enabled} + > Anywhere (*.tc.json) - + +
@@ -97,61 +106,103 @@ const Config: FC = ({ initialConfig }) => {
Code browser integrations
- - setConfig((prev) => ({ - ...prev, - integrationGitHubCodeBrowser: detail.checked, - })) - } - checked={config.integrationGitHubCodeBrowser} - > - GitHub (github.com/*) - - - setConfig((prev) => ({ - ...prev, - integrationAmazonCodeBrowser: detail.checked, - })) - } - checked={config.integrationAmazonCodeBrowser} - > - Amazon Code (code.amazon.com/*) - - - setConfig((prev) => ({ - ...prev, - integrationCodeCatalystCodeBrowser: detail.checked, - })) - } - checked={config.integrationCodeCatalystCodeBrowser} - > - Amazon CodeCatalyst (codecatalyst.aws/*) - - - setConfig((prev) => ({ - ...prev, - integrationBitBucketCodeBrowser: detail.checked, - })) - } - checked={config.integrationBitBucketCodeBrowser} - > - Bitbucket (bitbucket.org/*) - - - setConfig((prev) => ({ - ...prev, - integrationGitLabCodeBrowser: detail.checked, - })) - } - checked={config.integrationGitLabCodeBrowser} - > - GitLab - + + + setConfig((prev) => ({ + ...prev, + integrations: { + ...prev.integrations, + [IntegrationTypes.GITHUB]: { + ...prev.integrations[IntegrationTypes.GITHUB], + enabled: detail.checked, + }, + }, + })) + } + checked={config.integrations[IntegrationTypes.GITHUB].enabled} + >GitHub + +
diff --git a/packages/threat-composer-app-browser-extension/src/entrypoints/popup/ExtensionConfigProvider.tsx b/packages/threat-composer-app-browser-extension/src/entrypoints/popup/ExtensionConfigProvider.tsx new file mode 100644 index 00000000..c98efd9a --- /dev/null +++ b/packages/threat-composer-app-browser-extension/src/entrypoints/popup/ExtensionConfigProvider.tsx @@ -0,0 +1,46 @@ +/** ******************************************************************************************************************* + Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. + + Licensed under the Apache License, Version 2.0 (the "License"). + You may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + ******************************************************************************************************************** */ +import { Spinner } from '@cloudscape-design/components'; +import { FC, useEffect, ReactNode, createContext } from 'react'; +import { TCConfig, DefaultConfig, getExtensionConfig, useExtensionConfig } from './config'; +import { logDebugMessage } from '../../debugLogger'; + +export interface ExtensionConfigProviderProps { + children: ReactNode; +} + +export interface ConfigContext { + config: TCConfig; + setConfig: (doSetConfig:(prevConfig: TCConfig) => TCConfig) => void; +} + +export const ExtensionConfigContext = createContext({ config: DefaultConfig, setConfig: ()=>{} }); + +export const ExtensionConfigProvider: FC = ({ children }) => { + const [config, setConfig] = useExtensionConfig(); + useEffect(() => { + getExtensionConfig() + .then((loadedConfig) => setConfig(() => loadedConfig)) + .catch((error) => { + logDebugMessage({ debug: true } as any, error); + }); + }, []); + return ( + config ? ( + {children} + ) : + ); +}; \ No newline at end of file diff --git a/packages/threat-composer-app-browser-extension/src/entrypoints/popup/RegexArrayForm.tsx b/packages/threat-composer-app-browser-extension/src/entrypoints/popup/RegexArrayForm.tsx new file mode 100644 index 00000000..9f98222b --- /dev/null +++ b/packages/threat-composer-app-browser-extension/src/entrypoints/popup/RegexArrayForm.tsx @@ -0,0 +1,65 @@ +/** ******************************************************************************************************************* + Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. + + Licensed under the Apache License, Version 2.0 (the "License"). + You may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + ******************************************************************************************************************** */ +import { Button, Input, SpaceBetween, TokenGroup } from '@cloudscape-design/components'; +import { FC, useCallback, useState } from 'react'; + +export interface RegexArrayFormProps { + readonly strings: string[]; + readonly setStrings: (strings: string[]) => void; + readonly placeholder?: string; + readonly allowEmpty?: boolean; +} + +export const RegexArrayForm: FC = ({ strings, setStrings, placeholder, allowEmpty }) => { + const [value, setValue] = useState(''); + + const [valid, setValid] = useState(true); + + const onAdd = useCallback(() => { + setStrings([...strings, value]); + setValue(''); + }, [value, strings]); + + return ( + + + { + setValue(e.detail.value); + try { + new RegExp(e.detail.value); + setValid(true); + } catch { + setValid(false); + } + }} /> + + + ({ + label: v, + value: v, + }))} + onDismiss={({ detail: { itemIndex } }) => { + if (strings.length > 1) { + setStrings([...strings.slice(0, itemIndex), ...strings.slice(itemIndex + 1)]); + } + }} + /> + + ); +}; \ No newline at end of file diff --git a/packages/threat-composer-app-browser-extension/src/entrypoints/popup/config.ts b/packages/threat-composer-app-browser-extension/src/entrypoints/popup/config.ts index 7b9fb503..c19fab0c 100644 --- a/packages/threat-composer-app-browser-extension/src/entrypoints/popup/config.ts +++ b/packages/threat-composer-app-browser-extension/src/entrypoints/popup/config.ts @@ -24,40 +24,57 @@ export enum ThreatComposerTarget { export interface TCConfig { - baseUrlRegex: RegExp; + baseUrlRegex: string; debug: boolean; fileExtension: string; - integrationAmazonCodeBrowser: boolean; - integrationAmazonCodeBrowserUrlRegexes: RegExp[]; - integrationBitBucketCodeBrowser: boolean; - integrationBitBucketCodeBrowserUrlRegexes: RegExp[]; - integrationCodeCatalystCodeBrowser: boolean; - integrationCodeCatalystCodeBrowserUrlRegexes: RegExp[]; - integrationGitHubCodeBrowser: boolean; - integrationGitHubCodeBrowserUrlRegexes: RegExp[]; - integrationGitLabCodeBrowser: boolean; - integrationGitLabCodeBrowserUrlRegexes: RegExp[]; - integrationRaw: boolean; - integrationRawUrlRegexes: RegExp[]; + integrations: {[integrationType: string]: IntegrationConfig }; target: ThreatComposerTarget; } +export interface IntegrationConfig { + enabled: boolean; + urlRegexes: string[]; +} + +export const IntegrationTypes = { + GITHUB: 'github', + GITLAB: 'gitlab', + BITBUCKET: 'bitbucket', + CODEAMAZON: 'codeamazon', + CODECATALYST: 'codecatalyst', + RAW: 'raw', +} as const; + export const DefaultConfig: TCConfig = { - baseUrlRegex: /^.*:\/\/.*\/.*\.tc\.json([?#].*)?$/, + baseUrlRegex: '^.*:\/\/.*\/.*\.tc\.json([?#].*)?$', debug: true, fileExtension: '.tc.json', - integrationAmazonCodeBrowser: true, - integrationAmazonCodeBrowserUrlRegexes: [/code.amazon.com/], - integrationBitBucketCodeBrowser: true, - integrationBitBucketCodeBrowserUrlRegexes: [/bitbucket.org/], - integrationCodeCatalystCodeBrowser: true, - integrationCodeCatalystCodeBrowserUrlRegexes: [/codecatalyst.aws/], - integrationGitHubCodeBrowser: true, - integrationGitHubCodeBrowserUrlRegexes: [/github.com/], - integrationGitLabCodeBrowser: true, - integrationGitLabCodeBrowserUrlRegexes: [/gitlab.com/], - integrationRaw: true, - integrationRawUrlRegexes: [/raw.githubusercontent.com/, /raw=1/, /raw/], + integrations: { + [IntegrationTypes.GITHUB]: { + enabled: true, + urlRegexes: ['github.com'], + }, + [IntegrationTypes.GITLAB]: { + enabled: true, + urlRegexes: ['gitlab.com'], + }, + [IntegrationTypes.BITBUCKET]: { + enabled: true, + urlRegexes: ['bitbucket.org'], + }, + [IntegrationTypes.CODEAMAZON]: { + enabled: true, + urlRegexes: ['code.amazon.com'], + }, + [IntegrationTypes.CODECATALYST]: { + enabled: true, + urlRegexes: ['codecatalyst.aws'], + }, + [IntegrationTypes.RAW]: { + enabled: true, + urlRegexes: ['raw.githubusercontent.com', 'raw=1', 'raw'], + }, + }, target: ThreatComposerTarget.BUILT_IN, }; @@ -78,12 +95,12 @@ export function setExtensionConfig(config: TCConfig) { }); } -export const useExtensionConfig = (defaultConfig: TCConfig) => { - const [value, setValue] = useState(defaultConfig); +export const useExtensionConfig = () => { + const [value, setValue] = useState(); const handleValueChange = (doSetConfig: (prevConfig: TCConfig) => TCConfig) => { setValue((prev) => { - const newConfig = doSetConfig(prev); + const newConfig = doSetConfig(prev ?? DefaultConfig); setExtensionConfig(newConfig); return newConfig; }); diff --git a/packages/threat-composer-app-browser-extension/src/entrypoints/popup/main.tsx b/packages/threat-composer-app-browser-extension/src/entrypoints/popup/main.tsx index 536f1da7..81e031af 100644 --- a/packages/threat-composer-app-browser-extension/src/entrypoints/popup/main.tsx +++ b/packages/threat-composer-app-browser-extension/src/entrypoints/popup/main.tsx @@ -15,12 +15,17 @@ ******************************************************************************************************************** */ import React from 'react'; import ReactDOM from 'react-dom'; -//import { BrowserRouter } from 'react-router-dom'; +import { MemoryRouter } from 'react-router-dom'; import App from './App.tsx'; +import { ExtensionConfigProvider } from './ExtensionConfigProvider.js'; ReactDOM.render( - + + + + + , document.getElementById('root'), );