diff --git a/keyserver/src/responders/website-responders.js b/keyserver/src/responders/website-responders.js --- a/keyserver/src/responders/website-responders.js +++ b/keyserver/src/responders/website-responders.js @@ -70,6 +70,7 @@ +cssInclude: string, +olmFilename: string, +sqljsFilename: string, + +opaqueURL: string, }; let assetInfo: ?AssetInfo = null; async function getAssetInfo() { @@ -84,6 +85,7 @@ cssInclude: '', olmFilename: '', sqljsFilename: '', + opaqueURL: 'http://localhost:8080/opaque-ke.wasm', }; return assetInfo; } @@ -107,6 +109,7 @@ `, olmFilename: manifest['olm.wasm'], sqljsFilename: webworkersManifest['sql-wasm.wasm'], + opaqueURL: `compiled/${manifest['comm_opaque2_wasm_bg.wasm']}`, }; return assetInfo; } catch { @@ -332,7 +335,7 @@ return pushConfig.publicKey; })(); - const { jsURL, fontsURL, cssInclude, olmFilename, sqljsFilename } = + const { jsURL, fontsURL, cssInclude, olmFilename, sqljsFilename, opaqueURL } = await assetInfoPromise; // prettier-ignore @@ -433,6 +436,7 @@ var baseURL = "${baseURL}"; var olmFilename = "${olmFilename}"; var sqljsFilename = "${sqljsFilename}"; + var opaqueURL = "${opaqueURL}"; diff --git a/web/app.react.js b/web/app.react.js --- a/web/app.react.js +++ b/web/app.react.js @@ -34,6 +34,7 @@ import Chat from './chat/chat.react.js'; import { TooltipProvider } from './chat/tooltip-provider.js'; import NavigationArrows from './components/navigation-arrows.react.js'; +import { initOpaque } from './crypto/opaque-utils.js'; import electron from './electron.js'; import InputStateContainer from './input/input-state-container.react.js'; import LoadingIndicator from './loading-indicator.react.js'; @@ -61,6 +62,8 @@ import { type NavInfo } from './types/nav-types.js'; import { canonicalURLFromReduxState, navInfoFromURL } from './url-utils.js'; +initOpaque(); + // We want Webpack's css-loader and style-loader to handle the Fontawesome CSS, // so we disable the autoAddCss logic and import the CSS file. Otherwise every // icon flashes huge for a second before the CSS is loaded. diff --git a/web/crypto/opaque-utils.js b/web/crypto/opaque-utils.js new file mode 100644 --- /dev/null +++ b/web/crypto/opaque-utils.js @@ -0,0 +1,19 @@ +// @flow + +import initOpaqueKe from '@commapp/opaque-ke-wasm'; + +declare var opaqueURL: string; + +let opaqueKeLoadingState: void | true | Promise; + +function initOpaque(): Promise { + if (opaqueKeLoadingState === true) { + return Promise.resolve(); + } + if (!opaqueKeLoadingState) { + opaqueKeLoadingState = initOpaqueKe(opaqueURL); + } + return opaqueKeLoadingState; +} + +export { initOpaque }; diff --git a/web/flow-typed/npm/@commapp/opaque-ke-wasm_vx.x.x.js b/web/flow-typed/npm/@commapp/opaque-ke-wasm_vx.x.x.js new file mode 100644 --- /dev/null +++ b/web/flow-typed/npm/@commapp/opaque-ke-wasm_vx.x.x.js @@ -0,0 +1,25 @@ +// flow-typed signature: 8ee70b4d84f861b07c5c7ae0ccf6ca25 +// flow-typed version: <>/@commapp/opaque-ke-wasm_v0.0.3/flow_v0.182.0 + +declare module '@commapp/opaque-ke-wasm' { + + declare export class Login { + constructor(): void; + free(): void; + start(password: string): Uint8Array; + finish(response_payload: Uint8Array): Uint8Array; + +session_key: Uint8Array; + } + + declare export class Registration { + constructor(): void; + free(): void; + start(password: string): Uint8Array; + finish(password: string, response_payload: Uint8Array): Uint8Array; + } + + declare export default function init( + input: void | string | Request | URL, + ): Promise; + +} diff --git a/web/package.json b/web/package.json --- a/web/package.json +++ b/web/package.json @@ -35,6 +35,7 @@ }, "dependencies": { "@babel/runtime": "^7.13.10", + "@commapp/opaque-ke-wasm": "npm:@commapp/opaque-ke-wasm@^0.0.3", "@emoji-mart/data": "^1.1.2", "@emoji-mart/react": "^1.1.1", "@fortawesome/fontawesome-svg-core": "1.2.25", diff --git a/web/webpack.config.cjs b/web/webpack.config.cjs --- a/web/webpack.config.cjs +++ b/web/webpack.config.cjs @@ -57,6 +57,16 @@ }, ], }), + new CopyPlugin({ + patterns: [ + { + from: + 'node_modules/@commapp/opaque-ke-wasm' + + '/pkg/comm_opaque2_wasm_bg.wasm', + to: path.join(__dirname, 'dist', 'opaque-ke.wasm'), + }, + ], + }), ], }; @@ -71,6 +81,16 @@ }, ], }), + new CopyPlugin({ + patterns: [ + { + from: + 'node_modules/@commapp/opaque-ke-wasm' + + '/pkg/comm_opaque2_wasm_bg.wasm', + to: path.join(__dirname, 'dist', 'opaque-ke.[contenthash:12].wasm'), + }, + ], + }), new WebpackManifestPlugin({ publicPath: '', }), diff --git a/yarn.lock b/yarn.lock --- a/yarn.lock +++ b/yarn.lock @@ -1719,6 +1719,11 @@ stream-browserify "^3.0.0" util "^0.12.4" +"@commapp/opaque-ke-wasm@npm:@commapp/opaque-ke-wasm@^0.0.3": + version "0.0.3" + resolved "https://registry.yarnpkg.com/@commapp/opaque-ke-wasm/-/opaque-ke-wasm-0.0.3.tgz#789b7351e593932461858658c61da5c2de51dc03" + integrity sha512-K88XPRnwKmpRCQqU26R7w1Syflp9IB1Ets1UPXTB3roumLweiHG8Y7UA+LrlpzCYd+8d8Tukp7i+/h4OFfovUw== + "@commapp/sqlcipher-amalgamation@^4.4.3-a": version "4.4.3-a" resolved "https://registry.yarnpkg.com/@commapp/sqlcipher-amalgamation/-/sqlcipher-amalgamation-4.4.3-a.tgz#39c297132b9ad02358bf022a164bfc03292ecce1"