@lamalibre/create-lamaste 4.0.0 → 4.2.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/package.json +2 -2
- package/scripts/lamaste-priv +21 -2
- package/src/lib/oidc-issuer-key.js +124 -0
- package/src/lib/relay-services.js +4 -0
- package/src/lib/service-config.js +16 -0
- package/vendor/docs/00-introduction/how-it-works.md +2 -2
- package/vendor/docs/00-introduction/quickstart.md +5 -5
- package/vendor/docs/00-introduction/what-is-lamaste.md +5 -5
- package/vendor/docs/01-concepts/authentication.md +45 -1
- package/vendor/docs/01-concepts/certificates.md +3 -3
- package/vendor/docs/01-concepts/mtls.md +2 -2
- package/vendor/docs/01-concepts/security-model.md +1 -1
- package/vendor/docs/01-concepts/tickets.md +2 -2
- package/vendor/docs/01-concepts/tunneling.md +4 -4
- package/vendor/docs/02-guides/agent-setup.md +3 -3
- package/vendor/docs/02-guides/certificate-management.md +2 -2
- package/vendor/docs/02-guides/cloud-provisioning.md +3 -3
- package/vendor/docs/02-guides/desktop-app-setup.md +10 -10
- package/vendor/docs/02-guides/installation.md +3 -3
- package/vendor/docs/02-guides/onboarding.md +2 -2
- package/vendor/docs/02-guides/standalone-plugin-with-tickets.md +2 -2
- package/vendor/docs/03-architecture/installer-flow.md +2 -2
- package/vendor/docs/03-architecture/installer.md +6 -5
- package/vendor/docs/03-architecture/management-flow.md +1 -1
- package/vendor/docs/03-architecture/overview.md +5 -5
- package/vendor/docs/03-architecture/panel-client.md +6 -6
- package/vendor/docs/03-architecture/panel-server.md +2 -2
- package/vendor/docs/03-architecture/state-management.md +2 -2
- package/vendor/docs/03-architecture/system-overview.md +1 -1
- package/vendor/docs/04-api-reference/onboarding.md +1 -1
- package/vendor/docs/04-api-reference/overview.md +111 -105
- package/vendor/docs/04-api-reference/registry-and-oidc.md +207 -0
- package/vendor/docs/05-operations/backup-and-restore.md +1 -1
- package/vendor/docs/05-operations/uninstalling.md +1 -1
- package/vendor/docs/05-operations/upgrades.md +6 -5
- package/vendor/docs/06-reference/config-files.md +103 -45
- package/vendor/docs/06-reference/glossary.md +3 -3
- package/vendor/docs/06-reference/installer-flags.md +13 -13
- package/vendor/docs/06-reference/ports-and-services.md +1 -1
- package/vendor/docs/06-reference/troubleshooting.md +8 -8
- package/vendor/docs/_index.json +5 -0
- package/vendor/docs/gatekeeper-design.md +8 -8
- package/vendor/docs/identity-directory-design.md +443 -0
- package/vendor/docs/package.json +1 -1
- package/vendor/docs/todo/lib-cli-desktop-refactor.md +27 -27
- package/vendor/gatekeeper/package.json +1 -1
- package/vendor/server/bin/lamaste-server.js +10 -1
- package/vendor/server/package.json +4 -3
- package/vendor/server/src/commands/plugins.js +200 -158
- package/vendor/server/src/commands/registry-credential.js +142 -0
- package/vendor/server/src/panel-api.js +86 -39
- package/vendor/server-ui/dist/assets/{index-B0nWuUyL.js → index-B5Wp8lu-.js} +26 -26
- package/vendor/server-ui/dist/index.html +1 -1
- package/vendor/serverd/package.json +5 -2
- package/vendor/serverd/src/index.js +11 -0
- package/vendor/serverd/src/lib/authelia.js +11 -0
- package/vendor/serverd/src/lib/migrations/state/0005_plugin_hosting.sql +3 -0
- package/vendor/serverd/src/lib/plugin-oidc.js +233 -0
- package/vendor/serverd/src/lib/plugins.js +37 -5
- package/vendor/serverd/src/lib/registry-credential.js +145 -0
- package/vendor/serverd/src/routes/management/agents.js +81 -0
- package/vendor/serverd/src/routes/management/plugins.js +65 -2
- package/vendor/serverd/src/routes/management/registry-credential.js +170 -0
- package/vendor/serverd/src/routes/management/storage.js +10 -2
- package/vendor/serverd/src/routes/management/users.js +31 -0
- package/vendor/serverd/src/routes/management.js +2 -0
|
@@ -13,18 +13,95 @@ import { PKI_DIR } from './config.js';
|
|
|
13
13
|
|
|
14
14
|
const PANEL_URL = 'https://127.0.0.1:9292';
|
|
15
15
|
|
|
16
|
+
/**
|
|
17
|
+
* The curl argument vector for one panel request. Pure, exported for tests.
|
|
18
|
+
*
|
|
19
|
+
* The JSON content type and the body travel together: a `Content-Type:
|
|
20
|
+
* application/json` header on a body-less DELETE made Fastify answer 400
|
|
21
|
+
* ("Body cannot be empty when content-type is set"), so `registry-credential
|
|
22
|
+
* clear`, `tunnels delete` and `sites delete` never reached their routes.
|
|
23
|
+
*
|
|
24
|
+
* @param {{ method: string, path: string, body?: Record<string, unknown> | null, p12Path: string, configPath: string }} request
|
|
25
|
+
* @returns {string[]}
|
|
26
|
+
*/
|
|
27
|
+
export function buildPanelCurlArgs({ method, path, body = null, p12Path, configPath }) {
|
|
28
|
+
const args = [
|
|
29
|
+
'-K',
|
|
30
|
+
configPath,
|
|
31
|
+
'--cert-type',
|
|
32
|
+
'P12',
|
|
33
|
+
'--cert',
|
|
34
|
+
p12Path,
|
|
35
|
+
'-k', // Server uses self-signed cert on localhost
|
|
36
|
+
'-s', // Silent
|
|
37
|
+
'-S', // Show errors
|
|
38
|
+
'-X',
|
|
39
|
+
method,
|
|
40
|
+
'-H',
|
|
41
|
+
'Accept: application/json',
|
|
42
|
+
];
|
|
43
|
+
if (body !== null && body !== undefined) {
|
|
44
|
+
args.push('-H', 'Content-Type: application/json', '-d', JSON.stringify(body));
|
|
45
|
+
}
|
|
46
|
+
// Append the HTTP status on its own line so an error response is not
|
|
47
|
+
// mistaken for a result — the panel answers errors with a JSON body.
|
|
48
|
+
args.push('-w', '\n%{http_code}', `${PANEL_URL}${path}`);
|
|
49
|
+
return args;
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
/**
|
|
53
|
+
* Split curl's output (`<payload>\n<status>`) and turn a non-2xx status
|
|
54
|
+
* into an error carrying the panel's `error` (and `details`). Pure,
|
|
55
|
+
* exported for tests.
|
|
56
|
+
*
|
|
57
|
+
* @param {string} stdout
|
|
58
|
+
* @param {string} method
|
|
59
|
+
* @param {string} path
|
|
60
|
+
* @returns {Record<string, unknown>}
|
|
61
|
+
*/
|
|
62
|
+
export function parsePanelResponse(stdout, method, path) {
|
|
63
|
+
const split = stdout.lastIndexOf('\n');
|
|
64
|
+
const payload = stdout.slice(0, split).trim();
|
|
65
|
+
const status = Number(stdout.slice(split + 1).trim());
|
|
66
|
+
let parsed = {};
|
|
67
|
+
if (payload) {
|
|
68
|
+
try {
|
|
69
|
+
parsed = JSON.parse(payload);
|
|
70
|
+
} catch {
|
|
71
|
+
parsed = { error: payload };
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
// Anything but a 2xx is an error: 4xx/5xx from the panel, a 3xx curl did
|
|
76
|
+
// not follow, or 0 when curl reported no status at all.
|
|
77
|
+
if (!Number.isInteger(status) || status < 200 || status >= 300) {
|
|
78
|
+
const reason = [parsed.error, parsed.details].filter(Boolean).join(': ');
|
|
79
|
+
const err = new Error(
|
|
80
|
+
`${method} ${path} failed (HTTP ${status})${reason ? `: ${reason}` : ''}`,
|
|
81
|
+
);
|
|
82
|
+
err.statusCode = status;
|
|
83
|
+
throw err;
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
return parsed;
|
|
87
|
+
}
|
|
88
|
+
|
|
16
89
|
/**
|
|
17
90
|
* Make an authenticated API request to the local panel server.
|
|
18
91
|
*
|
|
19
92
|
* Uses curl with the admin client certificate (mTLS) and a temporary
|
|
20
|
-
* config file for the P12 password (never in process args).
|
|
93
|
+
* config file for the P12 password (never in process args). Resolves with
|
|
94
|
+
* the JSON body; rejects with an Error (`statusCode`, the panel's `error`
|
|
95
|
+
* in the message) for any non-2xx answer.
|
|
21
96
|
*
|
|
22
97
|
* @param {string} method
|
|
23
98
|
* @param {string} path e.g. '/api/tunnels'
|
|
24
|
-
* @param {Record<string, unknown> | null} [body]
|
|
99
|
+
* @param {Record<string, unknown> | null} [body] sent as JSON when given
|
|
100
|
+
* @param {{ timeoutMs?: number }} [options] `timeoutMs` for calls the panel
|
|
101
|
+
* needs longer to answer (a plugin install runs npm); default 30 s
|
|
25
102
|
* @returns {Promise<Record<string, unknown>>}
|
|
26
103
|
*/
|
|
27
|
-
export async function panelRequest(method, path, body = null) {
|
|
104
|
+
export async function panelRequest(method, path, body = null, { timeoutMs = 30000 } = {}) {
|
|
28
105
|
const p12Path = `${PKI_DIR}/client.p12`;
|
|
29
106
|
|
|
30
107
|
// Read p12 password from the stored file
|
|
@@ -42,43 +119,13 @@ export async function panelRequest(method, path, body = null) {
|
|
|
42
119
|
try {
|
|
43
120
|
await writeFile(tmpConfigPath, `--pass "${p12Password}"\n`, { mode: 0o600 });
|
|
44
121
|
|
|
45
|
-
const
|
|
46
|
-
'
|
|
47
|
-
tmpConfigPath,
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
'--cert',
|
|
51
|
-
p12Path,
|
|
52
|
-
'-k', // Server uses self-signed cert on localhost
|
|
53
|
-
'-s', // Silent
|
|
54
|
-
'-S', // Show errors
|
|
55
|
-
'-X',
|
|
56
|
-
method,
|
|
57
|
-
'-H',
|
|
58
|
-
'Content-Type: application/json',
|
|
59
|
-
];
|
|
60
|
-
|
|
61
|
-
if (body) {
|
|
62
|
-
curlArgs.push('-d', JSON.stringify(body));
|
|
63
|
-
}
|
|
64
|
-
|
|
65
|
-
// Append the HTTP status on its own line so an error response is not
|
|
66
|
-
// mistaken for a result — the panel answers errors with a JSON body.
|
|
67
|
-
curlArgs.push('-w', '\n%{http_code}', `${PANEL_URL}${path}`);
|
|
68
|
-
|
|
69
|
-
const { stdout } = await execa('curl', curlArgs, { timeout: 30000 });
|
|
70
|
-
|
|
71
|
-
const split = stdout.lastIndexOf('\n');
|
|
72
|
-
const payload = stdout.slice(0, split).trim();
|
|
73
|
-
const status = Number(stdout.slice(split + 1).trim());
|
|
74
|
-
const parsed = payload ? JSON.parse(payload) : {};
|
|
75
|
-
|
|
76
|
-
if (!Number.isInteger(status) || status >= 400) {
|
|
77
|
-
const reason = [parsed.error, parsed.details].filter(Boolean).join(': ');
|
|
78
|
-
throw new Error(`${method} ${path} failed (HTTP ${status})${reason ? `: ${reason}` : ''}`);
|
|
79
|
-
}
|
|
122
|
+
const { stdout } = await execa(
|
|
123
|
+
'curl',
|
|
124
|
+
buildPanelCurlArgs({ method, path, body, p12Path, configPath: tmpConfigPath }),
|
|
125
|
+
{ timeout: timeoutMs },
|
|
126
|
+
);
|
|
80
127
|
|
|
81
|
-
return
|
|
128
|
+
return parsePanelResponse(stdout, method, path);
|
|
82
129
|
} finally {
|
|
83
130
|
await unlink(tmpConfigPath).catch(() => {});
|
|
84
131
|
}
|