diff --git a/package.json b/package.json index e7de5006..7427fdf5 100755 --- a/package.json +++ b/package.json @@ -39,7 +39,7 @@ "redux-thunk": "^2.4.2", "tailwindcss": "^3.3.3", "tlsn-js": "0.1.0-alpha.6.2", - "tlsn-jsV5.3": "npm:tlsn-js@0.1.0-alpha.5.3" + "tlsn-js-v5": "npm:tlsn-js@0.1.0-alpha.5.4" }, "devDependencies": { "@babel/core": "^7.20.12", diff --git a/plugins/README.md b/plugins/README.md deleted file mode 100644 index 37424d9b..00000000 --- a/plugins/README.md +++ /dev/null @@ -1 +0,0 @@ -You can find example plugins at https://github.com/tlsnotary/tlsn-plugin-boilerplate/tree/main/examples \ No newline at end of file diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 83f3e134..24daf9b0 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -74,9 +74,9 @@ dependencies: tlsn-js: specifier: 0.1.0-alpha.6.2 version: 0.1.0-alpha.6.2 - tlsn-jsV5.3: - specifier: npm:tlsn-js@0.1.0-alpha.5.3 - version: /tlsn-js@0.1.0-alpha.5.3 + tlsn-js-v5: + specifier: npm:tlsn-js@0.1.0-alpha.5.4 + version: /tlsn-js@0.1.0-alpha.5.4 devDependencies: '@babel/core': @@ -7974,8 +7974,8 @@ packages: resolution: {integrity: sha512-eHY7nBftgThBqOyHGVN+l8gF0BucP09fMo0oO/Lb0w1OF80dJv+lDVpXG60WMQvkcxAkNybKsrEIE3ZtKGmPrA==} dev: true - /tlsn-js@0.1.0-alpha.5.3: - resolution: {integrity: sha512-eTSCQ6MaH8mN2oCfLsQDe/mdfTlIq74MbKVesV6M01C2SRE0FJcVlTWMsnT3L+wOpvOlvsiBeCWV7T9m/YMzew==} + /tlsn-js@0.1.0-alpha.5.4: + resolution: {integrity: sha512-qbqaDjApXarohn/XMJrxMsNHYTCzy+pw0Fc8gtPPN17PLE+1DwwLTXAAhnxYqYQyo3+Hmy+ODd4C02+KCwRWmg==} engines: {node: '>= 16.20.2'} dependencies: comlink: 4.4.1 diff --git a/src/assets/plugins/discord_dm.wasm b/src/assets/plugins/discord_dm.wasm new file mode 100644 index 00000000..c9f58707 Binary files /dev/null and b/src/assets/plugins/discord_dm.wasm differ diff --git a/src/assets/plugins/twitter_profile.wasm b/src/assets/plugins/twitter_profile.wasm new file mode 100644 index 00000000..25dee0ac Binary files /dev/null and b/src/assets/plugins/twitter_profile.wasm differ diff --git a/src/components/PluginInfo/index.tsx b/src/components/PluginInfo/index.tsx index 214a2090..b08dc14e 100644 --- a/src/components/PluginInfo/index.tsx +++ b/src/components/PluginInfo/index.tsx @@ -24,6 +24,7 @@ import { } from '../../utils/plugins'; import { ErrorModal } from '../ErrorModal'; import classNames from 'classnames'; +import DefaultPluginIcon from '../../assets/img/default-plugin-icon.png'; export default function PluginUploadInfo(): ReactElement { const [error, showError] = useState(''); @@ -122,7 +123,7 @@ export function PluginInfoModal(props: { {header || (
- logo + logo {`Installing ${pluginContent.title}`}
)} @@ -132,7 +133,7 @@ export function PluginInfoModal(props: { <> Plugin Icon diff --git a/src/components/PluginList/index.tsx b/src/components/PluginList/index.tsx index e54f6671..7aaefcb4 100644 --- a/src/components/PluginList/index.tsx +++ b/src/components/PluginList/index.tsx @@ -169,7 +169,7 @@ export function Plugin(props: { Plugin Icon diff --git a/src/entries/Background/db.ts b/src/entries/Background/db.ts index 990815e6..4677e03b 100644 --- a/src/entries/Background/db.ts +++ b/src/entries/Background/db.ts @@ -28,6 +28,12 @@ const cookiesDb = db.sublevel('cookies', { const headersDb = db.sublevel('headers', { valueEncoding: 'json', }); +const appDb = db.sublevel('app', { + valueEncoding: 'json', +}); +enum AppDatabaseKey { + DefaultPluginsInstalled = 'DefaultPluginsInstalled', +} export async function addNotaryRequest( now = Date.now(), @@ -372,3 +378,19 @@ export async function getHeadersByHost(host: string) { } return ret; } + +async function getDefaultPluginsInstalled(): Promise { + return appDb.get(AppDatabaseKey.DefaultPluginsInstalled).catch(() => false); +} + +export async function setDefaultPluginsInstalled(installed = false) { + return mutex.runExclusive(async () => { + await appDb.put(AppDatabaseKey.DefaultPluginsInstalled, installed); + }); +} + +export async function getAppState() { + return { + defaultPluginsInstalled: await getDefaultPluginsInstalled(), + }; +} diff --git a/src/entries/Background/index.ts b/src/entries/Background/index.ts index 265db381..554bf82e 100644 --- a/src/entries/Background/index.ts +++ b/src/entries/Background/index.ts @@ -1,6 +1,8 @@ import { onBeforeRequest, onResponseStarted, onSendHeaders } from './handlers'; import { deleteCacheByTabId } from './cache'; import browser from 'webextension-polyfill'; +import { getAppState, setDefaultPluginsInstalled } from './db'; +import { installPlugin } from './plugins/utils'; (async () => { browser.webRequest.onSendHeaders.addListener( @@ -31,6 +33,19 @@ import browser from 'webextension-polyfill'; deleteCacheByTabId(tabId); }); + const { defaultPluginsInstalled } = await getAppState(); + + if (!defaultPluginsInstalled) { + try { + const twitterProfileUrl = browser.runtime.getURL('twitter_profile.wasm'); + const discordDmUrl = browser.runtime.getURL('discord_dm.wasm'); + await installPlugin(twitterProfileUrl); + await installPlugin(discordDmUrl); + } finally { + await setDefaultPluginsInstalled(true); + } + } + const { initRPC } = await import('./rpc'); await createOffscreenDocument(); initRPC(); diff --git a/src/entries/Background/plugins/utils.ts b/src/entries/Background/plugins/utils.ts new file mode 100644 index 00000000..cb7bc081 --- /dev/null +++ b/src/entries/Background/plugins/utils.ts @@ -0,0 +1,29 @@ +import { addPlugin, addPluginConfig, addPluginMetadata } from '../db'; +import { getPluginConfig } from '../../../utils/misc'; + +export async function installPlugin( + urlOrBuffer: ArrayBuffer | string, + origin = '', + filePath = '', + metadata: {[key: string]: string} = {}, +) { + let arrayBuffer; + + if (typeof urlOrBuffer === 'string') { + const resp = await fetch(urlOrBuffer); + arrayBuffer = await resp.arrayBuffer(); + } else { + arrayBuffer = urlOrBuffer; + } + + const config = await getPluginConfig(arrayBuffer); + const hex = Buffer.from(arrayBuffer).toString('hex'); + const hash = await addPlugin(hex); + await addPluginConfig(hash!, config); + await addPluginMetadata(hash!, { + ...metadata, + origin, + filePath, + }); + return hash; +} \ No newline at end of file diff --git a/src/entries/Background/rpc.ts b/src/entries/Background/rpc.ts index 37d4f1e4..e46f317c 100644 --- a/src/entries/Background/rpc.ts +++ b/src/entries/Background/rpc.ts @@ -24,6 +24,8 @@ import { getPlugins, getCookiesByHost, getHeadersByHost, + getAppState, + setDefaultPluginsInstalled, } from './db'; import { addOnePlugin, removeOnePlugin } from '../../reducers/plugins'; import { @@ -85,6 +87,8 @@ export enum BackgroundActiontype { run_plugin_request = 'run_plugin_request', run_plugin_response = 'run_plugin_response', get_logging_level = 'get_logging_level', + get_app_state = 'get_app_state', + set_default_plugins_installed = 'set_default_plugins_installed', } export type BackgroundAction = { @@ -192,6 +196,12 @@ export const initRPC = () => { case BackgroundActiontype.get_logging_level: getLoggingFilter().then(sendResponse); return true; + case BackgroundActiontype.get_app_state: + getAppState().then(sendResponse); + return true; + case BackgroundActiontype.set_default_plugins_installed: + setDefaultPluginsInstalled(request.data).then(sendResponse); + return true; default: break; } diff --git a/src/entries/Offscreen/Offscreen.tsx b/src/entries/Offscreen/Offscreen.tsx index 2a0b7c51..ed23be48 100644 --- a/src/entries/Offscreen/Offscreen.tsx +++ b/src/entries/Offscreen/Offscreen.tsx @@ -7,7 +7,7 @@ import { NotarizedSession as _NotarizedSession, TlsProof as _TlsProof, } from 'tlsn-js'; -import { verify } from 'tlsn-jsV5.3'; +import { verify } from 'tlsn-js-v5'; import { urlify } from '../../utils/misc'; import { BackgroundActiontype } from '../Background/rpc'; diff --git a/src/manifest.json b/src/manifest.json index 46f57109..d54cac22 100755 --- a/src/manifest.json +++ b/src/manifest.json @@ -28,7 +28,7 @@ ], "web_accessible_resources": [ { - "resources": ["content.styles.css", "icon-128.png", "icon-34.png", "content.bundle.js"], + "resources": ["content.styles.css", "icon-128.png", "icon-34.png", "content.bundle.js", "discord_dm.wasm", "twitter_profile.wasm"], "matches": ["http://*/*", "https://*/*", ""] } ], diff --git a/webpack.config.js b/webpack.config.js index e856c857..4ad7bc06 100755 --- a/webpack.config.js +++ b/webpack.config.js @@ -40,7 +40,8 @@ var options = { mode: process.env.NODE_ENV || "development", ignoreWarnings: [ /Circular dependency between chunks with runtime/, - /ResizeObserver loop completed with undelivered notifications/ + /ResizeObserver loop completed with undelivered notifications/, + /Should not import the named export/, ], entry: { @@ -199,31 +200,21 @@ var options = { }), new CopyWebpackPlugin({ patterns: [ - // { - // from: "node_modules/tlsn-js/build/7.js", - // to: path.join(__dirname, "build"), - // force: true, - // }, - // { - // from: "node_modules/tlsn-js/build/250.js", - // to: path.join(__dirname, "build"), - // force: true, - // }, - // { - // from: "node_modules/tlsn-js/build/278.js", - // to: path.join(__dirname, "build"), - // force: true, - // }, - // { - // from: "node_modules/tlsn-js/build/349.js", - // to: path.join(__dirname, "build"), - // force: true, - // }, { from: "node_modules/tlsn-js/build", to: path.join(__dirname, "build"), force: true, }, + { + from: "src/assets/plugins/discord_dm.wasm", + to: path.join(__dirname, "build"), + force: true, + }, + { + from: "src/assets/plugins/twitter_profile.wasm", + to: path.join(__dirname, "build"), + force: true, + }, ], }), new HtmlWebpackPlugin({