balanceofsatoshis 11.2.1 → 11.3.0
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/CHANGELOG.md +4 -0
- package/bos +2 -0
- package/lnd/credential_restrictions.js +41 -0
- package/lnd/get_credentials.js +2 -0
- package/lnd/lnd_credentials.js +15 -4
- package/package.json +2 -2
- package/test/lnd/test_credential_restrictions.js +74 -0
package/CHANGELOG.md
CHANGED
package/bos
CHANGED
|
@@ -420,6 +420,7 @@ prog
|
|
|
420
420
|
.help('Output encrypted remote access credentials. Use with "nodes --add"')
|
|
421
421
|
.option('--cleartext', 'Output remote access credentials without encryption')
|
|
422
422
|
.option('--days <days>', 'Expiration days for credentials', INT, 365)
|
|
423
|
+
.option('--method <method_name>', 'White-list specific method', REPEATABLE)
|
|
423
424
|
.option('--node <node_name>', 'Get credentials for a saved node')
|
|
424
425
|
.option('--nospend', 'Credentials do not include spending privileges')
|
|
425
426
|
.option('--readonly', 'Credentials only include read permissions')
|
|
@@ -432,6 +433,7 @@ prog
|
|
|
432
433
|
is_cleartext: options.cleartext,
|
|
433
434
|
is_nospend: options.nospend,
|
|
434
435
|
is_readonly: options.readonly,
|
|
436
|
+
methods: flatten([options.method].filter(n => !!n)),
|
|
435
437
|
node: options.node,
|
|
436
438
|
},
|
|
437
439
|
responses.returnObject({logger, reject, resolve}));
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
const {noSpendPerms} = require('./constants');
|
|
2
|
+
const {permissionEntities} = require('./constants');
|
|
3
|
+
|
|
4
|
+
const readPerms = permissionEntities.map(entity => `${entity}:read`);
|
|
5
|
+
|
|
6
|
+
/** Derive restrictions for macaroon
|
|
7
|
+
|
|
8
|
+
{
|
|
9
|
+
[is_nospend]: <Restrict Credentials To Non-Spending Permissions Bool>
|
|
10
|
+
[is_readonly]: <Restrict Credentials To Read-Only Permissions Bool>
|
|
11
|
+
[methods]: [<Allow Specific Method String>]
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
@returns
|
|
15
|
+
{
|
|
16
|
+
[allow]: {
|
|
17
|
+
methods: [<Allow Specific Method String>]
|
|
18
|
+
permissions: [<Entity:Action String>]
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
*/
|
|
22
|
+
module.exports = args => {
|
|
23
|
+
const methods = args.methods || [];
|
|
24
|
+
|
|
25
|
+
// Exit early when specific credentials are not requested
|
|
26
|
+
if (!args.is_readonly && !args.is_nospend && !methods.length) {
|
|
27
|
+
return {};
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
const permissions = [];
|
|
31
|
+
|
|
32
|
+
if (!!args.is_readonly) {
|
|
33
|
+
readPerms.forEach(n => permissions.push(n));
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
if (!!args.is_nospend) {
|
|
37
|
+
noSpendPerms.forEach(n => permissions.push(n));
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
return {allow: {methods, permissions}};
|
|
41
|
+
};
|
package/lnd/get_credentials.js
CHANGED
|
@@ -16,6 +16,7 @@ const {pemAsDer} = require('./../encryption');
|
|
|
16
16
|
is_nospend: <Restrict Credentials To Non-Spending Permissions Bool>
|
|
17
17
|
is_readonly: <Restrict Credentials To Read-Only Permissions Bool>
|
|
18
18
|
logger: <Winston Logger Object> ({info}) => ()
|
|
19
|
+
[methods]: [<Allow Specific Method String>]
|
|
19
20
|
[node]: <Node Name String>
|
|
20
21
|
}
|
|
21
22
|
|
|
@@ -81,6 +82,7 @@ module.exports = (args, cbk) => {
|
|
|
81
82
|
is_nospend: args.is_nospend,
|
|
82
83
|
is_readonly: args.is_readonly,
|
|
83
84
|
logger: args.logger,
|
|
85
|
+
methods: args.methods,
|
|
84
86
|
node: args.node,
|
|
85
87
|
},
|
|
86
88
|
cbk);
|
package/lnd/lnd_credentials.js
CHANGED
|
@@ -12,6 +12,7 @@ const {grantAccess} = require('ln-service');
|
|
|
12
12
|
const {restrictMacaroon} = require('ln-service');
|
|
13
13
|
const {returnResult} = require('asyncjs-util');
|
|
14
14
|
|
|
15
|
+
const credentialRestrictions = require('./credential_restrictions');
|
|
15
16
|
const {decryptCiphertext} = require('./../encryption');
|
|
16
17
|
const {derAsPem} = require('./../encryption');
|
|
17
18
|
const getCert = require('./get_cert');
|
|
@@ -38,6 +39,7 @@ const socket = 'localhost:10009';
|
|
|
38
39
|
[is_readonly]: <Restrict Credentials To Read-Only Permissions Bool>
|
|
39
40
|
[key]: <Encrypt to Public Key DER Hex String>
|
|
40
41
|
[logger]: <Winston Logger Object>
|
|
42
|
+
[methods]: [<Allow Specific Method String>]
|
|
41
43
|
[node]: <Node Name String> // Defaults to default local mainnet node creds
|
|
42
44
|
}
|
|
43
45
|
|
|
@@ -199,8 +201,14 @@ module.exports = (args, cbk) => {
|
|
|
199
201
|
'macaroon',
|
|
200
202
|
({credentials, macaroon}, cbk) =>
|
|
201
203
|
{
|
|
204
|
+
const {allow} = credentialRestrictions({
|
|
205
|
+
is_nospend: args.is_nospend,
|
|
206
|
+
is_readonly: args.is_readonly,
|
|
207
|
+
methods: args.methods,
|
|
208
|
+
});
|
|
209
|
+
|
|
202
210
|
// Exit early when readonly credentials are not requested
|
|
203
|
-
if (!
|
|
211
|
+
if (!allow) {
|
|
204
212
|
return cbk(null, {macaroon});
|
|
205
213
|
}
|
|
206
214
|
|
|
@@ -210,9 +218,12 @@ module.exports = (args, cbk) => {
|
|
|
210
218
|
socket: credentials.socket,
|
|
211
219
|
});
|
|
212
220
|
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
221
|
+
return grantAccess({
|
|
222
|
+
lnd,
|
|
223
|
+
methods: allow.methods,
|
|
224
|
+
permissions: allow.permissions,
|
|
225
|
+
},
|
|
226
|
+
cbk);
|
|
216
227
|
}],
|
|
217
228
|
|
|
218
229
|
// Final credentials with encryption applied
|
package/package.json
CHANGED
|
@@ -35,7 +35,7 @@
|
|
|
35
35
|
"inquirer": "8.1.5",
|
|
36
36
|
"invoices": "2.0.0",
|
|
37
37
|
"ln-accounting": "5.0.3",
|
|
38
|
-
"ln-service": "52.10.
|
|
38
|
+
"ln-service": "52.10.2",
|
|
39
39
|
"ln-sync": "2.0.2",
|
|
40
40
|
"ln-telegram": "3.3.0",
|
|
41
41
|
"moment": "2.29.1",
|
|
@@ -80,5 +80,5 @@
|
|
|
80
80
|
"postpublish": "docker buildx build --platform linux/amd64,linux/arm64,linux/arm/v7 -t alexbosworth/balanceofsatoshis --push .",
|
|
81
81
|
"test": "tap --branches=1 --functions=1 --lines=1 --statements=1 -t 60 test/arrays/*.js test/balances/*.js test/chain/*.js test/display/*.js test/encryption/*.js test/fiat/*.js test/lnd/*.js test/network/*.js test/nodes/*.js test/peers/*.js test/responses/*.js test/routing/*.js test/services/*.js test/swaps/*.js test/tags/*.js test/wallets/*.js"
|
|
82
82
|
},
|
|
83
|
-
"version": "11.
|
|
83
|
+
"version": "11.3.0"
|
|
84
84
|
}
|
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
const {test} = require('@alexbosworth/tap');
|
|
2
|
+
|
|
3
|
+
const method = require('./../../lnd/credential_restrictions');
|
|
4
|
+
|
|
5
|
+
const tests = [
|
|
6
|
+
{
|
|
7
|
+
args: {},
|
|
8
|
+
description: 'No restrictions results in no allow elements',
|
|
9
|
+
expected: {},
|
|
10
|
+
},
|
|
11
|
+
{
|
|
12
|
+
args: {is_nospend: true},
|
|
13
|
+
description: 'No spend results in nospend permissions',
|
|
14
|
+
expected: {
|
|
15
|
+
allow: {
|
|
16
|
+
methods: [],
|
|
17
|
+
permissions: [
|
|
18
|
+
'address:read',
|
|
19
|
+
'address:write',
|
|
20
|
+
'info:read',
|
|
21
|
+
'info:write',
|
|
22
|
+
'invoices:read',
|
|
23
|
+
'invoices:write',
|
|
24
|
+
'macaroon:read',
|
|
25
|
+
'message:read',
|
|
26
|
+
'offchain:read',
|
|
27
|
+
'onchain:read',
|
|
28
|
+
'peers:read',
|
|
29
|
+
'peers:write',
|
|
30
|
+
'signer:read',
|
|
31
|
+
],
|
|
32
|
+
},
|
|
33
|
+
},
|
|
34
|
+
},
|
|
35
|
+
{
|
|
36
|
+
args: {is_readonly: true},
|
|
37
|
+
description: 'Readonly results in read permissions',
|
|
38
|
+
expected: {
|
|
39
|
+
allow: {
|
|
40
|
+
methods: [],
|
|
41
|
+
permissions: [
|
|
42
|
+
'address:read',
|
|
43
|
+
'info:read',
|
|
44
|
+
'invoices:read',
|
|
45
|
+
'macaroon:read',
|
|
46
|
+
'message:read',
|
|
47
|
+
'offchain:read',
|
|
48
|
+
'onchain:read',
|
|
49
|
+
'peers:read',
|
|
50
|
+
'signer:read',
|
|
51
|
+
],
|
|
52
|
+
},
|
|
53
|
+
},
|
|
54
|
+
},
|
|
55
|
+
{
|
|
56
|
+
args: {methods: ['getWalletInfo']},
|
|
57
|
+
description: 'Readonly results in read permissions',
|
|
58
|
+
expected: {allow: {methods: ['getWalletInfo'], permissions: []}},
|
|
59
|
+
},
|
|
60
|
+
];
|
|
61
|
+
|
|
62
|
+
tests.forEach(({args, description, error, expected}) => {
|
|
63
|
+
return test(description, async ({end, strictSame, throws}) => {
|
|
64
|
+
if (!!error) {
|
|
65
|
+
throws(() => method(args), new Error(error), 'Got expected error');
|
|
66
|
+
} else {
|
|
67
|
+
const res = method(args);
|
|
68
|
+
|
|
69
|
+
strictSame(res, expected, 'Got expected result');
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
return end();
|
|
73
|
+
});
|
|
74
|
+
});
|