Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
39 changes: 32 additions & 7 deletions .github/workflows/test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,9 @@ on:
push:
branches:
- main
- feat-add-pro-backend-fns
pull_request:
branches:
- main
- feat-add-pro-backend-fns

concurrency:
group: ${{ github.workflow }}
Expand All @@ -33,9 +31,31 @@ jobs:
with:
submodules: "recursive"

- name: Setup ccache
uses: hendrikmuhs/ccache-action@5ebbd400eff9e74630f759d94ddd7b6c26299639 # v1.2
with:
key: ${{ matrix.os }}-ccache-libsession-util-nodejs-${{ github.head_ref || github.ref_name }}
# if the exact key is not found, fallback to one matching our cache_suffix
restore-keys: ${{ matrix.os }}-ccache-libsession-util-nodejs-

- name: Setup pnpm
uses: pnpm/action-setup@41ff72655975bd51cab0327fa583b6e92b6d3061 # v4

- name: Setup pnpm hoisted node-linker (Windows Only)
if: runner.os == 'Windows'
shell: bash
run: pnpm config set node-linker hoisted

- name: Setup node.js
uses: actions/setup-node@2028fbc5c25fe9cf00d9f06a71cc4710d4507903 # v6
with:
node-version-file: ".nvmrc"
cache: "pnpm"
cache-dependency-path: "pnpm-lock.yaml"

- name: Install correct clang versions
if: runner.os == 'Linux'
run: sudo apt update && sudo apt search clang && sudo apt install clang-format-19 #clang-tidy-19
run: sudo apt update && sudo apt search clang && sudo apt install clang-format-19
shell: bash

- name: Install node
Expand All @@ -53,13 +73,18 @@ jobs:

- name: build libsession-util-nodejs
shell: bash
run: yarn install --frozen-lockfile
run: pnpm install --frozen-lockfile
env:
CMAKE_C_COMPILER_LAUNCHER: ccache
CMAKE_CXX_COMPILER_LAUNCHER: ccache

- name: Check formatting
if: runner.os == 'Linux'
run: clang-format-19 --dry-run --Werror src/*.cpp include/*.hpp src/**/*.cpp include/**/*.hpp
shell: bash

# - name: Run clang-tidy
# run: clang-tidy-19 -p build src/*.cpp include/*.hpp src/**/*.cpp include/**/*.hpp
# shell: bash
- name: Ensure pnpm-lock.yaml has no duplicates
run: pnpm dedupe --check

- name: Validate formatting & linting changed no files
run: git diff --exit-code
3 changes: 0 additions & 3 deletions .yarnrc.yml

This file was deleted.

4 changes: 2 additions & 2 deletions BUILDING.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
# Building instructions

yarn install
pnpm install

For more advanced/customized builds, you may want to invoke `yarn cmake-js ...` directly.
For more advanced/customized builds, you may want to invoke `pnpm cmake-js ...` directly.
2 changes: 2 additions & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,8 @@ message(STATUS "Number of processors detected: ${N}")
add_definitions(-DNAPI_VERSION=8)
set(CMAKE_CONFIGURATION_TYPES Release)



project(libsession_util_nodejs LANGUAGES CXX)

SET(CMAKE_EXPORT_COMPILE_COMMANDS ON)
Expand Down
26 changes: 9 additions & 17 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,14 +2,6 @@

This library is the wrappers around libsession-util for NodeJS. It is built using the [node-addon-api](https://github.com/nodejs/node-addon-api) and [cmake-js](https://github.com/cmake-js/cmake-js). The build and dev instructions are quite custom, so check them out below.

### Issue with yarn

The yarn package manager (used on session-desktop) does understand what is a git url in a dependency as part of a package.json file, but won't do a full clone including submodules when forking such a repository. For more details, see https://github.com/yarnpkg/yarn/issues/1488

We tried using `cmake-js` and node's `preinstall scripts` to make this happen, but with the different platforms (linux, windows and macOS) having their own issues it turned out to be a nightmare.

Having lost enough time on this for now, I've decided to instead of relying of git submodules being fetched before the compilation can happen, I would generate a release tarball which includes the git modules and add that tarball dependency in the package.json of session-desktop.

### Dev instructions

Clone this project to somewhere **not** part of `session-desktop` node_modules:
Expand All @@ -20,22 +12,22 @@ git clone --recursive git@github.com:session-foundation/libsession-util-nodejs.g
```

Always do your changes in `[FOLDER_NOT_IN_SESSION_DESKTOP]/libsession-util-nodejs`, never in the one under session-desktop's `node_modules` as you might override your local changes.
Then, you can quickly compile a non-electron build by first running `yarn naughty-patch` and then `yarn install` from that folder. You should only have to run `yarn naughty-patch` manually once when you first setup the project. This is a quick incremental build which can check for C++ compilation errors.
Then, you can quickly compile a non-electron build by first running `pnpm install` from that folder. This is a quick incremental build which can check for C++ compilation errors.
Once your changes are ready to be tested in the `session-desktop` you can compile an electron build using this command:

```
cd [SESSION_DESKTOP_PATH]; rm -rf node_modules/libsession_util_nodejs; cp -R [THIS_PROJECT_PATH] node_modules/libsession_util_nodejs; cd node_modules/libsession_util_nodejs && rm -rf build && yarn install && cd [SESSION_DESKTOP_PATH] && yarn build:workers
cd [SESSION_DESKTOP_PATH]; rm -rf node_modules/libsession_util_nodejs; cp -R [THIS_PROJECT_PATH] node_modules/libsession_util_nodejs; cd node_modules/libsession_util_nodejs && rm -rf build && pnpm install && cd [SESSION_DESKTOP_PATH] && pnpm build:workers
```

Replace `[SESSION_DESKTOP_PATH]` with the full path to your `session-desktop` folder, replace `[THIS_PROJECT_PATH]` with the path to the root of this project folder.

Every part of this command is needed and might need to be updated using your paths. Also, the `worker:libsession` needs to be recompiled too to include the just created .node file in itself. This is done by the `yarn build:workers` command.
Every part of this command is needed and might need to be updated using your paths. Also, the `worker:libsession` needs to be recompiled too to include the just created .node file in itself. This is done by the `pnpm build:workers` command.

Note: The `electron` property in the `config` object will need to be updated in the `package.json` every time we update `electron` package in [session-desktop](https://github.com/session-foundation/session-desktop/) so that the versions match. It is a node version, but not part of the official node docs. If you compiled the node module for an incorrect electron/node version you will get an error on `session-desktop` start.

### Making a Release and updating Session-desktop

1. First, make sure all your changes are commited and pushed to the `libsession-util-nodejs` project from your `[FOLDER_NOT_IN_SESSION_DESKTOP]` folder.
1. First, make sure all your changes are committed and pushed to the `libsession-util-nodejs` project from your `[FOLDER_NOT_IN_SESSION_DESKTOP]` folder.

2. Then make sure the `libsession-util` is using the latest `dev` branch (unless there is a reason not to).

Expand All @@ -54,22 +46,22 @@ git commit
git push upstream main
# Make sure you do the steps above, otherwise the tag won't be on the right commit with the `gh release create`

yarn prepare_release
pnpm prepare_release
```

And then upload the generated `libsession_util_nodejs-v$PACKAGE_VERSION.tar.gz` to that release just created on github.
The git-archive-all relies on the `.gitattributes` to know what to include or exclude.

Once this is done, update the dependency on `session-desktop`.
Make sure to remove the existing one first (with the include `yarn remove` below) as you might have messed up your `node_modules` doing the dev instructions.
Make sure to remove the existing one first (with the include `pnpm remove` below) as you might have messed up your `node_modules` doing the dev instructions.

```
yarn remove libsession_util_nodejs && yarn add https://github.com/session-foundation/libsession-util-nodejs/releases/download/v0.1.15/libsession_util_nodejs-v0.1.15.tar.gz
pnpm remove libsession_util_nodejs && pnpm add https://github.com/session-foundation/libsession-util-nodejs/releases/download/v0.1.15/libsession_util_nodejs-v0.1.15.tar.gz
```

Keep in mind that you need to update the two version numbers (e.g. `0.1.15`) to the just created release version of this project.

The cmake-js script will be run on the yarn add and should recompile your latest release of the `libsession-util-nodejs` as part of the build process and as part of the github actions on `session-desktop`.
You most likely need to recompile the workers to include those new changes: `yarn worker:utils && yarn worker:libsession`.
The cmake-js script will be run on the pnpm add and should recompile your latest release of the `libsession-util-nodejs` as part of the build process and as part of the github actions on `session-desktop`.
You most likely need to recompile the workers to include those new changes: `pnpm worker:utils && pnpm worker:libsession`.

You should have your changes in the next release!
27 changes: 0 additions & 27 deletions include/blinding/blinding.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -36,10 +36,6 @@ class BlindingWrapper : public Napi::ObjectWrap<BlindingWrapper> {
"blindVersionSignRequest",
static_cast<napi_property_attributes>(
napi_writable | napi_configurable)),
StaticMethod<&BlindingWrapper::blindVersionSign>(
"blindVersionSign",
static_cast<napi_property_attributes>(
napi_writable | napi_configurable)),
});
}

Expand Down Expand Up @@ -105,28 +101,5 @@ class BlindingWrapper : public Napi::ObjectWrap<BlindingWrapper> {
ed25519_secret_key, sig_timestamp, sig_method, sig_path, sig_body);
});
};

static Napi::Value blindVersionSign(const Napi::CallbackInfo& info) {
return wrapResult(info, [&] {
assertInfoLength(info, 1);
assertIsObject(info[0]);
auto obj = info[0].As<Napi::Object>();

if (obj.IsEmpty())
throw std::invalid_argument("blindVersionSign received empty");

assertIsUInt8Array(obj.Get("ed25519SecretKey"), "BlindingWrapper::blindVersionSign");
auto ed25519_secret_key =
toCppBuffer(obj.Get("ed25519SecretKey"), "blindVersionSign.ed25519SecretKey");

assertIsNumber(obj.Get("sigTimestampSeconds"), "BlindingWrapper::blindVersionSign");
auto sig_timestamp = toCppInteger(
obj.Get("sigTimestampSeconds"), "blindVersionSign.sigTimestampSeconds", false);

return session::blind_version_sign(
ed25519_secret_key, Platform::desktop, sig_timestamp);
});
};
};

} // namespace session::nodeapi
72 changes: 72 additions & 0 deletions include/pro/pro.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
#include <oxenc/base64.h>
#include <oxenc/hex.h>

#include <cstddef>
#include <vector>

#include "meta/meta_base_wrapper.hpp"
Expand Down Expand Up @@ -93,6 +94,14 @@ class ProWrapper : public Napi::ObjectWrap<ProWrapper> {
"ProWrapperNode",
{
// Pro features
StaticMethod<&ProWrapper::utf16CountTruncatedToCodepoints>(
"utf16CountTruncatedToCodepoints",
static_cast<napi_property_attributes>(
napi_writable | napi_configurable)),
StaticMethod<&ProWrapper::utf16Count>(
"utf16Count",
static_cast<napi_property_attributes>(
napi_writable | napi_configurable)),
StaticMethod<&ProWrapper::proFeaturesForMessage>(
"proFeaturesForMessage",
static_cast<napi_property_attributes>(
Expand Down Expand Up @@ -150,6 +159,69 @@ class ProWrapper : public Napi::ObjectWrap<ProWrapper> {
});
};

static Napi::Value utf16Count(const Napi::CallbackInfo& info) {
return wrapResult(info, [&] {
// we expect one argument that matches:
// first: {
// "utf16": string,
// }
// we return an object with a single property {`codepointCount: number`}

assertInfoLength(info, 1);
assertIsObject(info[0]);
auto env = info.Env();

auto first = info[0].As<Napi::Object>();

if (first.IsEmpty())
throw std::invalid_argument("utf16Count first received empty");

auto lossless = true;

assertIsString(first.Get("utf16"), "utf16Count.utf16");
std::u16string utf16 = first.Get("utf16").As<Napi::String>().Utf16Value();
size_t codepoint_count = session::utf16_count(utf16);

auto obj = Napi::Object::New(env);
obj["codepointCount"] = toJs(env, codepoint_count);

return obj;
});
};

static Napi::Value utf16CountTruncatedToCodepoints(const Napi::CallbackInfo& info) {
return wrapResult(info, [&] {
// we expect one argument that matches:
// first: {
// "utf16": string,
// "codepointLen": number,
// }
// we return an object with a single property {`truncateAt: number`}

assertInfoLength(info, 1);
assertIsObject(info[0]);
auto env = info.Env();

auto first = info[0].As<Napi::Object>();

if (first.IsEmpty())
throw std::invalid_argument("utf16CountTruncatedToCodepoints first received empty");

assertIsString(first.Get("utf16"), "utf16CountTruncatedToCodepoints.utf16");
std::u16string utf16 = first.Get("utf16").As<Napi::String>().Utf16Value();
assertIsNumber(
first.Get("codepointLen"), "utf16CountTruncatedToCodepoints.codepointLen");
size_t codepointLen = first.Get("codepointLen").As<Napi::Number>().Uint32Value();

size_t truncate_at = session::utf16_count_truncated_to_codepoints(utf16, codepointLen);

auto obj = Napi::Object::New(env);
obj["truncateAt"] = toJs(env, truncate_at);

return obj;
});
};

static Napi::Value proProofRequestBody(const Napi::CallbackInfo& info) {
return wrapResult(info, [&] {
// we expect arguments that match:
Expand Down
8 changes: 4 additions & 4 deletions package.json
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
{
"main": "index.js",
"name": "libsession_util_nodejs",
"packageManager": "pnpm@10.28.1",
"description": "Wrappers for the Session Util Library",
"version": "0.6.9",
"version": "0.6.10",
"license": "GPL-3.0",
"author": {
"name": "Oxen Project",
Expand All @@ -14,7 +15,7 @@
"lint": "find src include -name '*.cpp' -o -name '*.hpp' | xargs clang-format-19 -i",
"install": "cmake-js build --runtime=electron --runtime-version=40.0.0 --CDSUBMODULE_CHECK=OFF --CDLOCAL_MIRROR=https://oxen.rocks/deps --CDENABLE_ONIONREQ=OFF --CDWITH_TESTS=OFF",
"prepare_release": "sh prepare_release.sh",
"dedup": "npx --yes yarn-deduplicate yarn.lock"
"dedup": "pnpm dedupe --check"
},
"devDependencies": {
"clang-format": "^1.8.0",
Expand All @@ -24,6 +25,5 @@
"cmake-js": "7.3.1",
"node-addon-api": "^8.3.1"
},
"typings": "index.d.ts",
"packageManager": "yarn@1.22.19"
"typings": "index.d.ts"
}
Loading
Loading