@matter/nodejs 0.11.0-alpha.0-20241005-e3e4e4a7a
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +201 -0
- package/README.md +1 -0
- package/dist/cjs/behavior/index.d.ts +7 -0
- package/dist/cjs/behavior/index.d.ts.map +1 -0
- package/dist/cjs/behavior/index.js +8 -0
- package/dist/cjs/behavior/index.js.map +6 -0
- package/dist/cjs/behavior/instrumentation.d.ts +11 -0
- package/dist/cjs/behavior/instrumentation.d.ts.map +1 -0
- package/dist/cjs/behavior/instrumentation.js +47 -0
- package/dist/cjs/behavior/instrumentation.js.map +6 -0
- package/dist/cjs/behavior/register.d.ts +7 -0
- package/dist/cjs/behavior/register.d.ts.map +1 -0
- package/dist/cjs/behavior/register.js +9 -0
- package/dist/cjs/behavior/register.js.map +6 -0
- package/dist/cjs/crypto/NodeJsCrypto.d.ts +29 -0
- package/dist/cjs/crypto/NodeJsCrypto.d.ts.map +1 -0
- package/dist/cjs/crypto/NodeJsCrypto.js +154 -0
- package/dist/cjs/crypto/NodeJsCrypto.js.map +6 -0
- package/dist/cjs/crypto/index.d.ts +8 -0
- package/dist/cjs/crypto/index.d.ts.map +1 -0
- package/dist/cjs/crypto/index.js +25 -0
- package/dist/cjs/crypto/index.js.map +6 -0
- package/dist/cjs/crypto/register.d.ts +7 -0
- package/dist/cjs/crypto/register.d.ts.map +1 -0
- package/dist/cjs/crypto/register.js +21 -0
- package/dist/cjs/crypto/register.js.map +6 -0
- package/dist/cjs/environment/NodeJsActionTracer.d.ts +15 -0
- package/dist/cjs/environment/NodeJsActionTracer.d.ts.map +1 -0
- package/dist/cjs/environment/NodeJsActionTracer.js +80 -0
- package/dist/cjs/environment/NodeJsActionTracer.js.map +6 -0
- package/dist/cjs/environment/NodeJsEnvironment.d.ts +55 -0
- package/dist/cjs/environment/NodeJsEnvironment.d.ts.map +1 -0
- package/dist/cjs/environment/NodeJsEnvironment.js +121 -0
- package/dist/cjs/environment/NodeJsEnvironment.js.map +6 -0
- package/dist/cjs/environment/ProcessManager.d.ts +45 -0
- package/dist/cjs/environment/ProcessManager.d.ts.map +1 -0
- package/dist/cjs/environment/ProcessManager.js +112 -0
- package/dist/cjs/environment/ProcessManager.js.map +6 -0
- package/dist/cjs/environment/index.d.ts +10 -0
- package/dist/cjs/environment/index.d.ts.map +1 -0
- package/dist/cjs/environment/index.js +27 -0
- package/dist/cjs/environment/index.js.map +6 -0
- package/dist/cjs/environment/register.d.ts +7 -0
- package/dist/cjs/environment/register.d.ts.map +1 -0
- package/dist/cjs/environment/register.js +10 -0
- package/dist/cjs/environment/register.js.map +6 -0
- package/dist/cjs/index.d.ts +12 -0
- package/dist/cjs/index.d.ts.map +1 -0
- package/dist/cjs/index.js +29 -0
- package/dist/cjs/index.js.map +6 -0
- package/dist/cjs/log/FileLogger.d.ts +13 -0
- package/dist/cjs/log/FileLogger.d.ts.map +1 -0
- package/dist/cjs/log/FileLogger.js +46 -0
- package/dist/cjs/log/FileLogger.js.map +6 -0
- package/dist/cjs/log/index.d.ts +7 -0
- package/dist/cjs/log/index.d.ts.map +1 -0
- package/dist/cjs/log/index.js +24 -0
- package/dist/cjs/log/index.js.map +6 -0
- package/dist/cjs/net/NodeJsNetwork.d.ts +27 -0
- package/dist/cjs/net/NodeJsNetwork.d.ts.map +1 -0
- package/dist/cjs/net/NodeJsNetwork.js +145 -0
- package/dist/cjs/net/NodeJsNetwork.js.map +6 -0
- package/dist/cjs/net/NodeJsUdpChannel.d.ts +23 -0
- package/dist/cjs/net/NodeJsUdpChannel.d.ts.map +1 -0
- package/dist/cjs/net/NodeJsUdpChannel.js +181 -0
- package/dist/cjs/net/NodeJsUdpChannel.js.map +6 -0
- package/dist/cjs/net/index.d.ts +9 -0
- package/dist/cjs/net/index.d.ts.map +1 -0
- package/dist/cjs/net/index.js +26 -0
- package/dist/cjs/net/index.js.map +6 -0
- package/dist/cjs/net/register.d.ts +7 -0
- package/dist/cjs/net/register.d.ts.map +1 -0
- package/dist/cjs/net/register.js +16 -0
- package/dist/cjs/net/register.js.map +6 -0
- package/dist/cjs/package.json +11 -0
- package/dist/cjs/storage/StorageBackendDisk.d.ts +27 -0
- package/dist/cjs/storage/StorageBackendDisk.d.ts.map +1 -0
- package/dist/cjs/storage/StorageBackendDisk.js +128 -0
- package/dist/cjs/storage/StorageBackendDisk.js.map +6 -0
- package/dist/cjs/storage/StorageBackendJsonFile.d.ts +27 -0
- package/dist/cjs/storage/StorageBackendJsonFile.d.ts.map +1 -0
- package/dist/cjs/storage/StorageBackendJsonFile.js +110 -0
- package/dist/cjs/storage/StorageBackendJsonFile.js.map +6 -0
- package/dist/cjs/storage/index.d.ts +8 -0
- package/dist/cjs/storage/index.d.ts.map +1 -0
- package/dist/cjs/storage/index.js +25 -0
- package/dist/cjs/storage/index.js.map +6 -0
- package/dist/cjs/tsconfig.tsbuildinfo +1 -0
- package/dist/esm/behavior/index.d.ts +7 -0
- package/dist/esm/behavior/index.d.ts.map +1 -0
- package/dist/esm/behavior/index.js +7 -0
- package/dist/esm/behavior/index.js.map +6 -0
- package/dist/esm/behavior/instrumentation.d.ts +11 -0
- package/dist/esm/behavior/instrumentation.d.ts.map +1 -0
- package/dist/esm/behavior/instrumentation.js +27 -0
- package/dist/esm/behavior/instrumentation.js.map +6 -0
- package/dist/esm/behavior/register.d.ts +7 -0
- package/dist/esm/behavior/register.d.ts.map +1 -0
- package/dist/esm/behavior/register.js +8 -0
- package/dist/esm/behavior/register.js.map +6 -0
- package/dist/esm/crypto/NodeJsCrypto.d.ts +29 -0
- package/dist/esm/crypto/NodeJsCrypto.d.ts.map +1 -0
- package/dist/esm/crypto/NodeJsCrypto.js +135 -0
- package/dist/esm/crypto/NodeJsCrypto.js.map +6 -0
- package/dist/esm/crypto/index.d.ts +8 -0
- package/dist/esm/crypto/index.d.ts.map +1 -0
- package/dist/esm/crypto/index.js +8 -0
- package/dist/esm/crypto/index.js.map +6 -0
- package/dist/esm/crypto/register.d.ts +7 -0
- package/dist/esm/crypto/register.d.ts.map +1 -0
- package/dist/esm/crypto/register.js +20 -0
- package/dist/esm/crypto/register.js.map +6 -0
- package/dist/esm/environment/NodeJsActionTracer.d.ts +15 -0
- package/dist/esm/environment/NodeJsActionTracer.d.ts.map +1 -0
- package/dist/esm/environment/NodeJsActionTracer.js +60 -0
- package/dist/esm/environment/NodeJsActionTracer.js.map +6 -0
- package/dist/esm/environment/NodeJsEnvironment.d.ts +55 -0
- package/dist/esm/environment/NodeJsEnvironment.d.ts.map +1 -0
- package/dist/esm/environment/NodeJsEnvironment.js +108 -0
- package/dist/esm/environment/NodeJsEnvironment.js.map +6 -0
- package/dist/esm/environment/ProcessManager.d.ts +45 -0
- package/dist/esm/environment/ProcessManager.d.ts.map +1 -0
- package/dist/esm/environment/ProcessManager.js +92 -0
- package/dist/esm/environment/ProcessManager.js.map +6 -0
- package/dist/esm/environment/index.d.ts +10 -0
- package/dist/esm/environment/index.d.ts.map +1 -0
- package/dist/esm/environment/index.js +10 -0
- package/dist/esm/environment/index.js.map +6 -0
- package/dist/esm/environment/register.d.ts +7 -0
- package/dist/esm/environment/register.d.ts.map +1 -0
- package/dist/esm/environment/register.js +9 -0
- package/dist/esm/environment/register.js.map +6 -0
- package/dist/esm/index.d.ts +12 -0
- package/dist/esm/index.d.ts.map +1 -0
- package/dist/esm/index.js +12 -0
- package/dist/esm/index.js.map +6 -0
- package/dist/esm/log/FileLogger.d.ts +13 -0
- package/dist/esm/log/FileLogger.d.ts.map +1 -0
- package/dist/esm/log/FileLogger.js +26 -0
- package/dist/esm/log/FileLogger.js.map +6 -0
- package/dist/esm/log/index.d.ts +7 -0
- package/dist/esm/log/index.d.ts.map +1 -0
- package/dist/esm/log/index.js +7 -0
- package/dist/esm/log/index.js.map +6 -0
- package/dist/esm/net/NodeJsNetwork.d.ts +27 -0
- package/dist/esm/net/NodeJsNetwork.d.ts.map +1 -0
- package/dist/esm/net/NodeJsNetwork.js +133 -0
- package/dist/esm/net/NodeJsNetwork.js.map +6 -0
- package/dist/esm/net/NodeJsUdpChannel.d.ts +23 -0
- package/dist/esm/net/NodeJsUdpChannel.d.ts.map +1 -0
- package/dist/esm/net/NodeJsUdpChannel.js +159 -0
- package/dist/esm/net/NodeJsUdpChannel.js.map +6 -0
- package/dist/esm/net/index.d.ts +9 -0
- package/dist/esm/net/index.d.ts.map +1 -0
- package/dist/esm/net/index.js +9 -0
- package/dist/esm/net/index.js.map +6 -0
- package/dist/esm/net/register.d.ts +7 -0
- package/dist/esm/net/register.d.ts.map +1 -0
- package/dist/esm/net/register.js +15 -0
- package/dist/esm/net/register.js.map +6 -0
- package/dist/esm/package.json +11 -0
- package/dist/esm/storage/StorageBackendDisk.d.ts +27 -0
- package/dist/esm/storage/StorageBackendDisk.d.ts.map +1 -0
- package/dist/esm/storage/StorageBackendDisk.js +108 -0
- package/dist/esm/storage/StorageBackendDisk.js.map +6 -0
- package/dist/esm/storage/StorageBackendJsonFile.d.ts +27 -0
- package/dist/esm/storage/StorageBackendJsonFile.d.ts.map +1 -0
- package/dist/esm/storage/StorageBackendJsonFile.js +90 -0
- package/dist/esm/storage/StorageBackendJsonFile.js.map +6 -0
- package/dist/esm/storage/index.d.ts +8 -0
- package/dist/esm/storage/index.d.ts.map +1 -0
- package/dist/esm/storage/index.js +8 -0
- package/dist/esm/storage/index.js.map +6 -0
- package/dist/esm/tsconfig.tsbuildinfo +1 -0
- package/package.json +114 -0
- package/src/behavior/index.ts +7 -0
- package/src/behavior/instrumentation.ts +32 -0
- package/src/behavior/register.ts +9 -0
- package/src/crypto/NodeJsCrypto.ts +164 -0
- package/src/crypto/index.ts +8 -0
- package/src/crypto/register.ts +25 -0
- package/src/environment/NodeJsActionTracer.ts +70 -0
- package/src/environment/NodeJsEnvironment.ts +172 -0
- package/src/environment/ProcessManager.ts +128 -0
- package/src/environment/index.ts +10 -0
- package/src/environment/register.ts +10 -0
- package/src/index.ts +12 -0
- package/src/log/FileLogger.ts +30 -0
- package/src/log/index.ts +7 -0
- package/src/net/NodeJsNetwork.ts +157 -0
- package/src/net/NodeJsUdpChannel.ts +179 -0
- package/src/net/index.ts +9 -0
- package/src/net/register.ts +20 -0
- package/src/storage/StorageBackendDisk.ts +132 -0
- package/src/storage/StorageBackendJsonFile.ts +102 -0
- package/src/storage/index.ts +8 -0
- package/src/tsconfig.json +28 -0
package/package.json
ADDED
|
@@ -0,0 +1,114 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@matter/nodejs",
|
|
3
|
+
"version": "0.11.0-alpha.0-20241005-e3e4e4a7a",
|
|
4
|
+
"description": "Node.js platform support for matter.js",
|
|
5
|
+
"keywords": [
|
|
6
|
+
"iot",
|
|
7
|
+
"home automation",
|
|
8
|
+
"matter",
|
|
9
|
+
"smart device"
|
|
10
|
+
],
|
|
11
|
+
"license": "Apache-2.0",
|
|
12
|
+
"author": "matter.js authors",
|
|
13
|
+
"contributors": [
|
|
14
|
+
"Martin Turon <mturon@google.com>",
|
|
15
|
+
"Marco Fucci di Napoli <mfucci@gmail.com>",
|
|
16
|
+
"Ingo Fischer <github@fischer-ka.de>",
|
|
17
|
+
"Greg Lauckhart <greg@lauckhart.com>"
|
|
18
|
+
],
|
|
19
|
+
"bugs": {
|
|
20
|
+
"url": "https://github.com/project-chip/matter.js/issues"
|
|
21
|
+
},
|
|
22
|
+
"homepage": "https://github.com/project-chip/matter.js",
|
|
23
|
+
"repository": {
|
|
24
|
+
"type": "git",
|
|
25
|
+
"url": "git+https://github.com/project-chip/matter.js.git"
|
|
26
|
+
},
|
|
27
|
+
"engines": {
|
|
28
|
+
"node": ">=18.0.0"
|
|
29
|
+
},
|
|
30
|
+
"scripts": {
|
|
31
|
+
"clean": "matter-build clean",
|
|
32
|
+
"build": "matter-build",
|
|
33
|
+
"build-clean": "matter-build --clean",
|
|
34
|
+
"test": "matter-test",
|
|
35
|
+
"coverage": "c8 matter-test esm",
|
|
36
|
+
"embed-examples": "embedme **/README.md"
|
|
37
|
+
},
|
|
38
|
+
"imports": {
|
|
39
|
+
"#general": "@matter/general",
|
|
40
|
+
"#types": "@matter/types",
|
|
41
|
+
"#clusters/*": "@matter/types/clusters/*",
|
|
42
|
+
"#node": "@matter/node",
|
|
43
|
+
"#protocol": "@matter/protocol",
|
|
44
|
+
"#*": "./src/*"
|
|
45
|
+
},
|
|
46
|
+
"dependencies": {
|
|
47
|
+
"@matter/general": "0.11.0-alpha.0-20241005-e3e4e4a7a",
|
|
48
|
+
"@matter/types": "0.11.0-alpha.0-20241005-e3e4e4a7a",
|
|
49
|
+
"@matter/protocol": "0.11.0-alpha.0-20241005-e3e4e4a7a",
|
|
50
|
+
"@matter/node": "0.11.0-alpha.0-20241005-e3e4e4a7a",
|
|
51
|
+
"@project-chip/matter.js": "0.11.0-alpha.0-20241005-e3e4e4a7a",
|
|
52
|
+
"node-localstorage": "^3.0.5"
|
|
53
|
+
},
|
|
54
|
+
"devDependencies": {
|
|
55
|
+
"@matter/model": "0.11.0-alpha.0-20241005-e3e4e4a7a",
|
|
56
|
+
"@matter/protocol": "0.11.0-alpha.0-20241005-e3e4e4a7a",
|
|
57
|
+
"@matter/tools": "0.11.0-alpha.0-20241005-e3e4e4a7a",
|
|
58
|
+
"@types/bytebuffer": "^5.0.49",
|
|
59
|
+
"@types/node-localstorage": "^1.3.3"
|
|
60
|
+
},
|
|
61
|
+
"files": [
|
|
62
|
+
"dist/**/*",
|
|
63
|
+
"src/**/*",
|
|
64
|
+
"LICENSE",
|
|
65
|
+
"README.md"
|
|
66
|
+
],
|
|
67
|
+
"type": "module",
|
|
68
|
+
"main": "dist/cjs/index.js",
|
|
69
|
+
"module": "dist/esm/index.js",
|
|
70
|
+
"exports": {
|
|
71
|
+
".": {
|
|
72
|
+
"import": {
|
|
73
|
+
"types": "./dist/esm/index.d.ts",
|
|
74
|
+
"default": "./dist/esm/index.js"
|
|
75
|
+
},
|
|
76
|
+
"require": {
|
|
77
|
+
"types": "./dist/cjs/index.d.ts",
|
|
78
|
+
"default": "./dist/cjs/index.js"
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
},
|
|
82
|
+
"types": "dist/esm/index.d.ts",
|
|
83
|
+
"typesVersions": {
|
|
84
|
+
"*": {
|
|
85
|
+
"interaction": [
|
|
86
|
+
"/dist/cjs/protocol/interaction/export.d.ts"
|
|
87
|
+
],
|
|
88
|
+
"model": [
|
|
89
|
+
"/dist/cjs/model/index.d.ts"
|
|
90
|
+
],
|
|
91
|
+
"securechannel": [
|
|
92
|
+
"/dist/cjs/protocol/securechannel/export.d.ts"
|
|
93
|
+
],
|
|
94
|
+
"behaviors/*": [
|
|
95
|
+
"/dist/cjs/behavior/definitions/*/export.d.ts"
|
|
96
|
+
],
|
|
97
|
+
"devices/*": [
|
|
98
|
+
"/dist/cjs/endpoint/definitions/device/*.d.ts"
|
|
99
|
+
],
|
|
100
|
+
"endpoints/*": [
|
|
101
|
+
"/dist/cjs/endpoint/definitions/system/*.d.ts"
|
|
102
|
+
],
|
|
103
|
+
".": [
|
|
104
|
+
"/dist/cjs/export.d.ts"
|
|
105
|
+
],
|
|
106
|
+
"*": [
|
|
107
|
+
"/dist/cjs/*/export.d.ts"
|
|
108
|
+
]
|
|
109
|
+
}
|
|
110
|
+
},
|
|
111
|
+
"publishConfig": {
|
|
112
|
+
"access": "public"
|
|
113
|
+
}
|
|
114
|
+
}
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @license
|
|
3
|
+
* Copyright 2022-2024 Matter.js Authors
|
|
4
|
+
* SPDX-License-Identifier: Apache-2.0
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
import { Instrumentation, Val } from "#node";
|
|
8
|
+
import { inspect } from "util";
|
|
9
|
+
|
|
10
|
+
/**
|
|
11
|
+
* Node's default console formatting makes it difficult to view the value of managed collections. This function
|
|
12
|
+
* instruments values to make inspection work more naturally.
|
|
13
|
+
*/
|
|
14
|
+
export function installInspectionInstrumentation() {
|
|
15
|
+
Instrumentation.instrumentStruct = constructor => {
|
|
16
|
+
constructor.prototype[inspect.custom] = function (this: Val.Struct) {
|
|
17
|
+
return { ...this };
|
|
18
|
+
};
|
|
19
|
+
|
|
20
|
+
return constructor;
|
|
21
|
+
};
|
|
22
|
+
|
|
23
|
+
Instrumentation.instrumentList = (factory): Instrumentation.ListFactory => {
|
|
24
|
+
return (handlers, target) => {
|
|
25
|
+
(target as any)[inspect.custom] = function (this: Val.List) {
|
|
26
|
+
return [...this];
|
|
27
|
+
};
|
|
28
|
+
|
|
29
|
+
return factory(handlers, target);
|
|
30
|
+
};
|
|
31
|
+
};
|
|
32
|
+
}
|
|
@@ -0,0 +1,164 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @license
|
|
3
|
+
* Copyright 2022-2024 Matter.js Authors
|
|
4
|
+
* SPDX-License-Identifier: Apache-2.0
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
import {
|
|
8
|
+
Bytes,
|
|
9
|
+
CRYPTO_AUTH_TAG_LENGTH,
|
|
10
|
+
CRYPTO_EC_CURVE,
|
|
11
|
+
CRYPTO_EC_KEY_BYTES,
|
|
12
|
+
CRYPTO_ENCRYPT_ALGORITHM,
|
|
13
|
+
CRYPTO_HASH_ALGORITHM,
|
|
14
|
+
CRYPTO_SYMMETRIC_KEY_LENGTH,
|
|
15
|
+
Crypto,
|
|
16
|
+
CryptoDsaEncoding,
|
|
17
|
+
CryptoVerifyError,
|
|
18
|
+
PrivateKey,
|
|
19
|
+
} from "#general";
|
|
20
|
+
import * as crypto from "crypto";
|
|
21
|
+
|
|
22
|
+
export class NodeJsCrypto extends Crypto {
|
|
23
|
+
encrypt(key: Uint8Array, data: Uint8Array, nonce: Uint8Array, aad?: Uint8Array): Uint8Array {
|
|
24
|
+
const cipher = crypto.createCipheriv(CRYPTO_ENCRYPT_ALGORITHM, key, nonce, {
|
|
25
|
+
authTagLength: CRYPTO_AUTH_TAG_LENGTH,
|
|
26
|
+
});
|
|
27
|
+
if (aad !== undefined) {
|
|
28
|
+
cipher.setAAD(aad, { plaintextLength: data.length });
|
|
29
|
+
}
|
|
30
|
+
const encrypted = cipher.update(data);
|
|
31
|
+
cipher.final();
|
|
32
|
+
return Bytes.concat(encrypted, cipher.getAuthTag());
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
decrypt(key: Uint8Array, data: Uint8Array, nonce: Uint8Array, aad?: Uint8Array): Uint8Array {
|
|
36
|
+
const cipher = crypto.createDecipheriv(CRYPTO_ENCRYPT_ALGORITHM, key, nonce, {
|
|
37
|
+
authTagLength: CRYPTO_AUTH_TAG_LENGTH,
|
|
38
|
+
});
|
|
39
|
+
const plaintextLength = data.length - CRYPTO_AUTH_TAG_LENGTH;
|
|
40
|
+
if (aad !== undefined) {
|
|
41
|
+
cipher.setAAD(aad, { plaintextLength });
|
|
42
|
+
}
|
|
43
|
+
cipher.setAuthTag(data.slice(plaintextLength));
|
|
44
|
+
const result = cipher.update(data.slice(0, plaintextLength));
|
|
45
|
+
cipher.final();
|
|
46
|
+
return new Uint8Array(result);
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
getRandomData(length: number): Uint8Array {
|
|
50
|
+
return new Uint8Array(crypto.randomBytes(length));
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
ecdhGeneratePublicKey(): { publicKey: Uint8Array; ecdh: any } {
|
|
54
|
+
const ecdh = crypto.createECDH(CRYPTO_EC_CURVE);
|
|
55
|
+
ecdh.generateKeys();
|
|
56
|
+
return { publicKey: new Uint8Array(ecdh.getPublicKey()), ecdh: ecdh };
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
ecdhGeneratePublicKeyAndSecret(peerPublicKey: Uint8Array): { publicKey: Uint8Array; sharedSecret: Uint8Array } {
|
|
60
|
+
const ecdh = crypto.createECDH(CRYPTO_EC_CURVE);
|
|
61
|
+
ecdh.generateKeys();
|
|
62
|
+
return {
|
|
63
|
+
publicKey: new Uint8Array(ecdh.getPublicKey()),
|
|
64
|
+
sharedSecret: new Uint8Array(ecdh.computeSecret(peerPublicKey)),
|
|
65
|
+
};
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
ecdhGenerateSecret(peerPublicKey: Uint8Array, ecdh: crypto.ECDH): Uint8Array {
|
|
69
|
+
return new Uint8Array(ecdh.computeSecret(peerPublicKey));
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
hash(data: Uint8Array | Uint8Array[]): Uint8Array {
|
|
73
|
+
const hasher = crypto.createHash(CRYPTO_HASH_ALGORITHM);
|
|
74
|
+
if (Array.isArray(data)) {
|
|
75
|
+
data.forEach(chunk => hasher.update(chunk));
|
|
76
|
+
} else {
|
|
77
|
+
hasher.update(data);
|
|
78
|
+
}
|
|
79
|
+
return new Uint8Array(hasher.digest());
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
pbkdf2(secret: Uint8Array, salt: Uint8Array, iteration: number, keyLength: number): Promise<Uint8Array> {
|
|
83
|
+
return new Promise<Uint8Array>((resolver, rejecter) => {
|
|
84
|
+
crypto.pbkdf2(secret, salt, iteration, keyLength, CRYPTO_HASH_ALGORITHM, (error, key) => {
|
|
85
|
+
if (error !== null) rejecter(error);
|
|
86
|
+
resolver(new Uint8Array(key));
|
|
87
|
+
});
|
|
88
|
+
});
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
hkdf(
|
|
92
|
+
secret: Uint8Array,
|
|
93
|
+
salt: Uint8Array,
|
|
94
|
+
info: Uint8Array,
|
|
95
|
+
length: number = CRYPTO_SYMMETRIC_KEY_LENGTH,
|
|
96
|
+
): Promise<Uint8Array> {
|
|
97
|
+
return new Promise<Uint8Array>((resolver, rejecter) => {
|
|
98
|
+
crypto.hkdf(CRYPTO_HASH_ALGORITHM, secret, salt, info, length, (error, key) => {
|
|
99
|
+
if (error !== null) rejecter(error);
|
|
100
|
+
resolver(new Uint8Array(key));
|
|
101
|
+
});
|
|
102
|
+
});
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
hmac(key: Uint8Array, data: Uint8Array): Uint8Array {
|
|
106
|
+
const hmac = crypto.createHmac(CRYPTO_HASH_ALGORITHM, key);
|
|
107
|
+
hmac.update(data);
|
|
108
|
+
return new Uint8Array(hmac.digest());
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
sign(
|
|
112
|
+
privateKey: JsonWebKey,
|
|
113
|
+
data: Uint8Array | Uint8Array[],
|
|
114
|
+
dsaEncoding: CryptoDsaEncoding = "ieee-p1363",
|
|
115
|
+
): Uint8Array {
|
|
116
|
+
const signer = crypto.createSign(CRYPTO_HASH_ALGORITHM);
|
|
117
|
+
if (Array.isArray(data)) {
|
|
118
|
+
data.forEach(chunk => signer.update(chunk));
|
|
119
|
+
} else {
|
|
120
|
+
signer.update(data);
|
|
121
|
+
}
|
|
122
|
+
return new Uint8Array(
|
|
123
|
+
signer.sign({
|
|
124
|
+
key: privateKey as any,
|
|
125
|
+
format: "jwk",
|
|
126
|
+
type: "pkcs8",
|
|
127
|
+
dsaEncoding,
|
|
128
|
+
}),
|
|
129
|
+
);
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
verify(
|
|
133
|
+
publicKey: JsonWebKey,
|
|
134
|
+
data: Uint8Array,
|
|
135
|
+
signature: Uint8Array,
|
|
136
|
+
dsaEncoding: CryptoDsaEncoding = "ieee-p1363",
|
|
137
|
+
) {
|
|
138
|
+
const verifier = crypto.createVerify(CRYPTO_HASH_ALGORITHM);
|
|
139
|
+
verifier.update(data);
|
|
140
|
+
const success = verifier.verify(
|
|
141
|
+
{
|
|
142
|
+
key: publicKey as any,
|
|
143
|
+
format: "jwk",
|
|
144
|
+
type: "spki",
|
|
145
|
+
dsaEncoding,
|
|
146
|
+
},
|
|
147
|
+
signature,
|
|
148
|
+
);
|
|
149
|
+
if (!success) throw new CryptoVerifyError("Signature verification failed");
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
createKeyPair() {
|
|
153
|
+
const ecdh = crypto.createECDH(CRYPTO_EC_CURVE);
|
|
154
|
+
ecdh.generateKeys();
|
|
155
|
+
|
|
156
|
+
// The key exported from Node doesn't include most-significant bytes that are 0. This doesn't affect how we
|
|
157
|
+
// currently use keys but it's a little weird so 0 pad to avoid future confusion
|
|
158
|
+
const privateKey = new Uint8Array(CRYPTO_EC_KEY_BYTES);
|
|
159
|
+
const nodePrivateKey = ecdh.getPrivateKey();
|
|
160
|
+
privateKey.set(nodePrivateKey, CRYPTO_EC_KEY_BYTES - nodePrivateKey.length);
|
|
161
|
+
|
|
162
|
+
return PrivateKey(privateKey, { publicKey: ecdh.getPublicKey() });
|
|
163
|
+
}
|
|
164
|
+
}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @license
|
|
3
|
+
* Copyright 2022-2024 Matter.js Authors
|
|
4
|
+
* SPDX-License-Identifier: Apache-2.0
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
import { Crypto, NoProviderError, singleton } from "#general";
|
|
8
|
+
import { NodeJsCrypto } from "./NodeJsCrypto.js";
|
|
9
|
+
|
|
10
|
+
// Check if Crypto singleton is already registered
|
|
11
|
+
let needCrypto = true;
|
|
12
|
+
try {
|
|
13
|
+
const crypto = Crypto.get();
|
|
14
|
+
|
|
15
|
+
if ((crypto as { mock?: boolean }).mock !== true) {
|
|
16
|
+
needCrypto = false;
|
|
17
|
+
}
|
|
18
|
+
} catch (error) {
|
|
19
|
+
NoProviderError.accept(error);
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
// Register if necessary
|
|
23
|
+
if (needCrypto) {
|
|
24
|
+
Crypto.get = singleton(() => new NodeJsCrypto());
|
|
25
|
+
}
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @license
|
|
3
|
+
* Copyright 2022-2024 Matter.js Authors
|
|
4
|
+
* SPDX-License-Identifier: Apache-2.0
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
import { Environment, MaybePromise, serialize } from "#general";
|
|
8
|
+
import { ActionTracer } from "#node";
|
|
9
|
+
import { FileHandle, open } from "fs/promises";
|
|
10
|
+
import { resolve } from "path";
|
|
11
|
+
|
|
12
|
+
export class NodeJsActionTracer extends ActionTracer {
|
|
13
|
+
#path: string;
|
|
14
|
+
#output?: FileHandle;
|
|
15
|
+
#write?: MaybePromise<void>;
|
|
16
|
+
|
|
17
|
+
constructor(path: string) {
|
|
18
|
+
super();
|
|
19
|
+
|
|
20
|
+
this.#path = path;
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
static configure(env: Environment) {
|
|
24
|
+
env.vars.use(() => {
|
|
25
|
+
if (env.has(ActionTracer)) {
|
|
26
|
+
env.delete(env.get(ActionTracer).constructor as new () => ActionTracer);
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
if (!env.vars.boolean("trace.enable")) {
|
|
30
|
+
return;
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
const path = resolve(env.vars.get("path.root", "."), env.vars.get("trace.path", "trace.jsonl"));
|
|
34
|
+
|
|
35
|
+
const tracer = new NodeJsActionTracer(path);
|
|
36
|
+
env.set(ActionTracer, tracer);
|
|
37
|
+
env.runtime.add(tracer);
|
|
38
|
+
});
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
[Symbol.asyncDispose]() {
|
|
42
|
+
MaybePromise.then(this.#write, () => this.#output?.close());
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
override record(action: ActionTracer.Action) {
|
|
46
|
+
const raw = {
|
|
47
|
+
...action,
|
|
48
|
+
path: action.path?.toString(false),
|
|
49
|
+
mutations: action.mutations
|
|
50
|
+
? action.mutations.map(m => ({ ...m, path: m.path.toString(false) }))
|
|
51
|
+
: undefined,
|
|
52
|
+
};
|
|
53
|
+
this.#write = MaybePromise.then(this.#write, () => this.#record(raw));
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
async #record(action: object) {
|
|
57
|
+
if (this.#output === undefined) {
|
|
58
|
+
this.#output = await open(this.#path, "w");
|
|
59
|
+
}
|
|
60
|
+
await this.#output.write(JSON.stringify(action, replacer));
|
|
61
|
+
await this.#output.write("\n");
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
function replacer(_key: string, value: any) {
|
|
66
|
+
if (typeof value === "bigint" || ArrayBuffer.isView(value)) {
|
|
67
|
+
return serialize(value);
|
|
68
|
+
}
|
|
69
|
+
return value;
|
|
70
|
+
}
|
|
@@ -0,0 +1,172 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @license
|
|
3
|
+
* Copyright 2022-2024 Matter.js Authors
|
|
4
|
+
* SPDX-License-Identifier: Apache-2.0
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
import {
|
|
8
|
+
Environment,
|
|
9
|
+
ImplementationError,
|
|
10
|
+
LogFormat,
|
|
11
|
+
Logger,
|
|
12
|
+
Network,
|
|
13
|
+
StorageService,
|
|
14
|
+
VariableService,
|
|
15
|
+
} from "#general";
|
|
16
|
+
import { existsSync, readFileSync } from "fs";
|
|
17
|
+
import { resolve } from "path";
|
|
18
|
+
import { NodeJsNetwork } from "../net/NodeJsNetwork.js";
|
|
19
|
+
import { StorageBackendDisk } from "../storage/StorageBackendDisk.js";
|
|
20
|
+
import { NodeJsActionTracer } from "./NodeJsActionTracer.js";
|
|
21
|
+
import { ProcessManager } from "./ProcessManager.js";
|
|
22
|
+
|
|
23
|
+
/**
|
|
24
|
+
* This is the default environment implementation for Node.js:
|
|
25
|
+
*
|
|
26
|
+
* - Sets variables using rudimentary command line, environment and configuration file parsers.
|
|
27
|
+
*
|
|
28
|
+
* - Processes UNIX-style signals and sets process exit codes via {@link ProcessManager}
|
|
29
|
+
*
|
|
30
|
+
* - Creates a default storage pool using the loaded configuration.
|
|
31
|
+
*
|
|
32
|
+
* You can modify this behavior:
|
|
33
|
+
*
|
|
34
|
+
* - Via configuration
|
|
35
|
+
*
|
|
36
|
+
* - By modifying {@link Environment.default}
|
|
37
|
+
*
|
|
38
|
+
* - By providing an {@link Environment} to your components other than {@link Environment.default}
|
|
39
|
+
*
|
|
40
|
+
* The settings are applied in this order (the higher numbers overwrite lower numbers):
|
|
41
|
+
* 1. Some internal Defaults (mainly Loglevel and such)
|
|
42
|
+
* 2. Config file
|
|
43
|
+
* 3. Environment variables (MATTER_*)
|
|
44
|
+
* 4. Command line parameters
|
|
45
|
+
*
|
|
46
|
+
* The following variables are defined by this class additionally to {@link Environment}:
|
|
47
|
+
* * `environment` - Name of the environment, Default "default"
|
|
48
|
+
* * `path.root` - Path considered as root for any files to store, Fallback: ".", Default: APPDATA/.matter (Windows), HOME/.matter else (or .matter-<envname>)
|
|
49
|
+
* * `path.config` - Path to config file, Default: "config.json"
|
|
50
|
+
* * `trace.path` - Path of the trace file to write, Default: "trace.jsonl" relative to path.root
|
|
51
|
+
* * `trace.enable` - Enable writing a trace file
|
|
52
|
+
* * `storage.path` - Where to store storage files, Default: "path.root"
|
|
53
|
+
* * `storage.clear` - Clear storage on start? Default: false
|
|
54
|
+
* * `runtime.signals` - By default register SIGINT and SIGUSR2 (diag) handlers, set to false if not wanted
|
|
55
|
+
* * `runtime.exitcode` - By default we set the process.exitcode to 0 (ok) or 1 (crash); set to false to disable
|
|
56
|
+
* * `runtime.unhandlederrors` - By default we log unhandled errors to matter.js log; set to false to disable
|
|
57
|
+
*/
|
|
58
|
+
export function NodeJsEnvironment() {
|
|
59
|
+
const env = new Environment("default");
|
|
60
|
+
|
|
61
|
+
loadVariables(env);
|
|
62
|
+
configureRuntime(env);
|
|
63
|
+
configureStorage(env);
|
|
64
|
+
configureNetwork(env);
|
|
65
|
+
|
|
66
|
+
// When no logger format is set, we still use the default, and the process is running in a TTY, use ANSI formatting
|
|
67
|
+
// If a user wants to change the log format he still can do after the environment was initialized (which should be
|
|
68
|
+
// first thing anyway)
|
|
69
|
+
if (!env.vars.has("logger.format") && Logger.format === LogFormat.PLAIN && process.stdin?.isTTY) {
|
|
70
|
+
env.vars.set("logger.format", LogFormat.ANSI);
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
NodeJsActionTracer.configure(env);
|
|
74
|
+
|
|
75
|
+
return env;
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
function loadVariables(env: Environment) {
|
|
79
|
+
const vars = env.vars;
|
|
80
|
+
|
|
81
|
+
// Install defaults
|
|
82
|
+
vars.addConfigStyle(getDefaults(vars));
|
|
83
|
+
|
|
84
|
+
// Preload environment and argv so we can use it to find config file
|
|
85
|
+
vars.addUnixEnvStyle(process.env);
|
|
86
|
+
vars.addArgvStyle(process.argv);
|
|
87
|
+
|
|
88
|
+
// Load config files
|
|
89
|
+
vars.addConfigStyle(loadConfigFile(vars));
|
|
90
|
+
|
|
91
|
+
// Reload environment and argv so they override config
|
|
92
|
+
vars.addUnixEnvStyle(process.env);
|
|
93
|
+
vars.addArgvStyle(process.argv);
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
function configureRuntime(env: Environment) {
|
|
97
|
+
const processManager = new ProcessManager(env);
|
|
98
|
+
env.set(ProcessManager, processManager);
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
function configureStorage(env: Environment) {
|
|
102
|
+
const service = env.get(StorageService);
|
|
103
|
+
|
|
104
|
+
env.vars.use(() => {
|
|
105
|
+
const location = env.vars.get("storage.path", env.vars.get("path.root", "."));
|
|
106
|
+
service.location = location;
|
|
107
|
+
});
|
|
108
|
+
|
|
109
|
+
service.factory = namespace =>
|
|
110
|
+
new StorageBackendDisk(resolve(service.location ?? ".", namespace), env.vars.get("storage.clear", false));
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
function configureNetwork(env: Environment) {
|
|
114
|
+
env.set(Network, new NodeJsNetwork());
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
export function loadConfigFile(vars: VariableService) {
|
|
118
|
+
const path = vars.get("path.config", "config.json");
|
|
119
|
+
|
|
120
|
+
if (!existsSync(path)) {
|
|
121
|
+
return {};
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
let configJson;
|
|
125
|
+
try {
|
|
126
|
+
configJson = readFileSync(path).toString();
|
|
127
|
+
} catch (e) {
|
|
128
|
+
throw new ImplementationError(`Error reading configuration file ${path}: ${(e as Error).message}`);
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
let configVars;
|
|
132
|
+
try {
|
|
133
|
+
configVars = JSON.parse(configJson);
|
|
134
|
+
} catch (e) {
|
|
135
|
+
throw new ImplementationError(`Error parsing configuration file ${path}: ${(e as Error).message}`);
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
return configVars;
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
function getDefaultRoot(envName: string) {
|
|
142
|
+
let matterDir;
|
|
143
|
+
if (process.platform === "win32") {
|
|
144
|
+
matterDir = resolve(process.env.APPDATA ?? ".", "matter");
|
|
145
|
+
} else {
|
|
146
|
+
matterDir = resolve(process.env.HOME ?? ".", ".matter");
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
if (envName !== "default") {
|
|
150
|
+
matterDir = `${matterDir}-${envName}`;
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
return matterDir;
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
export function getDefaults(vars: VariableService) {
|
|
157
|
+
const envName = vars.get("environment", "default");
|
|
158
|
+
const rootPath = vars.get("path.root", getDefaultRoot(envName));
|
|
159
|
+
const configPath = resolve(rootPath, vars.get("path.config", "config.json"));
|
|
160
|
+
|
|
161
|
+
return {
|
|
162
|
+
environment: envName,
|
|
163
|
+
path: {
|
|
164
|
+
root: rootPath,
|
|
165
|
+
config: configPath,
|
|
166
|
+
},
|
|
167
|
+
runtime: {
|
|
168
|
+
signals: true,
|
|
169
|
+
exitcode: true,
|
|
170
|
+
},
|
|
171
|
+
};
|
|
172
|
+
}
|