diff --git a/keyserver/addons/opaque-ke-napi/.gitignore b/keyserver/addons/opaque-ke-napi/.gitignore new file mode 100644 --- /dev/null +++ b/keyserver/addons/opaque-ke-napi/.gitignore @@ -0,0 +1,3 @@ +Cargo.lock +target +napi diff --git a/keyserver/addons/opaque-ke-napi/Cargo.toml b/keyserver/addons/opaque-ke-napi/Cargo.toml new file mode 100644 --- /dev/null +++ b/keyserver/addons/opaque-ke-napi/Cargo.toml @@ -0,0 +1,19 @@ +[package] +edition = "2021" +name = "opaque-ke-napi" +version = "0.1.0" +license = "BSD-3-Clause" + +[lib] +crate-type = ["cdylib"] + +[dependencies] +# Default enable napi4 feature, see https://nodejs.org/api/n-api.html#node-api-version-matrix +napi = { version = "2.10.1", default-features = false, features = ["napi4"] } +napi-derive = { version = "2.9.1", default-features = false } + +[build-dependencies] +napi-build = "2.0.1" + +[profile.release] +lto = true diff --git a/keyserver/addons/opaque-ke-napi/build.rs b/keyserver/addons/opaque-ke-napi/build.rs new file mode 100644 --- /dev/null +++ b/keyserver/addons/opaque-ke-napi/build.rs @@ -0,0 +1,5 @@ +extern crate napi_build; + +fn main() { + napi_build::setup(); +} diff --git a/keyserver/addons/opaque-ke-napi/index.js b/keyserver/addons/opaque-ke-napi/index.js new file mode 100644 --- /dev/null +++ b/keyserver/addons/opaque-ke-napi/index.js @@ -0,0 +1,32 @@ +// @flow + +const { platform, arch } = process; + +type RustAPI = { + +sum: (a: number, b: number) => number, +}; + +async function getRustAPI(): Promise { + let nativeBinding = null; + if (platform === 'darwin' && arch === 'x64') { + // $FlowFixMe + nativeBinding = await import('./napi/opaque-ke-napi.darwin-x64.node'); + } else if (platform === 'darwin' && arch === 'arm64') { + // $FlowFixMe + nativeBinding = await import('./napi/opaque-ke-napi.darwin-arm64.node'); + } else if (platform === 'linux' && arch === 'x64') { + // $FlowFixMe + nativeBinding = await import('./napi/opaque-ke-napi.linux-x64-gnu.node'); + } else { + throw new Error(`Unsupported OS: ${platform}, architecture: ${arch}`); + } + + if (!nativeBinding) { + throw new Error('Failed to load native binding'); + } + + const { sum } = nativeBinding.default; + return { sum }; +} + +export { getRustAPI }; diff --git a/keyserver/addons/opaque-ke-napi/package.json b/keyserver/addons/opaque-ke-napi/package.json new file mode 100644 --- /dev/null +++ b/keyserver/addons/opaque-ke-napi/package.json @@ -0,0 +1,32 @@ +{ + "name": "opaque-ke-napi", + "version": "0.0.1", + "main": "index.js", + "type": "module", + "napi": { + "name": "opaque-ke-napi", + "triples": { + "defaults": false, + "additional": [ + "aarch64-apple-darwin", + "x86_64-apple-darwin", + "x86_64-unknown-linux-gnu" + ] + } + }, + "license": "BSD-3-Clause", + "devDependencies": { + "@napi-rs/cli": "^2.13.0" + }, + "engines": { + "node": ">= 16" + }, + "scripts": { + "artifacts": "napi artifacts", + "build": "napi build --platform napi --release", + "build:debug": "napi build --platform napi", + "version": "napi version", + "postinstall": "yarn build", + "clean": "rm -rf target/ && rm -rf napi/ && rm -rf node_modules/" + } +} diff --git a/keyserver/addons/opaque-ke-napi/src/lib.rs b/keyserver/addons/opaque-ke-napi/src/lib.rs new file mode 100644 --- /dev/null +++ b/keyserver/addons/opaque-ke-napi/src/lib.rs @@ -0,0 +1,9 @@ +#![deny(clippy::all)] + +#[macro_use] +extern crate napi_derive; + +#[napi] +pub fn sum(a: i32, b: i32) -> i32 { + a + b +} diff --git a/keyserver/loader.mjs b/keyserver/loader.mjs --- a/keyserver/loader.mjs +++ b/keyserver/loader.mjs @@ -1,16 +1,21 @@ // @flow -const localPackages = ['landing', 'lib', 'web']; +const localPackages = { + landing: 'landing', + lib: 'lib', + web: 'web', + ['opaque-ke-napi']: 'keyserver/addons/opaque-ke-napi', +}; async function resolve(specifier, context, nextResolve) { const defaultResult = await nextResolve(specifier, context); - // Special hack to use Babel-transpiled lib and web - if (localPackages.some(pkg => specifier.startsWith(`${pkg}/`))) { - const url = defaultResult.url.replace( - specifier, - `keyserver/dist/${specifier}`, - ); + for (const pkg in localPackages) { + if (specifier !== pkg && !specifier.startsWith(`${pkg}/`)) { + continue; + } + const path = localPackages[pkg]; + const url = defaultResult.url.replace(path, `keyserver/dist/${pkg}`); return { url }; } diff --git a/keyserver/package.json b/keyserver/package.json --- a/keyserver/package.json +++ b/keyserver/package.json @@ -8,7 +8,7 @@ "scripts": { "clean": "rm -rf dist/ && rm -rf node_modules/ && mkdir dist", "babel-build": ". bash/source-nvm.sh && yarn --silent babel src/ --out-dir dist/ --config-file ./babel.config.cjs --verbose --ignore 'src/landing/flow-typed','src/landing/node_modules','src/landing/package.json','src/lib/flow-typed','src/lib/node_modules','src/lib/package.json','src/web/flow-typed','src/web/node_modules','src/web/package.json','src/web/dist','src/web/webpack.config.js','src/web/account-bar.react.js','src/web/app.react.js','src/web/calendar','src/web/chat','src/web/flow','src/web/loading-indicator.react.js','src/web/modals','src/web/root.js','src/web/router-history.js','src/web/script.js','src/web/selectors/chat-selectors.js','src/web/selectors/entry-selectors.js','src/web/splash','src/web/vector-utils.js','src/web/vectors.react.js'", - "rsync": "rsync -rLpmuv --exclude '*/package.json' --exclude '*/node_modules/*' --include '*.json' --include '*.cjs' --exclude '*.*' src/ dist/", + "rsync": "rsync -rLpmuv --exclude '*/package.json' --exclude '*/node_modules/*' --include '*.json' --include '*.cjs' --include '*.node' --exclude '*.*' src/ dist/", "prod-build": "yarn babel-build && yarn rsync && yarn update-geoip", "update-geoip": "yarn script dist/scripts/update-geoip.js", "prod": "node --trace-warnings --experimental-json-modules --loader=./loader.mjs --experimental-specifier-resolution=node dist/keyserver", @@ -62,6 +62,7 @@ "mysql2": "^2.3.3", "node-schedule": "^2.1.0", "nodemailer": "^6.6.1", + "opaque-ke-napi": "0.0.1", "react": "17.0.2", "react-dom": "17.0.2", "react-html-email": "^3.0.0", diff --git a/keyserver/src/opaque-ke-napi b/keyserver/src/opaque-ke-napi new file mode 120000 --- /dev/null +++ b/keyserver/src/opaque-ke-napi @@ -0,0 +1 @@ +../addons/opaque-ke-napi \ No newline at end of file diff --git a/package.json b/package.json --- a/package.json +++ b/package.json @@ -8,10 +8,10 @@ "keyserver", "landing", "desktop", - "keyserver/addons/opaque-ke-node" + "keyserver/addons/opaque-ke-napi" ], "scripts": { - "clean": "yarn workspace lib clean && yarn workspace web clean && yarn workspace native clean && yarn workspace keyserver clean && yarn workspace landing clean && yarn workspace desktop clean && rm -rf node_modules/", + "clean": "yarn workspace lib clean && yarn workspace web clean && yarn workspace native clean && yarn workspace keyserver clean && yarn workspace landing clean && yarn workspace desktop clean && yarn workspace opaque-ke-napi clean && rm -rf node_modules/", "cleaninstall": "(killall flow || pkill flow || true) && yarn clean && yarn", "eslint": "eslint .", "eslint:fix": "eslint --fix .", diff --git a/yarn.lock b/yarn.lock --- a/yarn.lock +++ b/yarn.lock @@ -3106,6 +3106,11 @@ resolved "https://registry.yarnpkg.com/@metamask/safe-event-emitter/-/safe-event-emitter-2.0.0.tgz#af577b477c683fad17c619a78208cede06f9605c" integrity sha512-/kSXhY692qiV1MXu6EeOZvg5nECLclxNXcKCxJ3cXQgYuRymRHpdx/t7JXfsK+JLjwA1e1c1/SBrlQYpusC29Q== +"@napi-rs/cli@^2.13.0": + version "2.13.0" + resolved "https://registry.yarnpkg.com/@napi-rs/cli/-/cli-2.13.0.tgz#227f1b63edc6fb9364317e4719884b4451d147b6" + integrity sha512-8U6TLh2PYXM2SX7HnpRBCqlPU48M9tRe0TLlb4qgUx61bt6PT6Qtdeho3e0ila70fnrbqCA6dnJWrbgbJIopcQ== + "@nicolo-ribaudo/chokidar-2@2.1.8-no-fsevents": version "2.1.8-no-fsevents" resolved "https://registry.yarnpkg.com/@nicolo-ribaudo/chokidar-2/-/chokidar-2-2.1.8-no-fsevents.tgz#da7c3996b8e6e19ebd14d82eaced2313e7769f9b" @@ -6785,11 +6790,6 @@ dependencies: rsvp "^4.8.4" -cargo-cp-artifact@^0.1: - version "0.1.7" - resolved "https://registry.yarnpkg.com/cargo-cp-artifact/-/cargo-cp-artifact-0.1.7.tgz#1181b9d6e71f00f17c068c05e3cd1b0864783341" - integrity sha512-pxEV9p1on8vu3BOKstVisF9TwMyGKCBRvzaVpQHuU2sLULCKrn3MJWx/4XlNzmG6xNCTPf78DJ7WCGgr2mOzjg== - chainsaw@~0.1.0: version "0.1.0" resolved "https://registry.yarnpkg.com/chainsaw/-/chainsaw-0.1.0.tgz#5eab50b28afe58074d0d58291388828b5e5fbc98"