@n42/cli 0.2.31 → 0.2.42
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/README.md +20 -5
- package/package.json +3 -2
- package/src/auth.js +60 -5
- package/src/cli.js +38 -3
- package/src/errors.js +4 -2
package/README.md
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
# Node42 CLI
|
|
1
|
+
# Node42 CLI
|
|
2
2
|
|
|
3
3
|
Command-line interface for **eDelivery discovery, diagnostics, and
|
|
4
4
|
validation**, with support for the Peppol network.
|
|
@@ -7,7 +7,11 @@ The Node42 CLI is designed for **system integrators, service providers,
|
|
|
7
7
|
and operators** who need fast, repeatable insight into eDelivery
|
|
8
8
|
routing, SML/SMK, SMP resolution, and Access Point behavior.
|
|
9
9
|
|
|
10
|
-
|
|
10
|
+
While Node42's toolset **includes** modules capable of constructing and **sending
|
|
11
|
+
standards-compliant messages**, it is **intended for diagnostics**, validation,
|
|
12
|
+
and testing — not for production message exchange.
|
|
13
|
+
|
|
14
|
+
|
|
11
15
|
|
|
12
16
|
## Features
|
|
13
17
|
|
|
@@ -128,9 +132,15 @@ Artefacts are stored under:
|
|
|
128
132
|
|
|
129
133
|
## Error Handling
|
|
130
134
|
|
|
131
|
-
Errors are printed with a clickable reference link
|
|
135
|
+
Errors are printed with a clickable reference link.
|
|
132
136
|
|
|
133
|
-
|
|
137
|
+
Example output:
|
|
138
|
+
|
|
139
|
+
``` bash
|
|
140
|
+
Error: 9031 [View details]
|
|
141
|
+
|
|
142
|
+
Invalid token: the authorization token provided is invalid
|
|
143
|
+
```
|
|
134
144
|
|
|
135
145
|
## Security
|
|
136
146
|
|
|
@@ -139,4 +149,9 @@ Errors are printed with a clickable reference link:
|
|
|
139
149
|
|
|
140
150
|
## License
|
|
141
151
|
|
|
142
|
-
MIT License
|
|
152
|
+
MIT License
|
|
153
|
+
|
|
154
|
+
## Author
|
|
155
|
+
|
|
156
|
+
Alex Olsson \
|
|
157
|
+
Node42
|
package/package.json
CHANGED
|
@@ -1,9 +1,10 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@n42/cli",
|
|
3
|
-
"version": "0.2.
|
|
3
|
+
"version": "0.2.42",
|
|
4
4
|
"description": "Node42 CLI – Command-line interface for Peppol eDelivery path discovery, diagnostics, and tooling",
|
|
5
5
|
"keywords": [
|
|
6
|
-
"node42"
|
|
6
|
+
"node42", "peppol", "edelivery", "diagnostics",
|
|
7
|
+
"cli", "api"
|
|
7
8
|
],
|
|
8
9
|
"homepage": "https://github.com/node42-dev/node42-cli",
|
|
9
10
|
"repository": {
|
package/src/auth.js
CHANGED
|
@@ -7,11 +7,54 @@ const { ask, startSpinner } = require("./utils");
|
|
|
7
7
|
const db = require("./db");
|
|
8
8
|
const C = require("./colors");
|
|
9
9
|
|
|
10
|
+
function setApiKey(userId, key) {
|
|
11
|
+
if (!key) return;
|
|
12
|
+
|
|
13
|
+
const database = db.load();
|
|
14
|
+
|
|
15
|
+
const u = database.user.find(x => x.id === userId);
|
|
16
|
+
if (!u) return;
|
|
17
|
+
|
|
18
|
+
u.apiKey = {
|
|
19
|
+
"value": key,
|
|
20
|
+
"createdAt": Date.now()
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
db.save(database);
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
function getApiKey(userId) {
|
|
27
|
+
const database = db.load();
|
|
28
|
+
|
|
29
|
+
const u = database.user.find(x => x.id === userId);
|
|
30
|
+
if (!u || !u.apiKey) return null;
|
|
31
|
+
|
|
32
|
+
return u.apiKey.value;
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
function removeApiKey(userId) {
|
|
36
|
+
const database = db.load();
|
|
37
|
+
|
|
38
|
+
const u = database.user.find(x => x.id === userId);
|
|
39
|
+
if (!u || !u.apiKey) return false;
|
|
40
|
+
|
|
41
|
+
delete u.apiKey;
|
|
42
|
+
db.save(database);
|
|
43
|
+
|
|
44
|
+
return true;
|
|
45
|
+
}
|
|
10
46
|
|
|
11
47
|
async function login() {
|
|
12
48
|
console.log(`${C.BOLD}Sign in to your account${C.RESET}`);
|
|
13
49
|
let user = getUserWithIndex(0);
|
|
14
50
|
|
|
51
|
+
const apiKey = getApiKey(user.id);
|
|
52
|
+
if (apiKey) {
|
|
53
|
+
console.log(`\n${C.RED}API key authentication is configured.${C.RESET}`);
|
|
54
|
+
console.log(`Login is not required.\n`);
|
|
55
|
+
return;
|
|
56
|
+
}
|
|
57
|
+
|
|
15
58
|
const username = await ask("Username", user.userMail ?? "");
|
|
16
59
|
const password = await ask("Password", null, true);
|
|
17
60
|
console.log();
|
|
@@ -158,21 +201,33 @@ async function refreshSession() {
|
|
|
158
201
|
}
|
|
159
202
|
|
|
160
203
|
async function fetchWithAuth(url, options = {}) {
|
|
204
|
+
const user = getUserWithIndex(0);
|
|
205
|
+
const apiKey = user ? getApiKey(user.id) : null;
|
|
206
|
+
|
|
161
207
|
let { accessToken } = loadTokens();
|
|
162
|
-
|
|
208
|
+
|
|
209
|
+
if (!accessToken && !apiKey) {
|
|
163
210
|
handleError({ code: "N42E-9032" });
|
|
164
|
-
return;
|
|
211
|
+
return null;
|
|
212
|
+
}
|
|
213
|
+
|
|
214
|
+
if (apiKey) {
|
|
215
|
+
console.log(`${C.DIM}Authenticating with API key.${C.RESET}\n`);
|
|
165
216
|
}
|
|
166
217
|
|
|
167
218
|
const res = await fetch(url, {
|
|
168
219
|
...options,
|
|
169
220
|
headers: {
|
|
170
221
|
...(options.headers || {}),
|
|
171
|
-
...(accessToken
|
|
222
|
+
...(accessToken
|
|
223
|
+
? { Authorization: `Bearer ${accessToken}` }
|
|
224
|
+
: apiKey
|
|
225
|
+
? { "X-Api-Key": apiKey }
|
|
226
|
+
: {})
|
|
172
227
|
}
|
|
173
228
|
});
|
|
174
229
|
|
|
175
|
-
if (res.status !== 401) {
|
|
230
|
+
if (apiKey || res.status !== 401) {
|
|
176
231
|
return res;
|
|
177
232
|
}
|
|
178
233
|
|
|
@@ -191,4 +246,4 @@ async function fetchWithAuth(url, options = {}) {
|
|
|
191
246
|
});
|
|
192
247
|
}
|
|
193
248
|
|
|
194
|
-
module.exports = { login, logout, loadTokens, checkAuth, fetchWithAuth };
|
|
249
|
+
module.exports = { setApiKey, getApiKey, removeApiKey, login, logout, loadTokens, checkAuth, fetchWithAuth };
|
package/src/cli.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
|
|
3
3
|
const { Command } = require("commander");
|
|
4
|
-
const { login, logout, checkAuth } = require("./auth");
|
|
4
|
+
const { login, logout, checkAuth, setApiKey, getApiKey, removeApiKey } = require("./auth");
|
|
5
5
|
const { getUserWithIndex, getUserUsage } = require("./user");
|
|
6
6
|
const { runDiscovery } = require("./discover");
|
|
7
7
|
const { startSpinner, validateEnv, validateId, createAppDirs, capitalize, cleanAppDirs } = require("./utils");
|
|
@@ -40,6 +40,42 @@ program
|
|
|
40
40
|
console.log(`Run: ${C.BOLD}source ${dest}${C.RESET}\n`);
|
|
41
41
|
});
|
|
42
42
|
|
|
43
|
+
program
|
|
44
|
+
.command("apikey")
|
|
45
|
+
.description("Manage API key authentication")
|
|
46
|
+
.option("--set <key>", "Authenticate using an API key")
|
|
47
|
+
.option("--remove", "Remove stored API key")
|
|
48
|
+
.action((options) => {
|
|
49
|
+
const user = getUserWithIndex(0);
|
|
50
|
+
if (!user) {
|
|
51
|
+
console.error(`${C.RED}No local user context found${C.RESET}`);
|
|
52
|
+
process.exit(1);
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
console.log(`${C.BOLD}Node42 Account${C.RESET} (${user.userMail})\n`);
|
|
56
|
+
|
|
57
|
+
if (options.set) {
|
|
58
|
+
setApiKey(user.id, options.set);
|
|
59
|
+
|
|
60
|
+
if (getApiKey(user.id) === options.set) {
|
|
61
|
+
console.log(`${C.GREEN}API key authentication configured${C.RESET}\n`);
|
|
62
|
+
} else {
|
|
63
|
+
console.log(`${C.RED}API key configuration failed${C.RESET}\n`);
|
|
64
|
+
}
|
|
65
|
+
return;
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
if (options.remove) {
|
|
69
|
+
const removed = removeApiKey(user.id);
|
|
70
|
+
console.log(removed ? `${C.RED}API key removed${C.RESET}\n` : `${C.RED}No API key configured${C.RESET}\n`);
|
|
71
|
+
return;
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
// default: show status
|
|
75
|
+
const apiKey = getApiKey(user.id);
|
|
76
|
+
console.log(apiKey ? `${C.RED}API key configured${C.RESET}\n` : `${C.RED}No API key configured${C.RESET}\n`);
|
|
77
|
+
});
|
|
78
|
+
|
|
43
79
|
program
|
|
44
80
|
.command("login")
|
|
45
81
|
.description("Authenticate using username and password and store tokens locally")
|
|
@@ -78,9 +114,8 @@ program
|
|
|
78
114
|
|
|
79
115
|
const user = getUserWithIndex(0);
|
|
80
116
|
const currentMonth = new Date().toISOString().slice(0, 7);
|
|
81
|
-
console.log(`Node42 Account
|
|
117
|
+
console.log(`Node42 Account: ${C.BOLD}${user.id}${C.RESET}
|
|
82
118
|
${C.BOLD}User${C.RESET}
|
|
83
|
-
ID : ${C.CYAN}${user.id}${C.RESET}
|
|
84
119
|
Name : ${user.userName}
|
|
85
120
|
Email : ${user.userMail}
|
|
86
121
|
Role : ${user.role}
|
package/src/errors.js
CHANGED
|
@@ -15,10 +15,12 @@ function handleError(err) {
|
|
|
15
15
|
: `${WWW_URL}/errors`;
|
|
16
16
|
//console.log(url);
|
|
17
17
|
|
|
18
|
+
const link = `\u001B]8;;${url}\u0007View details\u001B]8;;\u0007`;
|
|
19
|
+
|
|
18
20
|
if (message) {
|
|
19
|
-
console.error(`\r${C.
|
|
21
|
+
console.error(`\r${C.BOLD}Error: ${code}${C.RESET} ${C.BLUE}[${link}]${C.RESET}\n\n${C.RED}${err.message}${C.RESET}\n`);
|
|
20
22
|
} else {
|
|
21
|
-
console.error(`\
|
|
23
|
+
console.error(`\r${C.BOLD}Error: ${code}${C.RESET} ${C.BLUE}[${url}]${C.RESET}\n\nFor details, see the documentation.\n`);
|
|
22
24
|
}
|
|
23
25
|
}
|
|
24
26
|
|