diff --git a/keyserver/Dockerfile b/keyserver/Dockerfile index e23668466..9d4305700 100644 --- a/keyserver/Dockerfile +++ b/keyserver/Dockerfile @@ -1,168 +1,168 @@ FROM node:16.18.0-bullseye #------------------------------------------------------------------------------- # STEP 0: SET UP USER # Set up Linux user and group for the container #------------------------------------------------------------------------------- # We use bind mounts for our backups folder, which means Docker on Linux will # blindly match the UID/GID for the backups folder on the container with the # host. In order to make sure the container is able to create backups with the # right UID/GID, we need to do two things: # 1. Make sure that the user that runs the Docker container on the host has # permissions to write to the backups folder on the host. We rely on the host # to configure this properly # 2. Make sure we're running this container with the same UID/GID that the host # is using, so the UID/GID show up correctly on both sides of the bind mount # To handle 2 correctly, we have the host pass the UID/GID with which they're # running the container. Our approach is based on this one: # https://github.com/mhart/alpine-node/issues/48#issuecomment-430902787 ARG HOST_UID ARG HOST_GID ARG COMM_ALCHEMY_KEY USER root RUN \ if [ -z "`getent group $HOST_GID`" ]; then \ addgroup --system --gid $HOST_GID comm; \ else \ groupmod --new-name comm `getent group $HOST_GID | cut -d: -f1`; \ fi && \ if [ -z "`getent passwd $HOST_UID`" ]; then \ adduser --system --uid $HOST_UID --ingroup comm --shell /bin/bash comm; \ else \ usermod --login comm --gid $HOST_GID --home /home/comm --move-home \ `getent passwd $HOST_UID | cut -d: -f1`; \ fi #------------------------------------------------------------------------------- # STEP 1: INSTALL PREREQS # Install prereqs first so we don't have to reinstall them if anything changes #------------------------------------------------------------------------------- # We need to add the MariaDB repo to apt in order to install mariadb-client RUN wget https://downloads.mariadb.com/MariaDB/mariadb_repo_setup \ && chmod +x mariadb_repo_setup \ && ./mariadb_repo_setup \ && rm mariadb_repo_setup # We need rsync in the prod-build yarn script # We need mariadb-client so we can use mysqldump for backups RUN apt-get update && DEBIAN_FRONTEND=noninteractive apt-get install -y \ rsync \ mariadb-client \ && rm -rf /var/lib/apt/lists/* #------------------------------------------------------------------------------- # STEP 2: DEVOLVE PRIVILEGES # Create another user to run the rest of the commands #------------------------------------------------------------------------------- USER comm WORKDIR /home/comm/app #------------------------------------------------------------------------------- # STEP 3: SET UP MYSQL BACKUPS # Prepare the system to properly handle mysqldump backups #------------------------------------------------------------------------------- # Prepare the directory that will hold the backups RUN mkdir /home/comm/backups #------------------------------------------------------------------------------- # STEP 4: SET UP CARGO (RUST PACKAGE MANAGER) # We use Cargo to build pre-compiled Node.js addons in Rust #------------------------------------------------------------------------------- # Install Rust and add Cargo's bin directory to the $PATH environment variable RUN curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh -s -- -y ENV PATH /home/comm/.cargo/bin:$PATH #------------------------------------------------------------------------------- # STEP 5: SET UP NVM # We use nvm to make sure we're running the right Node version #------------------------------------------------------------------------------- # First we install nvm ENV NVM_DIR /home/comm/.nvm RUN curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.39.1/install.sh \ | bash # Then we use nvm to install the right version of Node. We call this early so # Docker build caching saves us from re-downloading Node when any file changes COPY --chown=comm keyserver/.nvmrc keyserver/ COPY --chown=comm keyserver/bash/source-nvm.sh keyserver/bash/ RUN cd keyserver && . bash/source-nvm.sh #------------------------------------------------------------------------------- # STEP 6: YARN CLEANINSTALL # We run yarn cleaninstall before copying most of the files in for build caching #------------------------------------------------------------------------------- # Copy in package.json and yarn.lock files COPY --chown=comm package.json yarn.lock ./ COPY --chown=comm keyserver/package.json keyserver/.flowconfig keyserver/ COPY --chown=comm lib/package.json lib/.flowconfig lib/ COPY --chown=comm web/package.json web/.flowconfig web/ COPY --chown=comm native/package.json native/.flowconfig native/postinstall.sh native/ COPY --chown=comm landing/package.json landing/.flowconfig landing/ COPY --chown=comm desktop/package.json desktop/ -COPY --chown=comm keyserver/addons/opaque-ke-napi/package.json \ - keyserver/addons/opaque-ke-napi/ +COPY --chown=comm keyserver/addons/rust-node-addon/package.json \ + keyserver/addons/rust-node-addon/ COPY --chown=comm native/expo-modules/android-lifecycle/package.json \ native/expo-modules/android-lifecycle/ # Create empty Rust library and copy in Cargo.toml file -RUN cargo init keyserver/addons/opaque-ke-napi --lib -COPY --chown=comm keyserver/addons/opaque-ke-napi/Cargo.toml \ - keyserver/addons/opaque-ke-napi/ +RUN cargo init keyserver/addons/rust-node-addon --lib +COPY --chown=comm keyserver/addons/rust-node-addon/Cargo.toml \ + keyserver/addons/rust-node-addon/ # Copy in files needed for patch-package COPY --chown=comm patches patches/ # Actually run yarn RUN yarn cleaninstall #------------------------------------------------------------------------------- # STEP 7: WEBPACK BUILD # We do this first so Docker doesn't rebuild when only keyserver files change #------------------------------------------------------------------------------- COPY --chown=comm lib lib/ COPY --chown=comm landing landing/ RUN yarn workspace landing prod COPY --chown=comm web web/ RUN yarn workspace web prod #------------------------------------------------------------------------------- # STEP 8: COPY IN SOURCE FILES # We run this later so the above layers are cached if only source files change #------------------------------------------------------------------------------- COPY --chown=comm . . #------------------------------------------------------------------------------- # STEP 9: BUILD NODE ADDON -# Now that source files have been copied in, build the opaque-ke-napi addon +# Now that source files have been copied in, build rust-node-addon #------------------------------------------------------------------------------- -RUN yarn workspace opaque-ke-napi build +RUN yarn workspace rust-node-addon build #------------------------------------------------------------------------------- # STEP 10: RUN BUILD SCRIPTS # We need to populate keyserver/dist, among other things #------------------------------------------------------------------------------- # Babel transpilation of keyserver src RUN yarn workspace keyserver prod-build #------------------------------------------------------------------------------- # STEP 11: RUN THE SERVER # Actually run the Node.js keyserver using nvm #------------------------------------------------------------------------------- EXPOSE 3000 WORKDIR /home/comm/app/keyserver CMD bash/run-prod.sh diff --git a/keyserver/addons/opaque-ke-napi/.gitignore b/keyserver/addons/rust-node-addon/.gitignore similarity index 100% rename from keyserver/addons/opaque-ke-napi/.gitignore rename to keyserver/addons/rust-node-addon/.gitignore diff --git a/keyserver/addons/opaque-ke-napi/Cargo.toml b/keyserver/addons/rust-node-addon/Cargo.toml similarity index 94% rename from keyserver/addons/opaque-ke-napi/Cargo.toml rename to keyserver/addons/rust-node-addon/Cargo.toml index afa8e246b..ed8192965 100644 --- a/keyserver/addons/opaque-ke-napi/Cargo.toml +++ b/keyserver/addons/rust-node-addon/Cargo.toml @@ -1,19 +1,19 @@ [package] edition = "2021" -name = "opaque-ke-napi" +name = "rust-node-addon" 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/rust-node-addon/build.rs similarity index 100% rename from keyserver/addons/opaque-ke-napi/build.rs rename to keyserver/addons/rust-node-addon/build.rs diff --git a/keyserver/addons/opaque-ke-napi/index.js b/keyserver/addons/rust-node-addon/index.js similarity index 70% rename from keyserver/addons/opaque-ke-napi/index.js rename to keyserver/addons/rust-node-addon/index.js index e5e898a64..172ad002c 100644 --- a/keyserver/addons/opaque-ke-napi/index.js +++ b/keyserver/addons/rust-node-addon/index.js @@ -1,35 +1,35 @@ // @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'); + nativeBinding = await import('./napi/rust-node-addon.darwin-x64.node'); } else if (platform === 'darwin' && arch === 'arm64') { // $FlowFixMe - nativeBinding = await import('./napi/opaque-ke-napi.darwin-arm64.node'); + nativeBinding = await import('./napi/rust-node-addon.darwin-arm64.node'); } else if (platform === 'linux' && arch === 'x64') { // $FlowFixMe - nativeBinding = await import('./napi/opaque-ke-napi.linux-x64-gnu.node'); + nativeBinding = await import('./napi/rust-node-addon.linux-x64-gnu.node'); } else if (platform === 'linux' && arch === 'arm64') { // $FlowFixMe - nativeBinding = await import('./napi/opaque-ke-napi.linux-arm64-gnu.node'); + nativeBinding = await import('./napi/rust-node-addon.linux-arm64-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/rust-node-addon/package.json similarity index 93% rename from keyserver/addons/opaque-ke-napi/package.json rename to keyserver/addons/rust-node-addon/package.json index 6bb3d088e..691a8940f 100644 --- a/keyserver/addons/opaque-ke-napi/package.json +++ b/keyserver/addons/rust-node-addon/package.json @@ -1,39 +1,39 @@ { "workspaces": { "nohoist": [ "@napi-rs/cli" ] }, "private": true, - "name": "opaque-ke-napi", + "name": "rust-node-addon", "version": "0.0.1", "main": "index.js", "type": "module", "napi": { - "name": "opaque-ke-napi", + "name": "rust-node-addon", "triples": { "defaults": false, "additional": [ "x86_64-apple-darwin", "aarch64-apple-darwin", "x86_64-unknown-linux-gnu", "aarch64-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/rust-node-addon/src/lib.rs similarity index 100% rename from keyserver/addons/opaque-ke-napi/src/lib.rs rename to keyserver/addons/rust-node-addon/src/lib.rs diff --git a/keyserver/loader.mjs b/keyserver/loader.mjs index 31d328ad7..d76ddc1ed 100644 --- a/keyserver/loader.mjs +++ b/keyserver/loader.mjs @@ -1,25 +1,25 @@ // @flow const localPackages = { landing: 'landing', lib: 'lib', web: 'web', - ['opaque-ke-napi']: 'keyserver/addons/opaque-ke-napi', + ['rust-node-addon']: 'keyserver/addons/rust-node-addon', }; async function resolve(specifier, context, nextResolve) { const defaultResult = await nextResolve(specifier, context); 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 }; } return defaultResult; } export { resolve }; diff --git a/keyserver/package.json b/keyserver/package.json index 128693f45..48c98f77e 100644 --- a/keyserver/package.json +++ b/keyserver/package.json @@ -1,100 +1,100 @@ { "name": "keyserver", "version": "0.0.1", "type": "module", "private": true, "license": "BSD-3-Clause", "main": "dist/keyserver", "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' --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", "dev-rsync": "yarn --silent chokidar --initial --silent -s 'src/**/*.json' 'src/**/*.cjs' -c 'yarn rsync > /dev/null 2>&1'", "dev": ". bash/source-nvm.sh && yarn concurrently --names=\"BABEL,RSYNC,NODEM\" -c \"bgBlue.bold,bgMagenta.bold,bgGreen.bold\" \"yarn babel-build --source-maps --watch\" \"yarn dev-rsync\" \". bash/source-nvm.sh && NODE_ENV=development nodemon -e js,json,cjs --watch dist --experimental-json-modules --loader=./loader.mjs --experimental-specifier-resolution=node dist/keyserver\"", "script": ". bash/source-nvm.sh && NODE_ENV=development node --experimental-json-modules --loader=./loader.mjs --experimental-specifier-resolution=node", "test": "jest" }, "devDependencies": { "@babel/cli": "^7.13.14", "@babel/core": "^7.13.14", "@babel/node": "^7.13.13", "@babel/plugin-proposal-class-properties": "^7.13.0", "@babel/plugin-proposal-nullish-coalescing-operator": "^7.13.8", "@babel/plugin-proposal-object-rest-spread": "^7.13.8", "@babel/plugin-proposal-optional-chaining": "^7.13.12", "@babel/plugin-syntax-dynamic-import": "^7.8.3", "@babel/plugin-transform-runtime": "^7.13.10", "@babel/preset-env": "^7.13.12", "@babel/preset-flow": "^7.13.13", "@babel/preset-react": "^7.13.13", "babel-jest": "^26.6.3", "chokidar-cli": "^2.1.0", "concurrently": "^5.3.0", "flow-bin": "^0.182.0", "flow-typed": "^3.2.1", "jest": "^26.6.3", "nodemon": "^2.0.4" }, "dependencies": { "@babel/runtime": "^7.13.10", "@matrix-org/olm": "3.2.4", "@parse/node-apn": "^3.2.0", "@vingle/bmp-js": "^0.2.5", "JSONStream": "^1.3.5", "common-tags": "^1.7.2", "cookie-parser": "^1.4.3", "dateformat": "^3.0.3", "ethers": "^5.7.2", "express": "^4.17.3", "express-ws": "^4.0.0", "firebase-admin": "^10.1.0", "geoip-lite": "^1.4.5", "invariant": "^2.2.4", "landing": "0.0.1", "lib": "0.0.1", "lodash": "^4.17.21", "multer": "^1.4.1", "mysql2": "^2.3.3", "node-schedule": "^2.1.0", "nodemailer": "^6.6.1", - "opaque-ke-napi": "0.0.1", + "rust-node-addon": "0.0.1", "react": "18.1.0", "react-dom": "18.1.0", "react-html-email": "^3.0.0", "react-redux": "^7.1.1", "react-router": "^5.2.0", "redis": "^3.1.1", "redux": "^4.0.4", "replacestream": "^4.0.3", "rereadable-stream": "^1.4.5", "sharp": "^0.30.5", "siwe": "^1.1.6", "sql-template-strings": "^2.2.2", "stream-combiner": "^0.2.2", "tcomb": "^3.2.29", "twin-bcrypt": "^2.1.1", "uuid": "^3.3.3", "web": "0.0.1" }, "optionalDependencies": { "bufferutil": "^4.0.5", "utf-8-validate": "^5.0.7" }, "nodemonConfig": { "delay": "200" }, "jest": { "roots": [ "/src" ], "transform": { "\\.js$": "babel-jest" }, "transformIgnorePatterns": [ "/node_modules/(?!@babel/runtime)" ] } } diff --git a/keyserver/src/opaque-ke-napi b/keyserver/src/opaque-ke-napi deleted file mode 120000 index adc6954c8..000000000 --- a/keyserver/src/opaque-ke-napi +++ /dev/null @@ -1 +0,0 @@ -../addons/opaque-ke-napi \ No newline at end of file diff --git a/keyserver/src/rust-node-addon b/keyserver/src/rust-node-addon new file mode 120000 index 000000000..a25b80fa5 --- /dev/null +++ b/keyserver/src/rust-node-addon @@ -0,0 +1 @@ +../addons/rust-node-addon \ No newline at end of file diff --git a/package.json b/package.json index f87fd501a..63ab638b5 100644 --- a/package.json +++ b/package.json @@ -1,47 +1,47 @@ { "private": true, "license": "BSD-3-Clause", "workspaces": [ "lib", "web", "native", "keyserver", "landing", "desktop", - "keyserver/addons/opaque-ke-napi", + "keyserver/addons/rust-node-addon", "native/expo-modules/android-lifecycle" ], "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 && yarn workspace opaque-ke-napi 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 rust-node-addon clean && rm -rf node_modules/", "cleaninstall": "(killall flow || pkill flow || true) && yarn clean && yarn", "eslint": "eslint .", "eslint:fix": "eslint --fix .", "clang-format-all": "eval `node scripts/get_clang_paths_cli.js` | xargs clang-format -i", "rust-pre-commit": "./scripts/rust_pre_commit.sh", "terraform-pre-commit": "./scripts/terraform_pre_commit.sh", "prepare": "husky install", "arcpatch": "git pull --all --tags && arc patch" }, "devDependencies": { "babel-eslint": "^10.1.0", "clang-format": "^1.8.0", "core-js": "^3.6.5", "eslint": "^7.32.0", "eslint-config-prettier": "^8.1.0", "eslint-plugin-flowtype": "^5.4.0", "eslint-plugin-import": "^2.22.1", "eslint-plugin-jest": "^24.2.2", "eslint-plugin-monorepo": "^0.3.2", "eslint-plugin-prettier": "^3.3.1", "eslint-plugin-react": "^7.22.0", "eslint-plugin-react-hooks": "^4.2.0", "eslint-plugin-react-native": "^3.10.0", "gaxios": "^4.3.2", "husky": "^7.0.0", "lint-staged": "^12.1.4", "prettier": "^2.1.2" }, "resolutions": { "react-native-flipper": "https://registry.yarnpkg.com/@favware/skip-dependency/-/skip-dependency-1.0.2.tgz" } }