mirror of
https://github.com/standardnotes/server
synced 2026-02-02 08:01:14 -05:00
Compare commits
21 Commits
@standardn
...
@standardn
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
671f7a7074 | ||
|
|
55fd873b37 | ||
|
|
32c667b22d | ||
|
|
a6b062f638 | ||
|
|
f9183b4c62 | ||
|
|
c7d575a0ff | ||
|
|
a575e62519 | ||
|
|
3761d60f41 | ||
|
|
fd629d43ba | ||
|
|
76b1cb0f5a | ||
|
|
2f94abc9f7 | ||
|
|
c70040fe5d | ||
|
|
4b8a9e448a | ||
|
|
1e4c7d0f31 | ||
|
|
ec75795a02 | ||
|
|
ad26b64b28 | ||
|
|
9e4715ebbd | ||
|
|
cc612296d0 | ||
|
|
1148b3948c | ||
|
|
c7e605fd60 | ||
|
|
4ab32c670e |
11
.github/workflows/common-e2e.yml
vendored
11
.github/workflows/common-e2e.yml
vendored
@@ -50,7 +50,7 @@ jobs:
|
||||
run: yarn dlx mocha-headless-chrome --timeout 1200000 -f http://localhost:9001/mocha/test.html
|
||||
|
||||
e2e-home-server:
|
||||
name: (WIP - Home Server) E2E Test Suite
|
||||
name: (Home Server) E2E Test Suite
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
services:
|
||||
@@ -83,6 +83,10 @@ jobs:
|
||||
sed -i "s/AUTH_JWT_SECRET=/AUTH_JWT_SECRET=$(openssl rand -hex 32)/g" packages/home-server/.env
|
||||
sed -i "s/ENCRYPTION_SERVER_KEY=/ENCRYPTION_SERVER_KEY=$(openssl rand -hex 32)/g" packages/home-server/.env
|
||||
sed -i "s/PSEUDO_KEY_PARAMS_KEY=/PSEUDO_KEY_PARAMS_KEY=$(openssl rand -hex 32)/g" packages/home-server/.env
|
||||
sed -i "s/VALET_TOKEN_SECRET=/VALET_TOKEN_SECRET=$(openssl rand -hex 32)/g" packages/home-server/.env
|
||||
echo "ACCESS_TOKEN_AGE=4" >> packages/home-server/.env
|
||||
echo "REFRESH_TOKEN_AGE=7" >> packages/home-server/.env
|
||||
echo "REVISIONS_FREQUENCY=5" >> packages/home-server/.env
|
||||
|
||||
- name: Run Server
|
||||
run: nohup yarn workspace @standardnotes/home-server start &
|
||||
@@ -90,8 +94,7 @@ jobs:
|
||||
PORT: 3123
|
||||
|
||||
- name: Wait for server to start
|
||||
run: docker/is-available.sh http://localhost:3123 $(pwd)/logs
|
||||
run: for i in {1..30}; do curl -s http://localhost:3123/healthcheck && break || sleep 1; done
|
||||
|
||||
- name: Run E2E Test Suite
|
||||
continue-on-error: true
|
||||
run: yarn dlx mocha-headless-chrome --timeout 1200000 -f http://localhost:9001/mocha/test.html
|
||||
run: yarn dlx mocha-headless-chrome --timeout 1200000 -f http://localhost:9001/mocha/test.html?skip_paid_features=true
|
||||
|
||||
71
.pnp.cjs
generated
71
.pnp.cjs
generated
@@ -129,13 +129,13 @@ const RAW_RUNTIME_STATE =
|
||||
["@lerna-lite/version", "npm:2.3.0"],\
|
||||
["@types/jest", "npm:29.5.1"],\
|
||||
["@types/newrelic", "npm:9.13.0"],\
|
||||
["@types/node", "npm:20.1.0"],\
|
||||
["@types/node", "npm:20.2.5"],\
|
||||
["eslint", "npm:8.39.0"],\
|
||||
["eslint-config-prettier", "virtual:8859b278716fedf3e7458b5628625f7e35678c418626878559a0b816445001b7e24c55546f4677ba4c20b521aa0cf52cc33ac07deff171e383ada6eeab69933f#npm:8.8.0"],\
|
||||
["ini", "npm:3.0.1"],\
|
||||
["newrelic", "npm:10.1.0"],\
|
||||
["npm-check-updates", "npm:16.10.9"],\
|
||||
["ts-node", "virtual:ef6136dc31186c42f92851afb237eadaa9d36085920cabb6ed6ea317680c8271d6b94afcb795fd7e58c08243e470be87ece6bb707daf3ecb0604f7fd8c1aa682#npm:10.9.1"],\
|
||||
["ts-node", "virtual:8859b278716fedf3e7458b5628625f7e35678c418626878559a0b816445001b7e24c55546f4677ba4c20b521aa0cf52cc33ac07deff171e383ada6eeab69933f#npm:10.9.1"],\
|
||||
["typescript", "patch:typescript@npm%3A5.0.4#optional!builtin<compat/typescript>::version=5.0.4&hash=b5f058"]\
|
||||
],\
|
||||
"linkType": "SOFT"\
|
||||
@@ -4259,7 +4259,7 @@ const RAW_RUNTIME_STATE =
|
||||
["@types/jest", "npm:29.5.1"],\
|
||||
["@types/mixpanel", "npm:2.14.4"],\
|
||||
["@types/newrelic", "npm:9.13.0"],\
|
||||
["@types/node", "npm:20.1.0"],\
|
||||
["@types/node", "npm:20.2.5"],\
|
||||
["@typescript-eslint/eslint-plugin", "virtual:fd909b174d079e30b336c4ce72c38a88c1e447767b1a8dd7655e07719a1e31b97807f0931368724fc78897ff15e6a6d00b83316c0f76d11f85111f342e08bb79#npm:5.59.2"],\
|
||||
["@typescript-eslint/parser", "virtual:fd909b174d079e30b336c4ce72c38a88c1e447767b1a8dd7655e07719a1e31b97807f0931368724fc78897ff15e6a6d00b83316c0f76d11f85111f342e08bb79#npm:5.59.2"],\
|
||||
["dayjs", "npm:1.11.7"],\
|
||||
@@ -4419,7 +4419,7 @@ const RAW_RUNTIME_STATE =
|
||||
"packageDependencies": [\
|
||||
["@standardnotes/common", "workspace:packages/common"],\
|
||||
["@types/jest", "npm:29.5.1"],\
|
||||
["@types/node", "npm:20.1.0"],\
|
||||
["@types/node", "npm:20.2.5"],\
|
||||
["@typescript-eslint/eslint-plugin", "virtual:fd909b174d079e30b336c4ce72c38a88c1e447767b1a8dd7655e07719a1e31b97807f0931368724fc78897ff15e6a6d00b83316c0f76d11f85111f342e08bb79#npm:5.59.2"],\
|
||||
["@typescript-eslint/parser", "virtual:fd909b174d079e30b336c4ce72c38a88c1e447767b1a8dd7655e07719a1e31b97807f0931368724fc78897ff15e6a6d00b83316c0f76d11f85111f342e08bb79#npm:5.59.2"],\
|
||||
["eslint", "npm:8.39.0"],\
|
||||
@@ -4626,6 +4626,8 @@ const RAW_RUNTIME_STATE =
|
||||
["@standardnotes/auth-server", "workspace:packages/auth"],\
|
||||
["@standardnotes/domain-core", "workspace:packages/domain-core"],\
|
||||
["@standardnotes/domain-events-infra", "workspace:packages/domain-events-infra"],\
|
||||
["@standardnotes/files-server", "workspace:packages/files"],\
|
||||
["@standardnotes/revisions-server", "workspace:packages/revisions"],\
|
||||
["@standardnotes/syncing-server", "workspace:packages/syncing-server"],\
|
||||
["@types/cors", "npm:2.8.13"],\
|
||||
["@types/express", "npm:4.17.17"],\
|
||||
@@ -4733,7 +4735,7 @@ const RAW_RUNTIME_STATE =
|
||||
["reflect-metadata", "npm:0.1.13"],\
|
||||
["sqlite3", "virtual:31b5a94a105c89c9294c3d524a7f8929fe63ee5a2efadf21951ca4c0cfd2ecf02e8f4ef5a066bbda091f1e3a56e57c6749069a080618c96b22e51131a330fc4a#npm:5.1.6"],\
|
||||
["ts-jest", "virtual:fd909b174d079e30b336c4ce72c38a88c1e447767b1a8dd7655e07719a1e31b97807f0931368724fc78897ff15e6a6d00b83316c0f76d11f85111f342e08bb79#npm:29.1.0"],\
|
||||
["typeorm", "virtual:67ad3a1ca34e24ce4821cc48979e98af0c3e5dd7aabc7ad0b5d22d1d977d6f943f81c9f141a420105ebdc61ef777e508a96c7946081decd98f8c30543d468b33#npm:0.3.15"],\
|
||||
["typeorm", "virtual:365b8c88cdf194291829ee28b79556e2328175d26a621363e703848100bea0042e9500db2a1206c9bbc3a4a76a1d169639ef774b2ea3a1a98584a9936b58c6be#npm:0.3.15"],\
|
||||
["typescript", "patch:typescript@npm%3A5.0.4#optional!builtin<compat/typescript>::version=5.0.4&hash=b5f058"],\
|
||||
["winston", "npm:3.8.2"]\
|
||||
],\
|
||||
@@ -4756,7 +4758,7 @@ const RAW_RUNTIME_STATE =
|
||||
["@types/ioredis", "npm:5.0.0"],\
|
||||
["@types/jest", "npm:29.5.1"],\
|
||||
["@types/newrelic", "npm:9.13.0"],\
|
||||
["@types/node", "npm:20.1.0"],\
|
||||
["@types/node", "npm:20.2.5"],\
|
||||
["@typescript-eslint/eslint-plugin", "virtual:fd909b174d079e30b336c4ce72c38a88c1e447767b1a8dd7655e07719a1e31b97807f0931368724fc78897ff15e6a6d00b83316c0f76d11f85111f342e08bb79#npm:5.59.2"],\
|
||||
["@typescript-eslint/parser", "virtual:fd909b174d079e30b336c4ce72c38a88c1e447767b1a8dd7655e07719a1e31b97807f0931368724fc78897ff15e6a6d00b83316c0f76d11f85111f342e08bb79#npm:5.59.2"],\
|
||||
["dayjs", "npm:1.11.7"],\
|
||||
@@ -4813,13 +4815,13 @@ const RAW_RUNTIME_STATE =
|
||||
["@lerna-lite/version", "npm:2.3.0"],\
|
||||
["@types/jest", "npm:29.5.1"],\
|
||||
["@types/newrelic", "npm:9.13.0"],\
|
||||
["@types/node", "npm:20.1.0"],\
|
||||
["@types/node", "npm:20.2.5"],\
|
||||
["eslint", "npm:8.39.0"],\
|
||||
["eslint-config-prettier", "virtual:8859b278716fedf3e7458b5628625f7e35678c418626878559a0b816445001b7e24c55546f4677ba4c20b521aa0cf52cc33ac07deff171e383ada6eeab69933f#npm:8.8.0"],\
|
||||
["ini", "npm:3.0.1"],\
|
||||
["newrelic", "npm:10.1.0"],\
|
||||
["npm-check-updates", "npm:16.10.9"],\
|
||||
["ts-node", "virtual:ef6136dc31186c42f92851afb237eadaa9d36085920cabb6ed6ea317680c8271d6b94afcb795fd7e58c08243e470be87ece6bb707daf3ecb0604f7fd8c1aa682#npm:10.9.1"],\
|
||||
["ts-node", "virtual:8859b278716fedf3e7458b5628625f7e35678c418626878559a0b816445001b7e24c55546f4677ba4c20b521aa0cf52cc33ac07deff171e383ada6eeab69933f#npm:10.9.1"],\
|
||||
["typescript", "patch:typescript@npm%3A5.0.4#optional!builtin<compat/typescript>::version=5.0.4&hash=b5f058"]\
|
||||
],\
|
||||
"linkType": "SOFT"\
|
||||
@@ -4859,7 +4861,7 @@ const RAW_RUNTIME_STATE =
|
||||
["@standardnotes/sncrypto-node", "workspace:packages/sncrypto-node"],\
|
||||
["@standardnotes/sncrypto-common", "npm:1.13.3"],\
|
||||
["@types/jest", "npm:29.5.1"],\
|
||||
["@types/node", "npm:20.1.0"],\
|
||||
["@types/node", "npm:20.2.5"],\
|
||||
["@typescript-eslint/eslint-plugin", "virtual:fd909b174d079e30b336c4ce72c38a88c1e447767b1a8dd7655e07719a1e31b97807f0931368724fc78897ff15e6a6d00b83316c0f76d11f85111f342e08bb79#npm:5.59.2"],\
|
||||
["@typescript-eslint/parser", "virtual:fd909b174d079e30b336c4ce72c38a88c1e447767b1a8dd7655e07719a1e31b97807f0931368724fc78897ff15e6a6d00b83316c0f76d11f85111f342e08bb79#npm:5.59.2"],\
|
||||
["eslint", "npm:8.39.0"],\
|
||||
@@ -4925,7 +4927,7 @@ const RAW_RUNTIME_STATE =
|
||||
["reflect-metadata", "npm:0.1.13"],\
|
||||
["sqlite3", "virtual:31b5a94a105c89c9294c3d524a7f8929fe63ee5a2efadf21951ca4c0cfd2ecf02e8f4ef5a066bbda091f1e3a56e57c6749069a080618c96b22e51131a330fc4a#npm:5.1.6"],\
|
||||
["ts-jest", "virtual:fd909b174d079e30b336c4ce72c38a88c1e447767b1a8dd7655e07719a1e31b97807f0931368724fc78897ff15e6a6d00b83316c0f76d11f85111f342e08bb79#npm:29.1.0"],\
|
||||
["typeorm", "virtual:67ad3a1ca34e24ce4821cc48979e98af0c3e5dd7aabc7ad0b5d22d1d977d6f943f81c9f141a420105ebdc61ef777e508a96c7946081decd98f8c30543d468b33#npm:0.3.15"],\
|
||||
["typeorm", "virtual:365b8c88cdf194291829ee28b79556e2328175d26a621363e703848100bea0042e9500db2a1206c9bbc3a4a76a1d169639ef774b2ea3a1a98584a9936b58c6be#npm:0.3.15"],\
|
||||
["typescript", "patch:typescript@npm%3A5.0.4#optional!builtin<compat/typescript>::version=5.0.4&hash=b5f058"],\
|
||||
["ua-parser-js", "npm:1.0.35"],\
|
||||
["uuid", "npm:9.0.0"],\
|
||||
@@ -5460,6 +5462,13 @@ const RAW_RUNTIME_STATE =
|
||||
["@types/node", "npm:20.1.0"]\
|
||||
],\
|
||||
"linkType": "HARD"\
|
||||
}],\
|
||||
["npm:20.2.5", {\
|
||||
"packageLocation": "./.yarn/cache/@types-node-npm-20.2.5-0014d2d9ce-55e4f8d08e.zip/node_modules/@types/node/",\
|
||||
"packageDependencies": [\
|
||||
["@types/node", "npm:20.2.5"]\
|
||||
],\
|
||||
"linkType": "HARD"\
|
||||
}]\
|
||||
]],\
|
||||
["@types/nodemailer", [\
|
||||
@@ -14866,6 +14875,42 @@ const RAW_RUNTIME_STATE =
|
||||
],\
|
||||
"linkType": "SOFT"\
|
||||
}],\
|
||||
["virtual:8859b278716fedf3e7458b5628625f7e35678c418626878559a0b816445001b7e24c55546f4677ba4c20b521aa0cf52cc33ac07deff171e383ada6eeab69933f#npm:10.9.1", {\
|
||||
"packageLocation": "./.yarn/__virtual__/ts-node-virtual-ac01688ebc/0/cache/ts-node-npm-10.9.1-6c268be7f4-c4caff4b9b.zip/node_modules/ts-node/",\
|
||||
"packageDependencies": [\
|
||||
["ts-node", "virtual:8859b278716fedf3e7458b5628625f7e35678c418626878559a0b816445001b7e24c55546f4677ba4c20b521aa0cf52cc33ac07deff171e383ada6eeab69933f#npm:10.9.1"],\
|
||||
["@cspotcode/source-map-support", "npm:0.8.1"],\
|
||||
["@swc/core", null],\
|
||||
["@swc/wasm", null],\
|
||||
["@tsconfig/node10", "npm:1.0.9"],\
|
||||
["@tsconfig/node12", "npm:1.0.11"],\
|
||||
["@tsconfig/node14", "npm:1.0.3"],\
|
||||
["@tsconfig/node16", "npm:1.0.3"],\
|
||||
["@types/node", "npm:20.2.5"],\
|
||||
["@types/swc__core", null],\
|
||||
["@types/swc__wasm", null],\
|
||||
["@types/typescript", null],\
|
||||
["acorn", "npm:8.8.2"],\
|
||||
["acorn-walk", "npm:8.2.0"],\
|
||||
["arg", "npm:4.1.3"],\
|
||||
["create-require", "npm:1.1.1"],\
|
||||
["diff", "npm:4.0.2"],\
|
||||
["make-error", "npm:1.3.6"],\
|
||||
["typescript", "patch:typescript@npm%3A5.0.4#optional!builtin<compat/typescript>::version=5.0.4&hash=b5f058"],\
|
||||
["v8-compile-cache-lib", "npm:3.0.1"],\
|
||||
["yn", "npm:3.1.1"]\
|
||||
],\
|
||||
"packagePeers": [\
|
||||
"@swc/core",\
|
||||
"@swc/wasm",\
|
||||
"@types/node",\
|
||||
"@types/swc__core",\
|
||||
"@types/swc__wasm",\
|
||||
"@types/typescript",\
|
||||
"typescript"\
|
||||
],\
|
||||
"linkType": "HARD"\
|
||||
}],\
|
||||
["virtual:ef6136dc31186c42f92851afb237eadaa9d36085920cabb6ed6ea317680c8271d6b94afcb795fd7e58c08243e470be87ece6bb707daf3ecb0604f7fd8c1aa682#npm:10.9.1", {\
|
||||
"packageLocation": "./.yarn/__virtual__/ts-node-virtual-4c9d9a7987/0/cache/ts-node-npm-10.9.1-6c268be7f4-c4caff4b9b.zip/node_modules/ts-node/",\
|
||||
"packageDependencies": [\
|
||||
@@ -15166,10 +15211,10 @@ const RAW_RUNTIME_STATE =
|
||||
],\
|
||||
"linkType": "HARD"\
|
||||
}],\
|
||||
["virtual:67ad3a1ca34e24ce4821cc48979e98af0c3e5dd7aabc7ad0b5d22d1d977d6f943f81c9f141a420105ebdc61ef777e508a96c7946081decd98f8c30543d468b33#npm:0.3.15", {\
|
||||
"packageLocation": "./.yarn/__virtual__/typeorm-virtual-91f15b21d5/0/cache/typeorm-npm-0.3.15-20a6c4f754-db890f14cb.zip/node_modules/typeorm/",\
|
||||
["virtual:365b8c88cdf194291829ee28b79556e2328175d26a621363e703848100bea0042e9500db2a1206c9bbc3a4a76a1d169639ef774b2ea3a1a98584a9936b58c6be#npm:0.3.15", {\
|
||||
"packageLocation": "./.yarn/__virtual__/typeorm-virtual-7fe891193c/0/cache/typeorm-npm-0.3.15-20a6c4f754-db890f14cb.zip/node_modules/typeorm/",\
|
||||
"packageDependencies": [\
|
||||
["typeorm", "virtual:67ad3a1ca34e24ce4821cc48979e98af0c3e5dd7aabc7ad0b5d22d1d977d6f943f81c9f141a420105ebdc61ef777e508a96c7946081decd98f8c30543d468b33#npm:0.3.15"],\
|
||||
["typeorm", "virtual:365b8c88cdf194291829ee28b79556e2328175d26a621363e703848100bea0042e9500db2a1206c9bbc3a4a76a1d169639ef774b2ea3a1a98584a9936b58c6be#npm:0.3.15"],\
|
||||
["@google-cloud/spanner", null],\
|
||||
["@sap/hana-client", null],\
|
||||
["@sqltools/formatter", "npm:1.2.5"],\
|
||||
|
||||
BIN
.yarn/cache/@types-node-npm-20.2.5-0014d2d9ce-55e4f8d08e.zip
vendored
Normal file
BIN
.yarn/cache/@types-node-npm-20.2.5-0014d2d9ce-55e4f8d08e.zip
vendored
Normal file
Binary file not shown.
@@ -331,8 +331,8 @@ ifeq ($(strip $(foreach prefix,$(NO_LOAD),\
|
||||
endif
|
||||
|
||||
quiet_cmd_regen_makefile = ACTION Regenerating $@
|
||||
cmd_regen_makefile = cd $(srcdir); /Users/karolsojko/workspace/server/.yarn/unplugged/node-gyp-npm-9.3.1-43540bab9c/node_modules/node-gyp/gyp/gyp_main.py -fmake --ignore-environment "-Dlibrary=shared_library" "-Dvisibility=default" "-Dnode_root_dir=/Users/karolsojko/Library/Caches/node-gyp/20.1.0" "-Dnode_gyp_dir=/Users/karolsojko/workspace/server/.yarn/unplugged/node-gyp-npm-9.3.1-43540bab9c/node_modules/node-gyp" "-Dnode_lib_file=/Users/karolsojko/Library/Caches/node-gyp/20.1.0/<(target_arch)/node.lib" "-Dmodule_root_dir=/Users/karolsojko/workspace/server/.yarn/unplugged/@newrelic-native-metrics-npm-9.0.0-590d2e713a/node_modules/@newrelic/native-metrics" "-Dnode_engine=v8" "--depth=." "-Goutput_dir=." "--generator-output=build" -I/Users/karolsojko/workspace/server/.yarn/unplugged/@newrelic-native-metrics-npm-9.0.0-590d2e713a/node_modules/@newrelic/native-metrics/build/config.gypi -I/Users/karolsojko/workspace/server/.yarn/unplugged/node-gyp-npm-9.3.1-43540bab9c/node_modules/node-gyp/addon.gypi -I/Users/karolsojko/Library/Caches/node-gyp/20.1.0/include/node/common.gypi "--toplevel-dir=." binding.gyp
|
||||
Makefile: $(srcdir)/binding.gyp $(srcdir)/build/config.gypi $(srcdir)/../../../../node-gyp-npm-9.3.1-43540bab9c/node_modules/node-gyp/addon.gypi $(srcdir)/../../../../../../../../Library/Caches/node-gyp/20.1.0/include/node/common.gypi
|
||||
cmd_regen_makefile = cd $(srcdir); /Users/karolsojko/workspace/server/.yarn/unplugged/node-gyp-npm-9.3.1-43540bab9c/node_modules/node-gyp/gyp/gyp_main.py -fmake --ignore-environment "-Dlibrary=shared_library" "-Dvisibility=default" "-Dnode_root_dir=/Users/karolsojko/Library/Caches/node-gyp/20.2.0" "-Dnode_gyp_dir=/Users/karolsojko/workspace/server/.yarn/unplugged/node-gyp-npm-9.3.1-43540bab9c/node_modules/node-gyp" "-Dnode_lib_file=/Users/karolsojko/Library/Caches/node-gyp/20.2.0/<(target_arch)/node.lib" "-Dmodule_root_dir=/Users/karolsojko/workspace/server/.yarn/unplugged/@newrelic-native-metrics-npm-9.0.0-590d2e713a/node_modules/@newrelic/native-metrics" "-Dnode_engine=v8" "--depth=." "-Goutput_dir=." "--generator-output=build" -I/Users/karolsojko/workspace/server/.yarn/unplugged/@newrelic-native-metrics-npm-9.0.0-590d2e713a/node_modules/@newrelic/native-metrics/build/config.gypi -I/Users/karolsojko/workspace/server/.yarn/unplugged/node-gyp-npm-9.3.1-43540bab9c/node_modules/node-gyp/addon.gypi -I/Users/karolsojko/Library/Caches/node-gyp/20.2.0/include/node/common.gypi "--toplevel-dir=." binding.gyp
|
||||
Makefile: $(srcdir)/build/config.gypi $(srcdir)/../../../../node-gyp-npm-9.3.1-43540bab9c/node_modules/node-gyp/addon.gypi $(srcdir)/binding.gyp $(srcdir)/../../../../../../../../Library/Caches/node-gyp/20.2.0/include/node/common.gypi
|
||||
$(call do_cmd,regen_makefile)
|
||||
|
||||
# "all" is a concatenation of the "all" targets from all the included
|
||||
|
||||
@@ -1,69 +1,69 @@
|
||||
cmd_Release/obj.target/native_metrics/src/GCBinder.o := c++ -o Release/obj.target/native_metrics/src/GCBinder.o ../src/GCBinder.cpp '-DNODE_GYP_MODULE_NAME=native_metrics' '-DUSING_UV_SHARED=1' '-DUSING_V8_SHARED=1' '-DV8_DEPRECATION_WARNINGS=1' '-DV8_DEPRECATION_WARNINGS' '-DV8_IMMINENT_DEPRECATION_WARNINGS' '-D_GLIBCXX_USE_CXX11_ABI=1' '-D_DARWIN_USE_64_BIT_INODE=1' '-D_LARGEFILE_SOURCE' '-D_FILE_OFFSET_BITS=64' '-DOPENSSL_NO_PINSHARED' '-DOPENSSL_THREADS' '-DNOMINMAX' '-DBUILDING_NODE_EXTENSION' -I/Users/karolsojko/Library/Caches/node-gyp/20.1.0/include/node -I/Users/karolsojko/Library/Caches/node-gyp/20.1.0/src -I/Users/karolsojko/Library/Caches/node-gyp/20.1.0/deps/openssl/config -I/Users/karolsojko/Library/Caches/node-gyp/20.1.0/deps/openssl/openssl/include -I/Users/karolsojko/Library/Caches/node-gyp/20.1.0/deps/uv/include -I/Users/karolsojko/Library/Caches/node-gyp/20.1.0/deps/zlib -I/Users/karolsojko/Library/Caches/node-gyp/20.1.0/deps/v8/include -I../src -I../../../../../nan-npm-2.17.0-bf36a21d6f/node_modules/nan -O3 -gdwarf-2 -mmacosx-version-min=10.15 -arch arm64 -Wall -Wendif-labels -W -Wno-unused-parameter -std=gnu++17 -stdlib=libc++ -fno-rtti -fno-exceptions -fno-strict-aliasing -MMD -MF ./Release/.deps/Release/obj.target/native_metrics/src/GCBinder.o.d.raw -c
|
||||
cmd_Release/obj.target/native_metrics/src/GCBinder.o := c++ -o Release/obj.target/native_metrics/src/GCBinder.o ../src/GCBinder.cpp '-DNODE_GYP_MODULE_NAME=native_metrics' '-DUSING_UV_SHARED=1' '-DUSING_V8_SHARED=1' '-DV8_DEPRECATION_WARNINGS=1' '-DV8_DEPRECATION_WARNINGS' '-DV8_IMMINENT_DEPRECATION_WARNINGS' '-D_GLIBCXX_USE_CXX11_ABI=1' '-D_DARWIN_USE_64_BIT_INODE=1' '-D_LARGEFILE_SOURCE' '-D_FILE_OFFSET_BITS=64' '-DOPENSSL_NO_PINSHARED' '-DOPENSSL_THREADS' '-DNOMINMAX' '-DBUILDING_NODE_EXTENSION' -I/Users/karolsojko/Library/Caches/node-gyp/20.2.0/include/node -I/Users/karolsojko/Library/Caches/node-gyp/20.2.0/src -I/Users/karolsojko/Library/Caches/node-gyp/20.2.0/deps/openssl/config -I/Users/karolsojko/Library/Caches/node-gyp/20.2.0/deps/openssl/openssl/include -I/Users/karolsojko/Library/Caches/node-gyp/20.2.0/deps/uv/include -I/Users/karolsojko/Library/Caches/node-gyp/20.2.0/deps/zlib -I/Users/karolsojko/Library/Caches/node-gyp/20.2.0/deps/v8/include -I../src -I../../../../../nan-npm-2.17.0-bf36a21d6f/node_modules/nan -O3 -gdwarf-2 -mmacosx-version-min=10.15 -arch arm64 -Wall -Wendif-labels -W -Wno-unused-parameter -std=gnu++17 -stdlib=libc++ -fno-rtti -fno-exceptions -fno-strict-aliasing -MMD -MF ./Release/.deps/Release/obj.target/native_metrics/src/GCBinder.o.d.raw -c
|
||||
Release/obj.target/native_metrics/src/GCBinder.o: ../src/GCBinder.cpp \
|
||||
../src/GCBinder.hpp \
|
||||
../../../../../nan-npm-2.17.0-bf36a21d6f/node_modules/nan/nan.h \
|
||||
/Users/karolsojko/Library/Caches/node-gyp/20.1.0/include/node/node_version.h \
|
||||
/Users/karolsojko/Library/Caches/node-gyp/20.1.0/include/node/uv.h \
|
||||
/Users/karolsojko/Library/Caches/node-gyp/20.1.0/include/node/uv/errno.h \
|
||||
/Users/karolsojko/Library/Caches/node-gyp/20.1.0/include/node/uv/version.h \
|
||||
/Users/karolsojko/Library/Caches/node-gyp/20.1.0/include/node/uv/unix.h \
|
||||
/Users/karolsojko/Library/Caches/node-gyp/20.1.0/include/node/uv/threadpool.h \
|
||||
/Users/karolsojko/Library/Caches/node-gyp/20.1.0/include/node/uv/darwin.h \
|
||||
/Users/karolsojko/Library/Caches/node-gyp/20.1.0/include/node/node.h \
|
||||
/Users/karolsojko/Library/Caches/node-gyp/20.1.0/include/node/v8.h \
|
||||
/Users/karolsojko/Library/Caches/node-gyp/20.1.0/include/node/cppgc/common.h \
|
||||
/Users/karolsojko/Library/Caches/node-gyp/20.1.0/include/node/v8config.h \
|
||||
/Users/karolsojko/Library/Caches/node-gyp/20.1.0/include/node/v8-array-buffer.h \
|
||||
/Users/karolsojko/Library/Caches/node-gyp/20.1.0/include/node/v8-local-handle.h \
|
||||
/Users/karolsojko/Library/Caches/node-gyp/20.1.0/include/node/v8-internal.h \
|
||||
/Users/karolsojko/Library/Caches/node-gyp/20.1.0/include/node/v8-version.h \
|
||||
/Users/karolsojko/Library/Caches/node-gyp/20.1.0/include/node/v8-object.h \
|
||||
/Users/karolsojko/Library/Caches/node-gyp/20.1.0/include/node/v8-maybe.h \
|
||||
/Users/karolsojko/Library/Caches/node-gyp/20.1.0/include/node/v8-persistent-handle.h \
|
||||
/Users/karolsojko/Library/Caches/node-gyp/20.1.0/include/node/v8-weak-callback-info.h \
|
||||
/Users/karolsojko/Library/Caches/node-gyp/20.1.0/include/node/v8-primitive.h \
|
||||
/Users/karolsojko/Library/Caches/node-gyp/20.1.0/include/node/v8-data.h \
|
||||
/Users/karolsojko/Library/Caches/node-gyp/20.1.0/include/node/v8-value.h \
|
||||
/Users/karolsojko/Library/Caches/node-gyp/20.1.0/include/node/v8-traced-handle.h \
|
||||
/Users/karolsojko/Library/Caches/node-gyp/20.1.0/include/node/v8-container.h \
|
||||
/Users/karolsojko/Library/Caches/node-gyp/20.1.0/include/node/v8-context.h \
|
||||
/Users/karolsojko/Library/Caches/node-gyp/20.1.0/include/node/v8-snapshot.h \
|
||||
/Users/karolsojko/Library/Caches/node-gyp/20.1.0/include/node/v8-date.h \
|
||||
/Users/karolsojko/Library/Caches/node-gyp/20.1.0/include/node/v8-debug.h \
|
||||
/Users/karolsojko/Library/Caches/node-gyp/20.1.0/include/node/v8-script.h \
|
||||
/Users/karolsojko/Library/Caches/node-gyp/20.1.0/include/node/v8-callbacks.h \
|
||||
/Users/karolsojko/Library/Caches/node-gyp/20.1.0/include/node/v8-promise.h \
|
||||
/Users/karolsojko/Library/Caches/node-gyp/20.1.0/include/node/v8-message.h \
|
||||
/Users/karolsojko/Library/Caches/node-gyp/20.1.0/include/node/v8-exception.h \
|
||||
/Users/karolsojko/Library/Caches/node-gyp/20.1.0/include/node/v8-extension.h \
|
||||
/Users/karolsojko/Library/Caches/node-gyp/20.1.0/include/node/v8-external.h \
|
||||
/Users/karolsojko/Library/Caches/node-gyp/20.1.0/include/node/v8-function.h \
|
||||
/Users/karolsojko/Library/Caches/node-gyp/20.1.0/include/node/v8-function-callback.h \
|
||||
/Users/karolsojko/Library/Caches/node-gyp/20.1.0/include/node/v8-template.h \
|
||||
/Users/karolsojko/Library/Caches/node-gyp/20.1.0/include/node/v8-memory-span.h \
|
||||
/Users/karolsojko/Library/Caches/node-gyp/20.1.0/include/node/v8-initialization.h \
|
||||
/Users/karolsojko/Library/Caches/node-gyp/20.1.0/include/node/v8-isolate.h \
|
||||
/Users/karolsojko/Library/Caches/node-gyp/20.1.0/include/node/v8-embedder-heap.h \
|
||||
/Users/karolsojko/Library/Caches/node-gyp/20.1.0/include/node/v8-microtask.h \
|
||||
/Users/karolsojko/Library/Caches/node-gyp/20.1.0/include/node/v8-statistics.h \
|
||||
/Users/karolsojko/Library/Caches/node-gyp/20.1.0/include/node/v8-unwinder.h \
|
||||
/Users/karolsojko/Library/Caches/node-gyp/20.1.0/include/node/v8-embedder-state-scope.h \
|
||||
/Users/karolsojko/Library/Caches/node-gyp/20.1.0/include/node/v8-platform.h \
|
||||
/Users/karolsojko/Library/Caches/node-gyp/20.1.0/include/node/v8-json.h \
|
||||
/Users/karolsojko/Library/Caches/node-gyp/20.1.0/include/node/v8-locker.h \
|
||||
/Users/karolsojko/Library/Caches/node-gyp/20.1.0/include/node/v8-microtask-queue.h \
|
||||
/Users/karolsojko/Library/Caches/node-gyp/20.1.0/include/node/v8-primitive-object.h \
|
||||
/Users/karolsojko/Library/Caches/node-gyp/20.1.0/include/node/v8-proxy.h \
|
||||
/Users/karolsojko/Library/Caches/node-gyp/20.1.0/include/node/v8-regexp.h \
|
||||
/Users/karolsojko/Library/Caches/node-gyp/20.1.0/include/node/v8-typed-array.h \
|
||||
/Users/karolsojko/Library/Caches/node-gyp/20.1.0/include/node/v8-value-serializer.h \
|
||||
/Users/karolsojko/Library/Caches/node-gyp/20.1.0/include/node/v8-wasm.h \
|
||||
/Users/karolsojko/Library/Caches/node-gyp/20.1.0/include/node/node_api.h \
|
||||
/Users/karolsojko/Library/Caches/node-gyp/20.1.0/include/node/js_native_api.h \
|
||||
/Users/karolsojko/Library/Caches/node-gyp/20.1.0/include/node/js_native_api_types.h \
|
||||
/Users/karolsojko/Library/Caches/node-gyp/20.1.0/include/node/node_api_types.h \
|
||||
/Users/karolsojko/Library/Caches/node-gyp/20.1.0/include/node/node_buffer.h \
|
||||
/Users/karolsojko/Library/Caches/node-gyp/20.1.0/include/node/node_object_wrap.h \
|
||||
/Users/karolsojko/Library/Caches/node-gyp/20.2.0/include/node/node_version.h \
|
||||
/Users/karolsojko/Library/Caches/node-gyp/20.2.0/include/node/uv.h \
|
||||
/Users/karolsojko/Library/Caches/node-gyp/20.2.0/include/node/uv/errno.h \
|
||||
/Users/karolsojko/Library/Caches/node-gyp/20.2.0/include/node/uv/version.h \
|
||||
/Users/karolsojko/Library/Caches/node-gyp/20.2.0/include/node/uv/unix.h \
|
||||
/Users/karolsojko/Library/Caches/node-gyp/20.2.0/include/node/uv/threadpool.h \
|
||||
/Users/karolsojko/Library/Caches/node-gyp/20.2.0/include/node/uv/darwin.h \
|
||||
/Users/karolsojko/Library/Caches/node-gyp/20.2.0/include/node/node.h \
|
||||
/Users/karolsojko/Library/Caches/node-gyp/20.2.0/include/node/v8.h \
|
||||
/Users/karolsojko/Library/Caches/node-gyp/20.2.0/include/node/cppgc/common.h \
|
||||
/Users/karolsojko/Library/Caches/node-gyp/20.2.0/include/node/v8config.h \
|
||||
/Users/karolsojko/Library/Caches/node-gyp/20.2.0/include/node/v8-array-buffer.h \
|
||||
/Users/karolsojko/Library/Caches/node-gyp/20.2.0/include/node/v8-local-handle.h \
|
||||
/Users/karolsojko/Library/Caches/node-gyp/20.2.0/include/node/v8-internal.h \
|
||||
/Users/karolsojko/Library/Caches/node-gyp/20.2.0/include/node/v8-version.h \
|
||||
/Users/karolsojko/Library/Caches/node-gyp/20.2.0/include/node/v8-object.h \
|
||||
/Users/karolsojko/Library/Caches/node-gyp/20.2.0/include/node/v8-maybe.h \
|
||||
/Users/karolsojko/Library/Caches/node-gyp/20.2.0/include/node/v8-persistent-handle.h \
|
||||
/Users/karolsojko/Library/Caches/node-gyp/20.2.0/include/node/v8-weak-callback-info.h \
|
||||
/Users/karolsojko/Library/Caches/node-gyp/20.2.0/include/node/v8-primitive.h \
|
||||
/Users/karolsojko/Library/Caches/node-gyp/20.2.0/include/node/v8-data.h \
|
||||
/Users/karolsojko/Library/Caches/node-gyp/20.2.0/include/node/v8-value.h \
|
||||
/Users/karolsojko/Library/Caches/node-gyp/20.2.0/include/node/v8-traced-handle.h \
|
||||
/Users/karolsojko/Library/Caches/node-gyp/20.2.0/include/node/v8-container.h \
|
||||
/Users/karolsojko/Library/Caches/node-gyp/20.2.0/include/node/v8-context.h \
|
||||
/Users/karolsojko/Library/Caches/node-gyp/20.2.0/include/node/v8-snapshot.h \
|
||||
/Users/karolsojko/Library/Caches/node-gyp/20.2.0/include/node/v8-date.h \
|
||||
/Users/karolsojko/Library/Caches/node-gyp/20.2.0/include/node/v8-debug.h \
|
||||
/Users/karolsojko/Library/Caches/node-gyp/20.2.0/include/node/v8-script.h \
|
||||
/Users/karolsojko/Library/Caches/node-gyp/20.2.0/include/node/v8-callbacks.h \
|
||||
/Users/karolsojko/Library/Caches/node-gyp/20.2.0/include/node/v8-promise.h \
|
||||
/Users/karolsojko/Library/Caches/node-gyp/20.2.0/include/node/v8-message.h \
|
||||
/Users/karolsojko/Library/Caches/node-gyp/20.2.0/include/node/v8-exception.h \
|
||||
/Users/karolsojko/Library/Caches/node-gyp/20.2.0/include/node/v8-extension.h \
|
||||
/Users/karolsojko/Library/Caches/node-gyp/20.2.0/include/node/v8-external.h \
|
||||
/Users/karolsojko/Library/Caches/node-gyp/20.2.0/include/node/v8-function.h \
|
||||
/Users/karolsojko/Library/Caches/node-gyp/20.2.0/include/node/v8-function-callback.h \
|
||||
/Users/karolsojko/Library/Caches/node-gyp/20.2.0/include/node/v8-template.h \
|
||||
/Users/karolsojko/Library/Caches/node-gyp/20.2.0/include/node/v8-memory-span.h \
|
||||
/Users/karolsojko/Library/Caches/node-gyp/20.2.0/include/node/v8-initialization.h \
|
||||
/Users/karolsojko/Library/Caches/node-gyp/20.2.0/include/node/v8-isolate.h \
|
||||
/Users/karolsojko/Library/Caches/node-gyp/20.2.0/include/node/v8-embedder-heap.h \
|
||||
/Users/karolsojko/Library/Caches/node-gyp/20.2.0/include/node/v8-microtask.h \
|
||||
/Users/karolsojko/Library/Caches/node-gyp/20.2.0/include/node/v8-statistics.h \
|
||||
/Users/karolsojko/Library/Caches/node-gyp/20.2.0/include/node/v8-unwinder.h \
|
||||
/Users/karolsojko/Library/Caches/node-gyp/20.2.0/include/node/v8-embedder-state-scope.h \
|
||||
/Users/karolsojko/Library/Caches/node-gyp/20.2.0/include/node/v8-platform.h \
|
||||
/Users/karolsojko/Library/Caches/node-gyp/20.2.0/include/node/v8-json.h \
|
||||
/Users/karolsojko/Library/Caches/node-gyp/20.2.0/include/node/v8-locker.h \
|
||||
/Users/karolsojko/Library/Caches/node-gyp/20.2.0/include/node/v8-microtask-queue.h \
|
||||
/Users/karolsojko/Library/Caches/node-gyp/20.2.0/include/node/v8-primitive-object.h \
|
||||
/Users/karolsojko/Library/Caches/node-gyp/20.2.0/include/node/v8-proxy.h \
|
||||
/Users/karolsojko/Library/Caches/node-gyp/20.2.0/include/node/v8-regexp.h \
|
||||
/Users/karolsojko/Library/Caches/node-gyp/20.2.0/include/node/v8-typed-array.h \
|
||||
/Users/karolsojko/Library/Caches/node-gyp/20.2.0/include/node/v8-value-serializer.h \
|
||||
/Users/karolsojko/Library/Caches/node-gyp/20.2.0/include/node/v8-wasm.h \
|
||||
/Users/karolsojko/Library/Caches/node-gyp/20.2.0/include/node/node_api.h \
|
||||
/Users/karolsojko/Library/Caches/node-gyp/20.2.0/include/node/js_native_api.h \
|
||||
/Users/karolsojko/Library/Caches/node-gyp/20.2.0/include/node/js_native_api_types.h \
|
||||
/Users/karolsojko/Library/Caches/node-gyp/20.2.0/include/node/node_api_types.h \
|
||||
/Users/karolsojko/Library/Caches/node-gyp/20.2.0/include/node/node_buffer.h \
|
||||
/Users/karolsojko/Library/Caches/node-gyp/20.2.0/include/node/node_object_wrap.h \
|
||||
../../../../../nan-npm-2.17.0-bf36a21d6f/node_modules/nan/nan_callbacks.h \
|
||||
../../../../../nan-npm-2.17.0-bf36a21d6f/node_modules/nan/nan_callbacks_12_inl.h \
|
||||
../../../../../nan-npm-2.17.0-bf36a21d6f/node_modules/nan/nan_maybe_43_inl.h \
|
||||
@@ -82,68 +82,68 @@ Release/obj.target/native_metrics/src/GCBinder.o: ../src/GCBinder.cpp \
|
||||
../src/GCBinder.cpp:
|
||||
../src/GCBinder.hpp:
|
||||
../../../../../nan-npm-2.17.0-bf36a21d6f/node_modules/nan/nan.h:
|
||||
/Users/karolsojko/Library/Caches/node-gyp/20.1.0/include/node/node_version.h:
|
||||
/Users/karolsojko/Library/Caches/node-gyp/20.1.0/include/node/uv.h:
|
||||
/Users/karolsojko/Library/Caches/node-gyp/20.1.0/include/node/uv/errno.h:
|
||||
/Users/karolsojko/Library/Caches/node-gyp/20.1.0/include/node/uv/version.h:
|
||||
/Users/karolsojko/Library/Caches/node-gyp/20.1.0/include/node/uv/unix.h:
|
||||
/Users/karolsojko/Library/Caches/node-gyp/20.1.0/include/node/uv/threadpool.h:
|
||||
/Users/karolsojko/Library/Caches/node-gyp/20.1.0/include/node/uv/darwin.h:
|
||||
/Users/karolsojko/Library/Caches/node-gyp/20.1.0/include/node/node.h:
|
||||
/Users/karolsojko/Library/Caches/node-gyp/20.1.0/include/node/v8.h:
|
||||
/Users/karolsojko/Library/Caches/node-gyp/20.1.0/include/node/cppgc/common.h:
|
||||
/Users/karolsojko/Library/Caches/node-gyp/20.1.0/include/node/v8config.h:
|
||||
/Users/karolsojko/Library/Caches/node-gyp/20.1.0/include/node/v8-array-buffer.h:
|
||||
/Users/karolsojko/Library/Caches/node-gyp/20.1.0/include/node/v8-local-handle.h:
|
||||
/Users/karolsojko/Library/Caches/node-gyp/20.1.0/include/node/v8-internal.h:
|
||||
/Users/karolsojko/Library/Caches/node-gyp/20.1.0/include/node/v8-version.h:
|
||||
/Users/karolsojko/Library/Caches/node-gyp/20.1.0/include/node/v8-object.h:
|
||||
/Users/karolsojko/Library/Caches/node-gyp/20.1.0/include/node/v8-maybe.h:
|
||||
/Users/karolsojko/Library/Caches/node-gyp/20.1.0/include/node/v8-persistent-handle.h:
|
||||
/Users/karolsojko/Library/Caches/node-gyp/20.1.0/include/node/v8-weak-callback-info.h:
|
||||
/Users/karolsojko/Library/Caches/node-gyp/20.1.0/include/node/v8-primitive.h:
|
||||
/Users/karolsojko/Library/Caches/node-gyp/20.1.0/include/node/v8-data.h:
|
||||
/Users/karolsojko/Library/Caches/node-gyp/20.1.0/include/node/v8-value.h:
|
||||
/Users/karolsojko/Library/Caches/node-gyp/20.1.0/include/node/v8-traced-handle.h:
|
||||
/Users/karolsojko/Library/Caches/node-gyp/20.1.0/include/node/v8-container.h:
|
||||
/Users/karolsojko/Library/Caches/node-gyp/20.1.0/include/node/v8-context.h:
|
||||
/Users/karolsojko/Library/Caches/node-gyp/20.1.0/include/node/v8-snapshot.h:
|
||||
/Users/karolsojko/Library/Caches/node-gyp/20.1.0/include/node/v8-date.h:
|
||||
/Users/karolsojko/Library/Caches/node-gyp/20.1.0/include/node/v8-debug.h:
|
||||
/Users/karolsojko/Library/Caches/node-gyp/20.1.0/include/node/v8-script.h:
|
||||
/Users/karolsojko/Library/Caches/node-gyp/20.1.0/include/node/v8-callbacks.h:
|
||||
/Users/karolsojko/Library/Caches/node-gyp/20.1.0/include/node/v8-promise.h:
|
||||
/Users/karolsojko/Library/Caches/node-gyp/20.1.0/include/node/v8-message.h:
|
||||
/Users/karolsojko/Library/Caches/node-gyp/20.1.0/include/node/v8-exception.h:
|
||||
/Users/karolsojko/Library/Caches/node-gyp/20.1.0/include/node/v8-extension.h:
|
||||
/Users/karolsojko/Library/Caches/node-gyp/20.1.0/include/node/v8-external.h:
|
||||
/Users/karolsojko/Library/Caches/node-gyp/20.1.0/include/node/v8-function.h:
|
||||
/Users/karolsojko/Library/Caches/node-gyp/20.1.0/include/node/v8-function-callback.h:
|
||||
/Users/karolsojko/Library/Caches/node-gyp/20.1.0/include/node/v8-template.h:
|
||||
/Users/karolsojko/Library/Caches/node-gyp/20.1.0/include/node/v8-memory-span.h:
|
||||
/Users/karolsojko/Library/Caches/node-gyp/20.1.0/include/node/v8-initialization.h:
|
||||
/Users/karolsojko/Library/Caches/node-gyp/20.1.0/include/node/v8-isolate.h:
|
||||
/Users/karolsojko/Library/Caches/node-gyp/20.1.0/include/node/v8-embedder-heap.h:
|
||||
/Users/karolsojko/Library/Caches/node-gyp/20.1.0/include/node/v8-microtask.h:
|
||||
/Users/karolsojko/Library/Caches/node-gyp/20.1.0/include/node/v8-statistics.h:
|
||||
/Users/karolsojko/Library/Caches/node-gyp/20.1.0/include/node/v8-unwinder.h:
|
||||
/Users/karolsojko/Library/Caches/node-gyp/20.1.0/include/node/v8-embedder-state-scope.h:
|
||||
/Users/karolsojko/Library/Caches/node-gyp/20.1.0/include/node/v8-platform.h:
|
||||
/Users/karolsojko/Library/Caches/node-gyp/20.1.0/include/node/v8-json.h:
|
||||
/Users/karolsojko/Library/Caches/node-gyp/20.1.0/include/node/v8-locker.h:
|
||||
/Users/karolsojko/Library/Caches/node-gyp/20.1.0/include/node/v8-microtask-queue.h:
|
||||
/Users/karolsojko/Library/Caches/node-gyp/20.1.0/include/node/v8-primitive-object.h:
|
||||
/Users/karolsojko/Library/Caches/node-gyp/20.1.0/include/node/v8-proxy.h:
|
||||
/Users/karolsojko/Library/Caches/node-gyp/20.1.0/include/node/v8-regexp.h:
|
||||
/Users/karolsojko/Library/Caches/node-gyp/20.1.0/include/node/v8-typed-array.h:
|
||||
/Users/karolsojko/Library/Caches/node-gyp/20.1.0/include/node/v8-value-serializer.h:
|
||||
/Users/karolsojko/Library/Caches/node-gyp/20.1.0/include/node/v8-wasm.h:
|
||||
/Users/karolsojko/Library/Caches/node-gyp/20.1.0/include/node/node_api.h:
|
||||
/Users/karolsojko/Library/Caches/node-gyp/20.1.0/include/node/js_native_api.h:
|
||||
/Users/karolsojko/Library/Caches/node-gyp/20.1.0/include/node/js_native_api_types.h:
|
||||
/Users/karolsojko/Library/Caches/node-gyp/20.1.0/include/node/node_api_types.h:
|
||||
/Users/karolsojko/Library/Caches/node-gyp/20.1.0/include/node/node_buffer.h:
|
||||
/Users/karolsojko/Library/Caches/node-gyp/20.1.0/include/node/node_object_wrap.h:
|
||||
/Users/karolsojko/Library/Caches/node-gyp/20.2.0/include/node/node_version.h:
|
||||
/Users/karolsojko/Library/Caches/node-gyp/20.2.0/include/node/uv.h:
|
||||
/Users/karolsojko/Library/Caches/node-gyp/20.2.0/include/node/uv/errno.h:
|
||||
/Users/karolsojko/Library/Caches/node-gyp/20.2.0/include/node/uv/version.h:
|
||||
/Users/karolsojko/Library/Caches/node-gyp/20.2.0/include/node/uv/unix.h:
|
||||
/Users/karolsojko/Library/Caches/node-gyp/20.2.0/include/node/uv/threadpool.h:
|
||||
/Users/karolsojko/Library/Caches/node-gyp/20.2.0/include/node/uv/darwin.h:
|
||||
/Users/karolsojko/Library/Caches/node-gyp/20.2.0/include/node/node.h:
|
||||
/Users/karolsojko/Library/Caches/node-gyp/20.2.0/include/node/v8.h:
|
||||
/Users/karolsojko/Library/Caches/node-gyp/20.2.0/include/node/cppgc/common.h:
|
||||
/Users/karolsojko/Library/Caches/node-gyp/20.2.0/include/node/v8config.h:
|
||||
/Users/karolsojko/Library/Caches/node-gyp/20.2.0/include/node/v8-array-buffer.h:
|
||||
/Users/karolsojko/Library/Caches/node-gyp/20.2.0/include/node/v8-local-handle.h:
|
||||
/Users/karolsojko/Library/Caches/node-gyp/20.2.0/include/node/v8-internal.h:
|
||||
/Users/karolsojko/Library/Caches/node-gyp/20.2.0/include/node/v8-version.h:
|
||||
/Users/karolsojko/Library/Caches/node-gyp/20.2.0/include/node/v8-object.h:
|
||||
/Users/karolsojko/Library/Caches/node-gyp/20.2.0/include/node/v8-maybe.h:
|
||||
/Users/karolsojko/Library/Caches/node-gyp/20.2.0/include/node/v8-persistent-handle.h:
|
||||
/Users/karolsojko/Library/Caches/node-gyp/20.2.0/include/node/v8-weak-callback-info.h:
|
||||
/Users/karolsojko/Library/Caches/node-gyp/20.2.0/include/node/v8-primitive.h:
|
||||
/Users/karolsojko/Library/Caches/node-gyp/20.2.0/include/node/v8-data.h:
|
||||
/Users/karolsojko/Library/Caches/node-gyp/20.2.0/include/node/v8-value.h:
|
||||
/Users/karolsojko/Library/Caches/node-gyp/20.2.0/include/node/v8-traced-handle.h:
|
||||
/Users/karolsojko/Library/Caches/node-gyp/20.2.0/include/node/v8-container.h:
|
||||
/Users/karolsojko/Library/Caches/node-gyp/20.2.0/include/node/v8-context.h:
|
||||
/Users/karolsojko/Library/Caches/node-gyp/20.2.0/include/node/v8-snapshot.h:
|
||||
/Users/karolsojko/Library/Caches/node-gyp/20.2.0/include/node/v8-date.h:
|
||||
/Users/karolsojko/Library/Caches/node-gyp/20.2.0/include/node/v8-debug.h:
|
||||
/Users/karolsojko/Library/Caches/node-gyp/20.2.0/include/node/v8-script.h:
|
||||
/Users/karolsojko/Library/Caches/node-gyp/20.2.0/include/node/v8-callbacks.h:
|
||||
/Users/karolsojko/Library/Caches/node-gyp/20.2.0/include/node/v8-promise.h:
|
||||
/Users/karolsojko/Library/Caches/node-gyp/20.2.0/include/node/v8-message.h:
|
||||
/Users/karolsojko/Library/Caches/node-gyp/20.2.0/include/node/v8-exception.h:
|
||||
/Users/karolsojko/Library/Caches/node-gyp/20.2.0/include/node/v8-extension.h:
|
||||
/Users/karolsojko/Library/Caches/node-gyp/20.2.0/include/node/v8-external.h:
|
||||
/Users/karolsojko/Library/Caches/node-gyp/20.2.0/include/node/v8-function.h:
|
||||
/Users/karolsojko/Library/Caches/node-gyp/20.2.0/include/node/v8-function-callback.h:
|
||||
/Users/karolsojko/Library/Caches/node-gyp/20.2.0/include/node/v8-template.h:
|
||||
/Users/karolsojko/Library/Caches/node-gyp/20.2.0/include/node/v8-memory-span.h:
|
||||
/Users/karolsojko/Library/Caches/node-gyp/20.2.0/include/node/v8-initialization.h:
|
||||
/Users/karolsojko/Library/Caches/node-gyp/20.2.0/include/node/v8-isolate.h:
|
||||
/Users/karolsojko/Library/Caches/node-gyp/20.2.0/include/node/v8-embedder-heap.h:
|
||||
/Users/karolsojko/Library/Caches/node-gyp/20.2.0/include/node/v8-microtask.h:
|
||||
/Users/karolsojko/Library/Caches/node-gyp/20.2.0/include/node/v8-statistics.h:
|
||||
/Users/karolsojko/Library/Caches/node-gyp/20.2.0/include/node/v8-unwinder.h:
|
||||
/Users/karolsojko/Library/Caches/node-gyp/20.2.0/include/node/v8-embedder-state-scope.h:
|
||||
/Users/karolsojko/Library/Caches/node-gyp/20.2.0/include/node/v8-platform.h:
|
||||
/Users/karolsojko/Library/Caches/node-gyp/20.2.0/include/node/v8-json.h:
|
||||
/Users/karolsojko/Library/Caches/node-gyp/20.2.0/include/node/v8-locker.h:
|
||||
/Users/karolsojko/Library/Caches/node-gyp/20.2.0/include/node/v8-microtask-queue.h:
|
||||
/Users/karolsojko/Library/Caches/node-gyp/20.2.0/include/node/v8-primitive-object.h:
|
||||
/Users/karolsojko/Library/Caches/node-gyp/20.2.0/include/node/v8-proxy.h:
|
||||
/Users/karolsojko/Library/Caches/node-gyp/20.2.0/include/node/v8-regexp.h:
|
||||
/Users/karolsojko/Library/Caches/node-gyp/20.2.0/include/node/v8-typed-array.h:
|
||||
/Users/karolsojko/Library/Caches/node-gyp/20.2.0/include/node/v8-value-serializer.h:
|
||||
/Users/karolsojko/Library/Caches/node-gyp/20.2.0/include/node/v8-wasm.h:
|
||||
/Users/karolsojko/Library/Caches/node-gyp/20.2.0/include/node/node_api.h:
|
||||
/Users/karolsojko/Library/Caches/node-gyp/20.2.0/include/node/js_native_api.h:
|
||||
/Users/karolsojko/Library/Caches/node-gyp/20.2.0/include/node/js_native_api_types.h:
|
||||
/Users/karolsojko/Library/Caches/node-gyp/20.2.0/include/node/node_api_types.h:
|
||||
/Users/karolsojko/Library/Caches/node-gyp/20.2.0/include/node/node_buffer.h:
|
||||
/Users/karolsojko/Library/Caches/node-gyp/20.2.0/include/node/node_object_wrap.h:
|
||||
../../../../../nan-npm-2.17.0-bf36a21d6f/node_modules/nan/nan_callbacks.h:
|
||||
../../../../../nan-npm-2.17.0-bf36a21d6f/node_modules/nan/nan_callbacks_12_inl.h:
|
||||
../../../../../nan-npm-2.17.0-bf36a21d6f/node_modules/nan/nan_maybe_43_inl.h:
|
||||
|
||||
@@ -1,70 +1,70 @@
|
||||
cmd_Release/obj.target/native_metrics/src/LoopChecker.o := c++ -o Release/obj.target/native_metrics/src/LoopChecker.o ../src/LoopChecker.cpp '-DNODE_GYP_MODULE_NAME=native_metrics' '-DUSING_UV_SHARED=1' '-DUSING_V8_SHARED=1' '-DV8_DEPRECATION_WARNINGS=1' '-DV8_DEPRECATION_WARNINGS' '-DV8_IMMINENT_DEPRECATION_WARNINGS' '-D_GLIBCXX_USE_CXX11_ABI=1' '-D_DARWIN_USE_64_BIT_INODE=1' '-D_LARGEFILE_SOURCE' '-D_FILE_OFFSET_BITS=64' '-DOPENSSL_NO_PINSHARED' '-DOPENSSL_THREADS' '-DNOMINMAX' '-DBUILDING_NODE_EXTENSION' -I/Users/karolsojko/Library/Caches/node-gyp/20.1.0/include/node -I/Users/karolsojko/Library/Caches/node-gyp/20.1.0/src -I/Users/karolsojko/Library/Caches/node-gyp/20.1.0/deps/openssl/config -I/Users/karolsojko/Library/Caches/node-gyp/20.1.0/deps/openssl/openssl/include -I/Users/karolsojko/Library/Caches/node-gyp/20.1.0/deps/uv/include -I/Users/karolsojko/Library/Caches/node-gyp/20.1.0/deps/zlib -I/Users/karolsojko/Library/Caches/node-gyp/20.1.0/deps/v8/include -I../src -I../../../../../nan-npm-2.17.0-bf36a21d6f/node_modules/nan -O3 -gdwarf-2 -mmacosx-version-min=10.15 -arch arm64 -Wall -Wendif-labels -W -Wno-unused-parameter -std=gnu++17 -stdlib=libc++ -fno-rtti -fno-exceptions -fno-strict-aliasing -MMD -MF ./Release/.deps/Release/obj.target/native_metrics/src/LoopChecker.o.d.raw -c
|
||||
cmd_Release/obj.target/native_metrics/src/LoopChecker.o := c++ -o Release/obj.target/native_metrics/src/LoopChecker.o ../src/LoopChecker.cpp '-DNODE_GYP_MODULE_NAME=native_metrics' '-DUSING_UV_SHARED=1' '-DUSING_V8_SHARED=1' '-DV8_DEPRECATION_WARNINGS=1' '-DV8_DEPRECATION_WARNINGS' '-DV8_IMMINENT_DEPRECATION_WARNINGS' '-D_GLIBCXX_USE_CXX11_ABI=1' '-D_DARWIN_USE_64_BIT_INODE=1' '-D_LARGEFILE_SOURCE' '-D_FILE_OFFSET_BITS=64' '-DOPENSSL_NO_PINSHARED' '-DOPENSSL_THREADS' '-DNOMINMAX' '-DBUILDING_NODE_EXTENSION' -I/Users/karolsojko/Library/Caches/node-gyp/20.2.0/include/node -I/Users/karolsojko/Library/Caches/node-gyp/20.2.0/src -I/Users/karolsojko/Library/Caches/node-gyp/20.2.0/deps/openssl/config -I/Users/karolsojko/Library/Caches/node-gyp/20.2.0/deps/openssl/openssl/include -I/Users/karolsojko/Library/Caches/node-gyp/20.2.0/deps/uv/include -I/Users/karolsojko/Library/Caches/node-gyp/20.2.0/deps/zlib -I/Users/karolsojko/Library/Caches/node-gyp/20.2.0/deps/v8/include -I../src -I../../../../../nan-npm-2.17.0-bf36a21d6f/node_modules/nan -O3 -gdwarf-2 -mmacosx-version-min=10.15 -arch arm64 -Wall -Wendif-labels -W -Wno-unused-parameter -std=gnu++17 -stdlib=libc++ -fno-rtti -fno-exceptions -fno-strict-aliasing -MMD -MF ./Release/.deps/Release/obj.target/native_metrics/src/LoopChecker.o.d.raw -c
|
||||
Release/obj.target/native_metrics/src/LoopChecker.o: \
|
||||
../src/LoopChecker.cpp \
|
||||
/Users/karolsojko/Library/Caches/node-gyp/20.1.0/include/node/uv.h \
|
||||
/Users/karolsojko/Library/Caches/node-gyp/20.1.0/include/node/uv/errno.h \
|
||||
/Users/karolsojko/Library/Caches/node-gyp/20.1.0/include/node/uv/version.h \
|
||||
/Users/karolsojko/Library/Caches/node-gyp/20.1.0/include/node/uv/unix.h \
|
||||
/Users/karolsojko/Library/Caches/node-gyp/20.1.0/include/node/uv/threadpool.h \
|
||||
/Users/karolsojko/Library/Caches/node-gyp/20.1.0/include/node/uv/darwin.h \
|
||||
/Users/karolsojko/Library/Caches/node-gyp/20.2.0/include/node/uv.h \
|
||||
/Users/karolsojko/Library/Caches/node-gyp/20.2.0/include/node/uv/errno.h \
|
||||
/Users/karolsojko/Library/Caches/node-gyp/20.2.0/include/node/uv/version.h \
|
||||
/Users/karolsojko/Library/Caches/node-gyp/20.2.0/include/node/uv/unix.h \
|
||||
/Users/karolsojko/Library/Caches/node-gyp/20.2.0/include/node/uv/threadpool.h \
|
||||
/Users/karolsojko/Library/Caches/node-gyp/20.2.0/include/node/uv/darwin.h \
|
||||
../src/LoopChecker.hpp \
|
||||
../../../../../nan-npm-2.17.0-bf36a21d6f/node_modules/nan/nan.h \
|
||||
/Users/karolsojko/Library/Caches/node-gyp/20.1.0/include/node/node_version.h \
|
||||
/Users/karolsojko/Library/Caches/node-gyp/20.1.0/include/node/node.h \
|
||||
/Users/karolsojko/Library/Caches/node-gyp/20.1.0/include/node/v8.h \
|
||||
/Users/karolsojko/Library/Caches/node-gyp/20.1.0/include/node/cppgc/common.h \
|
||||
/Users/karolsojko/Library/Caches/node-gyp/20.1.0/include/node/v8config.h \
|
||||
/Users/karolsojko/Library/Caches/node-gyp/20.1.0/include/node/v8-array-buffer.h \
|
||||
/Users/karolsojko/Library/Caches/node-gyp/20.1.0/include/node/v8-local-handle.h \
|
||||
/Users/karolsojko/Library/Caches/node-gyp/20.1.0/include/node/v8-internal.h \
|
||||
/Users/karolsojko/Library/Caches/node-gyp/20.1.0/include/node/v8-version.h \
|
||||
/Users/karolsojko/Library/Caches/node-gyp/20.1.0/include/node/v8-object.h \
|
||||
/Users/karolsojko/Library/Caches/node-gyp/20.1.0/include/node/v8-maybe.h \
|
||||
/Users/karolsojko/Library/Caches/node-gyp/20.1.0/include/node/v8-persistent-handle.h \
|
||||
/Users/karolsojko/Library/Caches/node-gyp/20.1.0/include/node/v8-weak-callback-info.h \
|
||||
/Users/karolsojko/Library/Caches/node-gyp/20.1.0/include/node/v8-primitive.h \
|
||||
/Users/karolsojko/Library/Caches/node-gyp/20.1.0/include/node/v8-data.h \
|
||||
/Users/karolsojko/Library/Caches/node-gyp/20.1.0/include/node/v8-value.h \
|
||||
/Users/karolsojko/Library/Caches/node-gyp/20.1.0/include/node/v8-traced-handle.h \
|
||||
/Users/karolsojko/Library/Caches/node-gyp/20.1.0/include/node/v8-container.h \
|
||||
/Users/karolsojko/Library/Caches/node-gyp/20.1.0/include/node/v8-context.h \
|
||||
/Users/karolsojko/Library/Caches/node-gyp/20.1.0/include/node/v8-snapshot.h \
|
||||
/Users/karolsojko/Library/Caches/node-gyp/20.1.0/include/node/v8-date.h \
|
||||
/Users/karolsojko/Library/Caches/node-gyp/20.1.0/include/node/v8-debug.h \
|
||||
/Users/karolsojko/Library/Caches/node-gyp/20.1.0/include/node/v8-script.h \
|
||||
/Users/karolsojko/Library/Caches/node-gyp/20.1.0/include/node/v8-callbacks.h \
|
||||
/Users/karolsojko/Library/Caches/node-gyp/20.1.0/include/node/v8-promise.h \
|
||||
/Users/karolsojko/Library/Caches/node-gyp/20.1.0/include/node/v8-message.h \
|
||||
/Users/karolsojko/Library/Caches/node-gyp/20.1.0/include/node/v8-exception.h \
|
||||
/Users/karolsojko/Library/Caches/node-gyp/20.1.0/include/node/v8-extension.h \
|
||||
/Users/karolsojko/Library/Caches/node-gyp/20.1.0/include/node/v8-external.h \
|
||||
/Users/karolsojko/Library/Caches/node-gyp/20.1.0/include/node/v8-function.h \
|
||||
/Users/karolsojko/Library/Caches/node-gyp/20.1.0/include/node/v8-function-callback.h \
|
||||
/Users/karolsojko/Library/Caches/node-gyp/20.1.0/include/node/v8-template.h \
|
||||
/Users/karolsojko/Library/Caches/node-gyp/20.1.0/include/node/v8-memory-span.h \
|
||||
/Users/karolsojko/Library/Caches/node-gyp/20.1.0/include/node/v8-initialization.h \
|
||||
/Users/karolsojko/Library/Caches/node-gyp/20.1.0/include/node/v8-isolate.h \
|
||||
/Users/karolsojko/Library/Caches/node-gyp/20.1.0/include/node/v8-embedder-heap.h \
|
||||
/Users/karolsojko/Library/Caches/node-gyp/20.1.0/include/node/v8-microtask.h \
|
||||
/Users/karolsojko/Library/Caches/node-gyp/20.1.0/include/node/v8-statistics.h \
|
||||
/Users/karolsojko/Library/Caches/node-gyp/20.1.0/include/node/v8-unwinder.h \
|
||||
/Users/karolsojko/Library/Caches/node-gyp/20.1.0/include/node/v8-embedder-state-scope.h \
|
||||
/Users/karolsojko/Library/Caches/node-gyp/20.1.0/include/node/v8-platform.h \
|
||||
/Users/karolsojko/Library/Caches/node-gyp/20.1.0/include/node/v8-json.h \
|
||||
/Users/karolsojko/Library/Caches/node-gyp/20.1.0/include/node/v8-locker.h \
|
||||
/Users/karolsojko/Library/Caches/node-gyp/20.1.0/include/node/v8-microtask-queue.h \
|
||||
/Users/karolsojko/Library/Caches/node-gyp/20.1.0/include/node/v8-primitive-object.h \
|
||||
/Users/karolsojko/Library/Caches/node-gyp/20.1.0/include/node/v8-proxy.h \
|
||||
/Users/karolsojko/Library/Caches/node-gyp/20.1.0/include/node/v8-regexp.h \
|
||||
/Users/karolsojko/Library/Caches/node-gyp/20.1.0/include/node/v8-typed-array.h \
|
||||
/Users/karolsojko/Library/Caches/node-gyp/20.1.0/include/node/v8-value-serializer.h \
|
||||
/Users/karolsojko/Library/Caches/node-gyp/20.1.0/include/node/v8-wasm.h \
|
||||
/Users/karolsojko/Library/Caches/node-gyp/20.1.0/include/node/node_api.h \
|
||||
/Users/karolsojko/Library/Caches/node-gyp/20.1.0/include/node/js_native_api.h \
|
||||
/Users/karolsojko/Library/Caches/node-gyp/20.1.0/include/node/js_native_api_types.h \
|
||||
/Users/karolsojko/Library/Caches/node-gyp/20.1.0/include/node/node_api_types.h \
|
||||
/Users/karolsojko/Library/Caches/node-gyp/20.1.0/include/node/node_buffer.h \
|
||||
/Users/karolsojko/Library/Caches/node-gyp/20.1.0/include/node/node_object_wrap.h \
|
||||
/Users/karolsojko/Library/Caches/node-gyp/20.2.0/include/node/node_version.h \
|
||||
/Users/karolsojko/Library/Caches/node-gyp/20.2.0/include/node/node.h \
|
||||
/Users/karolsojko/Library/Caches/node-gyp/20.2.0/include/node/v8.h \
|
||||
/Users/karolsojko/Library/Caches/node-gyp/20.2.0/include/node/cppgc/common.h \
|
||||
/Users/karolsojko/Library/Caches/node-gyp/20.2.0/include/node/v8config.h \
|
||||
/Users/karolsojko/Library/Caches/node-gyp/20.2.0/include/node/v8-array-buffer.h \
|
||||
/Users/karolsojko/Library/Caches/node-gyp/20.2.0/include/node/v8-local-handle.h \
|
||||
/Users/karolsojko/Library/Caches/node-gyp/20.2.0/include/node/v8-internal.h \
|
||||
/Users/karolsojko/Library/Caches/node-gyp/20.2.0/include/node/v8-version.h \
|
||||
/Users/karolsojko/Library/Caches/node-gyp/20.2.0/include/node/v8-object.h \
|
||||
/Users/karolsojko/Library/Caches/node-gyp/20.2.0/include/node/v8-maybe.h \
|
||||
/Users/karolsojko/Library/Caches/node-gyp/20.2.0/include/node/v8-persistent-handle.h \
|
||||
/Users/karolsojko/Library/Caches/node-gyp/20.2.0/include/node/v8-weak-callback-info.h \
|
||||
/Users/karolsojko/Library/Caches/node-gyp/20.2.0/include/node/v8-primitive.h \
|
||||
/Users/karolsojko/Library/Caches/node-gyp/20.2.0/include/node/v8-data.h \
|
||||
/Users/karolsojko/Library/Caches/node-gyp/20.2.0/include/node/v8-value.h \
|
||||
/Users/karolsojko/Library/Caches/node-gyp/20.2.0/include/node/v8-traced-handle.h \
|
||||
/Users/karolsojko/Library/Caches/node-gyp/20.2.0/include/node/v8-container.h \
|
||||
/Users/karolsojko/Library/Caches/node-gyp/20.2.0/include/node/v8-context.h \
|
||||
/Users/karolsojko/Library/Caches/node-gyp/20.2.0/include/node/v8-snapshot.h \
|
||||
/Users/karolsojko/Library/Caches/node-gyp/20.2.0/include/node/v8-date.h \
|
||||
/Users/karolsojko/Library/Caches/node-gyp/20.2.0/include/node/v8-debug.h \
|
||||
/Users/karolsojko/Library/Caches/node-gyp/20.2.0/include/node/v8-script.h \
|
||||
/Users/karolsojko/Library/Caches/node-gyp/20.2.0/include/node/v8-callbacks.h \
|
||||
/Users/karolsojko/Library/Caches/node-gyp/20.2.0/include/node/v8-promise.h \
|
||||
/Users/karolsojko/Library/Caches/node-gyp/20.2.0/include/node/v8-message.h \
|
||||
/Users/karolsojko/Library/Caches/node-gyp/20.2.0/include/node/v8-exception.h \
|
||||
/Users/karolsojko/Library/Caches/node-gyp/20.2.0/include/node/v8-extension.h \
|
||||
/Users/karolsojko/Library/Caches/node-gyp/20.2.0/include/node/v8-external.h \
|
||||
/Users/karolsojko/Library/Caches/node-gyp/20.2.0/include/node/v8-function.h \
|
||||
/Users/karolsojko/Library/Caches/node-gyp/20.2.0/include/node/v8-function-callback.h \
|
||||
/Users/karolsojko/Library/Caches/node-gyp/20.2.0/include/node/v8-template.h \
|
||||
/Users/karolsojko/Library/Caches/node-gyp/20.2.0/include/node/v8-memory-span.h \
|
||||
/Users/karolsojko/Library/Caches/node-gyp/20.2.0/include/node/v8-initialization.h \
|
||||
/Users/karolsojko/Library/Caches/node-gyp/20.2.0/include/node/v8-isolate.h \
|
||||
/Users/karolsojko/Library/Caches/node-gyp/20.2.0/include/node/v8-embedder-heap.h \
|
||||
/Users/karolsojko/Library/Caches/node-gyp/20.2.0/include/node/v8-microtask.h \
|
||||
/Users/karolsojko/Library/Caches/node-gyp/20.2.0/include/node/v8-statistics.h \
|
||||
/Users/karolsojko/Library/Caches/node-gyp/20.2.0/include/node/v8-unwinder.h \
|
||||
/Users/karolsojko/Library/Caches/node-gyp/20.2.0/include/node/v8-embedder-state-scope.h \
|
||||
/Users/karolsojko/Library/Caches/node-gyp/20.2.0/include/node/v8-platform.h \
|
||||
/Users/karolsojko/Library/Caches/node-gyp/20.2.0/include/node/v8-json.h \
|
||||
/Users/karolsojko/Library/Caches/node-gyp/20.2.0/include/node/v8-locker.h \
|
||||
/Users/karolsojko/Library/Caches/node-gyp/20.2.0/include/node/v8-microtask-queue.h \
|
||||
/Users/karolsojko/Library/Caches/node-gyp/20.2.0/include/node/v8-primitive-object.h \
|
||||
/Users/karolsojko/Library/Caches/node-gyp/20.2.0/include/node/v8-proxy.h \
|
||||
/Users/karolsojko/Library/Caches/node-gyp/20.2.0/include/node/v8-regexp.h \
|
||||
/Users/karolsojko/Library/Caches/node-gyp/20.2.0/include/node/v8-typed-array.h \
|
||||
/Users/karolsojko/Library/Caches/node-gyp/20.2.0/include/node/v8-value-serializer.h \
|
||||
/Users/karolsojko/Library/Caches/node-gyp/20.2.0/include/node/v8-wasm.h \
|
||||
/Users/karolsojko/Library/Caches/node-gyp/20.2.0/include/node/node_api.h \
|
||||
/Users/karolsojko/Library/Caches/node-gyp/20.2.0/include/node/js_native_api.h \
|
||||
/Users/karolsojko/Library/Caches/node-gyp/20.2.0/include/node/js_native_api_types.h \
|
||||
/Users/karolsojko/Library/Caches/node-gyp/20.2.0/include/node/node_api_types.h \
|
||||
/Users/karolsojko/Library/Caches/node-gyp/20.2.0/include/node/node_buffer.h \
|
||||
/Users/karolsojko/Library/Caches/node-gyp/20.2.0/include/node/node_object_wrap.h \
|
||||
../../../../../nan-npm-2.17.0-bf36a21d6f/node_modules/nan/nan_callbacks.h \
|
||||
../../../../../nan-npm-2.17.0-bf36a21d6f/node_modules/nan/nan_callbacks_12_inl.h \
|
||||
../../../../../nan-npm-2.17.0-bf36a21d6f/node_modules/nan/nan_maybe_43_inl.h \
|
||||
@@ -81,70 +81,70 @@ Release/obj.target/native_metrics/src/LoopChecker.o: \
|
||||
../../../../../nan-npm-2.17.0-bf36a21d6f/node_modules/nan/nan_scriptorigin.h \
|
||||
../src/Metric.hpp
|
||||
../src/LoopChecker.cpp:
|
||||
/Users/karolsojko/Library/Caches/node-gyp/20.1.0/include/node/uv.h:
|
||||
/Users/karolsojko/Library/Caches/node-gyp/20.1.0/include/node/uv/errno.h:
|
||||
/Users/karolsojko/Library/Caches/node-gyp/20.1.0/include/node/uv/version.h:
|
||||
/Users/karolsojko/Library/Caches/node-gyp/20.1.0/include/node/uv/unix.h:
|
||||
/Users/karolsojko/Library/Caches/node-gyp/20.1.0/include/node/uv/threadpool.h:
|
||||
/Users/karolsojko/Library/Caches/node-gyp/20.1.0/include/node/uv/darwin.h:
|
||||
/Users/karolsojko/Library/Caches/node-gyp/20.2.0/include/node/uv.h:
|
||||
/Users/karolsojko/Library/Caches/node-gyp/20.2.0/include/node/uv/errno.h:
|
||||
/Users/karolsojko/Library/Caches/node-gyp/20.2.0/include/node/uv/version.h:
|
||||
/Users/karolsojko/Library/Caches/node-gyp/20.2.0/include/node/uv/unix.h:
|
||||
/Users/karolsojko/Library/Caches/node-gyp/20.2.0/include/node/uv/threadpool.h:
|
||||
/Users/karolsojko/Library/Caches/node-gyp/20.2.0/include/node/uv/darwin.h:
|
||||
../src/LoopChecker.hpp:
|
||||
../../../../../nan-npm-2.17.0-bf36a21d6f/node_modules/nan/nan.h:
|
||||
/Users/karolsojko/Library/Caches/node-gyp/20.1.0/include/node/node_version.h:
|
||||
/Users/karolsojko/Library/Caches/node-gyp/20.1.0/include/node/node.h:
|
||||
/Users/karolsojko/Library/Caches/node-gyp/20.1.0/include/node/v8.h:
|
||||
/Users/karolsojko/Library/Caches/node-gyp/20.1.0/include/node/cppgc/common.h:
|
||||
/Users/karolsojko/Library/Caches/node-gyp/20.1.0/include/node/v8config.h:
|
||||
/Users/karolsojko/Library/Caches/node-gyp/20.1.0/include/node/v8-array-buffer.h:
|
||||
/Users/karolsojko/Library/Caches/node-gyp/20.1.0/include/node/v8-local-handle.h:
|
||||
/Users/karolsojko/Library/Caches/node-gyp/20.1.0/include/node/v8-internal.h:
|
||||
/Users/karolsojko/Library/Caches/node-gyp/20.1.0/include/node/v8-version.h:
|
||||
/Users/karolsojko/Library/Caches/node-gyp/20.1.0/include/node/v8-object.h:
|
||||
/Users/karolsojko/Library/Caches/node-gyp/20.1.0/include/node/v8-maybe.h:
|
||||
/Users/karolsojko/Library/Caches/node-gyp/20.1.0/include/node/v8-persistent-handle.h:
|
||||
/Users/karolsojko/Library/Caches/node-gyp/20.1.0/include/node/v8-weak-callback-info.h:
|
||||
/Users/karolsojko/Library/Caches/node-gyp/20.1.0/include/node/v8-primitive.h:
|
||||
/Users/karolsojko/Library/Caches/node-gyp/20.1.0/include/node/v8-data.h:
|
||||
/Users/karolsojko/Library/Caches/node-gyp/20.1.0/include/node/v8-value.h:
|
||||
/Users/karolsojko/Library/Caches/node-gyp/20.1.0/include/node/v8-traced-handle.h:
|
||||
/Users/karolsojko/Library/Caches/node-gyp/20.1.0/include/node/v8-container.h:
|
||||
/Users/karolsojko/Library/Caches/node-gyp/20.1.0/include/node/v8-context.h:
|
||||
/Users/karolsojko/Library/Caches/node-gyp/20.1.0/include/node/v8-snapshot.h:
|
||||
/Users/karolsojko/Library/Caches/node-gyp/20.1.0/include/node/v8-date.h:
|
||||
/Users/karolsojko/Library/Caches/node-gyp/20.1.0/include/node/v8-debug.h:
|
||||
/Users/karolsojko/Library/Caches/node-gyp/20.1.0/include/node/v8-script.h:
|
||||
/Users/karolsojko/Library/Caches/node-gyp/20.1.0/include/node/v8-callbacks.h:
|
||||
/Users/karolsojko/Library/Caches/node-gyp/20.1.0/include/node/v8-promise.h:
|
||||
/Users/karolsojko/Library/Caches/node-gyp/20.1.0/include/node/v8-message.h:
|
||||
/Users/karolsojko/Library/Caches/node-gyp/20.1.0/include/node/v8-exception.h:
|
||||
/Users/karolsojko/Library/Caches/node-gyp/20.1.0/include/node/v8-extension.h:
|
||||
/Users/karolsojko/Library/Caches/node-gyp/20.1.0/include/node/v8-external.h:
|
||||
/Users/karolsojko/Library/Caches/node-gyp/20.1.0/include/node/v8-function.h:
|
||||
/Users/karolsojko/Library/Caches/node-gyp/20.1.0/include/node/v8-function-callback.h:
|
||||
/Users/karolsojko/Library/Caches/node-gyp/20.1.0/include/node/v8-template.h:
|
||||
/Users/karolsojko/Library/Caches/node-gyp/20.1.0/include/node/v8-memory-span.h:
|
||||
/Users/karolsojko/Library/Caches/node-gyp/20.1.0/include/node/v8-initialization.h:
|
||||
/Users/karolsojko/Library/Caches/node-gyp/20.1.0/include/node/v8-isolate.h:
|
||||
/Users/karolsojko/Library/Caches/node-gyp/20.1.0/include/node/v8-embedder-heap.h:
|
||||
/Users/karolsojko/Library/Caches/node-gyp/20.1.0/include/node/v8-microtask.h:
|
||||
/Users/karolsojko/Library/Caches/node-gyp/20.1.0/include/node/v8-statistics.h:
|
||||
/Users/karolsojko/Library/Caches/node-gyp/20.1.0/include/node/v8-unwinder.h:
|
||||
/Users/karolsojko/Library/Caches/node-gyp/20.1.0/include/node/v8-embedder-state-scope.h:
|
||||
/Users/karolsojko/Library/Caches/node-gyp/20.1.0/include/node/v8-platform.h:
|
||||
/Users/karolsojko/Library/Caches/node-gyp/20.1.0/include/node/v8-json.h:
|
||||
/Users/karolsojko/Library/Caches/node-gyp/20.1.0/include/node/v8-locker.h:
|
||||
/Users/karolsojko/Library/Caches/node-gyp/20.1.0/include/node/v8-microtask-queue.h:
|
||||
/Users/karolsojko/Library/Caches/node-gyp/20.1.0/include/node/v8-primitive-object.h:
|
||||
/Users/karolsojko/Library/Caches/node-gyp/20.1.0/include/node/v8-proxy.h:
|
||||
/Users/karolsojko/Library/Caches/node-gyp/20.1.0/include/node/v8-regexp.h:
|
||||
/Users/karolsojko/Library/Caches/node-gyp/20.1.0/include/node/v8-typed-array.h:
|
||||
/Users/karolsojko/Library/Caches/node-gyp/20.1.0/include/node/v8-value-serializer.h:
|
||||
/Users/karolsojko/Library/Caches/node-gyp/20.1.0/include/node/v8-wasm.h:
|
||||
/Users/karolsojko/Library/Caches/node-gyp/20.1.0/include/node/node_api.h:
|
||||
/Users/karolsojko/Library/Caches/node-gyp/20.1.0/include/node/js_native_api.h:
|
||||
/Users/karolsojko/Library/Caches/node-gyp/20.1.0/include/node/js_native_api_types.h:
|
||||
/Users/karolsojko/Library/Caches/node-gyp/20.1.0/include/node/node_api_types.h:
|
||||
/Users/karolsojko/Library/Caches/node-gyp/20.1.0/include/node/node_buffer.h:
|
||||
/Users/karolsojko/Library/Caches/node-gyp/20.1.0/include/node/node_object_wrap.h:
|
||||
/Users/karolsojko/Library/Caches/node-gyp/20.2.0/include/node/node_version.h:
|
||||
/Users/karolsojko/Library/Caches/node-gyp/20.2.0/include/node/node.h:
|
||||
/Users/karolsojko/Library/Caches/node-gyp/20.2.0/include/node/v8.h:
|
||||
/Users/karolsojko/Library/Caches/node-gyp/20.2.0/include/node/cppgc/common.h:
|
||||
/Users/karolsojko/Library/Caches/node-gyp/20.2.0/include/node/v8config.h:
|
||||
/Users/karolsojko/Library/Caches/node-gyp/20.2.0/include/node/v8-array-buffer.h:
|
||||
/Users/karolsojko/Library/Caches/node-gyp/20.2.0/include/node/v8-local-handle.h:
|
||||
/Users/karolsojko/Library/Caches/node-gyp/20.2.0/include/node/v8-internal.h:
|
||||
/Users/karolsojko/Library/Caches/node-gyp/20.2.0/include/node/v8-version.h:
|
||||
/Users/karolsojko/Library/Caches/node-gyp/20.2.0/include/node/v8-object.h:
|
||||
/Users/karolsojko/Library/Caches/node-gyp/20.2.0/include/node/v8-maybe.h:
|
||||
/Users/karolsojko/Library/Caches/node-gyp/20.2.0/include/node/v8-persistent-handle.h:
|
||||
/Users/karolsojko/Library/Caches/node-gyp/20.2.0/include/node/v8-weak-callback-info.h:
|
||||
/Users/karolsojko/Library/Caches/node-gyp/20.2.0/include/node/v8-primitive.h:
|
||||
/Users/karolsojko/Library/Caches/node-gyp/20.2.0/include/node/v8-data.h:
|
||||
/Users/karolsojko/Library/Caches/node-gyp/20.2.0/include/node/v8-value.h:
|
||||
/Users/karolsojko/Library/Caches/node-gyp/20.2.0/include/node/v8-traced-handle.h:
|
||||
/Users/karolsojko/Library/Caches/node-gyp/20.2.0/include/node/v8-container.h:
|
||||
/Users/karolsojko/Library/Caches/node-gyp/20.2.0/include/node/v8-context.h:
|
||||
/Users/karolsojko/Library/Caches/node-gyp/20.2.0/include/node/v8-snapshot.h:
|
||||
/Users/karolsojko/Library/Caches/node-gyp/20.2.0/include/node/v8-date.h:
|
||||
/Users/karolsojko/Library/Caches/node-gyp/20.2.0/include/node/v8-debug.h:
|
||||
/Users/karolsojko/Library/Caches/node-gyp/20.2.0/include/node/v8-script.h:
|
||||
/Users/karolsojko/Library/Caches/node-gyp/20.2.0/include/node/v8-callbacks.h:
|
||||
/Users/karolsojko/Library/Caches/node-gyp/20.2.0/include/node/v8-promise.h:
|
||||
/Users/karolsojko/Library/Caches/node-gyp/20.2.0/include/node/v8-message.h:
|
||||
/Users/karolsojko/Library/Caches/node-gyp/20.2.0/include/node/v8-exception.h:
|
||||
/Users/karolsojko/Library/Caches/node-gyp/20.2.0/include/node/v8-extension.h:
|
||||
/Users/karolsojko/Library/Caches/node-gyp/20.2.0/include/node/v8-external.h:
|
||||
/Users/karolsojko/Library/Caches/node-gyp/20.2.0/include/node/v8-function.h:
|
||||
/Users/karolsojko/Library/Caches/node-gyp/20.2.0/include/node/v8-function-callback.h:
|
||||
/Users/karolsojko/Library/Caches/node-gyp/20.2.0/include/node/v8-template.h:
|
||||
/Users/karolsojko/Library/Caches/node-gyp/20.2.0/include/node/v8-memory-span.h:
|
||||
/Users/karolsojko/Library/Caches/node-gyp/20.2.0/include/node/v8-initialization.h:
|
||||
/Users/karolsojko/Library/Caches/node-gyp/20.2.0/include/node/v8-isolate.h:
|
||||
/Users/karolsojko/Library/Caches/node-gyp/20.2.0/include/node/v8-embedder-heap.h:
|
||||
/Users/karolsojko/Library/Caches/node-gyp/20.2.0/include/node/v8-microtask.h:
|
||||
/Users/karolsojko/Library/Caches/node-gyp/20.2.0/include/node/v8-statistics.h:
|
||||
/Users/karolsojko/Library/Caches/node-gyp/20.2.0/include/node/v8-unwinder.h:
|
||||
/Users/karolsojko/Library/Caches/node-gyp/20.2.0/include/node/v8-embedder-state-scope.h:
|
||||
/Users/karolsojko/Library/Caches/node-gyp/20.2.0/include/node/v8-platform.h:
|
||||
/Users/karolsojko/Library/Caches/node-gyp/20.2.0/include/node/v8-json.h:
|
||||
/Users/karolsojko/Library/Caches/node-gyp/20.2.0/include/node/v8-locker.h:
|
||||
/Users/karolsojko/Library/Caches/node-gyp/20.2.0/include/node/v8-microtask-queue.h:
|
||||
/Users/karolsojko/Library/Caches/node-gyp/20.2.0/include/node/v8-primitive-object.h:
|
||||
/Users/karolsojko/Library/Caches/node-gyp/20.2.0/include/node/v8-proxy.h:
|
||||
/Users/karolsojko/Library/Caches/node-gyp/20.2.0/include/node/v8-regexp.h:
|
||||
/Users/karolsojko/Library/Caches/node-gyp/20.2.0/include/node/v8-typed-array.h:
|
||||
/Users/karolsojko/Library/Caches/node-gyp/20.2.0/include/node/v8-value-serializer.h:
|
||||
/Users/karolsojko/Library/Caches/node-gyp/20.2.0/include/node/v8-wasm.h:
|
||||
/Users/karolsojko/Library/Caches/node-gyp/20.2.0/include/node/node_api.h:
|
||||
/Users/karolsojko/Library/Caches/node-gyp/20.2.0/include/node/js_native_api.h:
|
||||
/Users/karolsojko/Library/Caches/node-gyp/20.2.0/include/node/js_native_api_types.h:
|
||||
/Users/karolsojko/Library/Caches/node-gyp/20.2.0/include/node/node_api_types.h:
|
||||
/Users/karolsojko/Library/Caches/node-gyp/20.2.0/include/node/node_buffer.h:
|
||||
/Users/karolsojko/Library/Caches/node-gyp/20.2.0/include/node/node_object_wrap.h:
|
||||
../../../../../nan-npm-2.17.0-bf36a21d6f/node_modules/nan/nan_callbacks.h:
|
||||
../../../../../nan-npm-2.17.0-bf36a21d6f/node_modules/nan/nan_callbacks_12_inl.h:
|
||||
../../../../../nan-npm-2.17.0-bf36a21d6f/node_modules/nan/nan_maybe_43_inl.h:
|
||||
|
||||
@@ -1,69 +1,69 @@
|
||||
cmd_Release/obj.target/native_metrics/src/native_metrics.o := c++ -o Release/obj.target/native_metrics/src/native_metrics.o ../src/native_metrics.cpp '-DNODE_GYP_MODULE_NAME=native_metrics' '-DUSING_UV_SHARED=1' '-DUSING_V8_SHARED=1' '-DV8_DEPRECATION_WARNINGS=1' '-DV8_DEPRECATION_WARNINGS' '-DV8_IMMINENT_DEPRECATION_WARNINGS' '-D_GLIBCXX_USE_CXX11_ABI=1' '-D_DARWIN_USE_64_BIT_INODE=1' '-D_LARGEFILE_SOURCE' '-D_FILE_OFFSET_BITS=64' '-DOPENSSL_NO_PINSHARED' '-DOPENSSL_THREADS' '-DNOMINMAX' '-DBUILDING_NODE_EXTENSION' -I/Users/karolsojko/Library/Caches/node-gyp/20.1.0/include/node -I/Users/karolsojko/Library/Caches/node-gyp/20.1.0/src -I/Users/karolsojko/Library/Caches/node-gyp/20.1.0/deps/openssl/config -I/Users/karolsojko/Library/Caches/node-gyp/20.1.0/deps/openssl/openssl/include -I/Users/karolsojko/Library/Caches/node-gyp/20.1.0/deps/uv/include -I/Users/karolsojko/Library/Caches/node-gyp/20.1.0/deps/zlib -I/Users/karolsojko/Library/Caches/node-gyp/20.1.0/deps/v8/include -I../src -I../../../../../nan-npm-2.17.0-bf36a21d6f/node_modules/nan -O3 -gdwarf-2 -mmacosx-version-min=10.15 -arch arm64 -Wall -Wendif-labels -W -Wno-unused-parameter -std=gnu++17 -stdlib=libc++ -fno-rtti -fno-exceptions -fno-strict-aliasing -MMD -MF ./Release/.deps/Release/obj.target/native_metrics/src/native_metrics.o.d.raw -c
|
||||
cmd_Release/obj.target/native_metrics/src/native_metrics.o := c++ -o Release/obj.target/native_metrics/src/native_metrics.o ../src/native_metrics.cpp '-DNODE_GYP_MODULE_NAME=native_metrics' '-DUSING_UV_SHARED=1' '-DUSING_V8_SHARED=1' '-DV8_DEPRECATION_WARNINGS=1' '-DV8_DEPRECATION_WARNINGS' '-DV8_IMMINENT_DEPRECATION_WARNINGS' '-D_GLIBCXX_USE_CXX11_ABI=1' '-D_DARWIN_USE_64_BIT_INODE=1' '-D_LARGEFILE_SOURCE' '-D_FILE_OFFSET_BITS=64' '-DOPENSSL_NO_PINSHARED' '-DOPENSSL_THREADS' '-DNOMINMAX' '-DBUILDING_NODE_EXTENSION' -I/Users/karolsojko/Library/Caches/node-gyp/20.2.0/include/node -I/Users/karolsojko/Library/Caches/node-gyp/20.2.0/src -I/Users/karolsojko/Library/Caches/node-gyp/20.2.0/deps/openssl/config -I/Users/karolsojko/Library/Caches/node-gyp/20.2.0/deps/openssl/openssl/include -I/Users/karolsojko/Library/Caches/node-gyp/20.2.0/deps/uv/include -I/Users/karolsojko/Library/Caches/node-gyp/20.2.0/deps/zlib -I/Users/karolsojko/Library/Caches/node-gyp/20.2.0/deps/v8/include -I../src -I../../../../../nan-npm-2.17.0-bf36a21d6f/node_modules/nan -O3 -gdwarf-2 -mmacosx-version-min=10.15 -arch arm64 -Wall -Wendif-labels -W -Wno-unused-parameter -std=gnu++17 -stdlib=libc++ -fno-rtti -fno-exceptions -fno-strict-aliasing -MMD -MF ./Release/.deps/Release/obj.target/native_metrics/src/native_metrics.o.d.raw -c
|
||||
Release/obj.target/native_metrics/src/native_metrics.o: \
|
||||
../src/native_metrics.cpp \
|
||||
../../../../../nan-npm-2.17.0-bf36a21d6f/node_modules/nan/nan.h \
|
||||
/Users/karolsojko/Library/Caches/node-gyp/20.1.0/include/node/node_version.h \
|
||||
/Users/karolsojko/Library/Caches/node-gyp/20.1.0/include/node/uv.h \
|
||||
/Users/karolsojko/Library/Caches/node-gyp/20.1.0/include/node/uv/errno.h \
|
||||
/Users/karolsojko/Library/Caches/node-gyp/20.1.0/include/node/uv/version.h \
|
||||
/Users/karolsojko/Library/Caches/node-gyp/20.1.0/include/node/uv/unix.h \
|
||||
/Users/karolsojko/Library/Caches/node-gyp/20.1.0/include/node/uv/threadpool.h \
|
||||
/Users/karolsojko/Library/Caches/node-gyp/20.1.0/include/node/uv/darwin.h \
|
||||
/Users/karolsojko/Library/Caches/node-gyp/20.1.0/include/node/node.h \
|
||||
/Users/karolsojko/Library/Caches/node-gyp/20.1.0/include/node/v8.h \
|
||||
/Users/karolsojko/Library/Caches/node-gyp/20.1.0/include/node/cppgc/common.h \
|
||||
/Users/karolsojko/Library/Caches/node-gyp/20.1.0/include/node/v8config.h \
|
||||
/Users/karolsojko/Library/Caches/node-gyp/20.1.0/include/node/v8-array-buffer.h \
|
||||
/Users/karolsojko/Library/Caches/node-gyp/20.1.0/include/node/v8-local-handle.h \
|
||||
/Users/karolsojko/Library/Caches/node-gyp/20.1.0/include/node/v8-internal.h \
|
||||
/Users/karolsojko/Library/Caches/node-gyp/20.1.0/include/node/v8-version.h \
|
||||
/Users/karolsojko/Library/Caches/node-gyp/20.1.0/include/node/v8-object.h \
|
||||
/Users/karolsojko/Library/Caches/node-gyp/20.1.0/include/node/v8-maybe.h \
|
||||
/Users/karolsojko/Library/Caches/node-gyp/20.1.0/include/node/v8-persistent-handle.h \
|
||||
/Users/karolsojko/Library/Caches/node-gyp/20.1.0/include/node/v8-weak-callback-info.h \
|
||||
/Users/karolsojko/Library/Caches/node-gyp/20.1.0/include/node/v8-primitive.h \
|
||||
/Users/karolsojko/Library/Caches/node-gyp/20.1.0/include/node/v8-data.h \
|
||||
/Users/karolsojko/Library/Caches/node-gyp/20.1.0/include/node/v8-value.h \
|
||||
/Users/karolsojko/Library/Caches/node-gyp/20.1.0/include/node/v8-traced-handle.h \
|
||||
/Users/karolsojko/Library/Caches/node-gyp/20.1.0/include/node/v8-container.h \
|
||||
/Users/karolsojko/Library/Caches/node-gyp/20.1.0/include/node/v8-context.h \
|
||||
/Users/karolsojko/Library/Caches/node-gyp/20.1.0/include/node/v8-snapshot.h \
|
||||
/Users/karolsojko/Library/Caches/node-gyp/20.1.0/include/node/v8-date.h \
|
||||
/Users/karolsojko/Library/Caches/node-gyp/20.1.0/include/node/v8-debug.h \
|
||||
/Users/karolsojko/Library/Caches/node-gyp/20.1.0/include/node/v8-script.h \
|
||||
/Users/karolsojko/Library/Caches/node-gyp/20.1.0/include/node/v8-callbacks.h \
|
||||
/Users/karolsojko/Library/Caches/node-gyp/20.1.0/include/node/v8-promise.h \
|
||||
/Users/karolsojko/Library/Caches/node-gyp/20.1.0/include/node/v8-message.h \
|
||||
/Users/karolsojko/Library/Caches/node-gyp/20.1.0/include/node/v8-exception.h \
|
||||
/Users/karolsojko/Library/Caches/node-gyp/20.1.0/include/node/v8-extension.h \
|
||||
/Users/karolsojko/Library/Caches/node-gyp/20.1.0/include/node/v8-external.h \
|
||||
/Users/karolsojko/Library/Caches/node-gyp/20.1.0/include/node/v8-function.h \
|
||||
/Users/karolsojko/Library/Caches/node-gyp/20.1.0/include/node/v8-function-callback.h \
|
||||
/Users/karolsojko/Library/Caches/node-gyp/20.1.0/include/node/v8-template.h \
|
||||
/Users/karolsojko/Library/Caches/node-gyp/20.1.0/include/node/v8-memory-span.h \
|
||||
/Users/karolsojko/Library/Caches/node-gyp/20.1.0/include/node/v8-initialization.h \
|
||||
/Users/karolsojko/Library/Caches/node-gyp/20.1.0/include/node/v8-isolate.h \
|
||||
/Users/karolsojko/Library/Caches/node-gyp/20.1.0/include/node/v8-embedder-heap.h \
|
||||
/Users/karolsojko/Library/Caches/node-gyp/20.1.0/include/node/v8-microtask.h \
|
||||
/Users/karolsojko/Library/Caches/node-gyp/20.1.0/include/node/v8-statistics.h \
|
||||
/Users/karolsojko/Library/Caches/node-gyp/20.1.0/include/node/v8-unwinder.h \
|
||||
/Users/karolsojko/Library/Caches/node-gyp/20.1.0/include/node/v8-embedder-state-scope.h \
|
||||
/Users/karolsojko/Library/Caches/node-gyp/20.1.0/include/node/v8-platform.h \
|
||||
/Users/karolsojko/Library/Caches/node-gyp/20.1.0/include/node/v8-json.h \
|
||||
/Users/karolsojko/Library/Caches/node-gyp/20.1.0/include/node/v8-locker.h \
|
||||
/Users/karolsojko/Library/Caches/node-gyp/20.1.0/include/node/v8-microtask-queue.h \
|
||||
/Users/karolsojko/Library/Caches/node-gyp/20.1.0/include/node/v8-primitive-object.h \
|
||||
/Users/karolsojko/Library/Caches/node-gyp/20.1.0/include/node/v8-proxy.h \
|
||||
/Users/karolsojko/Library/Caches/node-gyp/20.1.0/include/node/v8-regexp.h \
|
||||
/Users/karolsojko/Library/Caches/node-gyp/20.1.0/include/node/v8-typed-array.h \
|
||||
/Users/karolsojko/Library/Caches/node-gyp/20.1.0/include/node/v8-value-serializer.h \
|
||||
/Users/karolsojko/Library/Caches/node-gyp/20.1.0/include/node/v8-wasm.h \
|
||||
/Users/karolsojko/Library/Caches/node-gyp/20.1.0/include/node/node_api.h \
|
||||
/Users/karolsojko/Library/Caches/node-gyp/20.1.0/include/node/js_native_api.h \
|
||||
/Users/karolsojko/Library/Caches/node-gyp/20.1.0/include/node/js_native_api_types.h \
|
||||
/Users/karolsojko/Library/Caches/node-gyp/20.1.0/include/node/node_api_types.h \
|
||||
/Users/karolsojko/Library/Caches/node-gyp/20.1.0/include/node/node_buffer.h \
|
||||
/Users/karolsojko/Library/Caches/node-gyp/20.1.0/include/node/node_object_wrap.h \
|
||||
/Users/karolsojko/Library/Caches/node-gyp/20.2.0/include/node/node_version.h \
|
||||
/Users/karolsojko/Library/Caches/node-gyp/20.2.0/include/node/uv.h \
|
||||
/Users/karolsojko/Library/Caches/node-gyp/20.2.0/include/node/uv/errno.h \
|
||||
/Users/karolsojko/Library/Caches/node-gyp/20.2.0/include/node/uv/version.h \
|
||||
/Users/karolsojko/Library/Caches/node-gyp/20.2.0/include/node/uv/unix.h \
|
||||
/Users/karolsojko/Library/Caches/node-gyp/20.2.0/include/node/uv/threadpool.h \
|
||||
/Users/karolsojko/Library/Caches/node-gyp/20.2.0/include/node/uv/darwin.h \
|
||||
/Users/karolsojko/Library/Caches/node-gyp/20.2.0/include/node/node.h \
|
||||
/Users/karolsojko/Library/Caches/node-gyp/20.2.0/include/node/v8.h \
|
||||
/Users/karolsojko/Library/Caches/node-gyp/20.2.0/include/node/cppgc/common.h \
|
||||
/Users/karolsojko/Library/Caches/node-gyp/20.2.0/include/node/v8config.h \
|
||||
/Users/karolsojko/Library/Caches/node-gyp/20.2.0/include/node/v8-array-buffer.h \
|
||||
/Users/karolsojko/Library/Caches/node-gyp/20.2.0/include/node/v8-local-handle.h \
|
||||
/Users/karolsojko/Library/Caches/node-gyp/20.2.0/include/node/v8-internal.h \
|
||||
/Users/karolsojko/Library/Caches/node-gyp/20.2.0/include/node/v8-version.h \
|
||||
/Users/karolsojko/Library/Caches/node-gyp/20.2.0/include/node/v8-object.h \
|
||||
/Users/karolsojko/Library/Caches/node-gyp/20.2.0/include/node/v8-maybe.h \
|
||||
/Users/karolsojko/Library/Caches/node-gyp/20.2.0/include/node/v8-persistent-handle.h \
|
||||
/Users/karolsojko/Library/Caches/node-gyp/20.2.0/include/node/v8-weak-callback-info.h \
|
||||
/Users/karolsojko/Library/Caches/node-gyp/20.2.0/include/node/v8-primitive.h \
|
||||
/Users/karolsojko/Library/Caches/node-gyp/20.2.0/include/node/v8-data.h \
|
||||
/Users/karolsojko/Library/Caches/node-gyp/20.2.0/include/node/v8-value.h \
|
||||
/Users/karolsojko/Library/Caches/node-gyp/20.2.0/include/node/v8-traced-handle.h \
|
||||
/Users/karolsojko/Library/Caches/node-gyp/20.2.0/include/node/v8-container.h \
|
||||
/Users/karolsojko/Library/Caches/node-gyp/20.2.0/include/node/v8-context.h \
|
||||
/Users/karolsojko/Library/Caches/node-gyp/20.2.0/include/node/v8-snapshot.h \
|
||||
/Users/karolsojko/Library/Caches/node-gyp/20.2.0/include/node/v8-date.h \
|
||||
/Users/karolsojko/Library/Caches/node-gyp/20.2.0/include/node/v8-debug.h \
|
||||
/Users/karolsojko/Library/Caches/node-gyp/20.2.0/include/node/v8-script.h \
|
||||
/Users/karolsojko/Library/Caches/node-gyp/20.2.0/include/node/v8-callbacks.h \
|
||||
/Users/karolsojko/Library/Caches/node-gyp/20.2.0/include/node/v8-promise.h \
|
||||
/Users/karolsojko/Library/Caches/node-gyp/20.2.0/include/node/v8-message.h \
|
||||
/Users/karolsojko/Library/Caches/node-gyp/20.2.0/include/node/v8-exception.h \
|
||||
/Users/karolsojko/Library/Caches/node-gyp/20.2.0/include/node/v8-extension.h \
|
||||
/Users/karolsojko/Library/Caches/node-gyp/20.2.0/include/node/v8-external.h \
|
||||
/Users/karolsojko/Library/Caches/node-gyp/20.2.0/include/node/v8-function.h \
|
||||
/Users/karolsojko/Library/Caches/node-gyp/20.2.0/include/node/v8-function-callback.h \
|
||||
/Users/karolsojko/Library/Caches/node-gyp/20.2.0/include/node/v8-template.h \
|
||||
/Users/karolsojko/Library/Caches/node-gyp/20.2.0/include/node/v8-memory-span.h \
|
||||
/Users/karolsojko/Library/Caches/node-gyp/20.2.0/include/node/v8-initialization.h \
|
||||
/Users/karolsojko/Library/Caches/node-gyp/20.2.0/include/node/v8-isolate.h \
|
||||
/Users/karolsojko/Library/Caches/node-gyp/20.2.0/include/node/v8-embedder-heap.h \
|
||||
/Users/karolsojko/Library/Caches/node-gyp/20.2.0/include/node/v8-microtask.h \
|
||||
/Users/karolsojko/Library/Caches/node-gyp/20.2.0/include/node/v8-statistics.h \
|
||||
/Users/karolsojko/Library/Caches/node-gyp/20.2.0/include/node/v8-unwinder.h \
|
||||
/Users/karolsojko/Library/Caches/node-gyp/20.2.0/include/node/v8-embedder-state-scope.h \
|
||||
/Users/karolsojko/Library/Caches/node-gyp/20.2.0/include/node/v8-platform.h \
|
||||
/Users/karolsojko/Library/Caches/node-gyp/20.2.0/include/node/v8-json.h \
|
||||
/Users/karolsojko/Library/Caches/node-gyp/20.2.0/include/node/v8-locker.h \
|
||||
/Users/karolsojko/Library/Caches/node-gyp/20.2.0/include/node/v8-microtask-queue.h \
|
||||
/Users/karolsojko/Library/Caches/node-gyp/20.2.0/include/node/v8-primitive-object.h \
|
||||
/Users/karolsojko/Library/Caches/node-gyp/20.2.0/include/node/v8-proxy.h \
|
||||
/Users/karolsojko/Library/Caches/node-gyp/20.2.0/include/node/v8-regexp.h \
|
||||
/Users/karolsojko/Library/Caches/node-gyp/20.2.0/include/node/v8-typed-array.h \
|
||||
/Users/karolsojko/Library/Caches/node-gyp/20.2.0/include/node/v8-value-serializer.h \
|
||||
/Users/karolsojko/Library/Caches/node-gyp/20.2.0/include/node/v8-wasm.h \
|
||||
/Users/karolsojko/Library/Caches/node-gyp/20.2.0/include/node/node_api.h \
|
||||
/Users/karolsojko/Library/Caches/node-gyp/20.2.0/include/node/js_native_api.h \
|
||||
/Users/karolsojko/Library/Caches/node-gyp/20.2.0/include/node/js_native_api_types.h \
|
||||
/Users/karolsojko/Library/Caches/node-gyp/20.2.0/include/node/node_api_types.h \
|
||||
/Users/karolsojko/Library/Caches/node-gyp/20.2.0/include/node/node_buffer.h \
|
||||
/Users/karolsojko/Library/Caches/node-gyp/20.2.0/include/node/node_object_wrap.h \
|
||||
../../../../../nan-npm-2.17.0-bf36a21d6f/node_modules/nan/nan_callbacks.h \
|
||||
../../../../../nan-npm-2.17.0-bf36a21d6f/node_modules/nan/nan_callbacks_12_inl.h \
|
||||
../../../../../nan-npm-2.17.0-bf36a21d6f/node_modules/nan/nan_maybe_43_inl.h \
|
||||
@@ -81,68 +81,68 @@ Release/obj.target/native_metrics/src/native_metrics.o: \
|
||||
../src/GCBinder.hpp ../src/Metric.hpp ../src/LoopChecker.hpp
|
||||
../src/native_metrics.cpp:
|
||||
../../../../../nan-npm-2.17.0-bf36a21d6f/node_modules/nan/nan.h:
|
||||
/Users/karolsojko/Library/Caches/node-gyp/20.1.0/include/node/node_version.h:
|
||||
/Users/karolsojko/Library/Caches/node-gyp/20.1.0/include/node/uv.h:
|
||||
/Users/karolsojko/Library/Caches/node-gyp/20.1.0/include/node/uv/errno.h:
|
||||
/Users/karolsojko/Library/Caches/node-gyp/20.1.0/include/node/uv/version.h:
|
||||
/Users/karolsojko/Library/Caches/node-gyp/20.1.0/include/node/uv/unix.h:
|
||||
/Users/karolsojko/Library/Caches/node-gyp/20.1.0/include/node/uv/threadpool.h:
|
||||
/Users/karolsojko/Library/Caches/node-gyp/20.1.0/include/node/uv/darwin.h:
|
||||
/Users/karolsojko/Library/Caches/node-gyp/20.1.0/include/node/node.h:
|
||||
/Users/karolsojko/Library/Caches/node-gyp/20.1.0/include/node/v8.h:
|
||||
/Users/karolsojko/Library/Caches/node-gyp/20.1.0/include/node/cppgc/common.h:
|
||||
/Users/karolsojko/Library/Caches/node-gyp/20.1.0/include/node/v8config.h:
|
||||
/Users/karolsojko/Library/Caches/node-gyp/20.1.0/include/node/v8-array-buffer.h:
|
||||
/Users/karolsojko/Library/Caches/node-gyp/20.1.0/include/node/v8-local-handle.h:
|
||||
/Users/karolsojko/Library/Caches/node-gyp/20.1.0/include/node/v8-internal.h:
|
||||
/Users/karolsojko/Library/Caches/node-gyp/20.1.0/include/node/v8-version.h:
|
||||
/Users/karolsojko/Library/Caches/node-gyp/20.1.0/include/node/v8-object.h:
|
||||
/Users/karolsojko/Library/Caches/node-gyp/20.1.0/include/node/v8-maybe.h:
|
||||
/Users/karolsojko/Library/Caches/node-gyp/20.1.0/include/node/v8-persistent-handle.h:
|
||||
/Users/karolsojko/Library/Caches/node-gyp/20.1.0/include/node/v8-weak-callback-info.h:
|
||||
/Users/karolsojko/Library/Caches/node-gyp/20.1.0/include/node/v8-primitive.h:
|
||||
/Users/karolsojko/Library/Caches/node-gyp/20.1.0/include/node/v8-data.h:
|
||||
/Users/karolsojko/Library/Caches/node-gyp/20.1.0/include/node/v8-value.h:
|
||||
/Users/karolsojko/Library/Caches/node-gyp/20.1.0/include/node/v8-traced-handle.h:
|
||||
/Users/karolsojko/Library/Caches/node-gyp/20.1.0/include/node/v8-container.h:
|
||||
/Users/karolsojko/Library/Caches/node-gyp/20.1.0/include/node/v8-context.h:
|
||||
/Users/karolsojko/Library/Caches/node-gyp/20.1.0/include/node/v8-snapshot.h:
|
||||
/Users/karolsojko/Library/Caches/node-gyp/20.1.0/include/node/v8-date.h:
|
||||
/Users/karolsojko/Library/Caches/node-gyp/20.1.0/include/node/v8-debug.h:
|
||||
/Users/karolsojko/Library/Caches/node-gyp/20.1.0/include/node/v8-script.h:
|
||||
/Users/karolsojko/Library/Caches/node-gyp/20.1.0/include/node/v8-callbacks.h:
|
||||
/Users/karolsojko/Library/Caches/node-gyp/20.1.0/include/node/v8-promise.h:
|
||||
/Users/karolsojko/Library/Caches/node-gyp/20.1.0/include/node/v8-message.h:
|
||||
/Users/karolsojko/Library/Caches/node-gyp/20.1.0/include/node/v8-exception.h:
|
||||
/Users/karolsojko/Library/Caches/node-gyp/20.1.0/include/node/v8-extension.h:
|
||||
/Users/karolsojko/Library/Caches/node-gyp/20.1.0/include/node/v8-external.h:
|
||||
/Users/karolsojko/Library/Caches/node-gyp/20.1.0/include/node/v8-function.h:
|
||||
/Users/karolsojko/Library/Caches/node-gyp/20.1.0/include/node/v8-function-callback.h:
|
||||
/Users/karolsojko/Library/Caches/node-gyp/20.1.0/include/node/v8-template.h:
|
||||
/Users/karolsojko/Library/Caches/node-gyp/20.1.0/include/node/v8-memory-span.h:
|
||||
/Users/karolsojko/Library/Caches/node-gyp/20.1.0/include/node/v8-initialization.h:
|
||||
/Users/karolsojko/Library/Caches/node-gyp/20.1.0/include/node/v8-isolate.h:
|
||||
/Users/karolsojko/Library/Caches/node-gyp/20.1.0/include/node/v8-embedder-heap.h:
|
||||
/Users/karolsojko/Library/Caches/node-gyp/20.1.0/include/node/v8-microtask.h:
|
||||
/Users/karolsojko/Library/Caches/node-gyp/20.1.0/include/node/v8-statistics.h:
|
||||
/Users/karolsojko/Library/Caches/node-gyp/20.1.0/include/node/v8-unwinder.h:
|
||||
/Users/karolsojko/Library/Caches/node-gyp/20.1.0/include/node/v8-embedder-state-scope.h:
|
||||
/Users/karolsojko/Library/Caches/node-gyp/20.1.0/include/node/v8-platform.h:
|
||||
/Users/karolsojko/Library/Caches/node-gyp/20.1.0/include/node/v8-json.h:
|
||||
/Users/karolsojko/Library/Caches/node-gyp/20.1.0/include/node/v8-locker.h:
|
||||
/Users/karolsojko/Library/Caches/node-gyp/20.1.0/include/node/v8-microtask-queue.h:
|
||||
/Users/karolsojko/Library/Caches/node-gyp/20.1.0/include/node/v8-primitive-object.h:
|
||||
/Users/karolsojko/Library/Caches/node-gyp/20.1.0/include/node/v8-proxy.h:
|
||||
/Users/karolsojko/Library/Caches/node-gyp/20.1.0/include/node/v8-regexp.h:
|
||||
/Users/karolsojko/Library/Caches/node-gyp/20.1.0/include/node/v8-typed-array.h:
|
||||
/Users/karolsojko/Library/Caches/node-gyp/20.1.0/include/node/v8-value-serializer.h:
|
||||
/Users/karolsojko/Library/Caches/node-gyp/20.1.0/include/node/v8-wasm.h:
|
||||
/Users/karolsojko/Library/Caches/node-gyp/20.1.0/include/node/node_api.h:
|
||||
/Users/karolsojko/Library/Caches/node-gyp/20.1.0/include/node/js_native_api.h:
|
||||
/Users/karolsojko/Library/Caches/node-gyp/20.1.0/include/node/js_native_api_types.h:
|
||||
/Users/karolsojko/Library/Caches/node-gyp/20.1.0/include/node/node_api_types.h:
|
||||
/Users/karolsojko/Library/Caches/node-gyp/20.1.0/include/node/node_buffer.h:
|
||||
/Users/karolsojko/Library/Caches/node-gyp/20.1.0/include/node/node_object_wrap.h:
|
||||
/Users/karolsojko/Library/Caches/node-gyp/20.2.0/include/node/node_version.h:
|
||||
/Users/karolsojko/Library/Caches/node-gyp/20.2.0/include/node/uv.h:
|
||||
/Users/karolsojko/Library/Caches/node-gyp/20.2.0/include/node/uv/errno.h:
|
||||
/Users/karolsojko/Library/Caches/node-gyp/20.2.0/include/node/uv/version.h:
|
||||
/Users/karolsojko/Library/Caches/node-gyp/20.2.0/include/node/uv/unix.h:
|
||||
/Users/karolsojko/Library/Caches/node-gyp/20.2.0/include/node/uv/threadpool.h:
|
||||
/Users/karolsojko/Library/Caches/node-gyp/20.2.0/include/node/uv/darwin.h:
|
||||
/Users/karolsojko/Library/Caches/node-gyp/20.2.0/include/node/node.h:
|
||||
/Users/karolsojko/Library/Caches/node-gyp/20.2.0/include/node/v8.h:
|
||||
/Users/karolsojko/Library/Caches/node-gyp/20.2.0/include/node/cppgc/common.h:
|
||||
/Users/karolsojko/Library/Caches/node-gyp/20.2.0/include/node/v8config.h:
|
||||
/Users/karolsojko/Library/Caches/node-gyp/20.2.0/include/node/v8-array-buffer.h:
|
||||
/Users/karolsojko/Library/Caches/node-gyp/20.2.0/include/node/v8-local-handle.h:
|
||||
/Users/karolsojko/Library/Caches/node-gyp/20.2.0/include/node/v8-internal.h:
|
||||
/Users/karolsojko/Library/Caches/node-gyp/20.2.0/include/node/v8-version.h:
|
||||
/Users/karolsojko/Library/Caches/node-gyp/20.2.0/include/node/v8-object.h:
|
||||
/Users/karolsojko/Library/Caches/node-gyp/20.2.0/include/node/v8-maybe.h:
|
||||
/Users/karolsojko/Library/Caches/node-gyp/20.2.0/include/node/v8-persistent-handle.h:
|
||||
/Users/karolsojko/Library/Caches/node-gyp/20.2.0/include/node/v8-weak-callback-info.h:
|
||||
/Users/karolsojko/Library/Caches/node-gyp/20.2.0/include/node/v8-primitive.h:
|
||||
/Users/karolsojko/Library/Caches/node-gyp/20.2.0/include/node/v8-data.h:
|
||||
/Users/karolsojko/Library/Caches/node-gyp/20.2.0/include/node/v8-value.h:
|
||||
/Users/karolsojko/Library/Caches/node-gyp/20.2.0/include/node/v8-traced-handle.h:
|
||||
/Users/karolsojko/Library/Caches/node-gyp/20.2.0/include/node/v8-container.h:
|
||||
/Users/karolsojko/Library/Caches/node-gyp/20.2.0/include/node/v8-context.h:
|
||||
/Users/karolsojko/Library/Caches/node-gyp/20.2.0/include/node/v8-snapshot.h:
|
||||
/Users/karolsojko/Library/Caches/node-gyp/20.2.0/include/node/v8-date.h:
|
||||
/Users/karolsojko/Library/Caches/node-gyp/20.2.0/include/node/v8-debug.h:
|
||||
/Users/karolsojko/Library/Caches/node-gyp/20.2.0/include/node/v8-script.h:
|
||||
/Users/karolsojko/Library/Caches/node-gyp/20.2.0/include/node/v8-callbacks.h:
|
||||
/Users/karolsojko/Library/Caches/node-gyp/20.2.0/include/node/v8-promise.h:
|
||||
/Users/karolsojko/Library/Caches/node-gyp/20.2.0/include/node/v8-message.h:
|
||||
/Users/karolsojko/Library/Caches/node-gyp/20.2.0/include/node/v8-exception.h:
|
||||
/Users/karolsojko/Library/Caches/node-gyp/20.2.0/include/node/v8-extension.h:
|
||||
/Users/karolsojko/Library/Caches/node-gyp/20.2.0/include/node/v8-external.h:
|
||||
/Users/karolsojko/Library/Caches/node-gyp/20.2.0/include/node/v8-function.h:
|
||||
/Users/karolsojko/Library/Caches/node-gyp/20.2.0/include/node/v8-function-callback.h:
|
||||
/Users/karolsojko/Library/Caches/node-gyp/20.2.0/include/node/v8-template.h:
|
||||
/Users/karolsojko/Library/Caches/node-gyp/20.2.0/include/node/v8-memory-span.h:
|
||||
/Users/karolsojko/Library/Caches/node-gyp/20.2.0/include/node/v8-initialization.h:
|
||||
/Users/karolsojko/Library/Caches/node-gyp/20.2.0/include/node/v8-isolate.h:
|
||||
/Users/karolsojko/Library/Caches/node-gyp/20.2.0/include/node/v8-embedder-heap.h:
|
||||
/Users/karolsojko/Library/Caches/node-gyp/20.2.0/include/node/v8-microtask.h:
|
||||
/Users/karolsojko/Library/Caches/node-gyp/20.2.0/include/node/v8-statistics.h:
|
||||
/Users/karolsojko/Library/Caches/node-gyp/20.2.0/include/node/v8-unwinder.h:
|
||||
/Users/karolsojko/Library/Caches/node-gyp/20.2.0/include/node/v8-embedder-state-scope.h:
|
||||
/Users/karolsojko/Library/Caches/node-gyp/20.2.0/include/node/v8-platform.h:
|
||||
/Users/karolsojko/Library/Caches/node-gyp/20.2.0/include/node/v8-json.h:
|
||||
/Users/karolsojko/Library/Caches/node-gyp/20.2.0/include/node/v8-locker.h:
|
||||
/Users/karolsojko/Library/Caches/node-gyp/20.2.0/include/node/v8-microtask-queue.h:
|
||||
/Users/karolsojko/Library/Caches/node-gyp/20.2.0/include/node/v8-primitive-object.h:
|
||||
/Users/karolsojko/Library/Caches/node-gyp/20.2.0/include/node/v8-proxy.h:
|
||||
/Users/karolsojko/Library/Caches/node-gyp/20.2.0/include/node/v8-regexp.h:
|
||||
/Users/karolsojko/Library/Caches/node-gyp/20.2.0/include/node/v8-typed-array.h:
|
||||
/Users/karolsojko/Library/Caches/node-gyp/20.2.0/include/node/v8-value-serializer.h:
|
||||
/Users/karolsojko/Library/Caches/node-gyp/20.2.0/include/node/v8-wasm.h:
|
||||
/Users/karolsojko/Library/Caches/node-gyp/20.2.0/include/node/node_api.h:
|
||||
/Users/karolsojko/Library/Caches/node-gyp/20.2.0/include/node/js_native_api.h:
|
||||
/Users/karolsojko/Library/Caches/node-gyp/20.2.0/include/node/js_native_api_types.h:
|
||||
/Users/karolsojko/Library/Caches/node-gyp/20.2.0/include/node/node_api_types.h:
|
||||
/Users/karolsojko/Library/Caches/node-gyp/20.2.0/include/node/node_buffer.h:
|
||||
/Users/karolsojko/Library/Caches/node-gyp/20.2.0/include/node/node_object_wrap.h:
|
||||
../../../../../nan-npm-2.17.0-bf36a21d6f/node_modules/nan/nan_callbacks.h:
|
||||
../../../../../nan-npm-2.17.0-bf36a21d6f/node_modules/nan/nan_callbacks_12_inl.h:
|
||||
../../../../../nan-npm-2.17.0-bf36a21d6f/node_modules/nan/nan_maybe_43_inl.h:
|
||||
|
||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
@@ -278,14 +278,11 @@
|
||||
"lib/internal/test_runner/reporter/dot.js",
|
||||
"lib/internal/test_runner/reporter/spec.js",
|
||||
"lib/internal/test_runner/reporter/tap.js",
|
||||
"lib/internal/test_runner/reporter/v8-serializer.js",
|
||||
"lib/internal/test_runner/runner.js",
|
||||
"lib/internal/test_runner/tap_checker.js",
|
||||
"lib/internal/test_runner/tap_lexer.js",
|
||||
"lib/internal/test_runner/tap_parser.js",
|
||||
"lib/internal/test_runner/test.js",
|
||||
"lib/internal/test_runner/tests_stream.js",
|
||||
"lib/internal/test_runner/utils.js",
|
||||
"lib/internal/test_runner/yaml_to_js.js",
|
||||
"lib/internal/timers.js",
|
||||
"lib/internal/tls/secure-context.js",
|
||||
"lib/internal/tls/secure-pair.js",
|
||||
@@ -408,8 +405,8 @@
|
||||
"v8_use_siphash": 1,
|
||||
"want_separate_host_toolset": 0,
|
||||
"xcode_version": "13.0",
|
||||
"nodedir": "/Users/karolsojko/Library/Caches/node-gyp/20.1.0",
|
||||
"nodedir": "/Users/karolsojko/Library/Caches/node-gyp/20.2.0",
|
||||
"standalone_static_library": 1,
|
||||
"user_agent": "yarn/4.0.0-rc.43 npm/? node/v20.1.0 darwin arm64"
|
||||
"user_agent": "yarn/4.0.0-rc.43 npm/? node/v20.2.0 darwin arm64"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -51,13 +51,13 @@ CFLAGS_OBJC_Debug :=
|
||||
CFLAGS_OBJCC_Debug :=
|
||||
|
||||
INCS_Debug := \
|
||||
-I/Users/karolsojko/Library/Caches/node-gyp/20.1.0/include/node \
|
||||
-I/Users/karolsojko/Library/Caches/node-gyp/20.1.0/src \
|
||||
-I/Users/karolsojko/Library/Caches/node-gyp/20.1.0/deps/openssl/config \
|
||||
-I/Users/karolsojko/Library/Caches/node-gyp/20.1.0/deps/openssl/openssl/include \
|
||||
-I/Users/karolsojko/Library/Caches/node-gyp/20.1.0/deps/uv/include \
|
||||
-I/Users/karolsojko/Library/Caches/node-gyp/20.1.0/deps/zlib \
|
||||
-I/Users/karolsojko/Library/Caches/node-gyp/20.1.0/deps/v8/include \
|
||||
-I/Users/karolsojko/Library/Caches/node-gyp/20.2.0/include/node \
|
||||
-I/Users/karolsojko/Library/Caches/node-gyp/20.2.0/src \
|
||||
-I/Users/karolsojko/Library/Caches/node-gyp/20.2.0/deps/openssl/config \
|
||||
-I/Users/karolsojko/Library/Caches/node-gyp/20.2.0/deps/openssl/openssl/include \
|
||||
-I/Users/karolsojko/Library/Caches/node-gyp/20.2.0/deps/uv/include \
|
||||
-I/Users/karolsojko/Library/Caches/node-gyp/20.2.0/deps/zlib \
|
||||
-I/Users/karolsojko/Library/Caches/node-gyp/20.2.0/deps/v8/include \
|
||||
-I$(srcdir)/src \
|
||||
-I$(srcdir)/../../../../nan-npm-2.17.0-bf36a21d6f/node_modules/nan
|
||||
|
||||
@@ -107,13 +107,13 @@ CFLAGS_OBJC_Release :=
|
||||
CFLAGS_OBJCC_Release :=
|
||||
|
||||
INCS_Release := \
|
||||
-I/Users/karolsojko/Library/Caches/node-gyp/20.1.0/include/node \
|
||||
-I/Users/karolsojko/Library/Caches/node-gyp/20.1.0/src \
|
||||
-I/Users/karolsojko/Library/Caches/node-gyp/20.1.0/deps/openssl/config \
|
||||
-I/Users/karolsojko/Library/Caches/node-gyp/20.1.0/deps/openssl/openssl/include \
|
||||
-I/Users/karolsojko/Library/Caches/node-gyp/20.1.0/deps/uv/include \
|
||||
-I/Users/karolsojko/Library/Caches/node-gyp/20.1.0/deps/zlib \
|
||||
-I/Users/karolsojko/Library/Caches/node-gyp/20.1.0/deps/v8/include \
|
||||
-I/Users/karolsojko/Library/Caches/node-gyp/20.2.0/include/node \
|
||||
-I/Users/karolsojko/Library/Caches/node-gyp/20.2.0/src \
|
||||
-I/Users/karolsojko/Library/Caches/node-gyp/20.2.0/deps/openssl/config \
|
||||
-I/Users/karolsojko/Library/Caches/node-gyp/20.2.0/deps/openssl/openssl/include \
|
||||
-I/Users/karolsojko/Library/Caches/node-gyp/20.2.0/deps/uv/include \
|
||||
-I/Users/karolsojko/Library/Caches/node-gyp/20.2.0/deps/zlib \
|
||||
-I/Users/karolsojko/Library/Caches/node-gyp/20.2.0/deps/v8/include \
|
||||
-I$(srcdir)/src \
|
||||
-I$(srcdir)/../../../../nan-npm-2.17.0-bf36a21d6f/node_modules/nan
|
||||
|
||||
|
||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
@@ -1,4 +1,4 @@
|
||||
FROM node:20.1.0-alpine
|
||||
FROM node:20.2.0-alpine
|
||||
|
||||
ENV NODE_ENV production
|
||||
|
||||
|
||||
@@ -28,7 +28,7 @@
|
||||
"@lerna-lite/version": "^2.3.0",
|
||||
"@types/jest": "^29.5.1",
|
||||
"@types/newrelic": "^9.13.0",
|
||||
"@types/node": "^20.1.0",
|
||||
"@types/node": "^20.2.0",
|
||||
"eslint": "^8.39.0",
|
||||
"eslint-config-prettier": "^8.8.0",
|
||||
"ini": "^3.0.0",
|
||||
|
||||
@@ -3,6 +3,16 @@
|
||||
All notable changes to this project will be documented in this file.
|
||||
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
|
||||
|
||||
# [2.23.0](https://github.com/standardnotes/server/compare/@standardnotes/analytics@2.22.5...@standardnotes/analytics@2.23.0) (2023-05-30)
|
||||
|
||||
### Features
|
||||
|
||||
* upgrade to node 20.2.0 ([#616](https://github.com/standardnotes/server/issues/616)) ([a6b062f](https://github.com/standardnotes/server/commit/a6b062f638595537e1ece28bc79bded41d875e18))
|
||||
|
||||
## [2.22.5](https://github.com/standardnotes/server/compare/@standardnotes/analytics@2.22.4...@standardnotes/analytics@2.22.5) (2023-05-29)
|
||||
|
||||
**Note:** Version bump only for package @standardnotes/analytics
|
||||
|
||||
## [2.22.4](https://github.com/standardnotes/server/compare/@standardnotes/analytics@2.22.3...@standardnotes/analytics@2.22.4) (2023-05-17)
|
||||
|
||||
**Note:** Version bump only for package @standardnotes/analytics
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
FROM node:20.1.0-alpine
|
||||
FROM node:20.2.0-alpine
|
||||
|
||||
RUN apk add --update \
|
||||
curl \
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@standardnotes/analytics",
|
||||
"version": "2.22.4",
|
||||
"version": "2.23.0",
|
||||
"engines": {
|
||||
"node": ">=18.0.0 <21.0.0"
|
||||
},
|
||||
@@ -29,7 +29,7 @@
|
||||
"@types/jest": "^29.5.1",
|
||||
"@types/mixpanel": "^2.14.4",
|
||||
"@types/newrelic": "^9.13.0",
|
||||
"@types/node": "^20.1.0",
|
||||
"@types/node": "^20.2.0",
|
||||
"@typescript-eslint/eslint-plugin": "^5.59.2",
|
||||
"@typescript-eslint/parser": "^5.59.2",
|
||||
"eslint": "^8.39.0",
|
||||
|
||||
@@ -3,6 +3,43 @@
|
||||
All notable changes to this project will be documented in this file.
|
||||
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
|
||||
|
||||
# [1.61.0](https://github.com/standardnotes/api-gateway/compare/@standardnotes/api-gateway@1.60.0...@standardnotes/api-gateway@1.61.0) (2023-05-30)
|
||||
|
||||
### Features
|
||||
|
||||
* make home server components publishable ([#617](https://github.com/standardnotes/api-gateway/issues/617)) ([55fd873](https://github.com/standardnotes/api-gateway/commit/55fd873b375e204dc9b0477b2cc6ed4582e5b603))
|
||||
|
||||
# [1.60.0](https://github.com/standardnotes/api-gateway/compare/@standardnotes/api-gateway@1.59.0...@standardnotes/api-gateway@1.60.0) (2023-05-30)
|
||||
|
||||
### Features
|
||||
|
||||
* upgrade to node 20.2.0 ([#616](https://github.com/standardnotes/api-gateway/issues/616)) ([a6b062f](https://github.com/standardnotes/api-gateway/commit/a6b062f638595537e1ece28bc79bded41d875e18))
|
||||
|
||||
# [1.59.0](https://github.com/standardnotes/api-gateway/compare/@standardnotes/api-gateway@1.58.0...@standardnotes/api-gateway@1.59.0) (2023-05-29)
|
||||
|
||||
### Features
|
||||
|
||||
* add files server as a service to home-server ([#614](https://github.com/standardnotes/api-gateway/issues/614)) ([c7d575a](https://github.com/standardnotes/api-gateway/commit/c7d575a0ffc7eb3e8799c3835da5727584f4f67b))
|
||||
|
||||
# [1.58.0](https://github.com/standardnotes/api-gateway/compare/@standardnotes/api-gateway@1.57.0...@standardnotes/api-gateway@1.58.0) (2023-05-25)
|
||||
|
||||
### Features
|
||||
|
||||
* add revisions service to home server ([#613](https://github.com/standardnotes/api-gateway/issues/613)) ([c70040f](https://github.com/standardnotes/api-gateway/commit/c70040fe5dfd35663b9811fbbaa9370bd0298482))
|
||||
|
||||
# [1.57.0](https://github.com/standardnotes/api-gateway/compare/@standardnotes/api-gateway@1.56.2...@standardnotes/api-gateway@1.57.0) (2023-05-25)
|
||||
|
||||
### Features
|
||||
|
||||
* refactor auth middleware to handle required and optional cross service token scenarios ([#612](https://github.com/standardnotes/api-gateway/issues/612)) ([1e4c7d0](https://github.com/standardnotes/api-gateway/commit/1e4c7d0f317d5c2d98065da12ffeb950b10ee5dc))
|
||||
|
||||
## [1.56.2](https://github.com/standardnotes/api-gateway/compare/@standardnotes/api-gateway@1.56.1...@standardnotes/api-gateway@1.56.2) (2023-05-18)
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* **api-gateway:** decorating responses for direct call proxy ([4ab32c6](https://github.com/standardnotes/api-gateway/commit/4ab32c670eedcfc64611a191bc25566d43372b23))
|
||||
* **api-gateway:** pkce endpoints resolution for direct code calls ([c7e605f](https://github.com/standardnotes/api-gateway/commit/c7e605fd6046e8476c493658c6feaed365e82e5d))
|
||||
|
||||
## [1.56.1](https://github.com/standardnotes/api-gateway/compare/@standardnotes/api-gateway@1.56.0...@standardnotes/api-gateway@1.56.1) (2023-05-18)
|
||||
|
||||
**Note:** Version bump only for package @standardnotes/api-gateway
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
FROM node:20.1.0-alpine
|
||||
FROM node:20.2.0-alpine
|
||||
|
||||
RUN apk add --update \
|
||||
curl \
|
||||
|
||||
@@ -1,10 +1,9 @@
|
||||
{
|
||||
"name": "@standardnotes/api-gateway",
|
||||
"version": "1.56.1",
|
||||
"version": "1.61.0",
|
||||
"engines": {
|
||||
"node": ">=18.0.0 <21.0.0"
|
||||
},
|
||||
"private": true,
|
||||
"description": "API Gateway For Standard Notes Services",
|
||||
"main": "dist/src/index.js",
|
||||
"types": "dist/src/index.d.ts",
|
||||
@@ -15,6 +14,9 @@
|
||||
"repository": "git@github.com:standardnotes/api-gateway.git",
|
||||
"author": "Karol Sójko <karolsojko@standardnotes.com>",
|
||||
"license": "AGPL-3.0-or-later",
|
||||
"publishConfig": {
|
||||
"access": "public"
|
||||
},
|
||||
"scripts": {
|
||||
"clean": "rm -fr dist",
|
||||
"build": "tsc --build",
|
||||
|
||||
@@ -8,7 +8,6 @@ import { Timer, TimerInterface } from '@standardnotes/time'
|
||||
|
||||
import { Env } from './Env'
|
||||
import { TYPES } from './Types'
|
||||
import { AuthMiddleware } from '../Controller/AuthMiddleware'
|
||||
import { ServiceProxyInterface } from '../Service/Http/ServiceProxyInterface'
|
||||
import { HttpServiceProxy } from '../Service/Http/HttpServiceProxy'
|
||||
import { SubscriptionTokenAuthMiddleware } from '../Controller/SubscriptionTokenAuthMiddleware'
|
||||
@@ -20,6 +19,8 @@ import { DirectCallServiceProxy } from '../Service/Proxy/DirectCallServiceProxy'
|
||||
import { ServiceContainerInterface } from '@standardnotes/domain-core'
|
||||
import { EndpointResolverInterface } from '../Service/Resolver/EndpointResolverInterface'
|
||||
import { EndpointResolver } from '../Service/Resolver/EndpointResolver'
|
||||
import { RequiredCrossServiceTokenMiddleware } from '../Controller/RequiredCrossServiceTokenMiddleware'
|
||||
import { OptionalCrossServiceTokenMiddleware } from '../Controller/OptionalCrossServiceTokenMiddleware'
|
||||
|
||||
// eslint-disable-next-line @typescript-eslint/no-var-requires
|
||||
const newrelicFormatter = require('@newrelic/winston-enricher')
|
||||
@@ -77,7 +78,12 @@ export class ContainerConfigLoader {
|
||||
container.bind(TYPES.CROSS_SERVICE_TOKEN_CACHE_TTL).toConstantValue(+env.get('CROSS_SERVICE_TOKEN_CACHE_TTL', true))
|
||||
|
||||
// Middleware
|
||||
container.bind<AuthMiddleware>(TYPES.AuthMiddleware).to(AuthMiddleware)
|
||||
container
|
||||
.bind<RequiredCrossServiceTokenMiddleware>(TYPES.RequiredCrossServiceTokenMiddleware)
|
||||
.to(RequiredCrossServiceTokenMiddleware)
|
||||
container
|
||||
.bind<OptionalCrossServiceTokenMiddleware>(TYPES.OptionalCrossServiceTokenMiddleware)
|
||||
.to(OptionalCrossServiceTokenMiddleware)
|
||||
container.bind<WebSocketAuthMiddleware>(TYPES.WebSocketAuthMiddleware).to(WebSocketAuthMiddleware)
|
||||
container
|
||||
.bind<SubscriptionTokenAuthMiddleware>(TYPES.SubscriptionTokenAuthMiddleware)
|
||||
@@ -90,7 +96,7 @@ export class ContainerConfigLoader {
|
||||
}
|
||||
container
|
||||
.bind<ServiceProxyInterface>(TYPES.ServiceProxy)
|
||||
.toConstantValue(new DirectCallServiceProxy(serviceContainer))
|
||||
.toConstantValue(new DirectCallServiceProxy(serviceContainer, container.get(TYPES.FILES_SERVER_URL)))
|
||||
} else {
|
||||
container.bind<ServiceProxyInterface>(TYPES.ServiceProxy).to(HttpServiceProxy)
|
||||
}
|
||||
|
||||
@@ -15,7 +15,8 @@ export const TYPES = {
|
||||
VERSION: Symbol.for('VERSION'),
|
||||
CROSS_SERVICE_TOKEN_CACHE_TTL: Symbol.for('CROSS_SERVICE_TOKEN_CACHE_TTL'),
|
||||
// Middleware
|
||||
AuthMiddleware: Symbol.for('AuthMiddleware'),
|
||||
RequiredCrossServiceTokenMiddleware: Symbol.for('RequiredCrossServiceTokenMiddleware'),
|
||||
OptionalCrossServiceTokenMiddleware: Symbol.for('OptionalCrossServiceTokenMiddleware'),
|
||||
WebSocketAuthMiddleware: Symbol.for('WebSocketAuthMiddleware'),
|
||||
SubscriptionTokenAuthMiddleware: Symbol.for('SubscriptionTokenAuthMiddleware'),
|
||||
// Services
|
||||
|
||||
@@ -1,3 +1,2 @@
|
||||
export * from './Container'
|
||||
export * from './Service'
|
||||
export * from './Types'
|
||||
|
||||
@@ -2,43 +2,33 @@ import { CrossServiceTokenData } from '@standardnotes/security'
|
||||
import { RoleName } from '@standardnotes/domain-core'
|
||||
import { TimerInterface } from '@standardnotes/time'
|
||||
import { NextFunction, Request, Response } from 'express'
|
||||
import { inject, injectable } from 'inversify'
|
||||
import { BaseMiddleware } from 'inversify-express-utils'
|
||||
import { verify } from 'jsonwebtoken'
|
||||
import { AxiosError } from 'axios'
|
||||
import { Logger } from 'winston'
|
||||
|
||||
import { TYPES } from '../Bootstrap/Types'
|
||||
import { CrossServiceTokenCacheInterface } from '../Service/Cache/CrossServiceTokenCacheInterface'
|
||||
import { ServiceProxyInterface } from '../Service/Http/ServiceProxyInterface'
|
||||
|
||||
@injectable()
|
||||
export class AuthMiddleware extends BaseMiddleware {
|
||||
export abstract class AuthMiddleware extends BaseMiddleware {
|
||||
constructor(
|
||||
@inject(TYPES.ServiceProxy) private serviceProxy: ServiceProxyInterface,
|
||||
@inject(TYPES.AUTH_JWT_SECRET) private jwtSecret: string,
|
||||
@inject(TYPES.CROSS_SERVICE_TOKEN_CACHE_TTL) private crossServiceTokenCacheTTL: number,
|
||||
@inject(TYPES.CrossServiceTokenCache) private crossServiceTokenCache: CrossServiceTokenCacheInterface,
|
||||
@inject(TYPES.Timer) private timer: TimerInterface,
|
||||
@inject(TYPES.Logger) private logger: Logger,
|
||||
private serviceProxy: ServiceProxyInterface,
|
||||
private jwtSecret: string,
|
||||
private crossServiceTokenCacheTTL: number,
|
||||
private crossServiceTokenCache: CrossServiceTokenCacheInterface,
|
||||
private timer: TimerInterface,
|
||||
private logger: Logger,
|
||||
) {
|
||||
super()
|
||||
}
|
||||
|
||||
async handler(request: Request, response: Response, next: NextFunction): Promise<void> {
|
||||
const authHeaderValue = request.headers.authorization as string
|
||||
|
||||
if (!authHeaderValue) {
|
||||
response.status(401).send({
|
||||
error: {
|
||||
tag: 'invalid-auth',
|
||||
message: 'Invalid login credentials.',
|
||||
},
|
||||
})
|
||||
|
||||
if (!this.handleMissingAuthHeader(request.headers.authorization, response, next)) {
|
||||
return
|
||||
}
|
||||
|
||||
const authHeaderValue = request.headers.authorization as string
|
||||
|
||||
try {
|
||||
let crossServiceTokenFetchedFromCache = true
|
||||
let crossServiceToken = null
|
||||
@@ -49,10 +39,7 @@ export class AuthMiddleware extends BaseMiddleware {
|
||||
if (crossServiceToken === null) {
|
||||
const authResponse = await this.serviceProxy.validateSession(authHeaderValue)
|
||||
|
||||
if (authResponse.status > 200) {
|
||||
response.setHeader('content-type', authResponse.headers.contentType)
|
||||
response.status(authResponse.status).send(authResponse.data)
|
||||
|
||||
if (!this.handleSessionValidationResponse(authResponse, response, next)) {
|
||||
return
|
||||
}
|
||||
|
||||
@@ -78,6 +65,7 @@ export class AuthMiddleware extends BaseMiddleware {
|
||||
}
|
||||
|
||||
response.locals.user = decodedToken.user
|
||||
response.locals.session = decodedToken.session
|
||||
response.locals.roles = decodedToken.roles
|
||||
} catch (error) {
|
||||
const errorMessage = (error as AxiosError).isAxiosError
|
||||
@@ -105,6 +93,24 @@ export class AuthMiddleware extends BaseMiddleware {
|
||||
return next()
|
||||
}
|
||||
|
||||
protected abstract handleSessionValidationResponse(
|
||||
authResponse: {
|
||||
status: number
|
||||
data: unknown
|
||||
headers: {
|
||||
contentType: string
|
||||
}
|
||||
},
|
||||
response: Response,
|
||||
next: NextFunction,
|
||||
): boolean
|
||||
|
||||
protected abstract handleMissingAuthHeader(
|
||||
authHeaderValue: string | undefined,
|
||||
response: Response,
|
||||
next: NextFunction,
|
||||
): boolean
|
||||
|
||||
private getCrossServiceTokenCacheExpireTimestamp(token: CrossServiceTokenData): number {
|
||||
const crossServiceTokenDefaultCacheExpiration = this.timer.getTimestampInSeconds() + this.crossServiceTokenCacheTTL
|
||||
|
||||
|
||||
@@ -29,17 +29,17 @@ export class LegacyController extends BaseHttpController {
|
||||
])
|
||||
}
|
||||
|
||||
@httpPost('/items/sync', TYPES.AuthMiddleware)
|
||||
@httpPost('/items/sync', TYPES.RequiredCrossServiceTokenMiddleware)
|
||||
async legacyItemsSync(request: Request, response: Response): Promise<void> {
|
||||
await this.httpService.callLegacySyncingServer(request, response, request.path.substring(1), request.body)
|
||||
}
|
||||
|
||||
@httpGet('/items/:item_id/revisions', TYPES.AuthMiddleware)
|
||||
@httpGet('/items/:item_id/revisions', TYPES.RequiredCrossServiceTokenMiddleware)
|
||||
async legacyGetRevisions(request: Request, response: Response): Promise<void> {
|
||||
await this.httpService.callLegacySyncingServer(request, response, request.path.substring(1), request.body)
|
||||
}
|
||||
|
||||
@httpGet('/items/:item_id/revisions/:id', TYPES.AuthMiddleware)
|
||||
@httpGet('/items/:item_id/revisions/:id', TYPES.RequiredCrossServiceTokenMiddleware)
|
||||
async legacyGetRevision(request: Request, response: Response): Promise<void> {
|
||||
await this.httpService.callLegacySyncingServer(request, response, request.path.substring(1), request.body)
|
||||
}
|
||||
|
||||
@@ -0,0 +1,51 @@
|
||||
import { TimerInterface } from '@standardnotes/time'
|
||||
import { NextFunction, Response } from 'express'
|
||||
import { inject, injectable } from 'inversify'
|
||||
import { Logger } from 'winston'
|
||||
|
||||
import { TYPES } from '../Bootstrap/Types'
|
||||
import { CrossServiceTokenCacheInterface } from '../Service/Cache/CrossServiceTokenCacheInterface'
|
||||
import { ServiceProxyInterface } from '../Service/Http/ServiceProxyInterface'
|
||||
import { AuthMiddleware } from './AuthMiddleware'
|
||||
|
||||
@injectable()
|
||||
export class OptionalCrossServiceTokenMiddleware extends AuthMiddleware {
|
||||
constructor(
|
||||
@inject(TYPES.ServiceProxy) serviceProxy: ServiceProxyInterface,
|
||||
@inject(TYPES.AUTH_JWT_SECRET) jwtSecret: string,
|
||||
@inject(TYPES.CROSS_SERVICE_TOKEN_CACHE_TTL) crossServiceTokenCacheTTL: number,
|
||||
@inject(TYPES.CrossServiceTokenCache) crossServiceTokenCache: CrossServiceTokenCacheInterface,
|
||||
@inject(TYPES.Timer) timer: TimerInterface,
|
||||
@inject(TYPES.Logger) logger: Logger,
|
||||
) {
|
||||
super(serviceProxy, jwtSecret, crossServiceTokenCacheTTL, crossServiceTokenCache, timer, logger)
|
||||
}
|
||||
|
||||
protected override handleSessionValidationResponse(
|
||||
authResponse: { status: number; data: unknown; headers: { contentType: string } },
|
||||
_response: Response,
|
||||
next: NextFunction,
|
||||
): boolean {
|
||||
if (authResponse.status > 200) {
|
||||
next()
|
||||
|
||||
return false
|
||||
}
|
||||
|
||||
return true
|
||||
}
|
||||
|
||||
protected override handleMissingAuthHeader(
|
||||
authHeaderValue: string | undefined,
|
||||
_response: Response,
|
||||
next: NextFunction,
|
||||
): boolean {
|
||||
if (!authHeaderValue) {
|
||||
next()
|
||||
|
||||
return false
|
||||
}
|
||||
|
||||
return true
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,57 @@
|
||||
import { TimerInterface } from '@standardnotes/time'
|
||||
import { NextFunction, Response } from 'express'
|
||||
import { inject, injectable } from 'inversify'
|
||||
import { Logger } from 'winston'
|
||||
|
||||
import { TYPES } from '../Bootstrap/Types'
|
||||
import { CrossServiceTokenCacheInterface } from '../Service/Cache/CrossServiceTokenCacheInterface'
|
||||
import { ServiceProxyInterface } from '../Service/Http/ServiceProxyInterface'
|
||||
import { AuthMiddleware } from './AuthMiddleware'
|
||||
|
||||
@injectable()
|
||||
export class RequiredCrossServiceTokenMiddleware extends AuthMiddleware {
|
||||
constructor(
|
||||
@inject(TYPES.ServiceProxy) serviceProxy: ServiceProxyInterface,
|
||||
@inject(TYPES.AUTH_JWT_SECRET) jwtSecret: string,
|
||||
@inject(TYPES.CROSS_SERVICE_TOKEN_CACHE_TTL) crossServiceTokenCacheTTL: number,
|
||||
@inject(TYPES.CrossServiceTokenCache) crossServiceTokenCache: CrossServiceTokenCacheInterface,
|
||||
@inject(TYPES.Timer) timer: TimerInterface,
|
||||
@inject(TYPES.Logger) logger: Logger,
|
||||
) {
|
||||
super(serviceProxy, jwtSecret, crossServiceTokenCacheTTL, crossServiceTokenCache, timer, logger)
|
||||
}
|
||||
|
||||
protected override handleSessionValidationResponse(
|
||||
authResponse: { status: number; data: unknown; headers: { contentType: string } },
|
||||
response: Response,
|
||||
_next: NextFunction,
|
||||
): boolean {
|
||||
if (authResponse.status > 200) {
|
||||
response.setHeader('content-type', authResponse.headers.contentType)
|
||||
response.status(authResponse.status).send(authResponse.data)
|
||||
|
||||
return false
|
||||
}
|
||||
|
||||
return true
|
||||
}
|
||||
|
||||
protected override handleMissingAuthHeader(
|
||||
authHeaderValue: string | undefined,
|
||||
response: Response,
|
||||
_next: NextFunction,
|
||||
): boolean {
|
||||
if (!authHeaderValue) {
|
||||
response.status(401).send({
|
||||
error: {
|
||||
tag: 'invalid-auth',
|
||||
message: 'Invalid login credentials.',
|
||||
},
|
||||
})
|
||||
|
||||
return false
|
||||
}
|
||||
|
||||
return true
|
||||
}
|
||||
}
|
||||
@@ -1,6 +1,5 @@
|
||||
export * from './AuthMiddleware'
|
||||
export * from './HealthCheckController'
|
||||
export * from './LegacyController'
|
||||
export * from './SubscriptionTokenAuthMiddleware'
|
||||
export * from './TokenAuthenticationMethod'
|
||||
export * from './WebSocketAuthMiddleware'
|
||||
|
||||
@@ -24,7 +24,7 @@ export class ActionsController extends BaseHttpController {
|
||||
)
|
||||
}
|
||||
|
||||
@httpGet('/login-params')
|
||||
@httpGet('/login-params', TYPES.OptionalCrossServiceTokenMiddleware)
|
||||
async loginParams(request: Request, response: Response): Promise<void> {
|
||||
await this.serviceProxy.callAuthServer(
|
||||
request,
|
||||
@@ -34,7 +34,7 @@ export class ActionsController extends BaseHttpController {
|
||||
)
|
||||
}
|
||||
|
||||
@httpPost('/logout')
|
||||
@httpPost('/logout', TYPES.OptionalCrossServiceTokenMiddleware)
|
||||
async logout(request: Request, response: Response): Promise<void> {
|
||||
await this.serviceProxy.callAuthServer(
|
||||
request,
|
||||
@@ -54,7 +54,7 @@ export class ActionsController extends BaseHttpController {
|
||||
)
|
||||
}
|
||||
|
||||
@httpPost('/recovery/codes', TYPES.AuthMiddleware)
|
||||
@httpPost('/recovery/codes', TYPES.RequiredCrossServiceTokenMiddleware)
|
||||
async recoveryCodes(request: Request, response: Response): Promise<void> {
|
||||
await this.serviceProxy.callAuthServer(
|
||||
request,
|
||||
|
||||
@@ -15,7 +15,7 @@ export class AuthenticatorsController extends BaseHttpController {
|
||||
super()
|
||||
}
|
||||
|
||||
@httpDelete('/:authenticatorId', TYPES.AuthMiddleware)
|
||||
@httpDelete('/:authenticatorId', TYPES.RequiredCrossServiceTokenMiddleware)
|
||||
async delete(request: Request, response: Response): Promise<void> {
|
||||
await this.httpService.callAuthServer(
|
||||
request,
|
||||
@@ -29,7 +29,7 @@ export class AuthenticatorsController extends BaseHttpController {
|
||||
)
|
||||
}
|
||||
|
||||
@httpGet('/', TYPES.AuthMiddleware)
|
||||
@httpGet('/', TYPES.RequiredCrossServiceTokenMiddleware)
|
||||
async list(request: Request, response: Response): Promise<void> {
|
||||
await this.httpService.callAuthServer(
|
||||
request,
|
||||
@@ -39,7 +39,7 @@ export class AuthenticatorsController extends BaseHttpController {
|
||||
)
|
||||
}
|
||||
|
||||
@httpGet('/generate-registration-options', TYPES.AuthMiddleware)
|
||||
@httpGet('/generate-registration-options', TYPES.RequiredCrossServiceTokenMiddleware)
|
||||
async generateRegistrationOptions(request: Request, response: Response): Promise<void> {
|
||||
await this.httpService.callAuthServer(
|
||||
request,
|
||||
@@ -59,7 +59,7 @@ export class AuthenticatorsController extends BaseHttpController {
|
||||
)
|
||||
}
|
||||
|
||||
@httpPost('/verify-registration', TYPES.AuthMiddleware)
|
||||
@httpPost('/verify-registration', TYPES.RequiredCrossServiceTokenMiddleware)
|
||||
async verifyRegistration(request: Request, response: Response): Promise<void> {
|
||||
await this.httpService.callAuthServer(
|
||||
request,
|
||||
|
||||
@@ -15,7 +15,7 @@ export class FilesController extends BaseHttpController {
|
||||
super()
|
||||
}
|
||||
|
||||
@httpPost('/valet-tokens', TYPES.AuthMiddleware)
|
||||
@httpPost('/valet-tokens', TYPES.RequiredCrossServiceTokenMiddleware)
|
||||
async createToken(request: Request, response: Response): Promise<void> {
|
||||
await this.httpService.callAuthServer(
|
||||
request,
|
||||
|
||||
@@ -5,7 +5,7 @@ import { TYPES } from '../../Bootstrap/Types'
|
||||
import { ServiceProxyInterface } from '../../Service/Http/ServiceProxyInterface'
|
||||
import { EndpointResolverInterface } from '../../Service/Resolver/EndpointResolverInterface'
|
||||
|
||||
@controller('/v1/items', TYPES.AuthMiddleware)
|
||||
@controller('/v1/items', TYPES.RequiredCrossServiceTokenMiddleware)
|
||||
export class ItemsController extends BaseHttpController {
|
||||
constructor(
|
||||
@inject(TYPES.ServiceProxy) private serviceProxy: ServiceProxyInterface,
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import { BaseHttpController, controller, httpDelete, httpGet, results } from 'inversify-express-utils'
|
||||
import { TYPES } from '../../Bootstrap/Types'
|
||||
|
||||
@controller('/v1/items/:item_id/revisions', TYPES.AuthMiddleware)
|
||||
@controller('/v1/items/:item_id/revisions', TYPES.RequiredCrossServiceTokenMiddleware)
|
||||
export class RevisionsController extends BaseHttpController {
|
||||
@httpGet('/')
|
||||
async getRevisions(): Promise<results.JsonResult> {
|
||||
|
||||
@@ -14,7 +14,7 @@ export class SessionsController extends BaseHttpController {
|
||||
super()
|
||||
}
|
||||
|
||||
@httpGet('/', TYPES.AuthMiddleware)
|
||||
@httpGet('/', TYPES.RequiredCrossServiceTokenMiddleware)
|
||||
async getSessions(request: Request, response: Response): Promise<void> {
|
||||
await this.httpService.callAuthServer(
|
||||
request,
|
||||
@@ -23,7 +23,7 @@ export class SessionsController extends BaseHttpController {
|
||||
)
|
||||
}
|
||||
|
||||
@httpDelete('/:uuid', TYPES.AuthMiddleware)
|
||||
@httpDelete('/:uuid', TYPES.RequiredCrossServiceTokenMiddleware)
|
||||
async deleteSession(request: Request, response: Response): Promise<void> {
|
||||
await this.httpService.callAuthServer(
|
||||
request,
|
||||
@@ -35,7 +35,7 @@ export class SessionsController extends BaseHttpController {
|
||||
)
|
||||
}
|
||||
|
||||
@httpDelete('/', TYPES.AuthMiddleware)
|
||||
@httpDelete('/', TYPES.RequiredCrossServiceTokenMiddleware)
|
||||
async deleteSessions(request: Request, response: Response): Promise<void> {
|
||||
await this.httpService.callAuthServer(
|
||||
request,
|
||||
|
||||
@@ -15,7 +15,7 @@ export class SubscriptionInvitesController extends BaseHttpController {
|
||||
super()
|
||||
}
|
||||
|
||||
@httpPost('/', TYPES.AuthMiddleware)
|
||||
@httpPost('/', TYPES.RequiredCrossServiceTokenMiddleware)
|
||||
async inviteToSubscriptionSharing(request: Request, response: Response): Promise<void> {
|
||||
await this.httpService.callAuthServer(
|
||||
request,
|
||||
@@ -25,7 +25,7 @@ export class SubscriptionInvitesController extends BaseHttpController {
|
||||
)
|
||||
}
|
||||
|
||||
@httpGet('/', TYPES.AuthMiddleware)
|
||||
@httpGet('/', TYPES.RequiredCrossServiceTokenMiddleware)
|
||||
async listInvites(request: Request, response: Response): Promise<void> {
|
||||
await this.httpService.callAuthServer(
|
||||
request,
|
||||
@@ -35,7 +35,7 @@ export class SubscriptionInvitesController extends BaseHttpController {
|
||||
)
|
||||
}
|
||||
|
||||
@httpDelete('/:inviteUuid', TYPES.AuthMiddleware)
|
||||
@httpDelete('/:inviteUuid', TYPES.RequiredCrossServiceTokenMiddleware)
|
||||
async cancelSubscriptionSharing(request: Request, response: Response): Promise<void> {
|
||||
await this.httpService.callAuthServer(
|
||||
request,
|
||||
@@ -48,7 +48,7 @@ export class SubscriptionInvitesController extends BaseHttpController {
|
||||
)
|
||||
}
|
||||
|
||||
@httpPost('/:inviteUuid/accept', TYPES.AuthMiddleware)
|
||||
@httpPost('/:inviteUuid/accept', TYPES.RequiredCrossServiceTokenMiddleware)
|
||||
async acceptInvite(request: Request, response: Response): Promise<void> {
|
||||
await this.httpService.callAuthServer(
|
||||
request,
|
||||
|
||||
@@ -15,7 +15,7 @@ export class TokensController extends BaseHttpController {
|
||||
super()
|
||||
}
|
||||
|
||||
@httpPost('/', TYPES.AuthMiddleware)
|
||||
@httpPost('/', TYPES.RequiredCrossServiceTokenMiddleware)
|
||||
async createToken(request: Request, response: Response): Promise<void> {
|
||||
await this.httpService.callAuthServer(
|
||||
request,
|
||||
|
||||
@@ -37,7 +37,7 @@ export class UsersController extends BaseHttpController {
|
||||
await this.httpService.callPaymentsServer(request, response, 'api/pro_users/send-activation-code', request.body)
|
||||
}
|
||||
|
||||
@httpPatch('/:userId', TYPES.AuthMiddleware)
|
||||
@httpPatch('/:userId', TYPES.RequiredCrossServiceTokenMiddleware)
|
||||
async updateUser(request: Request, response: Response): Promise<void> {
|
||||
await this.httpService.callAuthServer(
|
||||
request,
|
||||
@@ -47,7 +47,7 @@ export class UsersController extends BaseHttpController {
|
||||
)
|
||||
}
|
||||
|
||||
@httpPut('/:userUuid/password', TYPES.AuthMiddleware)
|
||||
@httpPut('/:userUuid/password', TYPES.RequiredCrossServiceTokenMiddleware)
|
||||
async changePassword(request: Request, response: Response): Promise<void> {
|
||||
this.logger.debug(
|
||||
'[DEPRECATED] use endpoint /v1/users/:userUuid/attributes/credentials instead of /v1/users/:userUuid/password',
|
||||
@@ -65,7 +65,7 @@ export class UsersController extends BaseHttpController {
|
||||
)
|
||||
}
|
||||
|
||||
@httpPut('/:userUuid/attributes/credentials', TYPES.AuthMiddleware)
|
||||
@httpPut('/:userUuid/attributes/credentials', TYPES.RequiredCrossServiceTokenMiddleware)
|
||||
async changeCredentials(request: Request, response: Response): Promise<void> {
|
||||
await this.httpService.callAuthServer(
|
||||
request,
|
||||
@@ -79,7 +79,7 @@ export class UsersController extends BaseHttpController {
|
||||
)
|
||||
}
|
||||
|
||||
@httpGet('/:userId/params', TYPES.AuthMiddleware)
|
||||
@httpGet('/:userId/params', TYPES.RequiredCrossServiceTokenMiddleware)
|
||||
async getKeyParams(request: Request, response: Response): Promise<void> {
|
||||
await this.httpService.callAuthServer(
|
||||
request,
|
||||
@@ -88,12 +88,12 @@ export class UsersController extends BaseHttpController {
|
||||
)
|
||||
}
|
||||
|
||||
@all('/:userId/mfa', TYPES.AuthMiddleware)
|
||||
@all('/:userId/mfa', TYPES.RequiredCrossServiceTokenMiddleware)
|
||||
async blockMFA(): Promise<results.StatusCodeResult> {
|
||||
return this.statusCode(401)
|
||||
}
|
||||
|
||||
@httpPost('/:userUuid/integrations/listed', TYPES.AuthMiddleware)
|
||||
@httpPost('/:userUuid/integrations/listed', TYPES.RequiredCrossServiceTokenMiddleware)
|
||||
async createListedAccount(request: Request, response: Response): Promise<void> {
|
||||
await this.httpService.callAuthServer(
|
||||
request,
|
||||
@@ -113,7 +113,7 @@ export class UsersController extends BaseHttpController {
|
||||
)
|
||||
}
|
||||
|
||||
@httpGet('/:userUuid/settings', TYPES.AuthMiddleware)
|
||||
@httpGet('/:userUuid/settings', TYPES.RequiredCrossServiceTokenMiddleware)
|
||||
async listSettings(request: Request, response: Response): Promise<void> {
|
||||
await this.httpService.callAuthServer(
|
||||
request,
|
||||
@@ -126,7 +126,7 @@ export class UsersController extends BaseHttpController {
|
||||
)
|
||||
}
|
||||
|
||||
@httpPut('/:userUuid/settings', TYPES.AuthMiddleware)
|
||||
@httpPut('/:userUuid/settings', TYPES.RequiredCrossServiceTokenMiddleware)
|
||||
async putSetting(request: Request, response: Response): Promise<void> {
|
||||
await this.httpService.callAuthServer(
|
||||
request,
|
||||
@@ -140,7 +140,7 @@ export class UsersController extends BaseHttpController {
|
||||
)
|
||||
}
|
||||
|
||||
@httpGet('/:userUuid/settings/:settingName', TYPES.AuthMiddleware)
|
||||
@httpGet('/:userUuid/settings/:settingName', TYPES.RequiredCrossServiceTokenMiddleware)
|
||||
async getSetting(request: Request, response: Response): Promise<void> {
|
||||
await this.httpService.callAuthServer(
|
||||
request,
|
||||
@@ -154,7 +154,7 @@ export class UsersController extends BaseHttpController {
|
||||
)
|
||||
}
|
||||
|
||||
@httpDelete('/:userUuid/settings/:settingName', TYPES.AuthMiddleware)
|
||||
@httpDelete('/:userUuid/settings/:settingName', TYPES.RequiredCrossServiceTokenMiddleware)
|
||||
async deleteSetting(request: Request, response: Response): Promise<void> {
|
||||
await this.httpService.callAuthServer(
|
||||
request,
|
||||
@@ -169,7 +169,7 @@ export class UsersController extends BaseHttpController {
|
||||
)
|
||||
}
|
||||
|
||||
@httpGet('/:userUuid/subscription-settings/:subscriptionSettingName', TYPES.AuthMiddleware)
|
||||
@httpGet('/:userUuid/subscription-settings/:subscriptionSettingName', TYPES.RequiredCrossServiceTokenMiddleware)
|
||||
async getSubscriptionSetting(request: Request, response: Response): Promise<void> {
|
||||
await this.httpService.callAuthServer(
|
||||
request,
|
||||
@@ -183,7 +183,7 @@ export class UsersController extends BaseHttpController {
|
||||
)
|
||||
}
|
||||
|
||||
@httpGet('/:userUuid/features', TYPES.AuthMiddleware)
|
||||
@httpGet('/:userUuid/features', TYPES.RequiredCrossServiceTokenMiddleware)
|
||||
async getFeatures(request: Request, response: Response): Promise<void> {
|
||||
await this.httpService.callAuthServer(
|
||||
request,
|
||||
@@ -196,7 +196,7 @@ export class UsersController extends BaseHttpController {
|
||||
)
|
||||
}
|
||||
|
||||
@httpGet('/:userUuid/subscription', TYPES.AuthMiddleware)
|
||||
@httpGet('/:userUuid/subscription', TYPES.RequiredCrossServiceTokenMiddleware)
|
||||
async getSubscription(request: Request, response: Response): Promise<void> {
|
||||
await this.httpService.callAuthServer(
|
||||
request,
|
||||
@@ -232,12 +232,12 @@ export class UsersController extends BaseHttpController {
|
||||
)
|
||||
}
|
||||
|
||||
@httpDelete('/:userUuid', TYPES.AuthMiddleware)
|
||||
@httpDelete('/:userUuid', TYPES.RequiredCrossServiceTokenMiddleware)
|
||||
async deleteUser(request: Request, response: Response): Promise<void> {
|
||||
await this.httpService.callPaymentsServer(request, response, 'api/account', request.body)
|
||||
}
|
||||
|
||||
@httpPost('/:userUuid/requests', TYPES.AuthMiddleware)
|
||||
@httpPost('/:userUuid/requests', TYPES.RequiredCrossServiceTokenMiddleware)
|
||||
async submitRequest(request: Request, response: Response): Promise<void> {
|
||||
await this.httpService.callAuthServer(
|
||||
request,
|
||||
|
||||
@@ -17,7 +17,7 @@ export class WebSocketsController extends BaseHttpController {
|
||||
super()
|
||||
}
|
||||
|
||||
@httpPost('/tokens', TYPES.AuthMiddleware)
|
||||
@httpPost('/tokens', TYPES.RequiredCrossServiceTokenMiddleware)
|
||||
async createWebSocketConnectionToken(request: Request, response: Response): Promise<void> {
|
||||
await this.httpService.callWebSocketServer(
|
||||
request,
|
||||
|
||||
@@ -9,7 +9,7 @@ import { EndpointResolverInterface } from '../../Service/Resolver/EndpointResolv
|
||||
@controller('/v2')
|
||||
export class ActionsControllerV2 extends BaseHttpController {
|
||||
constructor(
|
||||
@inject(TYPES.ServiceProxy) private httpService: ServiceProxyInterface,
|
||||
@inject(TYPES.ServiceProxy) private serviceProxy: ServiceProxyInterface,
|
||||
@inject(TYPES.EndpointResolver) private endpointResolver: EndpointResolverInterface,
|
||||
) {
|
||||
super()
|
||||
@@ -17,7 +17,7 @@ export class ActionsControllerV2 extends BaseHttpController {
|
||||
|
||||
@httpPost('/login')
|
||||
async login(request: Request, response: Response): Promise<void> {
|
||||
await this.httpService.callAuthServer(
|
||||
await this.serviceProxy.callAuthServer(
|
||||
request,
|
||||
response,
|
||||
this.endpointResolver.resolveEndpointOrMethodIdentifier('POST', 'auth/pkce_sign_in'),
|
||||
@@ -25,9 +25,9 @@ export class ActionsControllerV2 extends BaseHttpController {
|
||||
)
|
||||
}
|
||||
|
||||
@httpPost('/login-params')
|
||||
@httpPost('/login-params', TYPES.OptionalCrossServiceTokenMiddleware)
|
||||
async loginParams(request: Request, response: Response): Promise<void> {
|
||||
await this.httpService.callAuthServer(
|
||||
await this.serviceProxy.callAuthServer(
|
||||
request,
|
||||
response,
|
||||
this.endpointResolver.resolveEndpointOrMethodIdentifier('POST', 'auth/pkce_params'),
|
||||
|
||||
@@ -6,7 +6,7 @@ import { TYPES } from '../../Bootstrap/Types'
|
||||
import { ServiceProxyInterface } from '../../Service/Http/ServiceProxyInterface'
|
||||
import { EndpointResolverInterface } from '../../Service/Resolver/EndpointResolverInterface'
|
||||
|
||||
@controller('/v2/items/:itemUuid/revisions', TYPES.AuthMiddleware)
|
||||
@controller('/v2/items/:itemUuid/revisions', TYPES.RequiredCrossServiceTokenMiddleware)
|
||||
export class RevisionsControllerV2 extends BaseHttpController {
|
||||
constructor(
|
||||
@inject(TYPES.ServiceProxy) private httpService: ServiceProxyInterface,
|
||||
@@ -28,7 +28,7 @@ export class RevisionsControllerV2 extends BaseHttpController {
|
||||
)
|
||||
}
|
||||
|
||||
@httpGet('/:id')
|
||||
@httpGet('/:uuid')
|
||||
async getRevision(request: Request, response: Response): Promise<void> {
|
||||
await this.httpService.callRevisionsServer(
|
||||
request,
|
||||
@@ -37,12 +37,12 @@ export class RevisionsControllerV2 extends BaseHttpController {
|
||||
'GET',
|
||||
'items/:itemUuid/revisions/:id',
|
||||
request.params.itemUuid,
|
||||
request.params.id,
|
||||
request.params.uuid,
|
||||
),
|
||||
)
|
||||
}
|
||||
|
||||
@httpDelete('/:id')
|
||||
@httpDelete('/:uuid')
|
||||
async deleteRevision(request: Request, response: Response): Promise<void> {
|
||||
await this.httpService.callRevisionsServer(
|
||||
request,
|
||||
@@ -51,7 +51,7 @@ export class RevisionsControllerV2 extends BaseHttpController {
|
||||
'DELETE',
|
||||
'items/:itemUuid/revisions/:id',
|
||||
request.params.itemUuid,
|
||||
request.params.id,
|
||||
request.params.uuid,
|
||||
),
|
||||
)
|
||||
}
|
||||
|
||||
@@ -4,7 +4,7 @@ import { ServiceProxyInterface } from '../Http/ServiceProxyInterface'
|
||||
import { ServiceContainerInterface, ServiceIdentifier } from '@standardnotes/domain-core'
|
||||
|
||||
export class DirectCallServiceProxy implements ServiceProxyInterface {
|
||||
constructor(private serviceContainer: ServiceContainerInterface) {}
|
||||
constructor(private serviceContainer: ServiceContainerInterface, private filesServerUrl: string) {}
|
||||
|
||||
async validateSession(
|
||||
authorizationHeaderValue: string,
|
||||
@@ -49,7 +49,7 @@ export class DirectCallServiceProxy implements ServiceProxyInterface {
|
||||
json: Record<string, unknown>
|
||||
}
|
||||
|
||||
void (response as Response).status(serviceResponse.statusCode).send(serviceResponse.json)
|
||||
this.sendDecoratedResponse(response, serviceResponse)
|
||||
}
|
||||
|
||||
async callAuthServerWithLegacyFormat(
|
||||
@@ -66,7 +66,12 @@ export class DirectCallServiceProxy implements ServiceProxyInterface {
|
||||
throw new Error('Revisions service not found')
|
||||
}
|
||||
|
||||
await service.handleRequest(request, response, endpointOrMethodIdentifier)
|
||||
const serviceResponse = (await service.handleRequest(request, response, endpointOrMethodIdentifier)) as {
|
||||
statusCode: number
|
||||
json: Record<string, unknown>
|
||||
}
|
||||
|
||||
this.sendDecoratedResponse(response, serviceResponse)
|
||||
}
|
||||
|
||||
async callSyncingServer(request: never, response: never, endpointOrMethodIdentifier: string): Promise<void> {
|
||||
@@ -82,7 +87,7 @@ export class DirectCallServiceProxy implements ServiceProxyInterface {
|
||||
json: Record<string, unknown>
|
||||
}
|
||||
|
||||
void (response as Response).status(serviceResponse.statusCode).send(serviceResponse.json)
|
||||
this.sendDecoratedResponse(response, serviceResponse)
|
||||
}
|
||||
|
||||
async callLegacySyncingServer(
|
||||
@@ -104,4 +109,22 @@ export class DirectCallServiceProxy implements ServiceProxyInterface {
|
||||
): Promise<void> {
|
||||
throw new Error('Websockets server is not available.')
|
||||
}
|
||||
|
||||
private sendDecoratedResponse(
|
||||
response: Response,
|
||||
serviceResponse: { statusCode: number; json: Record<string, unknown> },
|
||||
): void {
|
||||
void response.status(serviceResponse.statusCode).send({
|
||||
meta: {
|
||||
auth: {
|
||||
userUuid: response.locals.user?.uuid,
|
||||
roles: response.locals.roles,
|
||||
},
|
||||
server: {
|
||||
filesServerUrl: this.filesServerUrl,
|
||||
},
|
||||
},
|
||||
data: serviceResponse.json,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
@@ -13,6 +13,9 @@ export class EndpointResolver implements EndpointResolverInterface {
|
||||
['[POST]:auth/recovery/codes', 'auth.generateRecoveryCodes'],
|
||||
['[POST]:auth/recovery/login', 'auth.signInWithRecoveryCodes'],
|
||||
['[POST]:auth/recovery/params', 'auth.recoveryKeyParams'],
|
||||
// v2 Actions Controller
|
||||
['[POST]:auth/pkce_sign_in', 'auth.pkceSignIn'],
|
||||
['[POST]:auth/pkce_params', 'auth.pkceParams'],
|
||||
// Authenticators Controller
|
||||
['[DELETE]:authenticators/:authenticatorId', 'auth.authenticators.delete'],
|
||||
['[GET]:authenticators/', 'auth.authenticators.list'],
|
||||
@@ -55,6 +58,10 @@ export class EndpointResolver implements EndpointResolverInterface {
|
||||
['[POST]:items/sync', 'sync.items.sync'],
|
||||
['[POST]:items/check-integrity', 'sync.items.check_integrity'],
|
||||
['[GET]:items/:uuid', 'sync.items.get_item'],
|
||||
// Revisions Controller V2
|
||||
['[GET]:items/:itemUuid/revisions', 'revisions.revisions.getRevisions'],
|
||||
['[GET]:items/:itemUuid/revisions/:id', 'revisions.revisions.getRevision'],
|
||||
['[DELETE]:items/:itemUuid/revisions/:id', 'revisions.revisions.deleteRevision'],
|
||||
])
|
||||
|
||||
resolveEndpointOrMethodIdentifier(method: string, endpoint: string, ...params: string[]): string {
|
||||
|
||||
@@ -3,6 +3,42 @@
|
||||
All notable changes to this project will be documented in this file.
|
||||
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
|
||||
|
||||
# [1.114.0](https://github.com/standardnotes/server/compare/@standardnotes/auth-server@1.113.0...@standardnotes/auth-server@1.114.0) (2023-05-30)
|
||||
|
||||
### Features
|
||||
|
||||
* make home server components publishable ([#617](https://github.com/standardnotes/server/issues/617)) ([55fd873](https://github.com/standardnotes/server/commit/55fd873b375e204dc9b0477b2cc6ed4582e5b603))
|
||||
|
||||
# [1.113.0](https://github.com/standardnotes/server/compare/@standardnotes/auth-server@1.112.0...@standardnotes/auth-server@1.113.0) (2023-05-30)
|
||||
|
||||
### Features
|
||||
|
||||
* upgrade to node 20.2.0 ([#616](https://github.com/standardnotes/server/issues/616)) ([a6b062f](https://github.com/standardnotes/server/commit/a6b062f638595537e1ece28bc79bded41d875e18))
|
||||
|
||||
# [1.112.0](https://github.com/standardnotes/server/compare/@standardnotes/auth-server@1.111.0...@standardnotes/auth-server@1.112.0) (2023-05-29)
|
||||
|
||||
### Features
|
||||
|
||||
* add files server as a service to home-server ([#614](https://github.com/standardnotes/server/issues/614)) ([c7d575a](https://github.com/standardnotes/server/commit/c7d575a0ffc7eb3e8799c3835da5727584f4f67b))
|
||||
|
||||
# [1.111.0](https://github.com/standardnotes/server/compare/@standardnotes/auth-server@1.110.0...@standardnotes/auth-server@1.111.0) (2023-05-25)
|
||||
|
||||
### Features
|
||||
|
||||
* add revisions service to home server ([#613](https://github.com/standardnotes/server/issues/613)) ([c70040f](https://github.com/standardnotes/server/commit/c70040fe5dfd35663b9811fbbaa9370bd0298482))
|
||||
|
||||
# [1.110.0](https://github.com/standardnotes/server/compare/@standardnotes/auth-server@1.109.2...@standardnotes/auth-server@1.110.0) (2023-05-25)
|
||||
|
||||
### Features
|
||||
|
||||
* refactor auth middleware to handle required and optional cross service token scenarios ([#612](https://github.com/standardnotes/server/issues/612)) ([1e4c7d0](https://github.com/standardnotes/server/commit/1e4c7d0f317d5c2d98065da12ffeb950b10ee5dc))
|
||||
|
||||
## [1.109.2](https://github.com/standardnotes/server/compare/@standardnotes/auth-server@1.109.1...@standardnotes/auth-server@1.109.2) (2023-05-18)
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* **auth:** changing user credentials to work both on http proxy and direct code call ([cc61229](https://github.com/standardnotes/server/commit/cc612296d0fbfa7e95556fda45eb9706845e4f58))
|
||||
|
||||
## [1.109.1](https://github.com/standardnotes/server/compare/@standardnotes/auth-server@1.109.0...@standardnotes/auth-server@1.109.1) (2023-05-18)
|
||||
|
||||
**Note:** Version bump only for package @standardnotes/auth-server
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
FROM node:20.1.0-alpine
|
||||
FROM node:20.2.0-alpine
|
||||
|
||||
RUN apk add --update \
|
||||
curl \
|
||||
|
||||
@@ -1,15 +1,17 @@
|
||||
{
|
||||
"name": "@standardnotes/auth-server",
|
||||
"version": "1.109.1",
|
||||
"version": "1.114.0",
|
||||
"engines": {
|
||||
"node": ">=18.0.0 <21.0.0"
|
||||
},
|
||||
"private": true,
|
||||
"description": "Auth Server",
|
||||
"main": "dist/src/index.js",
|
||||
"typings": "dist/src/index.d.ts",
|
||||
"author": "Karol Sójko <karolsojko@standardnotes.com>",
|
||||
"license": "AGPL-3.0-or-later",
|
||||
"publishConfig": {
|
||||
"access": "public"
|
||||
},
|
||||
"scripts": {
|
||||
"clean": "rm -fr dist",
|
||||
"setup:env": "cp .env.sample .env",
|
||||
|
||||
@@ -228,30 +228,28 @@ import { TypeORMEphemeralSessionRepository } from '../Infra/TypeORM/TypeORMEphem
|
||||
import { TypeORMOfflineSubscriptionTokenRepository } from '../Infra/TypeORM/TypeORMOfflineSubscriptionTokenRepository'
|
||||
import { TypeORMPKCERepository } from '../Infra/TypeORM/TypeORMPKCERepository'
|
||||
import { TypeORMSubscriptionTokenRepository } from '../Infra/TypeORM/TypeORMSubscriptionTokenRepository'
|
||||
import { InversifyExpressAuthController } from '../Infra/InversifyExpressUtils/InversifyExpressAuthController'
|
||||
import { InversifyExpressAuthenticatorsController } from '../Infra/InversifyExpressUtils/InversifyExpressAuthenticatorsController'
|
||||
import { InversifyExpressSubscriptionInvitesController } from '../Infra/InversifyExpressUtils/InversifyExpressSubscriptionInvitesController'
|
||||
import { InversifyExpressUserRequestsController } from '../Infra/InversifyExpressUtils/InversifyExpressUserRequestsController'
|
||||
import { InversifyExpressWebSocketsController } from '../Infra/InversifyExpressUtils/InversifyExpressWebSocketsController'
|
||||
import { InversifyExpressSessionsController } from '../Infra/InversifyExpressUtils/InversifyExpressSessionsController'
|
||||
import { InversifyExpressValetTokenController } from '../Infra/InversifyExpressUtils/InversifyExpressValetTokenController'
|
||||
import { InversifyExpressUsersController } from '../Infra/InversifyExpressUtils/InversifyExpressUsersController'
|
||||
import { InversifyExpressAdminController } from '../Infra/InversifyExpressUtils/InversifyExpressAdminController'
|
||||
import { InversifyExpressSubscriptionTokensController } from '../Infra/InversifyExpressUtils/InversifyExpressSubscriptionTokensController'
|
||||
import { InversifyExpressSubscriptionSettingsController } from '../Infra/InversifyExpressUtils/InversifyExpressSubscriptionSettingsController'
|
||||
import { InversifyExpressSettingsController } from '../Infra/InversifyExpressUtils/InversifyExpressSettingsController'
|
||||
import { SessionMiddleware } from '../Infra/InversifyExpressUtils/Middleware/SessionMiddleware'
|
||||
import { ApiGatewayAuthMiddleware } from '../Infra/InversifyExpressUtils/Middleware/ApiGatewayAuthMiddleware'
|
||||
import { ApiGatewayOfflineAuthMiddleware } from '../Infra/InversifyExpressUtils/Middleware/ApiGatewayOfflineAuthMiddleware'
|
||||
import { AuthMiddleware } from '../Infra/InversifyExpressUtils/Middleware/AuthMiddleware'
|
||||
import { OfflineUserAuthMiddleware } from '../Infra/InversifyExpressUtils/Middleware/OfflineUserAuthMiddleware'
|
||||
import { AuthMiddlewareWithoutResponse } from '../Infra/InversifyExpressUtils/Middleware/AuthMiddlewareWithoutResponse'
|
||||
import { LockMiddleware } from '../Infra/InversifyExpressUtils/Middleware/LockMiddleware'
|
||||
import { InversifyExpressSessionController } from '../Infra/InversifyExpressUtils/InversifyExpressSessionController'
|
||||
import { InversifyExpressOfflineController } from '../Infra/InversifyExpressUtils/InversifyExpressOfflineController'
|
||||
import { InversifyExpressListedController } from '../Infra/InversifyExpressUtils/InversifyExpressListedController'
|
||||
import { InversifyExpressInternalController } from '../Infra/InversifyExpressUtils/InversifyExpressInternalController'
|
||||
import { InversifyExpressFeaturesController } from '../Infra/InversifyExpressUtils/InversifyExpressFeaturesController'
|
||||
import { RequiredCrossServiceTokenMiddleware } from '../Infra/InversifyExpressUtils/Middleware/RequiredCrossServiceTokenMiddleware'
|
||||
import { OptionalCrossServiceTokenMiddleware } from '../Infra/InversifyExpressUtils/Middleware/OptionalCrossServiceTokenMiddleware'
|
||||
import { HomeServerSettingsController } from '../Infra/InversifyExpressUtils/HomeServer/HomeServerSettingsController'
|
||||
import { HomeServerAdminController } from '../Infra/InversifyExpressUtils/HomeServer/HomeServerAdminController'
|
||||
import { HomeServerAuthController } from '../Infra/InversifyExpressUtils/HomeServer/HomeServerAuthController'
|
||||
import { HomeServerAuthenticatorsController } from '../Infra/InversifyExpressUtils/HomeServer/HomeServerAuthenticatorsController'
|
||||
import { HomeServerFeaturesController } from '../Infra/InversifyExpressUtils/HomeServer/HomeServerFeaturesController'
|
||||
import { HomeServerListedController } from '../Infra/InversifyExpressUtils/HomeServer/HomeServerListedController'
|
||||
import { HomeServerOfflineController } from '../Infra/InversifyExpressUtils/HomeServer/HomeServerOfflineController'
|
||||
import { HomeServerSessionController } from '../Infra/InversifyExpressUtils/HomeServer/HomeServerSessionController'
|
||||
import { HomeServerSubscriptionInvitesController } from '../Infra/InversifyExpressUtils/HomeServer/HomeServerSubscriptionInvitesController'
|
||||
import { HomeServerSubscriptionSettingsController } from '../Infra/InversifyExpressUtils/HomeServer/HomeServerSubscriptionSettingsController'
|
||||
import { HomeServerSubscriptionTokensController } from '../Infra/InversifyExpressUtils/HomeServer/HomeServerSubscriptionTokensController'
|
||||
import { HomeServerUserRequestsController } from '../Infra/InversifyExpressUtils/HomeServer/HomeServerUserRequestsController'
|
||||
import { HomeServerUsersController } from '../Infra/InversifyExpressUtils/HomeServer/HomeServerUsersController'
|
||||
import { HomeServerValetTokenController } from '../Infra/InversifyExpressUtils/HomeServer/HomeServerValetTokenController'
|
||||
import { HomeServerWebSocketsController } from '../Infra/InversifyExpressUtils/HomeServer/HomeServerWebSocketsController'
|
||||
import { HomeServerSessionsController } from '../Infra/InversifyExpressUtils/HomeServer/HomeServerSessionsController'
|
||||
|
||||
// eslint-disable-next-line @typescript-eslint/no-var-requires
|
||||
const newrelicFormatter = require('@newrelic/winston-enricher')
|
||||
@@ -448,13 +446,14 @@ export class ContainerConfigLoader {
|
||||
)
|
||||
|
||||
// Middleware
|
||||
container.bind<AuthMiddleware>(TYPES.Auth_AuthMiddleware).to(AuthMiddleware)
|
||||
container.bind<SessionMiddleware>(TYPES.Auth_SessionMiddleware).to(SessionMiddleware)
|
||||
container.bind<LockMiddleware>(TYPES.Auth_LockMiddleware).to(LockMiddleware)
|
||||
container
|
||||
.bind<AuthMiddlewareWithoutResponse>(TYPES.Auth_AuthMiddlewareWithoutResponse)
|
||||
.to(AuthMiddlewareWithoutResponse)
|
||||
container.bind<ApiGatewayAuthMiddleware>(TYPES.Auth_ApiGatewayAuthMiddleware).to(ApiGatewayAuthMiddleware)
|
||||
.bind<RequiredCrossServiceTokenMiddleware>(TYPES.Auth_RequiredCrossServiceTokenMiddleware)
|
||||
.to(RequiredCrossServiceTokenMiddleware)
|
||||
container
|
||||
.bind<OptionalCrossServiceTokenMiddleware>(TYPES.Auth_OptionalCrossServiceTokenMiddleware)
|
||||
.to(OptionalCrossServiceTokenMiddleware)
|
||||
container
|
||||
.bind<ApiGatewayOfflineAuthMiddleware>(TYPES.Auth_ApiGatewayOfflineAuthMiddleware)
|
||||
.to(ApiGatewayOfflineAuthMiddleware)
|
||||
@@ -1012,9 +1011,9 @@ export class ContainerConfigLoader {
|
||||
}
|
||||
|
||||
container
|
||||
.bind<InversifyExpressAuthController>(TYPES.Auth_InversifyExpressAuthController)
|
||||
.bind<HomeServerAuthController>(TYPES.Auth_HomeServerAuthController)
|
||||
.toConstantValue(
|
||||
new InversifyExpressAuthController(
|
||||
new HomeServerAuthController(
|
||||
container.get(TYPES.Auth_VerifyMFA),
|
||||
container.get(TYPES.Auth_SignIn),
|
||||
container.get(TYPES.Auth_GetUserKeyParams),
|
||||
@@ -1029,42 +1028,42 @@ export class ContainerConfigLoader {
|
||||
// Inversify Controllers
|
||||
if (isConfiguredForHomeServer) {
|
||||
container
|
||||
.bind<InversifyExpressAuthenticatorsController>(TYPES.Auth_InversifyExpressAuthenticatorsController)
|
||||
.bind<HomeServerAuthenticatorsController>(TYPES.Auth_HomeServerAuthenticatorsController)
|
||||
.toConstantValue(
|
||||
new InversifyExpressAuthenticatorsController(
|
||||
new HomeServerAuthenticatorsController(
|
||||
container.get(TYPES.Auth_AuthenticatorsController),
|
||||
container.get(TYPES.Auth_ControllerContainer),
|
||||
),
|
||||
)
|
||||
container
|
||||
.bind<InversifyExpressSubscriptionInvitesController>(TYPES.Auth_InversifyExpressSubscriptionInvitesController)
|
||||
.bind<HomeServerSubscriptionInvitesController>(TYPES.Auth_HomeServerSubscriptionInvitesController)
|
||||
.toConstantValue(
|
||||
new InversifyExpressSubscriptionInvitesController(
|
||||
new HomeServerSubscriptionInvitesController(
|
||||
container.get(TYPES.Auth_SubscriptionInvitesController),
|
||||
container.get(TYPES.Auth_ControllerContainer),
|
||||
),
|
||||
)
|
||||
container
|
||||
.bind<InversifyExpressUserRequestsController>(TYPES.Auth_InversifyExpressUserRequestsController)
|
||||
.bind<HomeServerUserRequestsController>(TYPES.Auth_HomeServerUserRequestsController)
|
||||
.toConstantValue(
|
||||
new InversifyExpressUserRequestsController(
|
||||
new HomeServerUserRequestsController(
|
||||
container.get(TYPES.Auth_UserRequestsController),
|
||||
container.get(TYPES.Auth_ControllerContainer),
|
||||
),
|
||||
)
|
||||
container
|
||||
.bind<InversifyExpressWebSocketsController>(TYPES.Auth_InversifyExpressWebSocketsController)
|
||||
.bind<HomeServerWebSocketsController>(TYPES.Auth_HomeServerWebSocketsController)
|
||||
.toConstantValue(
|
||||
new InversifyExpressWebSocketsController(
|
||||
new HomeServerWebSocketsController(
|
||||
container.get(TYPES.Auth_CreateCrossServiceToken),
|
||||
container.get(TYPES.Auth_WebSocketConnectionTokenDecoder),
|
||||
container.get(TYPES.Auth_ControllerContainer),
|
||||
),
|
||||
)
|
||||
container
|
||||
.bind<InversifyExpressSessionsController>(TYPES.Auth_SessionsController)
|
||||
.bind<HomeServerSessionsController>(TYPES.Auth_HomeServerSessionsController)
|
||||
.toConstantValue(
|
||||
new InversifyExpressSessionsController(
|
||||
new HomeServerSessionsController(
|
||||
container.get(TYPES.Auth_GetActiveSessionsForUser),
|
||||
container.get(TYPES.Auth_AuthenticateRequest),
|
||||
container.get(TYPES.Auth_SessionProjector),
|
||||
@@ -1073,17 +1072,17 @@ export class ContainerConfigLoader {
|
||||
),
|
||||
)
|
||||
container
|
||||
.bind<InversifyExpressValetTokenController>(TYPES.Auth_InversifyExpressValetTokenController)
|
||||
.bind<HomeServerValetTokenController>(TYPES.Auth_HomeServerValetTokenController)
|
||||
.toConstantValue(
|
||||
new InversifyExpressValetTokenController(
|
||||
new HomeServerValetTokenController(
|
||||
container.get(TYPES.Auth_CreateValetToken),
|
||||
container.get(TYPES.Auth_ControllerContainer),
|
||||
),
|
||||
)
|
||||
container
|
||||
.bind<InversifyExpressUsersController>(TYPES.Auth_InversifyExpressUsersController)
|
||||
.bind<HomeServerUsersController>(TYPES.Auth_HomeServerUsersController)
|
||||
.toConstantValue(
|
||||
new InversifyExpressUsersController(
|
||||
new HomeServerUsersController(
|
||||
container.get(TYPES.Auth_UpdateUser),
|
||||
container.get(TYPES.Auth_GetUserKeyParams),
|
||||
container.get(TYPES.Auth_DeleteAccount),
|
||||
@@ -1095,9 +1094,9 @@ export class ContainerConfigLoader {
|
||||
),
|
||||
)
|
||||
container
|
||||
.bind<InversifyExpressAdminController>(TYPES.Auth_InversifyExpressAdminController)
|
||||
.bind<HomeServerAdminController>(TYPES.Auth_HomeServerAdminController)
|
||||
.toConstantValue(
|
||||
new InversifyExpressAdminController(
|
||||
new HomeServerAdminController(
|
||||
container.get(TYPES.Auth_DeleteSetting),
|
||||
container.get(TYPES.Auth_UserRepository),
|
||||
container.get(TYPES.Auth_CreateSubscriptionToken),
|
||||
@@ -1106,9 +1105,9 @@ export class ContainerConfigLoader {
|
||||
),
|
||||
)
|
||||
container
|
||||
.bind<InversifyExpressSubscriptionTokensController>(TYPES.Auth_InversifyExpressSubscriptionTokensController)
|
||||
.bind<HomeServerSubscriptionTokensController>(TYPES.Auth_HomeServerSubscriptionTokensController)
|
||||
.toConstantValue(
|
||||
new InversifyExpressSubscriptionTokensController(
|
||||
new HomeServerSubscriptionTokensController(
|
||||
container.get(TYPES.Auth_CreateSubscriptionToken),
|
||||
container.get(TYPES.Auth_AuthenticateSubscriptionToken),
|
||||
container.get(TYPES.Auth_SettingService),
|
||||
@@ -1120,17 +1119,17 @@ export class ContainerConfigLoader {
|
||||
),
|
||||
)
|
||||
container
|
||||
.bind<InversifyExpressSubscriptionSettingsController>(TYPES.Auth_InversifyExpressSubscriptionSettingsController)
|
||||
.bind<HomeServerSubscriptionSettingsController>(TYPES.Auth_HomeServerSubscriptionSettingsController)
|
||||
.toConstantValue(
|
||||
new InversifyExpressSubscriptionSettingsController(
|
||||
new HomeServerSubscriptionSettingsController(
|
||||
container.get(TYPES.Auth_GetSetting),
|
||||
container.get(TYPES.Auth_ControllerContainer),
|
||||
),
|
||||
)
|
||||
container
|
||||
.bind<InversifyExpressSettingsController>(TYPES.Auth_InversifyExpressSettingsController)
|
||||
.bind<HomeServerSettingsController>(TYPES.Auth_HomeServerSettingsController)
|
||||
.toConstantValue(
|
||||
new InversifyExpressSettingsController(
|
||||
new HomeServerSettingsController(
|
||||
container.get(TYPES.Auth_GetSettings),
|
||||
container.get(TYPES.Auth_GetSetting),
|
||||
container.get(TYPES.Auth_UpdateSetting),
|
||||
@@ -1139,9 +1138,9 @@ export class ContainerConfigLoader {
|
||||
),
|
||||
)
|
||||
container
|
||||
.bind<InversifyExpressSessionController>(TYPES.Auth_InversifyExpressSessionController)
|
||||
.bind<HomeServerSessionController>(TYPES.Auth_HomeServerSessionController)
|
||||
.toConstantValue(
|
||||
new InversifyExpressSessionController(
|
||||
new HomeServerSessionController(
|
||||
container.get(TYPES.Auth_DeleteSessionForUser),
|
||||
container.get(TYPES.Auth_DeletePreviousSessionsForUser),
|
||||
container.get(TYPES.Auth_RefreshSessionToken),
|
||||
@@ -1149,9 +1148,9 @@ export class ContainerConfigLoader {
|
||||
),
|
||||
)
|
||||
container
|
||||
.bind<InversifyExpressOfflineController>(TYPES.Auth_InversifyExpressOfflineController)
|
||||
.bind<HomeServerOfflineController>(TYPES.Auth_HomeServerOfflineController)
|
||||
.toConstantValue(
|
||||
new InversifyExpressOfflineController(
|
||||
new HomeServerOfflineController(
|
||||
container.get(TYPES.Auth_GetUserFeatures),
|
||||
container.get(TYPES.Auth_GetUserOfflineSubscription),
|
||||
container.get(TYPES.Auth_CreateOfflineSubscriptionToken),
|
||||
@@ -1163,25 +1162,17 @@ export class ContainerConfigLoader {
|
||||
),
|
||||
)
|
||||
container
|
||||
.bind<InversifyExpressListedController>(TYPES.Auth_InversifyExpressListedController)
|
||||
.bind<HomeServerListedController>(TYPES.Auth_HomeServerListedController)
|
||||
.toConstantValue(
|
||||
new InversifyExpressListedController(
|
||||
new HomeServerListedController(
|
||||
container.get(TYPES.Auth_CreateListedAccount),
|
||||
container.get(TYPES.Auth_ControllerContainer),
|
||||
),
|
||||
)
|
||||
container
|
||||
.bind<InversifyExpressInternalController>(TYPES.Auth_InversifyExpressInternalController)
|
||||
.bind<HomeServerFeaturesController>(TYPES.Auth_HomeServerFeaturesController)
|
||||
.toConstantValue(
|
||||
new InversifyExpressInternalController(
|
||||
container.get(TYPES.Auth_GetUserFeatures),
|
||||
container.get(TYPES.Auth_GetSetting),
|
||||
),
|
||||
)
|
||||
container
|
||||
.bind<InversifyExpressFeaturesController>(TYPES.Auth_InversifyExpressFeaturesController)
|
||||
.toConstantValue(
|
||||
new InversifyExpressFeaturesController(
|
||||
new HomeServerFeaturesController(
|
||||
container.get(TYPES.Auth_GetUserFeatures),
|
||||
container.get(TYPES.Auth_ControllerContainer),
|
||||
),
|
||||
|
||||
@@ -51,11 +51,10 @@ const TYPES = {
|
||||
Auth_ORMAuthenticatorChallengeRepository: Symbol.for('Auth_ORMAuthenticatorChallengeRepository'),
|
||||
Auth_ORMCacheEntryRepository: Symbol.for('Auth_ORMCacheEntryRepository'),
|
||||
// Middleware
|
||||
Auth_AuthMiddleware: Symbol.for('Auth_AuthMiddleware'),
|
||||
Auth_ApiGatewayAuthMiddleware: Symbol.for('Auth_ApiGatewayAuthMiddleware'),
|
||||
Auth_RequiredCrossServiceTokenMiddleware: Symbol.for('Auth_RequiredCrossServiceTokenMiddleware'),
|
||||
Auth_OptionalCrossServiceTokenMiddleware: Symbol.for('Auth_OptionalCrossServiceTokenMiddleware'),
|
||||
Auth_ApiGatewayOfflineAuthMiddleware: Symbol.for('Auth_ApiGatewayOfflineAuthMiddleware'),
|
||||
Auth_OfflineUserAuthMiddleware: Symbol.for('Auth_OfflineUserAuthMiddleware'),
|
||||
Auth_AuthMiddlewareWithoutResponse: Symbol.for('Auth_AuthMiddlewareWithoutResponse'),
|
||||
Auth_LockMiddleware: Symbol.for('Auth_LockMiddleware'),
|
||||
Auth_SessionMiddleware: Symbol.for('Auth_SessionMiddleware'),
|
||||
// Projectors
|
||||
@@ -217,25 +216,22 @@ const TYPES = {
|
||||
Auth_ProtocolVersionSelector: Symbol.for('Auth_ProtocolVersionSelector'),
|
||||
Auth_BooleanSelector: Symbol.for('Auth_BooleanSelector'),
|
||||
Auth_UserSubscriptionService: Symbol.for('Auth_UserSubscriptionService'),
|
||||
Auth_InversifyExpressAuthController: Symbol.for('Auth_InversifyExpressAuthController'),
|
||||
Auth_InversifyExpressAuthenticatorsController: Symbol.for('Auth_InversifyExpressAuthenticatorsController'),
|
||||
Auth_InversifyExpressSubscriptionInvitesController: Symbol.for('Auth_InversifyExpressSubscriptionInvitesController'),
|
||||
Auth_InversifyExpressUserRequestsController: Symbol.for('Auth_InversifyExpressUserRequestsController'),
|
||||
Auth_InversifyExpressWebSocketsController: Symbol.for('Auth_InversifyExpressWebSocketsController'),
|
||||
Auth_SessionsController: Symbol.for('Auth_SessionsController'),
|
||||
Auth_InversifyExpressValetTokenController: Symbol.for('Auth_InversifyExpressValetTokenController'),
|
||||
Auth_InversifyExpressUsersController: Symbol.for('Auth_InversifyExpressUsersController'),
|
||||
Auth_InversifyExpressAdminController: Symbol.for('Auth_InversifyExpressAdminController'),
|
||||
Auth_InversifyExpressSubscriptionTokensController: Symbol.for('Auth_InversifyExpressSubscriptionTokensController'),
|
||||
Auth_InversifyExpressSubscriptionSettingsController: Symbol.for(
|
||||
'Auth_InversifyExpressSubscriptionSettingsController',
|
||||
),
|
||||
Auth_InversifyExpressSettingsController: Symbol.for('Auth_InversifyExpressSettingsController'),
|
||||
Auth_InversifyExpressSessionController: Symbol.for('Auth_InversifyExpressSessionController'),
|
||||
Auth_InversifyExpressOfflineController: Symbol.for('Auth_InversifyExpressOfflineController'),
|
||||
Auth_InversifyExpressListedController: Symbol.for('Auth_InversifyExpressListedController'),
|
||||
Auth_InversifyExpressInternalController: Symbol.for('Auth_InversifyExpressInternalController'),
|
||||
Auth_InversifyExpressFeaturesController: Symbol.for('Auth_InversifyExpressFeaturesController'),
|
||||
Auth_HomeServerAuthController: Symbol.for('Auth_HomeServerAuthController'),
|
||||
Auth_HomeServerAuthenticatorsController: Symbol.for('Auth_HomeServerAuthenticatorsController'),
|
||||
Auth_HomeServerSubscriptionInvitesController: Symbol.for('Auth_HomeServerSubscriptionInvitesController'),
|
||||
Auth_HomeServerUserRequestsController: Symbol.for('Auth_HomeServerUserRequestsController'),
|
||||
Auth_HomeServerWebSocketsController: Symbol.for('Auth_HomeServerWebSocketsController'),
|
||||
Auth_HomeServerSessionsController: Symbol.for('Auth_HomeServerSessionsController'),
|
||||
Auth_HomeServerValetTokenController: Symbol.for('Auth_HomeServerValetTokenController'),
|
||||
Auth_HomeServerUsersController: Symbol.for('Auth_HomeServerUsersController'),
|
||||
Auth_HomeServerAdminController: Symbol.for('Auth_HomeServerAdminController'),
|
||||
Auth_HomeServerSubscriptionTokensController: Symbol.for('Auth_HomeServerSubscriptionTokensController'),
|
||||
Auth_HomeServerSubscriptionSettingsController: Symbol.for('Auth_HomeServerSubscriptionSettingsController'),
|
||||
Auth_HomeServerSettingsController: Symbol.for('Auth_HomeServerSettingsController'),
|
||||
Auth_HomeServerSessionController: Symbol.for('Auth_HomeServerSessionController'),
|
||||
Auth_HomeServerOfflineController: Symbol.for('Auth_HomeServerOfflineController'),
|
||||
Auth_HomeServerListedController: Symbol.for('Auth_HomeServerListedController'),
|
||||
Auth_HomeServerFeaturesController: Symbol.for('Auth_HomeServerFeaturesController'),
|
||||
}
|
||||
|
||||
export default TYPES
|
||||
|
||||
@@ -11,6 +11,7 @@ import { User } from '../../User/User'
|
||||
import { UserRepositoryInterface } from '../../User/UserRepositoryInterface'
|
||||
|
||||
import { ChangeCredentials } from './ChangeCredentials'
|
||||
import { Username } from '@standardnotes/domain-core'
|
||||
|
||||
describe('ChangeCredentials', () => {
|
||||
let userRepository: UserRepositoryInterface
|
||||
@@ -25,9 +26,6 @@ describe('ChangeCredentials', () => {
|
||||
new ChangeCredentials(userRepository, authResponseFactoryResolver, domainEventPublisher, domainEventFactory, timer)
|
||||
|
||||
beforeEach(() => {
|
||||
userRepository = {} as jest.Mocked<UserRepositoryInterface>
|
||||
userRepository.save = jest.fn()
|
||||
|
||||
authResponseFactory = {} as jest.Mocked<AuthResponseFactoryInterface>
|
||||
authResponseFactory.createResponse = jest.fn().mockReturnValue({ foo: 'bar' })
|
||||
|
||||
@@ -39,6 +37,10 @@ describe('ChangeCredentials', () => {
|
||||
user.uuid = '1-2-3'
|
||||
user.email = 'test@test.te'
|
||||
|
||||
userRepository = {} as jest.Mocked<UserRepositoryInterface>
|
||||
userRepository.save = jest.fn()
|
||||
userRepository.findOneByUsernameOrEmail = jest.fn().mockReturnValue(user)
|
||||
|
||||
domainEventPublisher = {} as jest.Mocked<DomainEventPublisherInterface>
|
||||
domainEventPublisher.publish = jest.fn()
|
||||
|
||||
@@ -52,7 +54,7 @@ describe('ChangeCredentials', () => {
|
||||
it('should change password', async () => {
|
||||
expect(
|
||||
await createUseCase().execute({
|
||||
user,
|
||||
username: Username.create('test@test.te').getValue(),
|
||||
apiVersion: '20190520',
|
||||
currentPassword: 'qweqwe123123',
|
||||
newPassword: 'test234',
|
||||
@@ -82,11 +84,11 @@ describe('ChangeCredentials', () => {
|
||||
})
|
||||
|
||||
it('should change email', async () => {
|
||||
userRepository.findOneByUsernameOrEmail = jest.fn().mockReturnValue(null)
|
||||
userRepository.findOneByUsernameOrEmail = jest.fn().mockReturnValueOnce(user).mockReturnValueOnce(null)
|
||||
|
||||
expect(
|
||||
await createUseCase().execute({
|
||||
user,
|
||||
username: Username.create('test@test.te').getValue(),
|
||||
apiVersion: '20190520',
|
||||
currentPassword: 'qweqwe123123',
|
||||
newPassword: 'test234',
|
||||
@@ -117,11 +119,14 @@ describe('ChangeCredentials', () => {
|
||||
})
|
||||
|
||||
it('should not change email if already taken', async () => {
|
||||
userRepository.findOneByUsernameOrEmail = jest.fn().mockReturnValue({} as jest.Mocked<User>)
|
||||
userRepository.findOneByUsernameOrEmail = jest
|
||||
.fn()
|
||||
.mockReturnValueOnce(user)
|
||||
.mockReturnValueOnce({} as jest.Mocked<User>)
|
||||
|
||||
expect(
|
||||
await createUseCase().execute({
|
||||
user,
|
||||
username: Username.create('test@test.te').getValue(),
|
||||
apiVersion: '20190520',
|
||||
currentPassword: 'qweqwe123123',
|
||||
newPassword: 'test234',
|
||||
@@ -144,7 +149,7 @@ describe('ChangeCredentials', () => {
|
||||
it('should not change email if the new email is invalid', async () => {
|
||||
expect(
|
||||
await createUseCase().execute({
|
||||
user,
|
||||
username: Username.create('test@test.te').getValue(),
|
||||
apiVersion: '20190520',
|
||||
currentPassword: 'qweqwe123123',
|
||||
newPassword: 'test234',
|
||||
@@ -164,10 +169,35 @@ describe('ChangeCredentials', () => {
|
||||
expect(domainEventPublisher.publish).not.toHaveBeenCalled()
|
||||
})
|
||||
|
||||
it('should not change email if the user is not found', async () => {
|
||||
userRepository.findOneByUsernameOrEmail = jest.fn().mockReturnValue(null)
|
||||
|
||||
expect(
|
||||
await createUseCase().execute({
|
||||
username: Username.create('test@test.te').getValue(),
|
||||
apiVersion: '20190520',
|
||||
currentPassword: 'qweqwe123123',
|
||||
newPassword: 'test234',
|
||||
newEmail: '',
|
||||
pwNonce: 'asdzxc',
|
||||
updatedWithUserAgent: 'Google Chrome',
|
||||
kpCreated: '123',
|
||||
kpOrigination: 'password-change',
|
||||
}),
|
||||
).toEqual({
|
||||
success: false,
|
||||
errorMessage: 'User not found.',
|
||||
})
|
||||
|
||||
expect(userRepository.save).not.toHaveBeenCalled()
|
||||
expect(domainEventFactory.createUserEmailChangedEvent).not.toHaveBeenCalled()
|
||||
expect(domainEventPublisher.publish).not.toHaveBeenCalled()
|
||||
})
|
||||
|
||||
it('should not change password if current password is incorrect', async () => {
|
||||
expect(
|
||||
await createUseCase().execute({
|
||||
user,
|
||||
username: Username.create('test@test.te').getValue(),
|
||||
apiVersion: '20190520',
|
||||
currentPassword: 'test123',
|
||||
newPassword: 'test234',
|
||||
@@ -185,7 +215,7 @@ describe('ChangeCredentials', () => {
|
||||
it('should update protocol version while changing password', async () => {
|
||||
expect(
|
||||
await createUseCase().execute({
|
||||
user,
|
||||
username: Username.create('test@test.te').getValue(),
|
||||
apiVersion: '20190520',
|
||||
currentPassword: 'qweqwe123123',
|
||||
newPassword: 'test234',
|
||||
|
||||
@@ -25,14 +25,22 @@ export class ChangeCredentials implements UseCaseInterface {
|
||||
) {}
|
||||
|
||||
async execute(dto: ChangeCredentialsDTO): Promise<ChangeCredentialsResponse> {
|
||||
if (!(await bcrypt.compare(dto.currentPassword, dto.user.encryptedPassword))) {
|
||||
const user = await this.userRepository.findOneByUsernameOrEmail(dto.username)
|
||||
if (!user) {
|
||||
return {
|
||||
success: false,
|
||||
errorMessage: 'User not found.',
|
||||
}
|
||||
}
|
||||
|
||||
if (!(await bcrypt.compare(dto.currentPassword, user.encryptedPassword))) {
|
||||
return {
|
||||
success: false,
|
||||
errorMessage: 'The current password you entered is incorrect. Please try again.',
|
||||
}
|
||||
}
|
||||
|
||||
dto.user.encryptedPassword = await bcrypt.hash(dto.newPassword, User.PASSWORD_HASH_COST)
|
||||
user.encryptedPassword = await bcrypt.hash(dto.newPassword, User.PASSWORD_HASH_COST)
|
||||
|
||||
let userEmailChangedEvent: UserEmailChangedEvent | undefined = undefined
|
||||
if (dto.newEmail !== undefined) {
|
||||
@@ -54,27 +62,27 @@ export class ChangeCredentials implements UseCaseInterface {
|
||||
}
|
||||
|
||||
userEmailChangedEvent = this.domainEventFactory.createUserEmailChangedEvent(
|
||||
dto.user.uuid,
|
||||
dto.user.email,
|
||||
user.uuid,
|
||||
user.email,
|
||||
newUsername.value,
|
||||
)
|
||||
|
||||
dto.user.email = newUsername.value
|
||||
user.email = newUsername.value
|
||||
}
|
||||
|
||||
dto.user.pwNonce = dto.pwNonce
|
||||
user.pwNonce = dto.pwNonce
|
||||
if (dto.protocolVersion) {
|
||||
dto.user.version = dto.protocolVersion
|
||||
user.version = dto.protocolVersion
|
||||
}
|
||||
if (dto.kpCreated) {
|
||||
dto.user.kpCreated = dto.kpCreated
|
||||
user.kpCreated = dto.kpCreated
|
||||
}
|
||||
if (dto.kpOrigination) {
|
||||
dto.user.kpOrigination = dto.kpOrigination
|
||||
user.kpOrigination = dto.kpOrigination
|
||||
}
|
||||
dto.user.updatedAt = this.timer.getUTCDate()
|
||||
user.updatedAt = this.timer.getUTCDate()
|
||||
|
||||
const updatedUser = await this.userRepository.save(dto.user)
|
||||
const updatedUser = await this.userRepository.save(user)
|
||||
|
||||
if (userEmailChangedEvent !== undefined) {
|
||||
await this.domainEventPublisher.publish(userEmailChangedEvent)
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import { User } from '../../User/User'
|
||||
import { Username } from '@standardnotes/domain-core'
|
||||
|
||||
export type ChangeCredentialsDTO = {
|
||||
user: User
|
||||
username: Username
|
||||
apiVersion: string
|
||||
currentPassword: string
|
||||
newPassword: string
|
||||
|
||||
@@ -35,9 +35,7 @@ describe('GetUserKeyParams', () => {
|
||||
})
|
||||
|
||||
it('should get key params for an authenticated user - searching by email', async () => {
|
||||
expect(
|
||||
await createUseCase().execute({ email: 'test@test.te', authenticated: true, authenticatedUser: user }),
|
||||
).toEqual({
|
||||
expect(await createUseCase().execute({ email: 'test@test.te', authenticated: true })).toEqual({
|
||||
keyParams: {
|
||||
foo: 'bar',
|
||||
},
|
||||
@@ -63,7 +61,7 @@ describe('GetUserKeyParams', () => {
|
||||
})
|
||||
|
||||
it('should get key params for an authenticated user - searching by uuid', async () => {
|
||||
expect(await createUseCase().execute({ userUuid: '1-2-3', authenticated: true, authenticatedUser: user })).toEqual({
|
||||
expect(await createUseCase().execute({ userUuid: '1-2-3', authenticated: true })).toEqual({
|
||||
keyParams: {
|
||||
foo: 'bar',
|
||||
},
|
||||
|
||||
@@ -22,16 +22,6 @@ export class GetUserKeyParams implements UseCaseInterface {
|
||||
) {}
|
||||
|
||||
async execute(dto: GetUserKeyParamsDTO): Promise<GetUserKeyParamsResponse> {
|
||||
if (dto.authenticatedUser) {
|
||||
this.logger.debug(`Creating key params for authenticated user ${dto.authenticatedUser.email}`)
|
||||
|
||||
const keyParams = await this.createKeyParams(dto, dto.authenticatedUser, true)
|
||||
|
||||
return {
|
||||
keyParams,
|
||||
}
|
||||
}
|
||||
|
||||
let user: User | null = null
|
||||
if (dto.email !== undefined) {
|
||||
const usernameOrError = Username.create(dto.email)
|
||||
|
||||
@@ -1,8 +1,5 @@
|
||||
import { User } from '../../User/User'
|
||||
|
||||
export type GetUserKeyParamsDTOV1Unchallenged = {
|
||||
authenticated: boolean
|
||||
email?: string
|
||||
userUuid?: string
|
||||
authenticatedUser?: User
|
||||
}
|
||||
|
||||
@@ -1,9 +1,6 @@
|
||||
import { User } from '../../User/User'
|
||||
|
||||
export type GetUserKeyParamsDTOV2Challenged = {
|
||||
authenticated: boolean
|
||||
codeChallenge: string
|
||||
email?: string
|
||||
userUuid?: string
|
||||
authenticatedUser?: User
|
||||
}
|
||||
|
||||
@@ -0,0 +1,121 @@
|
||||
import { ControllerContainerInterface, Username } from '@standardnotes/domain-core'
|
||||
import { BaseHttpController, results } from 'inversify-express-utils'
|
||||
import { SettingName } from '@standardnotes/settings'
|
||||
import { Request } from 'express'
|
||||
|
||||
import { CreateOfflineSubscriptionToken } from '../../../Domain/UseCase/CreateOfflineSubscriptionToken/CreateOfflineSubscriptionToken'
|
||||
import { CreateSubscriptionToken } from '../../../Domain/UseCase/CreateSubscriptionToken/CreateSubscriptionToken'
|
||||
import { DeleteSetting } from '../../../Domain/UseCase/DeleteSetting/DeleteSetting'
|
||||
import { UserRepositoryInterface } from '../../../Domain/User/UserRepositoryInterface'
|
||||
|
||||
export class HomeServerAdminController extends BaseHttpController {
|
||||
constructor(
|
||||
protected doDeleteSetting: DeleteSetting,
|
||||
protected userRepository: UserRepositoryInterface,
|
||||
protected createSubscriptionToken: CreateSubscriptionToken,
|
||||
protected createOfflineSubscriptionToken: CreateOfflineSubscriptionToken,
|
||||
private controllerContainer?: ControllerContainerInterface,
|
||||
) {
|
||||
super()
|
||||
|
||||
if (this.controllerContainer !== undefined) {
|
||||
this.controllerContainer.register('admin.getUser', this.getUser.bind(this))
|
||||
this.controllerContainer.register('admin.deleteMFASetting', this.deleteMFASetting.bind(this))
|
||||
this.controllerContainer.register('admin.createToken', this.createToken.bind(this))
|
||||
this.controllerContainer.register('admin.createOfflineToken', this.createOfflineToken.bind(this))
|
||||
this.controllerContainer.register('admin.disableEmailBackups', this.disableEmailBackups.bind(this))
|
||||
}
|
||||
}
|
||||
|
||||
async getUser(request: Request): Promise<results.JsonResult> {
|
||||
const usernameOrError = Username.create(request.params.email ?? '')
|
||||
if (usernameOrError.isFailed()) {
|
||||
return this.json(
|
||||
{
|
||||
error: {
|
||||
message: 'Missing email parameter.',
|
||||
},
|
||||
},
|
||||
400,
|
||||
)
|
||||
}
|
||||
const username = usernameOrError.getValue()
|
||||
|
||||
const user = await this.userRepository.findOneByUsernameOrEmail(username)
|
||||
|
||||
if (!user) {
|
||||
return this.json(
|
||||
{
|
||||
error: {
|
||||
message: `No user with email '${username.value}'.`,
|
||||
},
|
||||
},
|
||||
400,
|
||||
)
|
||||
}
|
||||
|
||||
return this.json({
|
||||
uuid: user.uuid,
|
||||
})
|
||||
}
|
||||
|
||||
async deleteMFASetting(request: Request): Promise<results.JsonResult> {
|
||||
const { userUuid } = request.params
|
||||
const { uuid, updatedAt } = request.body
|
||||
|
||||
const result = await this.doDeleteSetting.execute({
|
||||
uuid,
|
||||
userUuid,
|
||||
settingName: SettingName.NAMES.MfaSecret,
|
||||
timestamp: updatedAt,
|
||||
softDelete: true,
|
||||
})
|
||||
|
||||
if (result.success) {
|
||||
return this.json(result)
|
||||
}
|
||||
|
||||
return this.json(result, 400)
|
||||
}
|
||||
|
||||
async createToken(request: Request): Promise<results.JsonResult> {
|
||||
const { userUuid } = request.params
|
||||
const result = await this.createSubscriptionToken.execute({
|
||||
userUuid,
|
||||
})
|
||||
|
||||
return this.json({
|
||||
token: result.subscriptionToken.token,
|
||||
})
|
||||
}
|
||||
|
||||
async createOfflineToken(request: Request): Promise<results.JsonResult | results.BadRequestResult> {
|
||||
const { email } = request.params
|
||||
const result = await this.createOfflineSubscriptionToken.execute({
|
||||
userEmail: email,
|
||||
})
|
||||
|
||||
if (!result.success) {
|
||||
return this.badRequest()
|
||||
}
|
||||
|
||||
return this.json({
|
||||
token: result.offlineSubscriptionToken.token,
|
||||
})
|
||||
}
|
||||
|
||||
async disableEmailBackups(request: Request): Promise<results.BadRequestErrorMessageResult | results.OkResult> {
|
||||
const { userUuid } = request.params
|
||||
|
||||
const result = await this.doDeleteSetting.execute({
|
||||
userUuid,
|
||||
settingName: SettingName.NAMES.EmailBackupFrequency,
|
||||
})
|
||||
|
||||
if (result.success) {
|
||||
return this.ok()
|
||||
}
|
||||
|
||||
return this.badRequest('No email backups found')
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,299 @@
|
||||
import { ControllerContainerInterface } from '@standardnotes/domain-core'
|
||||
import { Request, Response } from 'express'
|
||||
import { Logger } from 'winston'
|
||||
|
||||
import { ClearLoginAttempts } from '../../../Domain/UseCase/ClearLoginAttempts'
|
||||
import { GetUserKeyParams } from '../../../Domain/UseCase/GetUserKeyParams/GetUserKeyParams'
|
||||
import { IncreaseLoginAttempts } from '../../../Domain/UseCase/IncreaseLoginAttempts'
|
||||
import { SignIn } from '../../../Domain/UseCase/SignIn'
|
||||
import { VerifyMFA } from '../../../Domain/UseCase/VerifyMFA'
|
||||
import { AuthController } from '../../../Controller/AuthController'
|
||||
import { BaseHttpController, results } from 'inversify-express-utils'
|
||||
|
||||
export class HomeServerAuthController extends BaseHttpController {
|
||||
constructor(
|
||||
protected verifyMFA: VerifyMFA,
|
||||
protected signInUseCase: SignIn,
|
||||
protected getUserKeyParams: GetUserKeyParams,
|
||||
protected clearLoginAttempts: ClearLoginAttempts,
|
||||
protected increaseLoginAttempts: IncreaseLoginAttempts,
|
||||
protected logger: Logger,
|
||||
protected authController: AuthController,
|
||||
private controllerContainer?: ControllerContainerInterface,
|
||||
) {
|
||||
super()
|
||||
|
||||
if (this.controllerContainer !== undefined) {
|
||||
this.controllerContainer.register('auth.params', this.params.bind(this))
|
||||
this.controllerContainer.register('auth.signIn', this.signIn.bind(this))
|
||||
this.controllerContainer.register('auth.pkceParams', this.pkceParams.bind(this))
|
||||
this.controllerContainer.register('auth.pkceSignIn', this.pkceSignIn.bind(this))
|
||||
this.controllerContainer.register('auth.users.register', this.register.bind(this))
|
||||
this.controllerContainer.register('auth.generateRecoveryCodes', this.generateRecoveryCodes.bind(this))
|
||||
this.controllerContainer.register('auth.signInWithRecoveryCodes', this.recoveryLogin.bind(this))
|
||||
this.controllerContainer.register('auth.recoveryKeyParams', this.recoveryParams.bind(this))
|
||||
this.controllerContainer.register('auth.signOut', this.signOut.bind(this))
|
||||
}
|
||||
}
|
||||
|
||||
async params(request: Request, response: Response): Promise<results.JsonResult> {
|
||||
if (response.locals.session) {
|
||||
const result = await this.getUserKeyParams.execute({
|
||||
email: response.locals.user.email,
|
||||
authenticated: true,
|
||||
})
|
||||
|
||||
return this.json(result.keyParams)
|
||||
}
|
||||
|
||||
if (!request.query.email) {
|
||||
return this.json(
|
||||
{
|
||||
error: {
|
||||
message: 'Please provide an email address.',
|
||||
},
|
||||
},
|
||||
400,
|
||||
)
|
||||
}
|
||||
|
||||
const verifyMFAResponse = await this.verifyMFA.execute({
|
||||
email: <string>request.query.email,
|
||||
requestParams: request.query,
|
||||
preventOTPFromFurtherUsage: false,
|
||||
})
|
||||
|
||||
if (!verifyMFAResponse.success) {
|
||||
return this.json(
|
||||
{
|
||||
error: {
|
||||
tag: verifyMFAResponse.errorTag,
|
||||
message: verifyMFAResponse.errorMessage,
|
||||
payload: verifyMFAResponse.errorPayload,
|
||||
},
|
||||
},
|
||||
401,
|
||||
)
|
||||
}
|
||||
|
||||
const result = await this.getUserKeyParams.execute({
|
||||
email: <string>request.query.email,
|
||||
authenticated: false,
|
||||
})
|
||||
|
||||
return this.json(result.keyParams)
|
||||
}
|
||||
|
||||
async signIn(request: Request): Promise<results.JsonResult> {
|
||||
if (!request.body.email || !request.body.password) {
|
||||
this.logger.debug('/auth/sign_in request missing credentials: %O', request.body)
|
||||
|
||||
return this.json(
|
||||
{
|
||||
error: {
|
||||
tag: 'invalid-auth',
|
||||
message: 'Invalid login credentials.',
|
||||
},
|
||||
},
|
||||
401,
|
||||
)
|
||||
}
|
||||
|
||||
const verifyMFAResponse = await this.verifyMFA.execute({
|
||||
email: request.body.email,
|
||||
requestParams: request.body,
|
||||
preventOTPFromFurtherUsage: true,
|
||||
})
|
||||
|
||||
if (!verifyMFAResponse.success) {
|
||||
return this.json(
|
||||
{
|
||||
error: {
|
||||
tag: verifyMFAResponse.errorTag,
|
||||
message: verifyMFAResponse.errorMessage,
|
||||
payload: verifyMFAResponse.errorPayload,
|
||||
},
|
||||
},
|
||||
401,
|
||||
)
|
||||
}
|
||||
|
||||
const signInResult = await this.signInUseCase.execute({
|
||||
apiVersion: request.body.api,
|
||||
userAgent: <string>request.headers['user-agent'],
|
||||
email: request.body.email,
|
||||
password: request.body.password,
|
||||
ephemeralSession: request.body.ephemeral ?? false,
|
||||
})
|
||||
|
||||
if (!signInResult.success) {
|
||||
await this.increaseLoginAttempts.execute({ email: request.body.email })
|
||||
|
||||
return this.json(
|
||||
{
|
||||
error: {
|
||||
message: signInResult.errorMessage,
|
||||
},
|
||||
},
|
||||
signInResult.errorCode ?? 401,
|
||||
)
|
||||
}
|
||||
|
||||
await this.clearLoginAttempts.execute({ email: request.body.email })
|
||||
|
||||
return this.json(signInResult.authResponse)
|
||||
}
|
||||
|
||||
async pkceParams(request: Request, response: Response): Promise<results.JsonResult> {
|
||||
if (!request.body.code_challenge) {
|
||||
return this.json(
|
||||
{
|
||||
error: {
|
||||
message: 'Please provide the code challenge parameter.',
|
||||
},
|
||||
},
|
||||
400,
|
||||
)
|
||||
}
|
||||
|
||||
if (response.locals.session) {
|
||||
const result = await this.getUserKeyParams.execute({
|
||||
email: response.locals.user.email,
|
||||
authenticated: true,
|
||||
codeChallenge: request.body.code_challenge as string,
|
||||
})
|
||||
|
||||
return this.json(result.keyParams)
|
||||
}
|
||||
|
||||
if (!request.body.email) {
|
||||
return this.json(
|
||||
{
|
||||
error: {
|
||||
message: 'Please provide an email address.',
|
||||
},
|
||||
},
|
||||
400,
|
||||
)
|
||||
}
|
||||
|
||||
const verifyMFAResponse = await this.verifyMFA.execute({
|
||||
email: <string>request.body.email,
|
||||
requestParams: request.body,
|
||||
preventOTPFromFurtherUsage: true,
|
||||
})
|
||||
|
||||
if (!verifyMFAResponse.success) {
|
||||
return this.json(
|
||||
{
|
||||
error: {
|
||||
tag: verifyMFAResponse.errorTag,
|
||||
message: verifyMFAResponse.errorMessage,
|
||||
payload: verifyMFAResponse.errorPayload,
|
||||
},
|
||||
},
|
||||
401,
|
||||
)
|
||||
}
|
||||
|
||||
const result = await this.getUserKeyParams.execute({
|
||||
email: <string>request.body.email,
|
||||
authenticated: false,
|
||||
codeChallenge: request.body.code_challenge as string,
|
||||
})
|
||||
|
||||
return this.json(result.keyParams)
|
||||
}
|
||||
|
||||
async pkceSignIn(request: Request): Promise<results.JsonResult> {
|
||||
if (!request.body.email || !request.body.password || !request.body.code_verifier) {
|
||||
this.logger.debug('/auth/sign_in request missing credentials: %O', request.body)
|
||||
|
||||
return this.json(
|
||||
{
|
||||
error: {
|
||||
tag: 'invalid-auth',
|
||||
message: 'Invalid login credentials.',
|
||||
},
|
||||
},
|
||||
401,
|
||||
)
|
||||
}
|
||||
|
||||
const signInResult = await this.signInUseCase.execute({
|
||||
apiVersion: request.body.api,
|
||||
userAgent: <string>request.headers['user-agent'],
|
||||
email: request.body.email,
|
||||
password: request.body.password,
|
||||
ephemeralSession: request.body.ephemeral ?? false,
|
||||
codeVerifier: request.body.code_verifier,
|
||||
})
|
||||
|
||||
if (!signInResult.success) {
|
||||
await this.increaseLoginAttempts.execute({ email: request.body.email })
|
||||
|
||||
return this.json(
|
||||
{
|
||||
error: {
|
||||
message: signInResult.errorMessage,
|
||||
},
|
||||
},
|
||||
401,
|
||||
)
|
||||
}
|
||||
|
||||
await this.clearLoginAttempts.execute({ email: request.body.email })
|
||||
|
||||
return this.json(signInResult.authResponse)
|
||||
}
|
||||
|
||||
async generateRecoveryCodes(_request: Request, response: Response): Promise<results.JsonResult> {
|
||||
const result = await this.authController.generateRecoveryCodes({
|
||||
userUuid: response.locals.user.uuid,
|
||||
})
|
||||
|
||||
return this.json(result.data, result.status)
|
||||
}
|
||||
|
||||
async recoveryLogin(request: Request): Promise<results.JsonResult> {
|
||||
const result = await this.authController.signInWithRecoveryCodes({
|
||||
apiVersion: request.body.api_version,
|
||||
userAgent: <string>request.headers['user-agent'],
|
||||
codeVerifier: request.body.code_verifier,
|
||||
username: request.body.username,
|
||||
recoveryCodes: request.body.recovery_codes,
|
||||
password: request.body.password,
|
||||
})
|
||||
|
||||
return this.json(result.data, result.status)
|
||||
}
|
||||
|
||||
async recoveryParams(request: Request): Promise<results.JsonResult> {
|
||||
const result = await this.authController.recoveryKeyParams({
|
||||
apiVersion: request.body.api_version,
|
||||
username: request.body.username,
|
||||
codeChallenge: request.body.code_challenge,
|
||||
recoveryCodes: request.body.recovery_codes,
|
||||
})
|
||||
|
||||
return this.json(result.data, result.status)
|
||||
}
|
||||
|
||||
async signOut(request: Request, response: Response): Promise<results.JsonResult | void> {
|
||||
const result = await this.authController.signOut({
|
||||
readOnlyAccess: response.locals.readOnlyAccess,
|
||||
authorizationHeader: <string>request.headers.authorization,
|
||||
})
|
||||
|
||||
return this.json(result.data, result.status)
|
||||
}
|
||||
|
||||
async register(request: Request): Promise<results.JsonResult> {
|
||||
const response = await this.authController.register({
|
||||
...request.body,
|
||||
userAgent: <string>request.headers['user-agent'],
|
||||
})
|
||||
|
||||
return this.json(response.data, response.status)
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,74 @@
|
||||
import { ControllerContainerInterface } from '@standardnotes/domain-core'
|
||||
import { Request, Response } from 'express'
|
||||
|
||||
import { AuthenticatorsController } from '../../../Controller/AuthenticatorsController'
|
||||
import { BaseHttpController, results } from 'inversify-express-utils'
|
||||
|
||||
export class HomeServerAuthenticatorsController extends BaseHttpController {
|
||||
constructor(
|
||||
protected authenticatorsController: AuthenticatorsController,
|
||||
private controllerContainer?: ControllerContainerInterface,
|
||||
) {
|
||||
super()
|
||||
|
||||
if (this.controllerContainer !== undefined) {
|
||||
this.controllerContainer.register('auth.authenticators.list', this.list.bind(this))
|
||||
this.controllerContainer.register('auth.authenticators.delete', this.delete.bind(this))
|
||||
this.controllerContainer.register(
|
||||
'auth.authenticators.generateRegistrationOptions',
|
||||
this.generateRegistrationOptions.bind(this),
|
||||
)
|
||||
this.controllerContainer.register(
|
||||
'auth.authenticators.verifyRegistrationResponse',
|
||||
this.verifyRegistration.bind(this),
|
||||
)
|
||||
this.controllerContainer.register(
|
||||
'auth.authenticators.generateAuthenticationOptions',
|
||||
this.generateAuthenticationOptions.bind(this),
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
async list(_request: Request, response: Response): Promise<results.JsonResult> {
|
||||
const result = await this.authenticatorsController.list({
|
||||
userUuid: response.locals.user.uuid,
|
||||
})
|
||||
|
||||
return this.json(result.data, result.status)
|
||||
}
|
||||
|
||||
async delete(request: Request, response: Response): Promise<results.JsonResult> {
|
||||
const result = await this.authenticatorsController.delete({
|
||||
userUuid: response.locals.user.uuid,
|
||||
authenticatorId: request.params.authenticatorId,
|
||||
})
|
||||
|
||||
return this.json(result.data, result.status)
|
||||
}
|
||||
|
||||
async generateRegistrationOptions(_request: Request, response: Response): Promise<results.JsonResult> {
|
||||
const result = await this.authenticatorsController.generateRegistrationOptions({
|
||||
username: response.locals.user.email,
|
||||
userUuid: response.locals.user.uuid,
|
||||
})
|
||||
|
||||
return this.json(result.data, result.status)
|
||||
}
|
||||
|
||||
async verifyRegistration(request: Request, response: Response): Promise<results.JsonResult> {
|
||||
const result = await this.authenticatorsController.verifyRegistrationResponse({
|
||||
userUuid: response.locals.user.uuid,
|
||||
attestationResponse: request.body.attestationResponse,
|
||||
})
|
||||
|
||||
return this.json(result.data, result.status)
|
||||
}
|
||||
|
||||
async generateAuthenticationOptions(request: Request): Promise<results.JsonResult> {
|
||||
const result = await this.authenticatorsController.generateAuthenticationOptions({
|
||||
username: request.body.username,
|
||||
})
|
||||
|
||||
return this.json(result.data, result.status)
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,42 @@
|
||||
import { ControllerContainerInterface } from '@standardnotes/domain-core'
|
||||
import { Request, Response } from 'express'
|
||||
|
||||
import { GetUserFeatures } from '../../../Domain/UseCase/GetUserFeatures/GetUserFeatures'
|
||||
import { BaseHttpController, results } from 'inversify-express-utils'
|
||||
|
||||
export class HomeServerFeaturesController extends BaseHttpController {
|
||||
constructor(
|
||||
protected doGetUserFeatures: GetUserFeatures,
|
||||
private controllerContainer?: ControllerContainerInterface,
|
||||
) {
|
||||
super()
|
||||
|
||||
if (this.controllerContainer !== undefined) {
|
||||
this.controllerContainer.register('auth.users.getFeatures', this.getFeatures.bind(this))
|
||||
}
|
||||
}
|
||||
|
||||
async getFeatures(request: Request, response: Response): Promise<results.JsonResult> {
|
||||
if (request.params.userUuid !== response.locals.user.uuid) {
|
||||
return this.json(
|
||||
{
|
||||
error: {
|
||||
message: 'Operation not allowed.',
|
||||
},
|
||||
},
|
||||
401,
|
||||
)
|
||||
}
|
||||
|
||||
const result = await this.doGetUserFeatures.execute({
|
||||
userUuid: request.params.userUuid,
|
||||
offline: false,
|
||||
})
|
||||
|
||||
if (result.success) {
|
||||
return this.json(result)
|
||||
}
|
||||
|
||||
return this.json(result, 400)
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,42 @@
|
||||
import { ControllerContainerInterface } from '@standardnotes/domain-core'
|
||||
import { ErrorTag } from '@standardnotes/responses'
|
||||
import { Request, Response } from 'express'
|
||||
|
||||
import { CreateListedAccount } from '../../../Domain/UseCase/CreateListedAccount/CreateListedAccount'
|
||||
import { BaseHttpController, results } from 'inversify-express-utils'
|
||||
|
||||
export class HomeServerListedController extends BaseHttpController {
|
||||
constructor(
|
||||
protected doCreateListedAccount: CreateListedAccount,
|
||||
private controllerContainer?: ControllerContainerInterface,
|
||||
) {
|
||||
super()
|
||||
|
||||
if (this.controllerContainer !== undefined) {
|
||||
this.controllerContainer.register('auth.users.createListedAccount', this.createListedAccount.bind(this))
|
||||
}
|
||||
}
|
||||
|
||||
async createListedAccount(_request: Request, response: Response): Promise<results.JsonResult> {
|
||||
if (response.locals.readOnlyAccess) {
|
||||
return this.json(
|
||||
{
|
||||
error: {
|
||||
tag: ErrorTag.ReadOnlyAccess,
|
||||
message: 'Session has read-only access.',
|
||||
},
|
||||
},
|
||||
401,
|
||||
)
|
||||
}
|
||||
|
||||
await this.doCreateListedAccount.execute({
|
||||
userUuid: response.locals.user.uuid,
|
||||
userEmail: response.locals.user.email,
|
||||
})
|
||||
|
||||
return this.json({
|
||||
message: 'Listed account creation requested successfully.',
|
||||
})
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,128 @@
|
||||
import { ControllerContainerInterface } from '@standardnotes/domain-core'
|
||||
import { Request, Response } from 'express'
|
||||
import { TokenEncoderInterface, OfflineUserTokenData } from '@standardnotes/security'
|
||||
import { Logger } from 'winston'
|
||||
import { BaseHttpController, results } from 'inversify-express-utils'
|
||||
|
||||
import { AuthenticateOfflineSubscriptionToken } from '../../../Domain/UseCase/AuthenticateOfflineSubscriptionToken/AuthenticateOfflineSubscriptionToken'
|
||||
import { CreateOfflineSubscriptionToken } from '../../../Domain/UseCase/CreateOfflineSubscriptionToken/CreateOfflineSubscriptionToken'
|
||||
import { GetUserFeatures } from '../../../Domain/UseCase/GetUserFeatures/GetUserFeatures'
|
||||
import { GetUserOfflineSubscription } from '../../../Domain/UseCase/GetUserOfflineSubscription/GetUserOfflineSubscription'
|
||||
|
||||
export class HomeServerOfflineController extends BaseHttpController {
|
||||
constructor(
|
||||
protected doGetUserFeatures: GetUserFeatures,
|
||||
protected getUserOfflineSubscription: GetUserOfflineSubscription,
|
||||
protected createOfflineSubscriptionToken: CreateOfflineSubscriptionToken,
|
||||
protected authenticateToken: AuthenticateOfflineSubscriptionToken,
|
||||
protected tokenEncoder: TokenEncoderInterface<OfflineUserTokenData>,
|
||||
protected jwtTTL: number,
|
||||
protected logger: Logger,
|
||||
private controllerContainer?: ControllerContainerInterface,
|
||||
) {
|
||||
super()
|
||||
|
||||
if (this.controllerContainer !== undefined) {
|
||||
this.controllerContainer.register('auth.offline.features', this.getOfflineFeatures.bind(this))
|
||||
this.controllerContainer.register('auth.offline.subscriptionTokens.create', this.createToken.bind(this))
|
||||
this.controllerContainer.register('auth.users.getOfflineSubscriptionByToken', this.getSubscription.bind(this))
|
||||
}
|
||||
}
|
||||
|
||||
async getOfflineFeatures(_request: Request, response: Response): Promise<results.JsonResult> {
|
||||
const result = await this.doGetUserFeatures.execute({
|
||||
email: response.locals.offlineUserEmail,
|
||||
offline: true,
|
||||
})
|
||||
|
||||
if (result.success) {
|
||||
return this.json(result)
|
||||
}
|
||||
|
||||
return this.json(result, 400)
|
||||
}
|
||||
|
||||
async createToken(request: Request): Promise<results.JsonResult> {
|
||||
if (!request.body.email) {
|
||||
return this.json(
|
||||
{
|
||||
error: {
|
||||
tag: 'invalid-request',
|
||||
message: 'Invalid request parameters.',
|
||||
},
|
||||
},
|
||||
400,
|
||||
)
|
||||
}
|
||||
|
||||
const response = await this.createOfflineSubscriptionToken.execute({
|
||||
userEmail: request.body.email,
|
||||
})
|
||||
|
||||
if (!response.success) {
|
||||
return this.json({ success: false, error: { tag: response.error } })
|
||||
}
|
||||
|
||||
return this.json({ success: true })
|
||||
}
|
||||
|
||||
async validate(request: Request): Promise<results.JsonResult> {
|
||||
if (!request.body.email) {
|
||||
this.logger.debug('[Offline Subscription Token Validation] Missing email')
|
||||
|
||||
return this.json(
|
||||
{
|
||||
error: {
|
||||
tag: 'invalid-request',
|
||||
message: 'Invalid request parameters.',
|
||||
},
|
||||
},
|
||||
400,
|
||||
)
|
||||
}
|
||||
|
||||
const authenticateTokenResponse = await this.authenticateToken.execute({
|
||||
token: request.params.token,
|
||||
userEmail: request.body.email,
|
||||
})
|
||||
|
||||
if (!authenticateTokenResponse.success) {
|
||||
this.logger.debug('[Offline Subscription Token Validation] invalid token')
|
||||
|
||||
return this.json(
|
||||
{
|
||||
error: {
|
||||
tag: 'invalid-auth',
|
||||
message: 'Invalid login credentials.',
|
||||
},
|
||||
},
|
||||
401,
|
||||
)
|
||||
}
|
||||
|
||||
const offlineAuthTokenData: OfflineUserTokenData = {
|
||||
userEmail: authenticateTokenResponse.email,
|
||||
featuresToken: authenticateTokenResponse.featuresToken,
|
||||
}
|
||||
|
||||
const authToken = this.tokenEncoder.encodeExpirableToken(offlineAuthTokenData, this.jwtTTL)
|
||||
|
||||
this.logger.debug(
|
||||
`[Offline Subscription Token Validation] authenticated token for user ${authenticateTokenResponse.email}`,
|
||||
)
|
||||
|
||||
return this.json({ authToken })
|
||||
}
|
||||
|
||||
async getSubscription(_request: Request, response: Response): Promise<results.JsonResult> {
|
||||
const result = await this.getUserOfflineSubscription.execute({
|
||||
userEmail: response.locals.userEmail,
|
||||
})
|
||||
|
||||
if (result.success) {
|
||||
return this.json(result)
|
||||
}
|
||||
|
||||
return this.json(result, 400)
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,153 @@
|
||||
import { ControllerContainerInterface } from '@standardnotes/domain-core'
|
||||
import { Request, Response } from 'express'
|
||||
import { BaseHttpController, results } from 'inversify-express-utils'
|
||||
import { ErrorTag } from '@standardnotes/responses'
|
||||
|
||||
import { DeletePreviousSessionsForUser } from '../../../Domain/UseCase/DeletePreviousSessionsForUser'
|
||||
import { DeleteSessionForUser } from '../../../Domain/UseCase/DeleteSessionForUser'
|
||||
import { RefreshSessionToken } from '../../../Domain/UseCase/RefreshSessionToken'
|
||||
|
||||
export class HomeServerSessionController extends BaseHttpController {
|
||||
constructor(
|
||||
protected deleteSessionForUser: DeleteSessionForUser,
|
||||
protected deletePreviousSessionsForUser: DeletePreviousSessionsForUser,
|
||||
protected refreshSessionToken: RefreshSessionToken,
|
||||
private controllerContainer?: ControllerContainerInterface,
|
||||
) {
|
||||
super()
|
||||
|
||||
if (this.controllerContainer !== undefined) {
|
||||
this.controllerContainer.register('auth.sessions.delete', this.deleteSession.bind(this))
|
||||
this.controllerContainer.register('auth.sessions.deleteAll', this.deleteAllSessions.bind(this))
|
||||
this.controllerContainer.register('auth.sessions.refresh', this.refresh.bind(this))
|
||||
}
|
||||
}
|
||||
|
||||
async deleteSession(request: Request, response: Response): Promise<results.JsonResult | results.StatusCodeResult> {
|
||||
if (response.locals.readOnlyAccess) {
|
||||
return this.json(
|
||||
{
|
||||
error: {
|
||||
tag: ErrorTag.ReadOnlyAccess,
|
||||
message: 'Session has read-only access.',
|
||||
},
|
||||
},
|
||||
401,
|
||||
)
|
||||
}
|
||||
|
||||
if (!request.body.uuid) {
|
||||
return this.json(
|
||||
{
|
||||
error: {
|
||||
message: 'Please provide the session identifier.',
|
||||
},
|
||||
},
|
||||
400,
|
||||
)
|
||||
}
|
||||
|
||||
if (request.body.uuid === response.locals.session.uuid) {
|
||||
return this.json(
|
||||
{
|
||||
error: {
|
||||
message: 'You can not delete your current session.',
|
||||
},
|
||||
},
|
||||
400,
|
||||
)
|
||||
}
|
||||
|
||||
const useCaseResponse = await this.deleteSessionForUser.execute({
|
||||
userUuid: response.locals.user.uuid,
|
||||
sessionUuid: request.body.uuid,
|
||||
})
|
||||
|
||||
if (!useCaseResponse.success) {
|
||||
return this.json(
|
||||
{
|
||||
error: {
|
||||
message: useCaseResponse.errorMessage,
|
||||
},
|
||||
},
|
||||
400,
|
||||
)
|
||||
}
|
||||
|
||||
response.setHeader('x-invalidate-cache', response.locals.user.uuid)
|
||||
|
||||
return this.statusCode(204)
|
||||
}
|
||||
|
||||
async deleteAllSessions(
|
||||
_request: Request,
|
||||
response: Response,
|
||||
): Promise<results.JsonResult | results.StatusCodeResult> {
|
||||
if (response.locals.readOnlyAccess) {
|
||||
return this.json(
|
||||
{
|
||||
error: {
|
||||
tag: ErrorTag.ReadOnlyAccess,
|
||||
message: 'Session has read-only access.',
|
||||
},
|
||||
},
|
||||
401,
|
||||
)
|
||||
}
|
||||
|
||||
if (!response.locals.user) {
|
||||
return this.json(
|
||||
{
|
||||
error: {
|
||||
message: 'No session exists with the provided identifier.',
|
||||
},
|
||||
},
|
||||
401,
|
||||
)
|
||||
}
|
||||
|
||||
await this.deletePreviousSessionsForUser.execute({
|
||||
userUuid: response.locals.user.uuid,
|
||||
currentSessionUuid: response.locals.session.uuid,
|
||||
})
|
||||
|
||||
response.setHeader('x-invalidate-cache', response.locals.user.uuid)
|
||||
|
||||
return this.statusCode(204)
|
||||
}
|
||||
|
||||
async refresh(request: Request, response: Response): Promise<results.JsonResult> {
|
||||
if (!request.body.access_token || !request.body.refresh_token) {
|
||||
return this.json(
|
||||
{
|
||||
error: {
|
||||
message: 'Please provide all required parameters.',
|
||||
},
|
||||
},
|
||||
400,
|
||||
)
|
||||
}
|
||||
|
||||
const result = await this.refreshSessionToken.execute({
|
||||
accessToken: request.body.access_token,
|
||||
refreshToken: request.body.refresh_token,
|
||||
})
|
||||
|
||||
if (!result.success) {
|
||||
return this.json(
|
||||
{
|
||||
error: {
|
||||
tag: result.errorTag,
|
||||
message: result.errorMessage,
|
||||
},
|
||||
},
|
||||
400,
|
||||
)
|
||||
}
|
||||
|
||||
response.setHeader('x-invalidate-cache', result.userUuid as string)
|
||||
return this.json({
|
||||
session: result.sessionPayload,
|
||||
})
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,75 @@
|
||||
import { ControllerContainerInterface } from '@standardnotes/domain-core'
|
||||
import { Request, Response } from 'express'
|
||||
|
||||
import { AuthenticateRequest } from '../../../Domain/UseCase/AuthenticateRequest'
|
||||
import { CreateCrossServiceToken } from '../../../Domain/UseCase/CreateCrossServiceToken/CreateCrossServiceToken'
|
||||
import { GetActiveSessionsForUser } from '../../../Domain/UseCase/GetActiveSessionsForUser'
|
||||
import { ProjectorInterface } from '../../../Projection/ProjectorInterface'
|
||||
import { Session } from '../../../Domain/Session/Session'
|
||||
import { BaseHttpController, results } from 'inversify-express-utils'
|
||||
import { User } from '../../../Domain/User/User'
|
||||
import { SessionProjector } from '../../../Projection/SessionProjector'
|
||||
|
||||
export class HomeServerSessionsController extends BaseHttpController {
|
||||
constructor(
|
||||
protected getActiveSessionsForUser: GetActiveSessionsForUser,
|
||||
protected authenticateRequest: AuthenticateRequest,
|
||||
protected sessionProjector: ProjectorInterface<Session>,
|
||||
protected createCrossServiceToken: CreateCrossServiceToken,
|
||||
private controllerContainer?: ControllerContainerInterface,
|
||||
) {
|
||||
super()
|
||||
|
||||
if (this.controllerContainer !== undefined) {
|
||||
this.controllerContainer.register('auth.sessions.list', this.getSessions.bind(this))
|
||||
this.controllerContainer.register('auth.sessions.validate', this.validate.bind(this))
|
||||
}
|
||||
}
|
||||
|
||||
async validate(request: Request): Promise<results.JsonResult> {
|
||||
const authenticateRequestResponse = await this.authenticateRequest.execute({
|
||||
authorizationHeader: request.headers.authorization,
|
||||
})
|
||||
|
||||
if (!authenticateRequestResponse.success) {
|
||||
return this.json(
|
||||
{
|
||||
error: {
|
||||
tag: authenticateRequestResponse.errorTag,
|
||||
message: authenticateRequestResponse.errorMessage,
|
||||
},
|
||||
},
|
||||
authenticateRequestResponse.responseCode,
|
||||
)
|
||||
}
|
||||
|
||||
const user = authenticateRequestResponse.user as User
|
||||
|
||||
const result = await this.createCrossServiceToken.execute({
|
||||
user,
|
||||
session: authenticateRequestResponse.session,
|
||||
})
|
||||
|
||||
return this.json({ authToken: result.token })
|
||||
}
|
||||
|
||||
async getSessions(_request: Request, response: Response): Promise<results.JsonResult> {
|
||||
if (response.locals.readOnlyAccess) {
|
||||
return this.json([])
|
||||
}
|
||||
|
||||
const useCaseResponse = await this.getActiveSessionsForUser.execute({
|
||||
userUuid: response.locals.user.uuid,
|
||||
})
|
||||
|
||||
return this.json(
|
||||
useCaseResponse.sessions.map((session) =>
|
||||
this.sessionProjector.projectCustom(
|
||||
SessionProjector.CURRENT_SESSION_PROJECTION.toString(),
|
||||
session,
|
||||
response.locals.session,
|
||||
),
|
||||
),
|
||||
)
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,153 @@
|
||||
import { ControllerContainerInterface } from '@standardnotes/domain-core'
|
||||
import { ErrorTag } from '@standardnotes/responses'
|
||||
import { Request, Response } from 'express'
|
||||
|
||||
import { DeleteSetting } from '../../../Domain/UseCase/DeleteSetting/DeleteSetting'
|
||||
import { GetSetting } from '../../../Domain/UseCase/GetSetting/GetSetting'
|
||||
import { GetSettings } from '../../../Domain/UseCase/GetSettings/GetSettings'
|
||||
import { UpdateSetting } from '../../../Domain/UseCase/UpdateSetting/UpdateSetting'
|
||||
import { BaseHttpController, results } from 'inversify-express-utils'
|
||||
import { EncryptionVersion } from '../../../Domain/Encryption/EncryptionVersion'
|
||||
|
||||
export class HomeServerSettingsController extends BaseHttpController {
|
||||
constructor(
|
||||
protected doGetSettings: GetSettings,
|
||||
protected doGetSetting: GetSetting,
|
||||
protected doUpdateSetting: UpdateSetting,
|
||||
protected doDeleteSetting: DeleteSetting,
|
||||
private controllerContainer?: ControllerContainerInterface,
|
||||
) {
|
||||
super()
|
||||
|
||||
if (this.controllerContainer !== undefined) {
|
||||
this.controllerContainer.register('auth.users.getSettings', this.getSettings.bind(this))
|
||||
this.controllerContainer.register('auth.users.getSetting', this.getSetting.bind(this))
|
||||
this.controllerContainer.register('auth.users.updateSetting', this.updateSetting.bind(this))
|
||||
this.controllerContainer.register('auth.users.deleteSetting', this.deleteSetting.bind(this))
|
||||
}
|
||||
}
|
||||
|
||||
async getSettings(request: Request, response: Response): Promise<results.JsonResult> {
|
||||
if (request.params.userUuid !== response.locals.user.uuid) {
|
||||
return this.json(
|
||||
{
|
||||
error: {
|
||||
message: 'Operation not allowed.',
|
||||
},
|
||||
},
|
||||
401,
|
||||
)
|
||||
}
|
||||
|
||||
const { userUuid } = request.params
|
||||
const result = await this.doGetSettings.execute({ userUuid })
|
||||
|
||||
return this.json(result)
|
||||
}
|
||||
|
||||
async getSetting(request: Request, response: Response): Promise<results.JsonResult> {
|
||||
if (request.params.userUuid !== response.locals.user.uuid) {
|
||||
return this.json(
|
||||
{
|
||||
error: {
|
||||
message: 'Operation not allowed.',
|
||||
},
|
||||
},
|
||||
401,
|
||||
)
|
||||
}
|
||||
|
||||
const { userUuid, settingName } = request.params
|
||||
const result = await this.doGetSetting.execute({ userUuid, settingName: settingName.toUpperCase() })
|
||||
|
||||
if (result.success) {
|
||||
return this.json(result)
|
||||
}
|
||||
|
||||
return this.json(result, 400)
|
||||
}
|
||||
|
||||
async updateSetting(request: Request, response: Response): Promise<results.JsonResult | results.StatusCodeResult> {
|
||||
if (response.locals.readOnlyAccess) {
|
||||
return this.json(
|
||||
{
|
||||
error: {
|
||||
tag: ErrorTag.ReadOnlyAccess,
|
||||
message: 'Session has read-only access.',
|
||||
},
|
||||
},
|
||||
401,
|
||||
)
|
||||
}
|
||||
|
||||
if (request.params.userUuid !== response.locals.user.uuid) {
|
||||
return this.json(
|
||||
{
|
||||
error: {
|
||||
message: 'Operation not allowed.',
|
||||
},
|
||||
},
|
||||
401,
|
||||
)
|
||||
}
|
||||
|
||||
const { name, value, serverEncryptionVersion = EncryptionVersion.Default, sensitive = false } = request.body
|
||||
|
||||
const props = {
|
||||
name,
|
||||
unencryptedValue: value,
|
||||
serverEncryptionVersion,
|
||||
sensitive,
|
||||
}
|
||||
|
||||
const { userUuid } = request.params
|
||||
const result = await this.doUpdateSetting.execute({
|
||||
userUuid,
|
||||
props,
|
||||
})
|
||||
|
||||
if (result.success) {
|
||||
return this.json({ setting: result.setting }, result.statusCode)
|
||||
}
|
||||
|
||||
return this.json(result, result.statusCode)
|
||||
}
|
||||
|
||||
async deleteSetting(request: Request, response: Response): Promise<results.JsonResult> {
|
||||
if (response.locals.readOnlyAccess) {
|
||||
return this.json(
|
||||
{
|
||||
error: {
|
||||
tag: ErrorTag.ReadOnlyAccess,
|
||||
message: 'Session has read-only access.',
|
||||
},
|
||||
},
|
||||
401,
|
||||
)
|
||||
}
|
||||
|
||||
if (request.params.userUuid !== response.locals.user.uuid) {
|
||||
return this.json(
|
||||
{
|
||||
error: {
|
||||
message: 'Operation not allowed.',
|
||||
},
|
||||
},
|
||||
401,
|
||||
)
|
||||
}
|
||||
|
||||
const { userUuid, settingName } = request.params
|
||||
|
||||
const result = await this.doDeleteSetting.execute({
|
||||
userUuid,
|
||||
settingName,
|
||||
})
|
||||
|
||||
if (result.success) {
|
||||
return this.json(result)
|
||||
}
|
||||
|
||||
return this.json(result, 400)
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,74 @@
|
||||
import { ControllerContainerInterface } from '@standardnotes/domain-core'
|
||||
import { Request, Response } from 'express'
|
||||
import { BaseHttpController, results } from 'inversify-express-utils'
|
||||
import { ApiVersion } from '@standardnotes/api'
|
||||
|
||||
import { SubscriptionInvitesController } from '../../../Controller/SubscriptionInvitesController'
|
||||
import { Role } from '../../../Domain/Role/Role'
|
||||
|
||||
export class HomeServerSubscriptionInvitesController extends BaseHttpController {
|
||||
constructor(
|
||||
protected subscriptionInvitesController: SubscriptionInvitesController,
|
||||
private controllerContainer?: ControllerContainerInterface,
|
||||
) {
|
||||
super()
|
||||
|
||||
if (this.controllerContainer !== undefined) {
|
||||
this.controllerContainer.register('auth.subscriptionInvites.accept', this.acceptInvite.bind(this))
|
||||
this.controllerContainer.register('auth.subscriptionInvites.declineInvite', this.declineInvite.bind(this))
|
||||
this.controllerContainer.register('auth.subscriptionInvites.create', this.inviteToSubscriptionSharing.bind(this))
|
||||
this.controllerContainer.register('auth.subscriptionInvites.delete', this.cancelSubscriptionSharing.bind(this))
|
||||
this.controllerContainer.register('auth.subscriptionInvites.list', this.listInvites.bind(this))
|
||||
}
|
||||
}
|
||||
|
||||
async acceptInvite(request: Request, response: Response): Promise<results.JsonResult> {
|
||||
const result = await this.subscriptionInvitesController.acceptInvite({
|
||||
api: request.query.api as ApiVersion,
|
||||
inviteUuid: request.params.inviteUuid,
|
||||
})
|
||||
|
||||
response.setHeader('x-invalidate-cache', response.locals.user.uuid)
|
||||
|
||||
return this.json(result.data, result.status)
|
||||
}
|
||||
|
||||
async declineInvite(request: Request): Promise<results.JsonResult> {
|
||||
const response = await this.subscriptionInvitesController.declineInvite({
|
||||
api: request.query.api as ApiVersion,
|
||||
inviteUuid: request.params.inviteUuid,
|
||||
})
|
||||
|
||||
return this.json(response.data, response.status)
|
||||
}
|
||||
|
||||
async inviteToSubscriptionSharing(request: Request, response: Response): Promise<results.JsonResult> {
|
||||
const result = await this.subscriptionInvitesController.invite({
|
||||
...request.body,
|
||||
inviterEmail: response.locals.user.email,
|
||||
inviterUuid: response.locals.user.uuid,
|
||||
inviterRoles: response.locals.roles.map((role: Role) => role.name),
|
||||
})
|
||||
|
||||
return this.json(result.data, result.status)
|
||||
}
|
||||
|
||||
async cancelSubscriptionSharing(request: Request, response: Response): Promise<results.JsonResult> {
|
||||
const result = await this.subscriptionInvitesController.cancelInvite({
|
||||
...request.body,
|
||||
inviteUuid: request.params.inviteUuid,
|
||||
inviterEmail: response.locals.user.email,
|
||||
})
|
||||
|
||||
return this.json(result.data, result.status)
|
||||
}
|
||||
|
||||
async listInvites(request: Request, response: Response): Promise<results.JsonResult> {
|
||||
const result = await this.subscriptionInvitesController.listInvites({
|
||||
...request.body,
|
||||
inviterEmail: response.locals.user.email,
|
||||
})
|
||||
|
||||
return this.json(result.data, result.status)
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,28 @@
|
||||
import { ControllerContainerInterface } from '@standardnotes/domain-core'
|
||||
import { BaseHttpController, results } from 'inversify-express-utils'
|
||||
import { Request, Response } from 'express'
|
||||
|
||||
import { GetSetting } from '../../../Domain/UseCase/GetSetting/GetSetting'
|
||||
|
||||
export class HomeServerSubscriptionSettingsController extends BaseHttpController {
|
||||
constructor(protected doGetSetting: GetSetting, private controllerContainer?: ControllerContainerInterface) {
|
||||
super()
|
||||
|
||||
if (this.controllerContainer !== undefined) {
|
||||
this.controllerContainer.register('auth.users.getSubscriptionSetting', this.getSubscriptionSetting.bind(this))
|
||||
}
|
||||
}
|
||||
|
||||
async getSubscriptionSetting(request: Request, response: Response): Promise<results.JsonResult> {
|
||||
const result = await this.doGetSetting.execute({
|
||||
userUuid: response.locals.user.uuid,
|
||||
settingName: request.params.subscriptionSettingName.toUpperCase(),
|
||||
})
|
||||
|
||||
if (result.success) {
|
||||
return this.json(result)
|
||||
}
|
||||
|
||||
return this.json(result, 400)
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,106 @@
|
||||
import { ControllerContainerInterface } from '@standardnotes/domain-core'
|
||||
import { ErrorTag } from '@standardnotes/responses'
|
||||
import { Role, TokenEncoderInterface, CrossServiceTokenData } from '@standardnotes/security'
|
||||
import { BaseHttpController, results } from 'inversify-express-utils'
|
||||
import { Request, Response } from 'express'
|
||||
|
||||
import { SettingServiceInterface } from '../../../Domain/Setting/SettingServiceInterface'
|
||||
import { AuthenticateSubscriptionToken } from '../../../Domain/UseCase/AuthenticateSubscriptionToken/AuthenticateSubscriptionToken'
|
||||
import { CreateSubscriptionToken } from '../../../Domain/UseCase/CreateSubscriptionToken/CreateSubscriptionToken'
|
||||
import { ProjectorInterface } from '../../../Projection/ProjectorInterface'
|
||||
import { SettingName } from '@standardnotes/settings'
|
||||
import { User } from '../../../Domain/User/User'
|
||||
|
||||
export class HomeServerSubscriptionTokensController extends BaseHttpController {
|
||||
constructor(
|
||||
protected createSubscriptionToken: CreateSubscriptionToken,
|
||||
protected authenticateToken: AuthenticateSubscriptionToken,
|
||||
protected settingService: SettingServiceInterface,
|
||||
protected userProjector: ProjectorInterface<User>,
|
||||
protected roleProjector: ProjectorInterface<Role>,
|
||||
protected tokenEncoder: TokenEncoderInterface<CrossServiceTokenData>,
|
||||
protected jwtTTL: number,
|
||||
private controllerContainer?: ControllerContainerInterface,
|
||||
) {
|
||||
super()
|
||||
|
||||
if (this.controllerContainer !== undefined) {
|
||||
this.controllerContainer.register('auth.subscription-tokens.create', this.createToken.bind(this))
|
||||
}
|
||||
}
|
||||
|
||||
async createToken(_request: Request, response: Response): Promise<results.JsonResult> {
|
||||
if (response.locals.readOnlyAccess) {
|
||||
return this.json(
|
||||
{
|
||||
error: {
|
||||
tag: ErrorTag.ReadOnlyAccess,
|
||||
message: 'Session has read-only access.',
|
||||
},
|
||||
},
|
||||
401,
|
||||
)
|
||||
}
|
||||
|
||||
const result = await this.createSubscriptionToken.execute({
|
||||
userUuid: response.locals.user.uuid,
|
||||
})
|
||||
|
||||
return this.json({
|
||||
token: result.subscriptionToken.token,
|
||||
})
|
||||
}
|
||||
|
||||
async validate(request: Request): Promise<results.JsonResult> {
|
||||
const authenticateTokenResponse = await this.authenticateToken.execute({
|
||||
token: request.params.token,
|
||||
})
|
||||
|
||||
if (!authenticateTokenResponse.success) {
|
||||
return this.json(
|
||||
{
|
||||
error: {
|
||||
tag: 'invalid-auth',
|
||||
message: 'Invalid login credentials.',
|
||||
},
|
||||
},
|
||||
401,
|
||||
)
|
||||
}
|
||||
|
||||
const user = authenticateTokenResponse.user as User
|
||||
let extensionKey = undefined
|
||||
const extensionKeySetting = await this.settingService.findSettingWithDecryptedValue({
|
||||
settingName: SettingName.create(SettingName.NAMES.ExtensionKey).getValue(),
|
||||
userUuid: user.uuid,
|
||||
})
|
||||
if (extensionKeySetting !== null) {
|
||||
extensionKey = extensionKeySetting.value as string
|
||||
}
|
||||
|
||||
const roles = await user.roles
|
||||
|
||||
const authTokenData: CrossServiceTokenData = {
|
||||
user: await this.projectUser(user),
|
||||
roles: await this.projectRoles(roles),
|
||||
extensionKey,
|
||||
}
|
||||
|
||||
const authToken = this.tokenEncoder.encodeExpirableToken(authTokenData, this.jwtTTL)
|
||||
|
||||
return this.json({ authToken })
|
||||
}
|
||||
|
||||
private async projectUser(user: User): Promise<{ uuid: string; email: string }> {
|
||||
return <{ uuid: string; email: string }>await this.userProjector.projectSimple(user)
|
||||
}
|
||||
|
||||
private async projectRoles(roles: Array<Role>): Promise<Array<{ uuid: string; name: string }>> {
|
||||
const roleProjections = []
|
||||
for (const role of roles) {
|
||||
roleProjections.push(<{ uuid: string; name: string }>await this.roleProjector.projectSimple(role))
|
||||
}
|
||||
|
||||
return roleProjections
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,28 @@
|
||||
import { ControllerContainerInterface } from '@standardnotes/domain-core'
|
||||
import { BaseHttpController, results } from 'inversify-express-utils'
|
||||
import { Request, Response } from 'express'
|
||||
|
||||
import { UserRequestsController } from '../../../Controller/UserRequestsController'
|
||||
|
||||
export class HomeServerUserRequestsController extends BaseHttpController {
|
||||
constructor(
|
||||
protected userRequestsController: UserRequestsController,
|
||||
private controllerContainer?: ControllerContainerInterface,
|
||||
) {
|
||||
super()
|
||||
|
||||
if (this.controllerContainer !== undefined) {
|
||||
this.controllerContainer.register('auth.users.createRequest', this.submitRequest.bind(this))
|
||||
}
|
||||
}
|
||||
|
||||
async submitRequest(request: Request, response: Response): Promise<results.JsonResult> {
|
||||
const result = await this.userRequestsController.submitUserRequest({
|
||||
requestType: request.body.requestType,
|
||||
userUuid: response.locals.user.uuid,
|
||||
userEmail: response.locals.user.email,
|
||||
})
|
||||
|
||||
return this.json(result.data, result.status)
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,236 @@
|
||||
import { ControllerContainerInterface, Username } from '@standardnotes/domain-core'
|
||||
import { Request, Response } from 'express'
|
||||
import { BaseHttpController, results } from 'inversify-express-utils'
|
||||
|
||||
import { ChangeCredentials } from '../../../Domain/UseCase/ChangeCredentials/ChangeCredentials'
|
||||
import { ClearLoginAttempts } from '../../../Domain/UseCase/ClearLoginAttempts'
|
||||
import { DeleteAccount } from '../../../Domain/UseCase/DeleteAccount/DeleteAccount'
|
||||
import { GetUserKeyParams } from '../../../Domain/UseCase/GetUserKeyParams/GetUserKeyParams'
|
||||
import { GetUserSubscription } from '../../../Domain/UseCase/GetUserSubscription/GetUserSubscription'
|
||||
import { IncreaseLoginAttempts } from '../../../Domain/UseCase/IncreaseLoginAttempts'
|
||||
import { UpdateUser } from '../../../Domain/UseCase/UpdateUser'
|
||||
import { ErrorTag } from '@standardnotes/responses'
|
||||
|
||||
export class HomeServerUsersController extends BaseHttpController {
|
||||
constructor(
|
||||
protected updateUser: UpdateUser,
|
||||
protected getUserKeyParams: GetUserKeyParams,
|
||||
protected doDeleteAccount: DeleteAccount,
|
||||
protected doGetUserSubscription: GetUserSubscription,
|
||||
protected clearLoginAttempts: ClearLoginAttempts,
|
||||
protected increaseLoginAttempts: IncreaseLoginAttempts,
|
||||
protected changeCredentialsUseCase: ChangeCredentials,
|
||||
private controllerContainer?: ControllerContainerInterface,
|
||||
) {
|
||||
super()
|
||||
|
||||
if (this.controllerContainer !== undefined) {
|
||||
this.controllerContainer.register('auth.users.update', this.update.bind(this))
|
||||
this.controllerContainer.register('auth.users.getKeyParams', this.keyParams.bind(this))
|
||||
this.controllerContainer.register('auth.users.getSubscription', this.getSubscription.bind(this))
|
||||
this.controllerContainer.register('auth.users.updateCredentials', this.changeCredentials.bind(this))
|
||||
}
|
||||
}
|
||||
|
||||
async update(request: Request, response: Response): Promise<results.JsonResult> {
|
||||
if (response.locals.readOnlyAccess) {
|
||||
return this.json(
|
||||
{
|
||||
error: {
|
||||
tag: ErrorTag.ReadOnlyAccess,
|
||||
message: 'Session has read-only access.',
|
||||
},
|
||||
},
|
||||
401,
|
||||
)
|
||||
}
|
||||
|
||||
if (request.params.userId !== response.locals.user.uuid) {
|
||||
return this.json(
|
||||
{
|
||||
error: {
|
||||
message: 'Operation not allowed.',
|
||||
},
|
||||
},
|
||||
401,
|
||||
)
|
||||
}
|
||||
|
||||
const updateResult = await this.updateUser.execute({
|
||||
user: response.locals.user,
|
||||
updatedWithUserAgent: <string>request.headers['user-agent'],
|
||||
apiVersion: request.body.api,
|
||||
pwFunc: request.body.pw_func,
|
||||
pwAlg: request.body.pw_alg,
|
||||
pwCost: request.body.pw_cost,
|
||||
pwKeySize: request.body.pw_key_size,
|
||||
pwNonce: request.body.pw_nonce,
|
||||
pwSalt: request.body.pw_salt,
|
||||
kpOrigination: request.body.origination,
|
||||
kpCreated: request.body.created,
|
||||
version: request.body.version,
|
||||
})
|
||||
|
||||
if (updateResult.success) {
|
||||
response.setHeader('x-invalidate-cache', response.locals.user.uuid)
|
||||
|
||||
return this.json(updateResult.authResponse)
|
||||
}
|
||||
|
||||
return this.json(
|
||||
{
|
||||
error: {
|
||||
message: 'Could not update user.',
|
||||
},
|
||||
},
|
||||
400,
|
||||
)
|
||||
}
|
||||
|
||||
async keyParams(request: Request): Promise<results.JsonResult> {
|
||||
const email = 'email' in request.query ? <string>request.query.email : undefined
|
||||
const userUuid = 'uuid' in request.query ? <string>request.query.uuid : undefined
|
||||
|
||||
if (!email && !userUuid) {
|
||||
return this.json(
|
||||
{
|
||||
error: {
|
||||
message: 'Missing mandatory request query parameters.',
|
||||
},
|
||||
},
|
||||
400,
|
||||
)
|
||||
}
|
||||
|
||||
const result = await this.getUserKeyParams.execute({
|
||||
email,
|
||||
userUuid,
|
||||
authenticated: request.query.authenticated === 'true',
|
||||
})
|
||||
|
||||
return this.json(result.keyParams)
|
||||
}
|
||||
|
||||
async deleteAccount(request: Request): Promise<results.JsonResult> {
|
||||
const result = await this.doDeleteAccount.execute({
|
||||
email: request.params.email,
|
||||
})
|
||||
|
||||
return this.json({ message: result.message }, result.responseCode)
|
||||
}
|
||||
|
||||
async getSubscription(request: Request, response: Response): Promise<results.JsonResult> {
|
||||
if (request.params.userUuid !== response.locals.user.uuid) {
|
||||
return this.json(
|
||||
{
|
||||
error: {
|
||||
message: 'Operation not allowed.',
|
||||
},
|
||||
},
|
||||
401,
|
||||
)
|
||||
}
|
||||
|
||||
const result = await this.doGetUserSubscription.execute({
|
||||
userUuid: request.params.userUuid,
|
||||
})
|
||||
|
||||
if (result.success) {
|
||||
return this.json(result)
|
||||
}
|
||||
|
||||
return this.json(result, 400)
|
||||
}
|
||||
|
||||
async changeCredentials(request: Request, response: Response): Promise<results.JsonResult> {
|
||||
if (response.locals.readOnlyAccess) {
|
||||
return this.json(
|
||||
{
|
||||
error: {
|
||||
tag: ErrorTag.ReadOnlyAccess,
|
||||
message: 'Session has read-only access.',
|
||||
},
|
||||
},
|
||||
401,
|
||||
)
|
||||
}
|
||||
|
||||
if (!request.body.current_password) {
|
||||
return this.json(
|
||||
{
|
||||
error: {
|
||||
message:
|
||||
'Your current password is required to change your password. Please update your application if you do not see this option.',
|
||||
},
|
||||
},
|
||||
400,
|
||||
)
|
||||
}
|
||||
|
||||
if (!request.body.new_password) {
|
||||
return this.json(
|
||||
{
|
||||
error: {
|
||||
message: 'Your new password is required to change your password. Please try again.',
|
||||
},
|
||||
},
|
||||
400,
|
||||
)
|
||||
}
|
||||
|
||||
if (!request.body.pw_nonce) {
|
||||
return this.json(
|
||||
{
|
||||
error: {
|
||||
message: 'The change password request is missing new auth parameters. Please try again.',
|
||||
},
|
||||
},
|
||||
400,
|
||||
)
|
||||
}
|
||||
const usernameOrError = Username.create(response.locals.user.email)
|
||||
if (usernameOrError.isFailed()) {
|
||||
return this.json(
|
||||
{
|
||||
error: {
|
||||
message: 'Invalid username.',
|
||||
},
|
||||
},
|
||||
400,
|
||||
)
|
||||
}
|
||||
const username = usernameOrError.getValue()
|
||||
|
||||
const changeCredentialsResult = await this.changeCredentialsUseCase.execute({
|
||||
username,
|
||||
apiVersion: request.body.api,
|
||||
currentPassword: request.body.current_password,
|
||||
newPassword: request.body.new_password,
|
||||
newEmail: request.body.new_email,
|
||||
pwNonce: request.body.pw_nonce,
|
||||
kpCreated: request.body.created,
|
||||
kpOrigination: request.body.origination,
|
||||
updatedWithUserAgent: <string>request.headers['user-agent'],
|
||||
protocolVersion: request.body.version,
|
||||
})
|
||||
|
||||
if (!changeCredentialsResult.success) {
|
||||
await this.increaseLoginAttempts.execute({ email: response.locals.user.email })
|
||||
|
||||
return this.json(
|
||||
{
|
||||
error: {
|
||||
message: changeCredentialsResult.errorMessage,
|
||||
},
|
||||
},
|
||||
401,
|
||||
)
|
||||
}
|
||||
|
||||
await this.clearLoginAttempts.execute({ email: response.locals.user.email })
|
||||
|
||||
response.setHeader('x-invalidate-cache', response.locals.user.uuid)
|
||||
|
||||
return this.json(changeCredentialsResult.authResponse)
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,60 @@
|
||||
import { ControllerContainerInterface, Uuid } from '@standardnotes/domain-core'
|
||||
import { Request, Response } from 'express'
|
||||
import { BaseHttpController, results } from 'inversify-express-utils'
|
||||
|
||||
import { CreateValetToken } from '../../../Domain/UseCase/CreateValetToken/CreateValetToken'
|
||||
import { CreateValetTokenPayload, ErrorTag } from '@standardnotes/responses'
|
||||
import { ValetTokenOperation } from '@standardnotes/security'
|
||||
|
||||
export class HomeServerValetTokenController extends BaseHttpController {
|
||||
constructor(protected createValetKey: CreateValetToken, private controllerContainer?: ControllerContainerInterface) {
|
||||
super()
|
||||
|
||||
if (this.controllerContainer !== undefined) {
|
||||
this.controllerContainer.register('auth.valet-tokens.create', this.create.bind(this))
|
||||
}
|
||||
}
|
||||
|
||||
public async create(request: Request, response: Response): Promise<results.JsonResult> {
|
||||
const payload: CreateValetTokenPayload = request.body
|
||||
|
||||
if (response.locals.readOnlyAccess && payload.operation !== 'read') {
|
||||
return this.json(
|
||||
{
|
||||
error: {
|
||||
tag: ErrorTag.ReadOnlyAccess,
|
||||
message: 'Session has read-only access.',
|
||||
},
|
||||
},
|
||||
401,
|
||||
)
|
||||
}
|
||||
|
||||
for (const resource of payload.resources) {
|
||||
const resourceUuidOrError = Uuid.create(resource.remoteIdentifier)
|
||||
if (resourceUuidOrError.isFailed()) {
|
||||
return this.json(
|
||||
{
|
||||
error: {
|
||||
tag: ErrorTag.ParametersInvalid,
|
||||
message: 'Invalid remote resource identifier.',
|
||||
},
|
||||
},
|
||||
400,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
const createValetKeyResponse = await this.createValetKey.execute({
|
||||
userUuid: response.locals.user.uuid,
|
||||
operation: payload.operation as ValetTokenOperation,
|
||||
resources: payload.resources,
|
||||
})
|
||||
|
||||
if (!createValetKeyResponse.success) {
|
||||
return this.json(createValetKeyResponse, 403)
|
||||
}
|
||||
|
||||
return this.json(createValetKeyResponse)
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,55 @@
|
||||
import { ControllerContainerInterface } from '@standardnotes/domain-core'
|
||||
import { TokenDecoderInterface, WebSocketConnectionTokenData } from '@standardnotes/security'
|
||||
import { Request } from 'express'
|
||||
import { BaseHttpController, results } from 'inversify-express-utils'
|
||||
|
||||
import { CreateCrossServiceToken } from '../../../Domain/UseCase/CreateCrossServiceToken/CreateCrossServiceToken'
|
||||
import { ErrorTag } from '@standardnotes/responses'
|
||||
|
||||
export class HomeServerWebSocketsController extends BaseHttpController {
|
||||
constructor(
|
||||
protected createCrossServiceToken: CreateCrossServiceToken,
|
||||
protected tokenDecoder: TokenDecoderInterface<WebSocketConnectionTokenData>,
|
||||
private controllerContainer?: ControllerContainerInterface,
|
||||
) {
|
||||
super()
|
||||
|
||||
if (this.controllerContainer !== undefined) {
|
||||
this.controllerContainer.register('auth.webSockets.validateToken', this.validateToken.bind(this))
|
||||
}
|
||||
}
|
||||
|
||||
async validateToken(request: Request): Promise<results.JsonResult> {
|
||||
if (!request.headers.authorization) {
|
||||
return this.json(
|
||||
{
|
||||
error: {
|
||||
tag: ErrorTag.AuthInvalid,
|
||||
message: 'Invalid authorization token.',
|
||||
},
|
||||
},
|
||||
401,
|
||||
)
|
||||
}
|
||||
|
||||
const token: WebSocketConnectionTokenData | undefined = this.tokenDecoder.decodeToken(request.headers.authorization)
|
||||
|
||||
if (token === undefined) {
|
||||
return this.json(
|
||||
{
|
||||
error: {
|
||||
tag: ErrorTag.AuthInvalid,
|
||||
message: 'Invalid authorization token.',
|
||||
},
|
||||
},
|
||||
401,
|
||||
)
|
||||
}
|
||||
|
||||
const result = await this.createCrossServiceToken.execute({
|
||||
userUuid: token.userUuid,
|
||||
})
|
||||
|
||||
return this.json({ authToken: result.token })
|
||||
}
|
||||
}
|
||||
@@ -8,7 +8,6 @@ import * as express from 'express'
|
||||
import { DeleteSetting } from '../../Domain/UseCase/DeleteSetting/DeleteSetting'
|
||||
import { CreateSubscriptionToken } from '../../Domain/UseCase/CreateSubscriptionToken/CreateSubscriptionToken'
|
||||
import { CreateOfflineSubscriptionToken } from '../../Domain/UseCase/CreateOfflineSubscriptionToken/CreateOfflineSubscriptionToken'
|
||||
import { ControllerContainerInterface } from '@standardnotes/domain-core'
|
||||
|
||||
describe('InversifyExpressAdminController', () => {
|
||||
let deleteSetting: DeleteSetting
|
||||
@@ -17,7 +16,6 @@ describe('InversifyExpressAdminController', () => {
|
||||
let createOfflineSubscriptionToken: CreateOfflineSubscriptionToken
|
||||
let request: express.Request
|
||||
let user: User
|
||||
let controllerContainer: ControllerContainerInterface
|
||||
|
||||
const createController = () =>
|
||||
new InversifyExpressAdminController(
|
||||
@@ -25,7 +23,6 @@ describe('InversifyExpressAdminController', () => {
|
||||
userRepository,
|
||||
createSubscriptionToken,
|
||||
createOfflineSubscriptionToken,
|
||||
controllerContainer,
|
||||
)
|
||||
|
||||
beforeEach(() => {
|
||||
@@ -58,9 +55,6 @@ describe('InversifyExpressAdminController', () => {
|
||||
body: {},
|
||||
params: {},
|
||||
} as jest.Mocked<express.Request>
|
||||
|
||||
controllerContainer = {} as jest.Mocked<ControllerContainerInterface>
|
||||
controllerContainer.register = jest.fn()
|
||||
})
|
||||
|
||||
it('should return error if missing email parameter', async () => {
|
||||
|
||||
@@ -1,9 +1,6 @@
|
||||
import { ControllerContainerInterface, Username } from '@standardnotes/domain-core'
|
||||
import { SettingName } from '@standardnotes/settings'
|
||||
import { Request } from 'express'
|
||||
import { inject } from 'inversify'
|
||||
import {
|
||||
BaseHttpController,
|
||||
controller,
|
||||
httpDelete,
|
||||
httpGet,
|
||||
@@ -12,124 +9,48 @@ import {
|
||||
results,
|
||||
} from 'inversify-express-utils'
|
||||
import TYPES from '../../Bootstrap/Types'
|
||||
import { HomeServerAdminController } from './HomeServer/HomeServerAdminController'
|
||||
import { CreateOfflineSubscriptionToken } from '../../Domain/UseCase/CreateOfflineSubscriptionToken/CreateOfflineSubscriptionToken'
|
||||
import { CreateSubscriptionToken } from '../../Domain/UseCase/CreateSubscriptionToken/CreateSubscriptionToken'
|
||||
import { DeleteSetting } from '../../Domain/UseCase/DeleteSetting/DeleteSetting'
|
||||
import { UserRepositoryInterface } from '../../Domain/User/UserRepositoryInterface'
|
||||
|
||||
@controller('/admin')
|
||||
export class InversifyExpressAdminController extends BaseHttpController {
|
||||
export class InversifyExpressAdminController extends HomeServerAdminController {
|
||||
constructor(
|
||||
@inject(TYPES.Auth_DeleteSetting) private doDeleteSetting: DeleteSetting,
|
||||
@inject(TYPES.Auth_UserRepository) private userRepository: UserRepositoryInterface,
|
||||
@inject(TYPES.Auth_CreateSubscriptionToken) private createSubscriptionToken: CreateSubscriptionToken,
|
||||
@inject(TYPES.Auth_DeleteSetting) override doDeleteSetting: DeleteSetting,
|
||||
@inject(TYPES.Auth_UserRepository) override userRepository: UserRepositoryInterface,
|
||||
@inject(TYPES.Auth_CreateSubscriptionToken) override createSubscriptionToken: CreateSubscriptionToken,
|
||||
@inject(TYPES.Auth_CreateOfflineSubscriptionToken)
|
||||
private createOfflineSubscriptionToken: CreateOfflineSubscriptionToken,
|
||||
@inject(TYPES.Auth_ControllerContainer) private controllerContainer: ControllerContainerInterface,
|
||||
override createOfflineSubscriptionToken: CreateOfflineSubscriptionToken,
|
||||
) {
|
||||
super()
|
||||
|
||||
this.controllerContainer.register('admin.getUser', this.getUser.bind(this))
|
||||
this.controllerContainer.register('admin.deleteMFASetting', this.deleteMFASetting.bind(this))
|
||||
this.controllerContainer.register('admin.createToken', this.createToken.bind(this))
|
||||
this.controllerContainer.register('admin.createOfflineToken', this.createOfflineToken.bind(this))
|
||||
this.controllerContainer.register('admin.disableEmailBackups', this.disableEmailBackups.bind(this))
|
||||
super(doDeleteSetting, userRepository, createSubscriptionToken, createOfflineSubscriptionToken)
|
||||
}
|
||||
|
||||
@httpGet('/user/:email')
|
||||
async getUser(request: Request): Promise<results.JsonResult> {
|
||||
const usernameOrError = Username.create(request.params.email ?? '')
|
||||
if (usernameOrError.isFailed()) {
|
||||
return this.json(
|
||||
{
|
||||
error: {
|
||||
message: 'Missing email parameter.',
|
||||
},
|
||||
},
|
||||
400,
|
||||
)
|
||||
}
|
||||
const username = usernameOrError.getValue()
|
||||
|
||||
const user = await this.userRepository.findOneByUsernameOrEmail(username)
|
||||
|
||||
if (!user) {
|
||||
return this.json(
|
||||
{
|
||||
error: {
|
||||
message: `No user with email '${username.value}'.`,
|
||||
},
|
||||
},
|
||||
400,
|
||||
)
|
||||
}
|
||||
|
||||
return this.json({
|
||||
uuid: user.uuid,
|
||||
})
|
||||
override async getUser(request: Request): Promise<results.JsonResult> {
|
||||
return super.getUser(request)
|
||||
}
|
||||
|
||||
@httpDelete('/users/:userUuid/mfa')
|
||||
async deleteMFASetting(request: Request): Promise<results.JsonResult> {
|
||||
const { userUuid } = request.params
|
||||
const { uuid, updatedAt } = request.body
|
||||
|
||||
const result = await this.doDeleteSetting.execute({
|
||||
uuid,
|
||||
userUuid,
|
||||
settingName: SettingName.NAMES.MfaSecret,
|
||||
timestamp: updatedAt,
|
||||
softDelete: true,
|
||||
})
|
||||
|
||||
if (result.success) {
|
||||
return this.json(result)
|
||||
}
|
||||
|
||||
return this.json(result, 400)
|
||||
override async deleteMFASetting(request: Request): Promise<results.JsonResult> {
|
||||
return super.deleteMFASetting(request)
|
||||
}
|
||||
|
||||
@httpPost('/users/:userUuid/subscription-token')
|
||||
async createToken(request: Request): Promise<results.JsonResult> {
|
||||
const { userUuid } = request.params
|
||||
const result = await this.createSubscriptionToken.execute({
|
||||
userUuid,
|
||||
})
|
||||
|
||||
return this.json({
|
||||
token: result.subscriptionToken.token,
|
||||
})
|
||||
override async createToken(request: Request): Promise<results.JsonResult> {
|
||||
return super.createToken(request)
|
||||
}
|
||||
|
||||
@httpPost('/users/:email/offline-subscription-token')
|
||||
async createOfflineToken(request: Request): Promise<results.JsonResult | results.BadRequestResult> {
|
||||
const { email } = request.params
|
||||
const result = await this.createOfflineSubscriptionToken.execute({
|
||||
userEmail: email,
|
||||
})
|
||||
|
||||
if (!result.success) {
|
||||
return this.badRequest()
|
||||
}
|
||||
|
||||
return this.json({
|
||||
token: result.offlineSubscriptionToken.token,
|
||||
})
|
||||
override async createOfflineToken(request: Request): Promise<results.JsonResult | results.BadRequestResult> {
|
||||
return super.createOfflineToken(request)
|
||||
}
|
||||
|
||||
@httpPost('/users/:userUuid/email-backups')
|
||||
async disableEmailBackups(request: Request): Promise<results.BadRequestErrorMessageResult | results.OkResult> {
|
||||
const { userUuid } = request.params
|
||||
|
||||
const result = await this.doDeleteSetting.execute({
|
||||
userUuid,
|
||||
settingName: SettingName.NAMES.EmailBackupFrequency,
|
||||
})
|
||||
|
||||
if (result.success) {
|
||||
return this.ok()
|
||||
}
|
||||
|
||||
return this.badRequest('No email backups found')
|
||||
override async disableEmailBackups(
|
||||
request: Request,
|
||||
): Promise<results.BadRequestErrorMessageResult | results.OkResult> {
|
||||
return super.disableEmailBackups(request)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
import { Request, Response } from 'express'
|
||||
import {
|
||||
BaseHttpController,
|
||||
controller,
|
||||
httpGet,
|
||||
httpPost,
|
||||
@@ -16,303 +15,65 @@ import { IncreaseLoginAttempts } from '../../Domain/UseCase/IncreaseLoginAttempt
|
||||
import { Logger } from 'winston'
|
||||
import { GetUserKeyParams } from '../../Domain/UseCase/GetUserKeyParams/GetUserKeyParams'
|
||||
import { AuthController } from '../../Controller/AuthController'
|
||||
import { ControllerContainerInterface } from '@standardnotes/domain-core'
|
||||
import { inject } from 'inversify'
|
||||
import { HomeServerAuthController } from './HomeServer/HomeServerAuthController'
|
||||
|
||||
@controller('/auth')
|
||||
export class InversifyExpressAuthController extends BaseHttpController {
|
||||
export class InversifyExpressAuthController extends HomeServerAuthController {
|
||||
constructor(
|
||||
@inject(TYPES.Auth_VerifyMFA) private verifyMFA: VerifyMFA,
|
||||
@inject(TYPES.Auth_SignIn) private signInUseCase: SignIn,
|
||||
@inject(TYPES.Auth_GetUserKeyParams) private getUserKeyParams: GetUserKeyParams,
|
||||
@inject(TYPES.Auth_ClearLoginAttempts) private clearLoginAttempts: ClearLoginAttempts,
|
||||
@inject(TYPES.Auth_IncreaseLoginAttempts) private increaseLoginAttempts: IncreaseLoginAttempts,
|
||||
@inject(TYPES.Auth_Logger) private logger: Logger,
|
||||
@inject(TYPES.Auth_AuthController) private authController: AuthController,
|
||||
@inject(TYPES.Auth_ControllerContainer) private controllerContainer: ControllerContainerInterface,
|
||||
@inject(TYPES.Auth_VerifyMFA) override verifyMFA: VerifyMFA,
|
||||
@inject(TYPES.Auth_SignIn) override signInUseCase: SignIn,
|
||||
@inject(TYPES.Auth_GetUserKeyParams) override getUserKeyParams: GetUserKeyParams,
|
||||
@inject(TYPES.Auth_ClearLoginAttempts) override clearLoginAttempts: ClearLoginAttempts,
|
||||
@inject(TYPES.Auth_IncreaseLoginAttempts) override increaseLoginAttempts: IncreaseLoginAttempts,
|
||||
@inject(TYPES.Auth_Logger) override logger: Logger,
|
||||
@inject(TYPES.Auth_AuthController) override authController: AuthController,
|
||||
) {
|
||||
super()
|
||||
|
||||
this.controllerContainer.register('auth.params', this.params.bind(this))
|
||||
this.controllerContainer.register('auth.signIn', this.signIn.bind(this))
|
||||
this.controllerContainer.register('auth.pkceParams', this.pkceParams.bind(this))
|
||||
this.controllerContainer.register('auth.pkceSignIn', this.pkceSignIn.bind(this))
|
||||
this.controllerContainer.register('auth.users.register', this.register.bind(this))
|
||||
this.controllerContainer.register('auth.generateRecoveryCodes', this.generateRecoveryCodes.bind(this))
|
||||
this.controllerContainer.register('auth.signInWithRecoveryCodes', this.recoveryLogin.bind(this))
|
||||
this.controllerContainer.register('auth.recoveryKeyParams', this.recoveryParams.bind(this))
|
||||
this.controllerContainer.register('auth.signOut', this.signOut.bind(this))
|
||||
super(verifyMFA, signInUseCase, getUserKeyParams, clearLoginAttempts, increaseLoginAttempts, logger, authController)
|
||||
}
|
||||
|
||||
@httpGet('/params', TYPES.Auth_AuthMiddlewareWithoutResponse)
|
||||
async params(request: Request, response: Response): Promise<results.JsonResult> {
|
||||
if (response.locals.session) {
|
||||
const result = await this.getUserKeyParams.execute({
|
||||
email: response.locals.user.email,
|
||||
authenticated: true,
|
||||
authenticatedUser: response.locals.user,
|
||||
})
|
||||
|
||||
return this.json(result.keyParams)
|
||||
}
|
||||
|
||||
if (!request.query.email) {
|
||||
return this.json(
|
||||
{
|
||||
error: {
|
||||
message: 'Please provide an email address.',
|
||||
},
|
||||
},
|
||||
400,
|
||||
)
|
||||
}
|
||||
|
||||
const verifyMFAResponse = await this.verifyMFA.execute({
|
||||
email: <string>request.query.email,
|
||||
requestParams: request.query,
|
||||
preventOTPFromFurtherUsage: false,
|
||||
})
|
||||
|
||||
if (!verifyMFAResponse.success) {
|
||||
return this.json(
|
||||
{
|
||||
error: {
|
||||
tag: verifyMFAResponse.errorTag,
|
||||
message: verifyMFAResponse.errorMessage,
|
||||
payload: verifyMFAResponse.errorPayload,
|
||||
},
|
||||
},
|
||||
401,
|
||||
)
|
||||
}
|
||||
|
||||
const result = await this.getUserKeyParams.execute({
|
||||
email: <string>request.query.email,
|
||||
authenticated: false,
|
||||
})
|
||||
|
||||
return this.json(result.keyParams)
|
||||
@httpGet('/params', TYPES.Auth_OptionalCrossServiceTokenMiddleware)
|
||||
override async params(request: Request, response: Response): Promise<results.JsonResult> {
|
||||
return super.params(request, response)
|
||||
}
|
||||
|
||||
@httpPost('/sign_in', TYPES.Auth_LockMiddleware)
|
||||
async signIn(request: Request): Promise<results.JsonResult> {
|
||||
if (!request.body.email || !request.body.password) {
|
||||
this.logger.debug('/auth/sign_in request missing credentials: %O', request.body)
|
||||
|
||||
return this.json(
|
||||
{
|
||||
error: {
|
||||
tag: 'invalid-auth',
|
||||
message: 'Invalid login credentials.',
|
||||
},
|
||||
},
|
||||
401,
|
||||
)
|
||||
}
|
||||
|
||||
const verifyMFAResponse = await this.verifyMFA.execute({
|
||||
email: request.body.email,
|
||||
requestParams: request.body,
|
||||
preventOTPFromFurtherUsage: true,
|
||||
})
|
||||
|
||||
if (!verifyMFAResponse.success) {
|
||||
return this.json(
|
||||
{
|
||||
error: {
|
||||
tag: verifyMFAResponse.errorTag,
|
||||
message: verifyMFAResponse.errorMessage,
|
||||
payload: verifyMFAResponse.errorPayload,
|
||||
},
|
||||
},
|
||||
401,
|
||||
)
|
||||
}
|
||||
|
||||
const signInResult = await this.signInUseCase.execute({
|
||||
apiVersion: request.body.api,
|
||||
userAgent: <string>request.headers['user-agent'],
|
||||
email: request.body.email,
|
||||
password: request.body.password,
|
||||
ephemeralSession: request.body.ephemeral ?? false,
|
||||
})
|
||||
|
||||
if (!signInResult.success) {
|
||||
await this.increaseLoginAttempts.execute({ email: request.body.email })
|
||||
|
||||
return this.json(
|
||||
{
|
||||
error: {
|
||||
message: signInResult.errorMessage,
|
||||
},
|
||||
},
|
||||
signInResult.errorCode ?? 401,
|
||||
)
|
||||
}
|
||||
|
||||
await this.clearLoginAttempts.execute({ email: request.body.email })
|
||||
|
||||
return this.json(signInResult.authResponse)
|
||||
override async signIn(request: Request): Promise<results.JsonResult> {
|
||||
return super.signIn(request)
|
||||
}
|
||||
|
||||
@httpPost('/pkce_params', TYPES.Auth_AuthMiddlewareWithoutResponse)
|
||||
async pkceParams(request: Request, response: Response): Promise<results.JsonResult> {
|
||||
if (!request.body.code_challenge) {
|
||||
return this.json(
|
||||
{
|
||||
error: {
|
||||
message: 'Please provide the code challenge parameter.',
|
||||
},
|
||||
},
|
||||
400,
|
||||
)
|
||||
}
|
||||
|
||||
if (response.locals.session) {
|
||||
const result = await this.getUserKeyParams.execute({
|
||||
email: response.locals.user.email,
|
||||
authenticated: true,
|
||||
authenticatedUser: response.locals.user,
|
||||
codeChallenge: request.body.code_challenge as string,
|
||||
})
|
||||
|
||||
return this.json(result.keyParams)
|
||||
}
|
||||
|
||||
if (!request.body.email) {
|
||||
return this.json(
|
||||
{
|
||||
error: {
|
||||
message: 'Please provide an email address.',
|
||||
},
|
||||
},
|
||||
400,
|
||||
)
|
||||
}
|
||||
|
||||
const verifyMFAResponse = await this.verifyMFA.execute({
|
||||
email: <string>request.body.email,
|
||||
requestParams: request.body,
|
||||
preventOTPFromFurtherUsage: true,
|
||||
})
|
||||
|
||||
if (!verifyMFAResponse.success) {
|
||||
return this.json(
|
||||
{
|
||||
error: {
|
||||
tag: verifyMFAResponse.errorTag,
|
||||
message: verifyMFAResponse.errorMessage,
|
||||
payload: verifyMFAResponse.errorPayload,
|
||||
},
|
||||
},
|
||||
401,
|
||||
)
|
||||
}
|
||||
|
||||
const result = await this.getUserKeyParams.execute({
|
||||
email: <string>request.body.email,
|
||||
authenticated: false,
|
||||
codeChallenge: request.body.code_challenge as string,
|
||||
})
|
||||
|
||||
return this.json(result.keyParams)
|
||||
@httpPost('/pkce_params', TYPES.Auth_OptionalCrossServiceTokenMiddleware)
|
||||
override async pkceParams(request: Request, response: Response): Promise<results.JsonResult> {
|
||||
return super.pkceParams(request, response)
|
||||
}
|
||||
|
||||
@httpPost('/pkce_sign_in', TYPES.Auth_LockMiddleware)
|
||||
async pkceSignIn(request: Request): Promise<results.JsonResult> {
|
||||
if (!request.body.email || !request.body.password || !request.body.code_verifier) {
|
||||
this.logger.debug('/auth/sign_in request missing credentials: %O', request.body)
|
||||
|
||||
return this.json(
|
||||
{
|
||||
error: {
|
||||
tag: 'invalid-auth',
|
||||
message: 'Invalid login credentials.',
|
||||
},
|
||||
},
|
||||
401,
|
||||
)
|
||||
}
|
||||
|
||||
const signInResult = await this.signInUseCase.execute({
|
||||
apiVersion: request.body.api,
|
||||
userAgent: <string>request.headers['user-agent'],
|
||||
email: request.body.email,
|
||||
password: request.body.password,
|
||||
ephemeralSession: request.body.ephemeral ?? false,
|
||||
codeVerifier: request.body.code_verifier,
|
||||
})
|
||||
|
||||
if (!signInResult.success) {
|
||||
await this.increaseLoginAttempts.execute({ email: request.body.email })
|
||||
|
||||
return this.json(
|
||||
{
|
||||
error: {
|
||||
message: signInResult.errorMessage,
|
||||
},
|
||||
},
|
||||
401,
|
||||
)
|
||||
}
|
||||
|
||||
await this.clearLoginAttempts.execute({ email: request.body.email })
|
||||
|
||||
return this.json(signInResult.authResponse)
|
||||
override async pkceSignIn(request: Request): Promise<results.JsonResult> {
|
||||
return super.pkceSignIn(request)
|
||||
}
|
||||
|
||||
@httpPost('/recovery/codes', TYPES.Auth_ApiGatewayAuthMiddleware)
|
||||
async generateRecoveryCodes(_request: Request, response: Response): Promise<results.JsonResult> {
|
||||
const result = await this.authController.generateRecoveryCodes({
|
||||
userUuid: response.locals.user.uuid,
|
||||
})
|
||||
|
||||
return this.json(result.data, result.status)
|
||||
@httpPost('/recovery/codes', TYPES.Auth_RequiredCrossServiceTokenMiddleware)
|
||||
override async generateRecoveryCodes(_request: Request, response: Response): Promise<results.JsonResult> {
|
||||
return super.generateRecoveryCodes(_request, response)
|
||||
}
|
||||
|
||||
@httpPost('/recovery/login', TYPES.Auth_LockMiddleware)
|
||||
async recoveryLogin(request: Request): Promise<results.JsonResult> {
|
||||
const result = await this.authController.signInWithRecoveryCodes({
|
||||
apiVersion: request.body.api_version,
|
||||
userAgent: <string>request.headers['user-agent'],
|
||||
codeVerifier: request.body.code_verifier,
|
||||
username: request.body.username,
|
||||
recoveryCodes: request.body.recovery_codes,
|
||||
password: request.body.password,
|
||||
})
|
||||
|
||||
return this.json(result.data, result.status)
|
||||
override async recoveryLogin(request: Request): Promise<results.JsonResult> {
|
||||
return super.recoveryLogin(request)
|
||||
}
|
||||
|
||||
@httpPost('/recovery/params')
|
||||
async recoveryParams(request: Request): Promise<results.JsonResult> {
|
||||
const result = await this.authController.recoveryKeyParams({
|
||||
apiVersion: request.body.api_version,
|
||||
username: request.body.username,
|
||||
codeChallenge: request.body.code_challenge,
|
||||
recoveryCodes: request.body.recovery_codes,
|
||||
})
|
||||
|
||||
return this.json(result.data, result.status)
|
||||
override async recoveryParams(request: Request): Promise<results.JsonResult> {
|
||||
return super.recoveryParams(request)
|
||||
}
|
||||
|
||||
@httpPost('/sign_out', TYPES.Auth_AuthMiddlewareWithoutResponse)
|
||||
async signOut(request: Request, response: Response): Promise<results.JsonResult | void> {
|
||||
const result = await this.authController.signOut({
|
||||
readOnlyAccess: response.locals.readOnlyAccess,
|
||||
authorizationHeader: <string>request.headers.authorization,
|
||||
})
|
||||
|
||||
return this.json(result.data, result.status)
|
||||
@httpPost('/sign_out', TYPES.Auth_OptionalCrossServiceTokenMiddleware)
|
||||
override async signOut(request: Request, response: Response): Promise<results.JsonResult | void> {
|
||||
return super.signOut(request, response)
|
||||
}
|
||||
|
||||
@httpPost('/')
|
||||
async register(request: Request): Promise<results.JsonResult> {
|
||||
const response = await this.authController.register({
|
||||
...request.body,
|
||||
userAgent: <string>request.headers['user-agent'],
|
||||
})
|
||||
|
||||
return this.json(response.data, response.status)
|
||||
override async register(request: Request): Promise<results.JsonResult> {
|
||||
return super.register(request)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
import { Request, Response } from 'express'
|
||||
import {
|
||||
BaseHttpController,
|
||||
controller,
|
||||
httpDelete,
|
||||
httpGet,
|
||||
@@ -10,78 +9,39 @@ import {
|
||||
} from 'inversify-express-utils'
|
||||
import TYPES from '../../Bootstrap/Types'
|
||||
import { AuthenticatorsController } from '../../Controller/AuthenticatorsController'
|
||||
import { ControllerContainerInterface } from '@standardnotes/domain-core'
|
||||
import { inject } from 'inversify'
|
||||
import { HomeServerAuthenticatorsController } from './HomeServer/HomeServerAuthenticatorsController'
|
||||
|
||||
@controller('/authenticators')
|
||||
export class InversifyExpressAuthenticatorsController extends BaseHttpController {
|
||||
export class InversifyExpressAuthenticatorsController extends HomeServerAuthenticatorsController {
|
||||
constructor(
|
||||
@inject(TYPES.Auth_AuthenticatorsController) private authenticatorsController: AuthenticatorsController,
|
||||
@inject(TYPES.Auth_ControllerContainer) private controllerContainer: ControllerContainerInterface,
|
||||
@inject(TYPES.Auth_AuthenticatorsController) override authenticatorsController: AuthenticatorsController,
|
||||
) {
|
||||
super()
|
||||
|
||||
this.controllerContainer.register('auth.authenticators.list', this.list.bind(this))
|
||||
this.controllerContainer.register('auth.authenticators.delete', this.delete.bind(this))
|
||||
this.controllerContainer.register(
|
||||
'auth.authenticators.generateRegistrationOptions',
|
||||
this.generateRegistrationOptions.bind(this),
|
||||
)
|
||||
this.controllerContainer.register(
|
||||
'auth.authenticators.verifyRegistrationResponse',
|
||||
this.verifyRegistration.bind(this),
|
||||
)
|
||||
this.controllerContainer.register(
|
||||
'auth.authenticators.generateAuthenticationOptions',
|
||||
this.generateAuthenticationOptions.bind(this),
|
||||
)
|
||||
super(authenticatorsController)
|
||||
}
|
||||
|
||||
@httpGet('/', TYPES.Auth_ApiGatewayAuthMiddleware)
|
||||
async list(_request: Request, response: Response): Promise<results.JsonResult> {
|
||||
const result = await this.authenticatorsController.list({
|
||||
userUuid: response.locals.user.uuid,
|
||||
})
|
||||
|
||||
return this.json(result.data, result.status)
|
||||
@httpGet('/', TYPES.Auth_RequiredCrossServiceTokenMiddleware)
|
||||
override async list(_request: Request, response: Response): Promise<results.JsonResult> {
|
||||
return super.list(_request, response)
|
||||
}
|
||||
|
||||
@httpDelete('/:authenticatorId', TYPES.Auth_ApiGatewayAuthMiddleware)
|
||||
async delete(request: Request, response: Response): Promise<results.JsonResult> {
|
||||
const result = await this.authenticatorsController.delete({
|
||||
userUuid: response.locals.user.uuid,
|
||||
authenticatorId: request.params.authenticatorId,
|
||||
})
|
||||
|
||||
return this.json(result.data, result.status)
|
||||
@httpDelete('/:authenticatorId', TYPES.Auth_RequiredCrossServiceTokenMiddleware)
|
||||
override async delete(request: Request, response: Response): Promise<results.JsonResult> {
|
||||
return super.delete(request, response)
|
||||
}
|
||||
|
||||
@httpGet('/generate-registration-options', TYPES.Auth_ApiGatewayAuthMiddleware)
|
||||
async generateRegistrationOptions(_request: Request, response: Response): Promise<results.JsonResult> {
|
||||
const result = await this.authenticatorsController.generateRegistrationOptions({
|
||||
username: response.locals.user.email,
|
||||
userUuid: response.locals.user.uuid,
|
||||
})
|
||||
|
||||
return this.json(result.data, result.status)
|
||||
@httpGet('/generate-registration-options', TYPES.Auth_RequiredCrossServiceTokenMiddleware)
|
||||
override async generateRegistrationOptions(_request: Request, response: Response): Promise<results.JsonResult> {
|
||||
return super.generateRegistrationOptions(_request, response)
|
||||
}
|
||||
|
||||
@httpPost('/verify-registration', TYPES.Auth_ApiGatewayAuthMiddleware)
|
||||
async verifyRegistration(request: Request, response: Response): Promise<results.JsonResult> {
|
||||
const result = await this.authenticatorsController.verifyRegistrationResponse({
|
||||
userUuid: response.locals.user.uuid,
|
||||
attestationResponse: request.body.attestationResponse,
|
||||
})
|
||||
|
||||
return this.json(result.data, result.status)
|
||||
@httpPost('/verify-registration', TYPES.Auth_RequiredCrossServiceTokenMiddleware)
|
||||
override async verifyRegistration(request: Request, response: Response): Promise<results.JsonResult> {
|
||||
return super.verifyRegistration(request, response)
|
||||
}
|
||||
|
||||
@httpPost('/generate-authentication-options')
|
||||
async generateAuthenticationOptions(request: Request): Promise<results.JsonResult> {
|
||||
const result = await this.authenticatorsController.generateAuthenticationOptions({
|
||||
username: request.body.username,
|
||||
})
|
||||
|
||||
return this.json(result.data, result.status)
|
||||
override async generateAuthenticationOptions(request: Request): Promise<results.JsonResult> {
|
||||
return super.generateAuthenticationOptions(request)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -6,7 +6,6 @@ import { InversifyExpressFeaturesController } from './InversifyExpressFeaturesCo
|
||||
import { results } from 'inversify-express-utils'
|
||||
import { User } from '../../Domain/User/User'
|
||||
import { GetUserFeatures } from '../../Domain/UseCase/GetUserFeatures/GetUserFeatures'
|
||||
import { ControllerContainerInterface } from '@standardnotes/domain-core'
|
||||
|
||||
describe('InversifyExpressFeaturesController', () => {
|
||||
let getUserFeatures: GetUserFeatures
|
||||
@@ -14,14 +13,10 @@ describe('InversifyExpressFeaturesController', () => {
|
||||
let request: express.Request
|
||||
let response: express.Response
|
||||
let user: User
|
||||
let controllerContainer: ControllerContainerInterface
|
||||
|
||||
const createController = () => new InversifyExpressFeaturesController(getUserFeatures, controllerContainer)
|
||||
const createController = () => new InversifyExpressFeaturesController(getUserFeatures)
|
||||
|
||||
beforeEach(() => {
|
||||
controllerContainer = {} as jest.Mocked<ControllerContainerInterface>
|
||||
controllerContainer.register = jest.fn()
|
||||
|
||||
user = {} as jest.Mocked<User>
|
||||
user.uuid = '123'
|
||||
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
import { Request, Response } from 'express'
|
||||
import { inject } from 'inversify'
|
||||
import {
|
||||
BaseHttpController,
|
||||
controller,
|
||||
httpGet,
|
||||
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
||||
@@ -9,41 +8,16 @@ import {
|
||||
} from 'inversify-express-utils'
|
||||
import TYPES from '../../Bootstrap/Types'
|
||||
import { GetUserFeatures } from '../../Domain/UseCase/GetUserFeatures/GetUserFeatures'
|
||||
import { ControllerContainerInterface } from '@standardnotes/domain-core'
|
||||
import { HomeServerFeaturesController } from './HomeServer/HomeServerFeaturesController'
|
||||
|
||||
@controller('/users/:userUuid/features')
|
||||
export class InversifyExpressFeaturesController extends BaseHttpController {
|
||||
constructor(
|
||||
@inject(TYPES.Auth_GetUserFeatures) private doGetUserFeatures: GetUserFeatures,
|
||||
@inject(TYPES.Auth_ControllerContainer) private controllerContainer: ControllerContainerInterface,
|
||||
) {
|
||||
super()
|
||||
|
||||
this.controllerContainer.register('auth.users.getFeatures', this.getFeatures.bind(this))
|
||||
export class InversifyExpressFeaturesController extends HomeServerFeaturesController {
|
||||
constructor(@inject(TYPES.Auth_GetUserFeatures) override doGetUserFeatures: GetUserFeatures) {
|
||||
super(doGetUserFeatures)
|
||||
}
|
||||
|
||||
@httpGet('/', TYPES.Auth_ApiGatewayAuthMiddleware)
|
||||
async getFeatures(request: Request, response: Response): Promise<results.JsonResult> {
|
||||
if (request.params.userUuid !== response.locals.user.uuid) {
|
||||
return this.json(
|
||||
{
|
||||
error: {
|
||||
message: 'Operation not allowed.',
|
||||
},
|
||||
},
|
||||
401,
|
||||
)
|
||||
}
|
||||
|
||||
const result = await this.doGetUserFeatures.execute({
|
||||
userUuid: request.params.userUuid,
|
||||
offline: false,
|
||||
})
|
||||
|
||||
if (result.success) {
|
||||
return this.json(result)
|
||||
}
|
||||
|
||||
return this.json(result, 400)
|
||||
@httpGet('/', TYPES.Auth_RequiredCrossServiceTokenMiddleware)
|
||||
override async getFeatures(request: Request, response: Response): Promise<results.JsonResult> {
|
||||
return super.getFeatures(request, response)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -6,7 +6,6 @@ import { results } from 'inversify-express-utils'
|
||||
import { InversifyExpressListedController } from './InversifyExpressListedController'
|
||||
import { User } from '../../Domain/User/User'
|
||||
import { CreateListedAccount } from '../../Domain/UseCase/CreateListedAccount/CreateListedAccount'
|
||||
import { ControllerContainerInterface } from '@standardnotes/domain-core'
|
||||
|
||||
describe('InversifyExpressListedController', () => {
|
||||
let createListedAccount: CreateListedAccount
|
||||
@@ -14,14 +13,10 @@ describe('InversifyExpressListedController', () => {
|
||||
let request: express.Request
|
||||
let response: express.Response
|
||||
let user: User
|
||||
let controllerContainer: ControllerContainerInterface
|
||||
|
||||
const createController = () => new InversifyExpressListedController(createListedAccount, controllerContainer)
|
||||
const createController = () => new InversifyExpressListedController(createListedAccount)
|
||||
|
||||
beforeEach(() => {
|
||||
controllerContainer = {} as jest.Mocked<ControllerContainerInterface>
|
||||
controllerContainer.register = jest.fn()
|
||||
|
||||
user = {} as jest.Mocked<User>
|
||||
user.uuid = '123'
|
||||
|
||||
|
||||
@@ -1,44 +1,19 @@
|
||||
import { inject } from 'inversify'
|
||||
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
||||
import { BaseHttpController, controller, httpPost, results } from 'inversify-express-utils'
|
||||
import { controller, httpPost, results } from 'inversify-express-utils'
|
||||
import { Request, Response } from 'express'
|
||||
import TYPES from '../../Bootstrap/Types'
|
||||
import { CreateListedAccount } from '../../Domain/UseCase/CreateListedAccount/CreateListedAccount'
|
||||
import { ErrorTag } from '@standardnotes/responses'
|
||||
import { ControllerContainerInterface } from '@standardnotes/domain-core'
|
||||
import { HomeServerListedController } from './HomeServer/HomeServerListedController'
|
||||
|
||||
@controller('/listed')
|
||||
export class InversifyExpressListedController extends BaseHttpController {
|
||||
constructor(
|
||||
@inject(TYPES.Auth_CreateListedAccount) private doCreateListedAccount: CreateListedAccount,
|
||||
@inject(TYPES.Auth_ControllerContainer) private controllerContainer: ControllerContainerInterface,
|
||||
) {
|
||||
super()
|
||||
|
||||
this.controllerContainer.register('auth.users.createListedAccount', this.createListedAccount.bind(this))
|
||||
export class InversifyExpressListedController extends HomeServerListedController {
|
||||
constructor(@inject(TYPES.Auth_CreateListedAccount) override doCreateListedAccount: CreateListedAccount) {
|
||||
super(doCreateListedAccount)
|
||||
}
|
||||
|
||||
@httpPost('/', TYPES.Auth_ApiGatewayAuthMiddleware)
|
||||
async createListedAccount(_request: Request, response: Response): Promise<results.JsonResult> {
|
||||
if (response.locals.readOnlyAccess) {
|
||||
return this.json(
|
||||
{
|
||||
error: {
|
||||
tag: ErrorTag.ReadOnlyAccess,
|
||||
message: 'Session has read-only access.',
|
||||
},
|
||||
},
|
||||
401,
|
||||
)
|
||||
}
|
||||
|
||||
await this.doCreateListedAccount.execute({
|
||||
userUuid: response.locals.user.uuid,
|
||||
userEmail: response.locals.user.email,
|
||||
})
|
||||
|
||||
return this.json({
|
||||
message: 'Listed account creation requested successfully.',
|
||||
})
|
||||
@httpPost('/', TYPES.Auth_RequiredCrossServiceTokenMiddleware)
|
||||
override async createListedAccount(_request: Request, response: Response): Promise<results.JsonResult> {
|
||||
return super.createListedAccount(_request, response)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -14,7 +14,6 @@ import { GetUserOfflineSubscription } from '../../Domain/UseCase/GetUserOfflineS
|
||||
import { OfflineUserTokenData, TokenEncoderInterface } from '@standardnotes/security'
|
||||
import { SubscriptionName } from '@standardnotes/common'
|
||||
import { Logger } from 'winston'
|
||||
import { ControllerContainerInterface } from '@standardnotes/domain-core'
|
||||
|
||||
describe('InversifyExpressOfflineController', () => {
|
||||
let getUserFeatures: GetUserFeatures
|
||||
@@ -29,8 +28,6 @@ describe('InversifyExpressOfflineController', () => {
|
||||
let response: express.Response
|
||||
let user: User
|
||||
|
||||
let controllerContainer: ControllerContainerInterface
|
||||
|
||||
const createController = () =>
|
||||
new InversifyExpressOfflineController(
|
||||
getUserFeatures,
|
||||
@@ -40,13 +37,9 @@ describe('InversifyExpressOfflineController', () => {
|
||||
tokenEncoder,
|
||||
jwtTTL,
|
||||
logger,
|
||||
controllerContainer,
|
||||
)
|
||||
|
||||
beforeEach(() => {
|
||||
controllerContainer = {} as jest.Mocked<ControllerContainerInterface>
|
||||
controllerContainer.register = jest.fn()
|
||||
|
||||
user = {} as jest.Mocked<User>
|
||||
user.uuid = '123'
|
||||
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
import { Request, Response } from 'express'
|
||||
import { inject } from 'inversify'
|
||||
import {
|
||||
BaseHttpController,
|
||||
controller,
|
||||
httpGet,
|
||||
httpPost,
|
||||
@@ -10,132 +9,54 @@ import {
|
||||
} from 'inversify-express-utils'
|
||||
import { Logger } from 'winston'
|
||||
import { OfflineUserTokenData, TokenEncoderInterface } from '@standardnotes/security'
|
||||
import { ControllerContainerInterface } from '@standardnotes/domain-core'
|
||||
import TYPES from '../../Bootstrap/Types'
|
||||
import { AuthenticateOfflineSubscriptionToken } from '../../Domain/UseCase/AuthenticateOfflineSubscriptionToken/AuthenticateOfflineSubscriptionToken'
|
||||
import { CreateOfflineSubscriptionToken } from '../../Domain/UseCase/CreateOfflineSubscriptionToken/CreateOfflineSubscriptionToken'
|
||||
import { GetUserFeatures } from '../../Domain/UseCase/GetUserFeatures/GetUserFeatures'
|
||||
import { GetUserOfflineSubscription } from '../../Domain/UseCase/GetUserOfflineSubscription/GetUserOfflineSubscription'
|
||||
import { HomeServerOfflineController } from './HomeServer/HomeServerOfflineController'
|
||||
|
||||
@controller('/offline')
|
||||
export class InversifyExpressOfflineController extends BaseHttpController {
|
||||
export class InversifyExpressOfflineController extends HomeServerOfflineController {
|
||||
constructor(
|
||||
@inject(TYPES.Auth_GetUserFeatures) private doGetUserFeatures: GetUserFeatures,
|
||||
@inject(TYPES.Auth_GetUserOfflineSubscription) private getUserOfflineSubscription: GetUserOfflineSubscription,
|
||||
@inject(TYPES.Auth_GetUserFeatures) override doGetUserFeatures: GetUserFeatures,
|
||||
@inject(TYPES.Auth_GetUserOfflineSubscription) override getUserOfflineSubscription: GetUserOfflineSubscription,
|
||||
@inject(TYPES.Auth_CreateOfflineSubscriptionToken)
|
||||
private createOfflineSubscriptionToken: CreateOfflineSubscriptionToken,
|
||||
override createOfflineSubscriptionToken: CreateOfflineSubscriptionToken,
|
||||
@inject(TYPES.Auth_AuthenticateOfflineSubscriptionToken)
|
||||
private authenticateToken: AuthenticateOfflineSubscriptionToken,
|
||||
@inject(TYPES.Auth_OfflineUserTokenEncoder) private tokenEncoder: TokenEncoderInterface<OfflineUserTokenData>,
|
||||
@inject(TYPES.Auth_AUTH_JWT_TTL) private jwtTTL: number,
|
||||
@inject(TYPES.Auth_Logger) private logger: Logger,
|
||||
@inject(TYPES.Auth_ControllerContainer) private controllerContainer: ControllerContainerInterface,
|
||||
override authenticateToken: AuthenticateOfflineSubscriptionToken,
|
||||
@inject(TYPES.Auth_OfflineUserTokenEncoder) override tokenEncoder: TokenEncoderInterface<OfflineUserTokenData>,
|
||||
@inject(TYPES.Auth_AUTH_JWT_TTL) override jwtTTL: number,
|
||||
@inject(TYPES.Auth_Logger) override logger: Logger,
|
||||
) {
|
||||
super()
|
||||
|
||||
this.controllerContainer.register('auth.offline.features', this.getOfflineFeatures.bind(this))
|
||||
this.controllerContainer.register('auth.offline.subscriptionTokens.create', this.createToken.bind(this))
|
||||
this.controllerContainer.register('auth.users.getOfflineSubscriptionByToken', this.getSubscription.bind(this))
|
||||
super(
|
||||
doGetUserFeatures,
|
||||
getUserOfflineSubscription,
|
||||
createOfflineSubscriptionToken,
|
||||
authenticateToken,
|
||||
tokenEncoder,
|
||||
jwtTTL,
|
||||
logger,
|
||||
)
|
||||
}
|
||||
|
||||
@httpGet('/features', TYPES.Auth_OfflineUserAuthMiddleware)
|
||||
async getOfflineFeatures(_request: Request, response: Response): Promise<results.JsonResult> {
|
||||
const result = await this.doGetUserFeatures.execute({
|
||||
email: response.locals.offlineUserEmail,
|
||||
offline: true,
|
||||
})
|
||||
|
||||
if (result.success) {
|
||||
return this.json(result)
|
||||
}
|
||||
|
||||
return this.json(result, 400)
|
||||
override async getOfflineFeatures(_request: Request, response: Response): Promise<results.JsonResult> {
|
||||
return super.getOfflineFeatures(_request, response)
|
||||
}
|
||||
|
||||
@httpPost('/subscription-tokens')
|
||||
async createToken(request: Request): Promise<results.JsonResult> {
|
||||
if (!request.body.email) {
|
||||
return this.json(
|
||||
{
|
||||
error: {
|
||||
tag: 'invalid-request',
|
||||
message: 'Invalid request parameters.',
|
||||
},
|
||||
},
|
||||
400,
|
||||
)
|
||||
}
|
||||
|
||||
const response = await this.createOfflineSubscriptionToken.execute({
|
||||
userEmail: request.body.email,
|
||||
})
|
||||
|
||||
if (!response.success) {
|
||||
return this.json({ success: false, error: { tag: response.error } })
|
||||
}
|
||||
|
||||
return this.json({ success: true })
|
||||
override async createToken(request: Request): Promise<results.JsonResult> {
|
||||
return super.createToken(request)
|
||||
}
|
||||
|
||||
@httpPost('/subscription-tokens/:token/validate')
|
||||
async validate(request: Request): Promise<results.JsonResult> {
|
||||
if (!request.body.email) {
|
||||
this.logger.debug('[Offline Subscription Token Validation] Missing email')
|
||||
|
||||
return this.json(
|
||||
{
|
||||
error: {
|
||||
tag: 'invalid-request',
|
||||
message: 'Invalid request parameters.',
|
||||
},
|
||||
},
|
||||
400,
|
||||
)
|
||||
}
|
||||
|
||||
const authenticateTokenResponse = await this.authenticateToken.execute({
|
||||
token: request.params.token,
|
||||
userEmail: request.body.email,
|
||||
})
|
||||
|
||||
if (!authenticateTokenResponse.success) {
|
||||
this.logger.debug('[Offline Subscription Token Validation] invalid token')
|
||||
|
||||
return this.json(
|
||||
{
|
||||
error: {
|
||||
tag: 'invalid-auth',
|
||||
message: 'Invalid login credentials.',
|
||||
},
|
||||
},
|
||||
401,
|
||||
)
|
||||
}
|
||||
|
||||
const offlineAuthTokenData: OfflineUserTokenData = {
|
||||
userEmail: authenticateTokenResponse.email,
|
||||
featuresToken: authenticateTokenResponse.featuresToken,
|
||||
}
|
||||
|
||||
const authToken = this.tokenEncoder.encodeExpirableToken(offlineAuthTokenData, this.jwtTTL)
|
||||
|
||||
this.logger.debug(
|
||||
`[Offline Subscription Token Validation] authenticated token for user ${authenticateTokenResponse.email}`,
|
||||
)
|
||||
|
||||
return this.json({ authToken })
|
||||
override async validate(request: Request): Promise<results.JsonResult> {
|
||||
return super.validate(request)
|
||||
}
|
||||
|
||||
@httpGet('/users/subscription', TYPES.Auth_ApiGatewayOfflineAuthMiddleware)
|
||||
async getSubscription(_request: Request, response: Response): Promise<results.JsonResult> {
|
||||
const result = await this.getUserOfflineSubscription.execute({
|
||||
userEmail: response.locals.userEmail,
|
||||
})
|
||||
|
||||
if (result.success) {
|
||||
return this.json(result)
|
||||
}
|
||||
|
||||
return this.json(result, 400)
|
||||
override async getSubscription(_request: Request, response: Response): Promise<results.JsonResult> {
|
||||
return super.getSubscription(_request, response)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -4,7 +4,6 @@ import * as express from 'express'
|
||||
|
||||
import { InversifyExpressSessionController } from './InversifyExpressSessionController'
|
||||
import { results } from 'inversify-express-utils'
|
||||
import { ControllerContainerInterface } from '@standardnotes/domain-core'
|
||||
import { DeletePreviousSessionsForUser } from '../../Domain/UseCase/DeletePreviousSessionsForUser'
|
||||
import { DeleteSessionForUser } from '../../Domain/UseCase/DeleteSessionForUser'
|
||||
import { RefreshSessionToken } from '../../Domain/UseCase/RefreshSessionToken'
|
||||
@@ -15,20 +14,11 @@ describe('InversifyExpressSessionController', () => {
|
||||
let refreshSessionToken: RefreshSessionToken
|
||||
let request: express.Request
|
||||
let response: express.Response
|
||||
let controllerContainer: ControllerContainerInterface
|
||||
|
||||
const createController = () =>
|
||||
new InversifyExpressSessionController(
|
||||
deleteSessionForUser,
|
||||
deletePreviousSessionsForUser,
|
||||
refreshSessionToken,
|
||||
controllerContainer,
|
||||
)
|
||||
new InversifyExpressSessionController(deleteSessionForUser, deletePreviousSessionsForUser, refreshSessionToken)
|
||||
|
||||
beforeEach(() => {
|
||||
controllerContainer = {} as jest.Mocked<ControllerContainerInterface>
|
||||
controllerContainer.register = jest.fn()
|
||||
|
||||
deleteSessionForUser = {} as jest.Mocked<DeleteSessionForUser>
|
||||
deleteSessionForUser.execute = jest.fn().mockReturnValue({ success: true })
|
||||
|
||||
@@ -64,16 +54,12 @@ describe('InversifyExpressSessionController', () => {
|
||||
},
|
||||
})
|
||||
|
||||
await createController().refresh(request, response)
|
||||
const httpResult = <results.JsonResult>await createController().refresh(request, response)
|
||||
const result = await httpResult.executeAsync()
|
||||
|
||||
expect(response.send).toHaveBeenCalledWith({
|
||||
session: {
|
||||
access_token: '1231',
|
||||
refresh_token: '2341',
|
||||
access_expiration: 123123,
|
||||
refresh_expiration: 123123,
|
||||
},
|
||||
})
|
||||
expect(await result.content.readAsStringAsync()).toEqual(
|
||||
'{"session":{"access_token":"1231","refresh_token":"2341","access_expiration":123123,"refresh_expiration":123123}}',
|
||||
)
|
||||
})
|
||||
|
||||
it('should return bad request if tokens are missing from refresh token request', async () => {
|
||||
@@ -113,14 +99,15 @@ describe('InversifyExpressSessionController', () => {
|
||||
}
|
||||
request.body.uuid = '123'
|
||||
|
||||
await createController().deleteSession(request, response)
|
||||
const httpResult = <results.JsonResult>await createController().deleteSession(request, response)
|
||||
const result = await httpResult.executeAsync()
|
||||
|
||||
expect(deleteSessionForUser.execute).toBeCalledWith({
|
||||
userUuid: '123',
|
||||
sessionUuid: '123',
|
||||
})
|
||||
|
||||
expect(response.status).toHaveBeenCalledWith(204)
|
||||
expect(result.statusCode).toEqual(204)
|
||||
})
|
||||
|
||||
it('should not delete a specific session is current session has read only access', async () => {
|
||||
@@ -205,15 +192,16 @@ describe('InversifyExpressSessionController', () => {
|
||||
uuid: '234',
|
||||
},
|
||||
}
|
||||
await createController().deleteAllSessions(request, response)
|
||||
|
||||
const httpResult = <results.JsonResult>await createController().deleteAllSessions(request, response)
|
||||
const result = await httpResult.executeAsync()
|
||||
|
||||
expect(deletePreviousSessionsForUser.execute).toHaveBeenCalledWith({
|
||||
userUuid: '123',
|
||||
currentSessionUuid: '234',
|
||||
})
|
||||
|
||||
expect(response.status).toHaveBeenCalledWith(204)
|
||||
expect(response.send).toHaveBeenCalled()
|
||||
expect(result.statusCode).toEqual(204)
|
||||
})
|
||||
|
||||
it('should not delete all sessions if current sessions has read only access', async () => {
|
||||
|
||||
@@ -1,8 +1,6 @@
|
||||
import { ErrorTag } from '@standardnotes/responses'
|
||||
import { Request, Response } from 'express'
|
||||
import { inject } from 'inversify'
|
||||
import {
|
||||
BaseHttpController,
|
||||
controller,
|
||||
httpDelete,
|
||||
httpPost,
|
||||
@@ -13,147 +11,37 @@ import TYPES from '../../Bootstrap/Types'
|
||||
import { DeletePreviousSessionsForUser } from '../../Domain/UseCase/DeletePreviousSessionsForUser'
|
||||
import { DeleteSessionForUser } from '../../Domain/UseCase/DeleteSessionForUser'
|
||||
import { RefreshSessionToken } from '../../Domain/UseCase/RefreshSessionToken'
|
||||
import { ControllerContainerInterface } from '@standardnotes/domain-core'
|
||||
import { HomeServerSessionController } from './HomeServer/HomeServerSessionController'
|
||||
|
||||
@controller('/session')
|
||||
export class InversifyExpressSessionController extends BaseHttpController {
|
||||
export class InversifyExpressSessionController extends HomeServerSessionController {
|
||||
constructor(
|
||||
@inject(TYPES.Auth_DeleteSessionForUser) private deleteSessionForUser: DeleteSessionForUser,
|
||||
@inject(TYPES.Auth_DeleteSessionForUser) override deleteSessionForUser: DeleteSessionForUser,
|
||||
@inject(TYPES.Auth_DeletePreviousSessionsForUser)
|
||||
private deletePreviousSessionsForUser: DeletePreviousSessionsForUser,
|
||||
@inject(TYPES.Auth_RefreshSessionToken) private refreshSessionToken: RefreshSessionToken,
|
||||
@inject(TYPES.Auth_ControllerContainer) private controllerContainer: ControllerContainerInterface,
|
||||
override deletePreviousSessionsForUser: DeletePreviousSessionsForUser,
|
||||
@inject(TYPES.Auth_RefreshSessionToken) override refreshSessionToken: RefreshSessionToken,
|
||||
) {
|
||||
super()
|
||||
|
||||
this.controllerContainer.register('auth.session.delete', this.deleteSession.bind(this))
|
||||
this.controllerContainer.register('auth.session.deleteAll', this.deleteAllSessions.bind(this))
|
||||
this.controllerContainer.register('auth.session.refresh', this.refresh.bind(this))
|
||||
super(deleteSessionForUser, deletePreviousSessionsForUser, refreshSessionToken)
|
||||
}
|
||||
|
||||
@httpDelete('/', TYPES.Auth_AuthMiddleware, TYPES.Auth_SessionMiddleware)
|
||||
async deleteSession(request: Request, response: Response): Promise<results.JsonResult | void> {
|
||||
if (response.locals.readOnlyAccess) {
|
||||
return this.json(
|
||||
{
|
||||
error: {
|
||||
tag: ErrorTag.ReadOnlyAccess,
|
||||
message: 'Session has read-only access.',
|
||||
},
|
||||
},
|
||||
401,
|
||||
)
|
||||
}
|
||||
|
||||
if (!request.body.uuid) {
|
||||
return this.json(
|
||||
{
|
||||
error: {
|
||||
message: 'Please provide the session identifier.',
|
||||
},
|
||||
},
|
||||
400,
|
||||
)
|
||||
}
|
||||
|
||||
if (request.body.uuid === response.locals.session.uuid) {
|
||||
return this.json(
|
||||
{
|
||||
error: {
|
||||
message: 'You can not delete your current session.',
|
||||
},
|
||||
},
|
||||
400,
|
||||
)
|
||||
}
|
||||
|
||||
const useCaseResponse = await this.deleteSessionForUser.execute({
|
||||
userUuid: response.locals.user.uuid,
|
||||
sessionUuid: request.body.uuid,
|
||||
})
|
||||
|
||||
if (!useCaseResponse.success) {
|
||||
return this.json(
|
||||
{
|
||||
error: {
|
||||
message: useCaseResponse.errorMessage,
|
||||
},
|
||||
},
|
||||
400,
|
||||
)
|
||||
}
|
||||
|
||||
response.setHeader('x-invalidate-cache', response.locals.user.uuid)
|
||||
response.status(204).send()
|
||||
@httpDelete('/', TYPES.Auth_RequiredCrossServiceTokenMiddleware, TYPES.Auth_SessionMiddleware)
|
||||
override async deleteSession(
|
||||
request: Request,
|
||||
response: Response,
|
||||
): Promise<results.JsonResult | results.StatusCodeResult> {
|
||||
return super.deleteSession(request, response)
|
||||
}
|
||||
|
||||
@httpDelete('/all', TYPES.Auth_AuthMiddleware, TYPES.Auth_SessionMiddleware)
|
||||
async deleteAllSessions(_request: Request, response: Response): Promise<results.JsonResult | void> {
|
||||
if (response.locals.readOnlyAccess) {
|
||||
return this.json(
|
||||
{
|
||||
error: {
|
||||
tag: ErrorTag.ReadOnlyAccess,
|
||||
message: 'Session has read-only access.',
|
||||
},
|
||||
},
|
||||
401,
|
||||
)
|
||||
}
|
||||
|
||||
if (!response.locals.user) {
|
||||
return this.json(
|
||||
{
|
||||
error: {
|
||||
message: 'No session exists with the provided identifier.',
|
||||
},
|
||||
},
|
||||
401,
|
||||
)
|
||||
}
|
||||
|
||||
await this.deletePreviousSessionsForUser.execute({
|
||||
userUuid: response.locals.user.uuid,
|
||||
currentSessionUuid: response.locals.session.uuid,
|
||||
})
|
||||
|
||||
response.setHeader('x-invalidate-cache', response.locals.user.uuid)
|
||||
response.status(204).send()
|
||||
@httpDelete('/all', TYPES.Auth_RequiredCrossServiceTokenMiddleware, TYPES.Auth_SessionMiddleware)
|
||||
override async deleteAllSessions(
|
||||
_request: Request,
|
||||
response: Response,
|
||||
): Promise<results.JsonResult | results.StatusCodeResult> {
|
||||
return super.deleteAllSessions(_request, response)
|
||||
}
|
||||
|
||||
@httpPost('/refresh')
|
||||
async refresh(request: Request, response: Response): Promise<results.JsonResult | void> {
|
||||
if (!request.body.access_token || !request.body.refresh_token) {
|
||||
return this.json(
|
||||
{
|
||||
error: {
|
||||
message: 'Please provide all required parameters.',
|
||||
},
|
||||
},
|
||||
400,
|
||||
)
|
||||
}
|
||||
|
||||
const result = await this.refreshSessionToken.execute({
|
||||
accessToken: request.body.access_token,
|
||||
refreshToken: request.body.refresh_token,
|
||||
})
|
||||
|
||||
if (!result.success) {
|
||||
return this.json(
|
||||
{
|
||||
error: {
|
||||
tag: result.errorTag,
|
||||
message: result.errorMessage,
|
||||
},
|
||||
},
|
||||
400,
|
||||
)
|
||||
}
|
||||
|
||||
response.setHeader('x-invalidate-cache', result.userUuid as string)
|
||||
response.send({
|
||||
session: result.sessionPayload,
|
||||
})
|
||||
override async refresh(request: Request, response: Response): Promise<results.JsonResult> {
|
||||
return super.refresh(request, response)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -4,7 +4,6 @@ import * as express from 'express'
|
||||
|
||||
import { InversifyExpressSessionsController } from './InversifyExpressSessionsController'
|
||||
import { results } from 'inversify-express-utils'
|
||||
import { ControllerContainerInterface } from '@standardnotes/domain-core'
|
||||
import { User } from '@standardnotes/responses'
|
||||
|
||||
import { AuthenticateRequest } from '../../Domain/UseCase/AuthenticateRequest'
|
||||
@@ -22,7 +21,6 @@ describe('InversifyExpressSessionsController', () => {
|
||||
let response: express.Response
|
||||
let user: User
|
||||
let createCrossServiceToken: CreateCrossServiceToken
|
||||
let controllerContainer: ControllerContainerInterface
|
||||
|
||||
const createController = () =>
|
||||
new InversifyExpressSessionsController(
|
||||
@@ -30,13 +28,9 @@ describe('InversifyExpressSessionsController', () => {
|
||||
authenticateRequest,
|
||||
sessionProjector,
|
||||
createCrossServiceToken,
|
||||
controllerContainer,
|
||||
)
|
||||
|
||||
beforeEach(() => {
|
||||
controllerContainer = {} as jest.Mocked<ControllerContainerInterface>
|
||||
controllerContainer.register = jest.fn()
|
||||
|
||||
session = {} as jest.Mocked<Session>
|
||||
|
||||
user = {} as jest.Mocked<User>
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user