@lamalibre/create-lamaste 4.0.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/LICENSE.md +118 -0
- package/README.md +114 -0
- package/bin/create-lamaste.js +15 -0
- package/package.json +54 -0
- package/scripts/bundle-vendor.js +110 -0
- package/scripts/lamaste-cert-info +62 -0
- package/scripts/lamaste-certbot +96 -0
- package/scripts/lamaste-priv +693 -0
- package/src/index.js +646 -0
- package/src/lib/accounts.js +86 -0
- package/src/lib/binaries.js +137 -0
- package/src/lib/cert-help-page.js +160 -0
- package/src/lib/env.js +132 -0
- package/src/lib/http-redirect.js +38 -0
- package/src/lib/ownership.js +231 -0
- package/src/lib/relay-services.js +103 -0
- package/src/lib/secrets.js +19 -0
- package/src/lib/service-config.js +311 -0
- package/src/lib/summary.js +131 -0
- package/src/lib/wrappers.js +63 -0
- package/src/tasks/gatekeeper.js +233 -0
- package/src/tasks/harden.js +293 -0
- package/src/tasks/mtls.js +193 -0
- package/src/tasks/nginx.js +265 -0
- package/src/tasks/node.js +110 -0
- package/src/tasks/panel.js +408 -0
- package/src/tasks/redeploy.js +438 -0
- package/vendor/docs/00-introduction/how-it-works.md +447 -0
- package/vendor/docs/00-introduction/quickstart.md +472 -0
- package/vendor/docs/00-introduction/what-is-lamaste.md +112 -0
- package/vendor/docs/01-concepts/authentication.md +464 -0
- package/vendor/docs/01-concepts/authorization.md +242 -0
- package/vendor/docs/01-concepts/certificates.md +452 -0
- package/vendor/docs/01-concepts/dns-and-domains.md +343 -0
- package/vendor/docs/01-concepts/mtls.md +490 -0
- package/vendor/docs/01-concepts/nginx-reverse-proxy.md +540 -0
- package/vendor/docs/01-concepts/security-model.md +600 -0
- package/vendor/docs/01-concepts/tickets.md +414 -0
- package/vendor/docs/01-concepts/tunneling.md +367 -0
- package/vendor/docs/02-guides/agent-setup.md +194 -0
- package/vendor/docs/02-guides/certificate-management.md +341 -0
- package/vendor/docs/02-guides/cloud-provisioning.md +406 -0
- package/vendor/docs/02-guides/desktop-app-setup.md +226 -0
- package/vendor/docs/02-guides/disaster-recovery.md +464 -0
- package/vendor/docs/02-guides/first-tunnel.md +230 -0
- package/vendor/docs/02-guides/installation.md +393 -0
- package/vendor/docs/02-guides/managing-users.md +255 -0
- package/vendor/docs/02-guides/onboarding.md +244 -0
- package/vendor/docs/02-guides/standalone-plugin-with-tickets.md +375 -0
- package/vendor/docs/02-guides/static-sites.md +364 -0
- package/vendor/docs/03-architecture/e2e-three-vm-sequences.md +457 -0
- package/vendor/docs/03-architecture/installer-flow.md +151 -0
- package/vendor/docs/03-architecture/installer.md +445 -0
- package/vendor/docs/03-architecture/management-flow.md +288 -0
- package/vendor/docs/03-architecture/nginx-configuration.md +830 -0
- package/vendor/docs/03-architecture/onboarding-flow.md +164 -0
- package/vendor/docs/03-architecture/overview.md +541 -0
- package/vendor/docs/03-architecture/panel-client.md +416 -0
- package/vendor/docs/03-architecture/panel-server.md +695 -0
- package/vendor/docs/03-architecture/state-management.md +529 -0
- package/vendor/docs/03-architecture/system-overview.md +167 -0
- package/vendor/docs/04-api-reference/certificates.md +1141 -0
- package/vendor/docs/04-api-reference/gatekeeper.md +592 -0
- package/vendor/docs/04-api-reference/onboarding.md +473 -0
- package/vendor/docs/04-api-reference/overview.md +404 -0
- package/vendor/docs/04-api-reference/services.md +267 -0
- package/vendor/docs/04-api-reference/settings.md +343 -0
- package/vendor/docs/04-api-reference/sites.md +716 -0
- package/vendor/docs/04-api-reference/system.md +268 -0
- package/vendor/docs/04-api-reference/tickets.md +618 -0
- package/vendor/docs/04-api-reference/tunnels.md +417 -0
- package/vendor/docs/04-api-reference/users.md +333 -0
- package/vendor/docs/05-operations/backup-and-restore.md +342 -0
- package/vendor/docs/05-operations/monitoring.md +285 -0
- package/vendor/docs/05-operations/uninstalling.md +344 -0
- package/vendor/docs/05-operations/upgrades.md +270 -0
- package/vendor/docs/06-reference/config-files.md +1080 -0
- package/vendor/docs/06-reference/glossary.md +528 -0
- package/vendor/docs/06-reference/installer-flags.md +260 -0
- package/vendor/docs/06-reference/ports-and-services.md +244 -0
- package/vendor/docs/06-reference/troubleshooting.md +665 -0
- package/vendor/docs/_index.json +233 -0
- package/vendor/docs/gatekeeper-design.md +953 -0
- package/vendor/docs/package.json +15 -0
- package/vendor/docs/todo/lib-cli-desktop-refactor.md +641 -0
- package/vendor/gatekeeper/dist/boot.d.ts +1 -0
- package/vendor/gatekeeper/dist/boot.d.ts.map +1 -0
- package/vendor/gatekeeper/dist/boot.js +17 -0
- package/vendor/gatekeeper/dist/boot.js.map +1 -0
- package/vendor/gatekeeper/dist/cli/commands/access.d.ts +2 -0
- package/vendor/gatekeeper/dist/cli/commands/access.d.ts.map +1 -0
- package/vendor/gatekeeper/dist/cli/commands/access.js +33 -0
- package/vendor/gatekeeper/dist/cli/commands/access.js.map +1 -0
- package/vendor/gatekeeper/dist/cli/commands/grants.d.ts +2 -0
- package/vendor/gatekeeper/dist/cli/commands/grants.d.ts.map +1 -0
- package/vendor/gatekeeper/dist/cli/commands/grants.js +110 -0
- package/vendor/gatekeeper/dist/cli/commands/grants.js.map +1 -0
- package/vendor/gatekeeper/dist/cli/commands/groups.d.ts +2 -0
- package/vendor/gatekeeper/dist/cli/commands/groups.d.ts.map +1 -0
- package/vendor/gatekeeper/dist/cli/commands/groups.js +98 -0
- package/vendor/gatekeeper/dist/cli/commands/groups.js.map +1 -0
- package/vendor/gatekeeper/dist/cli/index.d.ts +3 -0
- package/vendor/gatekeeper/dist/cli/index.d.ts.map +1 -0
- package/vendor/gatekeeper/dist/cli/index.js +45 -0
- package/vendor/gatekeeper/dist/cli/index.js.map +1 -0
- package/vendor/gatekeeper/dist/index.d.ts +9 -0
- package/vendor/gatekeeper/dist/index.d.ts.map +1 -0
- package/vendor/gatekeeper/dist/index.js +13 -0
- package/vendor/gatekeeper/dist/index.js.map +1 -0
- package/vendor/gatekeeper/dist/lib/authz.d.ts +16 -0
- package/vendor/gatekeeper/dist/lib/authz.d.ts.map +1 -0
- package/vendor/gatekeeper/dist/lib/authz.js +42 -0
- package/vendor/gatekeeper/dist/lib/authz.js.map +1 -0
- package/vendor/gatekeeper/dist/lib/cache-bust.d.ts +15 -0
- package/vendor/gatekeeper/dist/lib/cache-bust.d.ts.map +1 -0
- package/vendor/gatekeeper/dist/lib/cache-bust.js +19 -0
- package/vendor/gatekeeper/dist/lib/cache-bust.js.map +1 -0
- package/vendor/gatekeeper/dist/lib/constants.d.ts +82 -0
- package/vendor/gatekeeper/dist/lib/constants.d.ts.map +1 -0
- package/vendor/gatekeeper/dist/lib/constants.js +79 -0
- package/vendor/gatekeeper/dist/lib/constants.js.map +1 -0
- package/vendor/gatekeeper/dist/lib/grants.d.ts +32 -0
- package/vendor/gatekeeper/dist/lib/grants.d.ts.map +1 -0
- package/vendor/gatekeeper/dist/lib/grants.js +314 -0
- package/vendor/gatekeeper/dist/lib/grants.js.map +1 -0
- package/vendor/gatekeeper/dist/lib/groups.d.ts +10 -0
- package/vendor/gatekeeper/dist/lib/groups.d.ts.map +1 -0
- package/vendor/gatekeeper/dist/lib/groups.js +247 -0
- package/vendor/gatekeeper/dist/lib/groups.js.map +1 -0
- package/vendor/gatekeeper/dist/lib/migration.d.ts +17 -0
- package/vendor/gatekeeper/dist/lib/migration.d.ts.map +1 -0
- package/vendor/gatekeeper/dist/lib/migration.js +79 -0
- package/vendor/gatekeeper/dist/lib/migration.js.map +1 -0
- package/vendor/gatekeeper/dist/lib/migrations/gatekeeper/0001_groups.sql +7 -0
- package/vendor/gatekeeper/dist/lib/migrations/gatekeeper/0002_access_grants.sql +14 -0
- package/vendor/gatekeeper/dist/lib/migrations/gatekeeper/0003_access_request_log.sql +9 -0
- package/vendor/gatekeeper/dist/lib/migrations/migrations/gatekeeper/0001_groups.sql +7 -0
- package/vendor/gatekeeper/dist/lib/migrations/migrations/gatekeeper/0002_access_grants.sql +14 -0
- package/vendor/gatekeeper/dist/lib/migrations/migrations/gatekeeper/0003_access_request_log.sql +9 -0
- package/vendor/gatekeeper/dist/lib/state-db.d.ts +16 -0
- package/vendor/gatekeeper/dist/lib/state-db.d.ts.map +1 -0
- package/vendor/gatekeeper/dist/lib/state-db.js +154 -0
- package/vendor/gatekeeper/dist/lib/state-db.js.map +1 -0
- package/vendor/gatekeeper/dist/lib/templates.d.ts +21 -0
- package/vendor/gatekeeper/dist/lib/templates.d.ts.map +1 -0
- package/vendor/gatekeeper/dist/lib/templates.js +151 -0
- package/vendor/gatekeeper/dist/lib/templates.js.map +1 -0
- package/vendor/gatekeeper/dist/lib/types.d.ts +178 -0
- package/vendor/gatekeeper/dist/lib/types.d.ts.map +1 -0
- package/vendor/gatekeeper/dist/lib/types.js +2 -0
- package/vendor/gatekeeper/dist/lib/types.js.map +1 -0
- package/vendor/gatekeeper/dist/server/index.d.ts +15 -0
- package/vendor/gatekeeper/dist/server/index.d.ts.map +1 -0
- package/vendor/gatekeeper/dist/server/index.js +251 -0
- package/vendor/gatekeeper/dist/server/index.js.map +1 -0
- package/vendor/gatekeeper/dist/server/routes/access-request.d.ts +7 -0
- package/vendor/gatekeeper/dist/server/routes/access-request.d.ts.map +1 -0
- package/vendor/gatekeeper/dist/server/routes/access-request.js +17 -0
- package/vendor/gatekeeper/dist/server/routes/access-request.js.map +1 -0
- package/vendor/gatekeeper/dist/server/routes/authz.d.ts +3 -0
- package/vendor/gatekeeper/dist/server/routes/authz.d.ts.map +1 -0
- package/vendor/gatekeeper/dist/server/routes/authz.js +279 -0
- package/vendor/gatekeeper/dist/server/routes/authz.js.map +1 -0
- package/vendor/gatekeeper/dist/server/routes/diagnostic.d.ts +13 -0
- package/vendor/gatekeeper/dist/server/routes/diagnostic.d.ts.map +1 -0
- package/vendor/gatekeeper/dist/server/routes/diagnostic.js +249 -0
- package/vendor/gatekeeper/dist/server/routes/diagnostic.js.map +1 -0
- package/vendor/gatekeeper/dist/server/routes/grants.d.ts +3 -0
- package/vendor/gatekeeper/dist/server/routes/grants.d.ts.map +1 -0
- package/vendor/gatekeeper/dist/server/routes/grants.js +112 -0
- package/vendor/gatekeeper/dist/server/routes/grants.js.map +1 -0
- package/vendor/gatekeeper/dist/server/routes/groups.d.ts +3 -0
- package/vendor/gatekeeper/dist/server/routes/groups.d.ts.map +1 -0
- package/vendor/gatekeeper/dist/server/routes/groups.js +139 -0
- package/vendor/gatekeeper/dist/server/routes/groups.js.map +1 -0
- package/vendor/gatekeeper/package.json +49 -0
- package/vendor/server/bin/lamaste-server.js +204 -0
- package/vendor/server/package.json +31 -0
- package/vendor/server/src/commands/certs.js +224 -0
- package/vendor/server/src/commands/chisel.js +132 -0
- package/vendor/server/src/commands/logs.js +49 -0
- package/vendor/server/src/commands/plugins.js +321 -0
- package/vendor/server/src/commands/reset-admin.js +478 -0
- package/vendor/server/src/commands/restart.js +94 -0
- package/vendor/server/src/commands/sites.js +257 -0
- package/vendor/server/src/commands/status.js +158 -0
- package/vendor/server/src/commands/tunnels.js +365 -0
- package/vendor/server/src/commands/uninstall.js +326 -0
- package/vendor/server/src/config.js +38 -0
- package/vendor/server/src/exec.js +26 -0
- package/vendor/server/src/logger.js +39 -0
- package/vendor/server/src/ndjson.js +56 -0
- package/vendor/server/src/panel-api.js +85 -0
- package/vendor/server/src/state.js +45 -0
- package/vendor/server-ui/dist/assets/index-B0nWuUyL.js +257 -0
- package/vendor/server-ui/dist/assets/index-BqWWFlTU.css +1 -0
- package/vendor/server-ui/dist/index.html +13 -0
- package/vendor/serverd/package.json +44 -0
- package/vendor/serverd/src/boot.js +13 -0
- package/vendor/serverd/src/index.js +191 -0
- package/vendor/serverd/src/lib/app-error.js +14 -0
- package/vendor/serverd/src/lib/authelia.js +85 -0
- package/vendor/serverd/src/lib/certbot.js +74 -0
- package/vendor/serverd/src/lib/chisel-args.js +6 -0
- package/vendor/serverd/src/lib/chisel-reconcile.js +232 -0
- package/vendor/serverd/src/lib/chisel-runtime.js +46 -0
- package/vendor/serverd/src/lib/chisel-users.js +109 -0
- package/vendor/serverd/src/lib/chisel.js +81 -0
- package/vendor/serverd/src/lib/config.js +190 -0
- package/vendor/serverd/src/lib/constants.js +8 -0
- package/vendor/serverd/src/lib/csr-signing.js +331 -0
- package/vendor/serverd/src/lib/enrollment.js +302 -0
- package/vendor/serverd/src/lib/files.js +19 -0
- package/vendor/serverd/src/lib/gatekeeper-client.js +135 -0
- package/vendor/serverd/src/lib/invite-page.js +281 -0
- package/vendor/serverd/src/lib/ip-utils.js +79 -0
- package/vendor/serverd/src/lib/migrations/state/0001_enrollment_tokens.sql +17 -0
- package/vendor/serverd/src/lib/migrations/state/0002_tickets.sql +70 -0
- package/vendor/serverd/src/lib/migrations/state/0003_plugins.sql +15 -0
- package/vendor/serverd/src/lib/migrations/state/0004_agents.sql +19 -0
- package/vendor/serverd/src/lib/mtls.js +795 -0
- package/vendor/serverd/src/lib/nginx.js +1090 -0
- package/vendor/serverd/src/lib/pki-paths.js +41 -0
- package/vendor/serverd/src/lib/pki-sign.js +103 -0
- package/vendor/serverd/src/lib/plugins.js +538 -0
- package/vendor/serverd/src/lib/push-install.js +390 -0
- package/vendor/serverd/src/lib/revocation.js +112 -0
- package/vendor/serverd/src/lib/services.js +131 -0
- package/vendor/serverd/src/lib/session.js +151 -0
- package/vendor/serverd/src/lib/state-db.js +130 -0
- package/vendor/serverd/src/lib/state.js +140 -0
- package/vendor/serverd/src/lib/storage.js +63 -0
- package/vendor/serverd/src/lib/system-stats.js +58 -0
- package/vendor/serverd/src/lib/tickets.js +1556 -0
- package/vendor/serverd/src/lib/totp.js +76 -0
- package/vendor/serverd/src/lib/tunnel-deps.js +41 -0
- package/vendor/serverd/src/lib/user-access-session.js +142 -0
- package/vendor/serverd/src/lib/user-access.js +52 -0
- package/vendor/serverd/src/middleware/errors.js +63 -0
- package/vendor/serverd/src/middleware/mtls.js +120 -0
- package/vendor/serverd/src/middleware/onboarding-guard.js +30 -0
- package/vendor/serverd/src/middleware/role-guard.js +58 -0
- package/vendor/serverd/src/middleware/twofa-session.js +65 -0
- package/vendor/serverd/src/middleware/user-access-session.js +52 -0
- package/vendor/serverd/src/routes/enrollment.js +120 -0
- package/vendor/serverd/src/routes/health.js +22 -0
- package/vendor/serverd/src/routes/invite.js +163 -0
- package/vendor/serverd/src/routes/management/agents.js +182 -0
- package/vendor/serverd/src/routes/management/certs.js +911 -0
- package/vendor/serverd/src/routes/management/gatekeeper-proxy.js +160 -0
- package/vendor/serverd/src/routes/management/identity.js +107 -0
- package/vendor/serverd/src/routes/management/invitations.js +166 -0
- package/vendor/serverd/src/routes/management/logs.js +218 -0
- package/vendor/serverd/src/routes/management/plugins.js +560 -0
- package/vendor/serverd/src/routes/management/services.js +63 -0
- package/vendor/serverd/src/routes/management/settings.js +325 -0
- package/vendor/serverd/src/routes/management/sites.js +522 -0
- package/vendor/serverd/src/routes/management/storage.js +192 -0
- package/vendor/serverd/src/routes/management/system.js +201 -0
- package/vendor/serverd/src/routes/management/tickets.js +457 -0
- package/vendor/serverd/src/routes/management/tunnels.js +709 -0
- package/vendor/serverd/src/routes/management/users.js +377 -0
- package/vendor/serverd/src/routes/management.js +36 -0
- package/vendor/serverd/src/routes/onboarding/dns.js +101 -0
- package/vendor/serverd/src/routes/onboarding/domain.js +42 -0
- package/vendor/serverd/src/routes/onboarding/index.js +18 -0
- package/vendor/serverd/src/routes/onboarding/provision.js +327 -0
- package/vendor/serverd/src/routes/onboarding/status.js +12 -0
- package/vendor/serverd/src/routes/plugin-router.js +79 -0
- package/vendor/serverd/src/routes/user-access.js +389 -0
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Server configuration helpers.
|
|
3
|
+
*
|
|
4
|
+
* Reads panel.json and provides common paths used by all commands.
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
import { readFile } from 'node:fs/promises';
|
|
8
|
+
|
|
9
|
+
/** Default paths used on the server. */
|
|
10
|
+
export const CONFIG_PATH =
|
|
11
|
+
process.env.LAMALIBRE_LAMASTE_CONFIG || '/etc/lamalibre/lamaste/panel.json';
|
|
12
|
+
export const STATE_DIR = process.env.LAMALIBRE_LAMASTE_DATA_DIR || '/etc/lamalibre/lamaste';
|
|
13
|
+
export const PKI_DIR = process.env.LAMALIBRE_LAMASTE_PKI_DIR || '/etc/lamalibre/lamaste/pki';
|
|
14
|
+
|
|
15
|
+
/** Systemd service names. */
|
|
16
|
+
export const PANEL_SERVICE = 'lamalibre-lamaste-serverd';
|
|
17
|
+
export const GATEKEEPER_SERVICE = 'lamalibre-lamaste-gatekeeper';
|
|
18
|
+
|
|
19
|
+
/**
|
|
20
|
+
* Read and parse panel.json.
|
|
21
|
+
* @returns {Promise<Record<string, unknown>>}
|
|
22
|
+
*/
|
|
23
|
+
export async function readConfig() {
|
|
24
|
+
const raw = await readFile(CONFIG_PATH, 'utf-8');
|
|
25
|
+
return JSON.parse(raw);
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
/**
|
|
29
|
+
* Read panel.json, returning null on error instead of throwing.
|
|
30
|
+
* @returns {Promise<Record<string, unknown> | null>}
|
|
31
|
+
*/
|
|
32
|
+
export async function readConfigSafe() {
|
|
33
|
+
try {
|
|
34
|
+
return await readConfig();
|
|
35
|
+
} catch {
|
|
36
|
+
return null;
|
|
37
|
+
}
|
|
38
|
+
}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Shared exec helper that wraps execa for use by core library functions.
|
|
3
|
+
*
|
|
4
|
+
* The core library (@lamalibre/lamaste/server) accepts an ExecFn dependency.
|
|
5
|
+
* This module provides the concrete implementation backed by execa.
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
import { execa } from 'execa';
|
|
9
|
+
|
|
10
|
+
/**
|
|
11
|
+
* Execute a command with array arguments via execa.
|
|
12
|
+
* Conforms to the ExecFn interface expected by @lamalibre/lamaste/server.
|
|
13
|
+
*
|
|
14
|
+
* @param {string} file
|
|
15
|
+
* @param {string[]} args
|
|
16
|
+
* @param {{ cwd?: string, timeout?: number, input?: string }} [options]
|
|
17
|
+
* @returns {Promise<{ stdout: string, stderr: string }>}
|
|
18
|
+
*/
|
|
19
|
+
export async function exec(file, args, options) {
|
|
20
|
+
const result = await execa(file, args, {
|
|
21
|
+
cwd: options?.cwd,
|
|
22
|
+
timeout: options?.timeout,
|
|
23
|
+
input: options?.input,
|
|
24
|
+
});
|
|
25
|
+
return { stdout: result.stdout, stderr: result.stderr };
|
|
26
|
+
}
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* CLI logger that satisfies the PluginLogger / TunnelLogger / SiteLogger
|
|
3
|
+
* interfaces expected by @lamalibre/lamaste/server.
|
|
4
|
+
*
|
|
5
|
+
* In normal mode, logs are written to stderr with chalk formatting.
|
|
6
|
+
* In --json mode, logs are suppressed (output goes through ndjson.js).
|
|
7
|
+
*/
|
|
8
|
+
|
|
9
|
+
import chalk from 'chalk';
|
|
10
|
+
|
|
11
|
+
/**
|
|
12
|
+
* Create a logger for CLI command use.
|
|
13
|
+
* @param {{ json: boolean }} options
|
|
14
|
+
* @returns {{ info: Function, warn: Function, error: Function }}
|
|
15
|
+
*/
|
|
16
|
+
export function createLogger({ json }) {
|
|
17
|
+
if (json) {
|
|
18
|
+
return {
|
|
19
|
+
info() {},
|
|
20
|
+
warn() {},
|
|
21
|
+
error() {},
|
|
22
|
+
};
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
return {
|
|
26
|
+
/** @param {Record<string, unknown>} _obj @param {string} [msg] */
|
|
27
|
+
info(_obj, msg) {
|
|
28
|
+
if (msg) process.stderr.write(` ${chalk.dim(msg)}\n`);
|
|
29
|
+
},
|
|
30
|
+
/** @param {Record<string, unknown>} _obj @param {string} [msg] */
|
|
31
|
+
warn(_obj, msg) {
|
|
32
|
+
if (msg) process.stderr.write(` ${chalk.yellow('warn:')} ${msg}\n`);
|
|
33
|
+
},
|
|
34
|
+
/** @param {Record<string, unknown>} _obj @param {string} [msg] */
|
|
35
|
+
error(_obj, msg) {
|
|
36
|
+
if (msg) process.stderr.write(` ${chalk.red('error:')} ${msg}\n`);
|
|
37
|
+
},
|
|
38
|
+
};
|
|
39
|
+
}
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* NDJSON output helper for --json mode.
|
|
3
|
+
*
|
|
4
|
+
* When --json is enabled, all output goes through this module as
|
|
5
|
+
* newline-delimited JSON on stdout. This is consumed by the desktop
|
|
6
|
+
* app (Tauri) and automation scripts.
|
|
7
|
+
*/
|
|
8
|
+
|
|
9
|
+
/**
|
|
10
|
+
* Write a single NDJSON event line to stdout.
|
|
11
|
+
* @param {Record<string, unknown>} event
|
|
12
|
+
*/
|
|
13
|
+
export function emit(event) {
|
|
14
|
+
process.stdout.write(JSON.stringify(event) + '\n');
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
/**
|
|
18
|
+
* Emit a step progress event.
|
|
19
|
+
* @param {string} step
|
|
20
|
+
* @param {'running' | 'complete' | 'skipped' | 'failed'} status
|
|
21
|
+
* @param {string} [detail]
|
|
22
|
+
*/
|
|
23
|
+
export function emitStep(step, status, detail) {
|
|
24
|
+
/** @type {Record<string, unknown>} */
|
|
25
|
+
const event = { event: 'step', step, status };
|
|
26
|
+
if (detail) event.detail = detail;
|
|
27
|
+
emit(event);
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
/**
|
|
31
|
+
* Emit an error event.
|
|
32
|
+
* @param {string} message
|
|
33
|
+
* @param {boolean} [recoverable]
|
|
34
|
+
*/
|
|
35
|
+
export function emitError(message, recoverable = false) {
|
|
36
|
+
emit({ event: 'error', message, recoverable });
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
/**
|
|
40
|
+
* Emit a completion event with result data.
|
|
41
|
+
* @param {Record<string, unknown>} data
|
|
42
|
+
*/
|
|
43
|
+
export function emitComplete(data) {
|
|
44
|
+
emit({ event: 'complete', ...data });
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
/**
|
|
48
|
+
* Emit a log event — non-step progress messages that consumers (desktop app,
|
|
49
|
+
* automation) can surface alongside step progress.
|
|
50
|
+
* @param {'debug' | 'info' | 'warn' | 'error'} level
|
|
51
|
+
* @param {string} message
|
|
52
|
+
* @param {Record<string, unknown>} [data]
|
|
53
|
+
*/
|
|
54
|
+
export function emitLog(level, message, data) {
|
|
55
|
+
emit({ event: 'log', level, message, ...(data ? { data } : {}) });
|
|
56
|
+
}
|
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Panel REST API client for localhost calls.
|
|
3
|
+
*
|
|
4
|
+
* Used by tunnel/site commands that need the full dependency stack
|
|
5
|
+
* (nginx, certbot, chisel) which lives in the running panel server.
|
|
6
|
+
* Authenticates via the admin mTLS client certificate.
|
|
7
|
+
*/
|
|
8
|
+
|
|
9
|
+
import { readFile, writeFile, unlink } from 'node:fs/promises';
|
|
10
|
+
import crypto from 'node:crypto';
|
|
11
|
+
import { execa } from 'execa';
|
|
12
|
+
import { PKI_DIR } from './config.js';
|
|
13
|
+
|
|
14
|
+
const PANEL_URL = 'https://127.0.0.1:9292';
|
|
15
|
+
|
|
16
|
+
/**
|
|
17
|
+
* Make an authenticated API request to the local panel server.
|
|
18
|
+
*
|
|
19
|
+
* Uses curl with the admin client certificate (mTLS) and a temporary
|
|
20
|
+
* config file for the P12 password (never in process args).
|
|
21
|
+
*
|
|
22
|
+
* @param {string} method
|
|
23
|
+
* @param {string} path e.g. '/api/tunnels'
|
|
24
|
+
* @param {Record<string, unknown> | null} [body]
|
|
25
|
+
* @returns {Promise<Record<string, unknown>>}
|
|
26
|
+
*/
|
|
27
|
+
export async function panelRequest(method, path, body = null) {
|
|
28
|
+
const p12Path = `${PKI_DIR}/client.p12`;
|
|
29
|
+
|
|
30
|
+
// Read p12 password from the stored file
|
|
31
|
+
let p12Password;
|
|
32
|
+
try {
|
|
33
|
+
p12Password = (await readFile(`${PKI_DIR}/.p12-password`, 'utf-8')).trim();
|
|
34
|
+
} catch {
|
|
35
|
+
throw new Error(
|
|
36
|
+
'Cannot read P12 password. Ensure the server is properly installed and /etc/lamalibre/lamaste/pki/.p12-password exists.',
|
|
37
|
+
);
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
// Write password to a temporary config file (never in process args)
|
|
41
|
+
const tmpConfigPath = `/tmp/lamalibre-lamaste-curl-${crypto.randomBytes(8).toString('hex')}`;
|
|
42
|
+
try {
|
|
43
|
+
await writeFile(tmpConfigPath, `--pass "${p12Password}"\n`, { mode: 0o600 });
|
|
44
|
+
|
|
45
|
+
const curlArgs = [
|
|
46
|
+
'-K',
|
|
47
|
+
tmpConfigPath,
|
|
48
|
+
'--cert-type',
|
|
49
|
+
'P12',
|
|
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
|
+
}
|
|
80
|
+
|
|
81
|
+
return parsed;
|
|
82
|
+
} finally {
|
|
83
|
+
await unlink(tmpConfigPath).catch(() => {});
|
|
84
|
+
}
|
|
85
|
+
}
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Direct state file readers for server CLI.
|
|
3
|
+
*
|
|
4
|
+
* Used by list/read commands that only need to read the JSON state files.
|
|
5
|
+
* Mutation commands use the panel REST API instead, since mutations require
|
|
6
|
+
* the full dependency stack (nginx, certbot, chisel).
|
|
7
|
+
*/
|
|
8
|
+
|
|
9
|
+
import { readFile } from 'node:fs/promises';
|
|
10
|
+
import path from 'node:path';
|
|
11
|
+
import { STATE_DIR } from './config.js';
|
|
12
|
+
|
|
13
|
+
/**
|
|
14
|
+
* Read and parse a JSON state file, returning a default value on ENOENT.
|
|
15
|
+
* @param {string} filename
|
|
16
|
+
* @param {unknown} defaultValue
|
|
17
|
+
* @returns {Promise<unknown>}
|
|
18
|
+
*/
|
|
19
|
+
async function readStateFile(filename, defaultValue) {
|
|
20
|
+
try {
|
|
21
|
+
const raw = await readFile(path.join(STATE_DIR, filename), 'utf-8');
|
|
22
|
+
return JSON.parse(raw);
|
|
23
|
+
} catch (err) {
|
|
24
|
+
if (err.code === 'ENOENT') return defaultValue;
|
|
25
|
+
throw new Error(`Failed to read ${filename}: ${err.message}`);
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
/**
|
|
30
|
+
* Read the tunnels array from tunnels.json.
|
|
31
|
+
* @returns {Promise<Array<Record<string, unknown>>>}
|
|
32
|
+
*/
|
|
33
|
+
export async function readTunnels() {
|
|
34
|
+
const data = await readStateFile('tunnels.json', []);
|
|
35
|
+
return Array.isArray(data) ? data : [];
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
/**
|
|
39
|
+
* Read the sites array from sites.json.
|
|
40
|
+
* @returns {Promise<Array<Record<string, unknown>>>}
|
|
41
|
+
*/
|
|
42
|
+
export async function readSites() {
|
|
43
|
+
const data = await readStateFile('sites.json', []);
|
|
44
|
+
return Array.isArray(data) ? data : [];
|
|
45
|
+
}
|