@lamalibre/create-lamaste 4.5.0 → 4.7.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/bundle-vendor.js +20 -3
- package/scripts/lamaste-priv +56 -5
- package/scripts/pin-release.js +98 -0
- package/src/index.js +8 -1
- package/src/lib/env.js +19 -0
- package/src/lib/service-config.js +7 -0
- package/src/tasks/redeploy.js +8 -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 +6 -2
- package/vendor/docs/01-concepts/authorization.md +4 -0
- package/vendor/docs/01-concepts/certificates.md +3 -3
- package/vendor/docs/01-concepts/dns-and-domains.md +9 -0
- package/vendor/docs/01-concepts/mtls.md +2 -2
- package/vendor/docs/01-concepts/security-model.md +28 -3
- 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 +5 -5
- 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/managing-users.md +5 -11
- package/vendor/docs/02-guides/onboarding.md +2 -2
- package/vendor/docs/02-guides/second-domain.md +82 -0
- package/vendor/docs/02-guides/standalone-plugin-with-tickets.md +2 -2
- package/vendor/docs/02-guides/static-sites.md +4 -0
- package/vendor/docs/03-architecture/installer-flow.md +2 -2
- package/vendor/docs/03-architecture/installer.md +4 -4
- package/vendor/docs/03-architecture/management-flow.md +1 -1
- package/vendor/docs/03-architecture/nginx-configuration.md +80 -12
- 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 +3 -3
- package/vendor/docs/03-architecture/system-overview.md +1 -1
- package/vendor/docs/04-api-reference/agent-hosted-plugins.md +116 -37
- package/vendor/docs/04-api-reference/app-host.md +3 -3
- package/vendor/docs/04-api-reference/domains.md +192 -0
- package/vendor/docs/04-api-reference/gatekeeper.md +54 -8
- package/vendor/docs/04-api-reference/lifecycle-hooks.md +4 -4
- package/vendor/docs/04-api-reference/onboarding.md +1 -1
- package/vendor/docs/04-api-reference/overview.md +9 -0
- package/vendor/docs/04-api-reference/registry-and-oidc.md +26 -13
- package/vendor/docs/04-api-reference/sites.md +9 -0
- package/vendor/docs/04-api-reference/tunnels.md +35 -28
- package/vendor/docs/04-api-reference/users.md +41 -29
- 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 +15 -6
- package/vendor/docs/06-reference/config-files.md +19 -15
- 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 +105 -19
- package/vendor/docs/external-members-design.md +816 -0
- package/vendor/docs/gatekeeper-design.md +8 -8
- package/vendor/docs/identity-directory-design.md +3 -3
- package/vendor/docs/multi-domain-relay-design.md +836 -0
- package/vendor/docs/package.json +1 -1
- package/vendor/docs/todo/lib-cli-desktop-refactor.md +27 -27
- package/vendor/gatekeeper/dist/index.d.ts +3 -3
- package/vendor/gatekeeper/dist/index.d.ts.map +1 -1
- package/vendor/gatekeeper/dist/index.js +2 -2
- package/vendor/gatekeeper/dist/index.js.map +1 -1
- package/vendor/gatekeeper/dist/lib/authz.d.ts +9 -0
- package/vendor/gatekeeper/dist/lib/authz.d.ts.map +1 -1
- package/vendor/gatekeeper/dist/lib/authz.js +31 -0
- package/vendor/gatekeeper/dist/lib/authz.js.map +1 -1
- package/vendor/gatekeeper/dist/lib/constants.d.ts +5 -2
- package/vendor/gatekeeper/dist/lib/constants.d.ts.map +1 -1
- package/vendor/gatekeeper/dist/lib/constants.js +5 -2
- package/vendor/gatekeeper/dist/lib/constants.js.map +1 -1
- package/vendor/gatekeeper/dist/lib/grants.d.ts.map +1 -1
- package/vendor/gatekeeper/dist/lib/grants.js +20 -13
- package/vendor/gatekeeper/dist/lib/grants.js.map +1 -1
- package/vendor/gatekeeper/dist/lib/migrations/gatekeeper/0004_unconsume_access_grants.sql +8 -0
- package/vendor/gatekeeper/dist/lib/secret.d.ts +6 -0
- package/vendor/gatekeeper/dist/lib/secret.d.ts.map +1 -0
- package/vendor/gatekeeper/dist/lib/secret.js +12 -0
- package/vendor/gatekeeper/dist/lib/secret.js.map +1 -0
- package/vendor/gatekeeper/dist/lib/templates.d.ts +20 -0
- package/vendor/gatekeeper/dist/lib/templates.d.ts.map +1 -1
- package/vendor/gatekeeper/dist/lib/templates.js +80 -14
- package/vendor/gatekeeper/dist/lib/templates.js.map +1 -1
- package/vendor/gatekeeper/dist/lib/tunnels.d.ts +3 -6
- package/vendor/gatekeeper/dist/lib/tunnels.d.ts.map +1 -1
- package/vendor/gatekeeper/dist/lib/tunnels.js +4 -16
- package/vendor/gatekeeper/dist/lib/tunnels.js.map +1 -1
- package/vendor/gatekeeper/dist/lib/types.d.ts +0 -19
- package/vendor/gatekeeper/dist/lib/types.d.ts.map +1 -1
- package/vendor/gatekeeper/dist/server/index.d.ts +6 -1
- package/vendor/gatekeeper/dist/server/index.d.ts.map +1 -1
- package/vendor/gatekeeper/dist/server/index.js +56 -11
- package/vendor/gatekeeper/dist/server/index.js.map +1 -1
- package/vendor/gatekeeper/dist/server/routes/authz.d.ts.map +1 -1
- package/vendor/gatekeeper/dist/server/routes/authz.js +325 -55
- package/vendor/gatekeeper/dist/server/routes/authz.js.map +1 -1
- package/vendor/gatekeeper/dist/server/routes/diagnostic.d.ts.map +1 -1
- package/vendor/gatekeeper/dist/server/routes/diagnostic.js +5 -2
- package/vendor/gatekeeper/dist/server/routes/diagnostic.js.map +1 -1
- package/vendor/gatekeeper/package.json +2 -2
- package/vendor/server/bin/lamaste-server.js +7 -0
- package/vendor/server/package.json +2 -2
- package/vendor/server/src/commands/domains.js +214 -0
- package/vendor/server/src/commands/plugin-identity.js +2 -16
- package/vendor/server/src/commands/plugin-web-surface.js +269 -0
- package/vendor/server/src/commands/plugins.js +175 -14
- package/vendor/server/src/commands/registry-credential.js +10 -3
- package/vendor/server/src/commands/sites.js +18 -1
- package/vendor/server/src/commands/status.js +19 -0
- package/vendor/server/src/commands/tunnels.js +4 -1
- package/vendor/server/src/commands/users.js +8 -19
- package/vendor/server/src/domains.js +92 -0
- package/vendor/server/src/fail.js +21 -0
- package/vendor/server/src/oidc-client-grants.js +63 -0
- package/vendor/server/src/panel-api.js +15 -0
- package/vendor/server/src/plugin-approval.js +80 -1
- package/vendor/server/src/plugin-web-surface.js +307 -0
- package/vendor/server-ui/dist/assets/index-B8Tv_ocF.js +84 -0
- package/vendor/server-ui/dist/assets/index-Cb-ADsbB.css +1 -0
- package/vendor/server-ui/dist/index.html +2 -2
- package/vendor/serverd/package.json +2 -2
- package/vendor/serverd/src/index.js +50 -19
- package/vendor/serverd/src/lib/app-error.js +24 -0
- package/vendor/serverd/src/lib/audience.js +12 -3
- package/vendor/serverd/src/lib/authelia.js +341 -35
- package/vendor/serverd/src/lib/chisel-runtime.js +18 -6
- package/vendor/serverd/src/lib/chisel.js +10 -2
- package/vendor/serverd/src/lib/directory.js +67 -52
- package/vendor/serverd/src/lib/domains.js +1792 -0
- package/vendor/serverd/src/lib/gatekeeper-client.js +34 -7
- package/vendor/serverd/src/lib/hook-pipelines.js +8 -3
- package/vendor/serverd/src/lib/identity-sync.js +35 -0
- package/vendor/serverd/src/lib/migrations/state/0015_plugin_web_surface.sql +14 -0
- package/vendor/serverd/src/lib/migrations/state/0016_domains.sql +53 -0
- package/vendor/serverd/src/lib/migrations/state/0017_membership_kind.sql +15 -0
- package/vendor/serverd/src/lib/migrations/state/0018_domain_group_keys.sql +23 -0
- package/vendor/serverd/src/lib/nginx.js +576 -131
- package/vendor/serverd/src/lib/owned-groups.js +326 -0
- package/vendor/serverd/src/lib/plugin-domain.js +86 -0
- package/vendor/serverd/src/lib/plugin-hooks.js +40 -11
- package/vendor/serverd/src/lib/plugin-lifecycle.js +129 -5
- package/vendor/serverd/src/lib/plugin-oidc.js +144 -42
- package/vendor/serverd/src/lib/plugin-packages.js +74 -2
- package/vendor/serverd/src/lib/plugins.js +82 -9
- package/vendor/serverd/src/lib/registry-credential.js +39 -6
- package/vendor/serverd/src/lib/services.js +9 -1
- package/vendor/serverd/src/lib/state.js +29 -0
- package/vendor/serverd/src/lib/tunnel-deps.js +2 -4
- package/vendor/serverd/src/lib/user-surface.js +77 -31
- package/vendor/serverd/src/lib/users-lock.js +23 -0
- package/vendor/serverd/src/lib/vhost-reconcile.js +151 -41
- package/vendor/serverd/src/lib/web-surface.js +783 -0
- package/vendor/serverd/src/middleware/user-access-session.js +11 -4
- package/vendor/serverd/src/routes/invite.js +15 -5
- package/vendor/serverd/src/routes/management/domains.js +154 -0
- package/vendor/serverd/src/routes/management/gatekeeper-proxy.js +44 -8
- package/vendor/serverd/src/routes/management/identity.js +21 -7
- package/vendor/serverd/src/routes/management/invitations.js +33 -4
- package/vendor/serverd/src/routes/management/plugin-web-surface.js +151 -0
- package/vendor/serverd/src/routes/management/plugins.js +6 -2
- package/vendor/serverd/src/routes/management/registry-credential.js +86 -57
- package/vendor/serverd/src/routes/management/sites.js +188 -71
- package/vendor/serverd/src/routes/management/tunnels.js +37 -22
- package/vendor/serverd/src/routes/management/users.js +184 -64
- package/vendor/serverd/src/routes/management.js +4 -0
- package/vendor/serverd/src/routes/onboarding/dns.js +3 -17
- package/vendor/serverd/src/routes/onboarding/provision.js +22 -13
- package/vendor/serverd/src/routes/user-access.js +13 -1
- package/vendor/gatekeeper/dist/lib/migrations/migrations/gatekeeper/0001_groups.sql +0 -7
- package/vendor/gatekeeper/dist/lib/migrations/migrations/gatekeeper/0002_access_grants.sql +0 -14
- package/vendor/gatekeeper/dist/lib/migrations/migrations/gatekeeper/0003_access_request_log.sql +0 -9
- package/vendor/server-ui/dist/assets/index-D-fer5ef.css +0 -1
- package/vendor/server-ui/dist/assets/index-DSaDPJaw.js +0 -84
|
@@ -37,15 +37,27 @@
|
|
|
37
37
|
* tunnel or agent backend keeps Authelia's session cookie from it
|
|
38
38
|
* (`$lamaste_backend_cookie`), so an installed vhost from before that is
|
|
39
39
|
* rewritten too.
|
|
40
|
+
*
|
|
41
|
+
* From the multi-domain relay, tunnel vhosts are named by their full
|
|
42
|
+
* hostname and every domain has its own auth portal
|
|
43
|
+
* (`lamalibre-lamaste-auth-<domain>`): {@link renameLegacyVhosts} renames
|
|
44
|
+
* the ones an older version named by subdomain, in one reload, before the
|
|
45
|
+
* reconcile renders them.
|
|
40
46
|
*/
|
|
41
47
|
|
|
42
|
-
import { tunnelUserSurfaceRoutes } from '@lamalibre/lamaste';
|
|
43
|
-
import { withTunnelLock } from '@lamalibre/lamaste/server';
|
|
48
|
+
import { domainOfHost, tunnelUserSurfaceRoutes } from '@lamalibre/lamaste';
|
|
49
|
+
import { tunnelHost, vhostTunnelHost, withTunnelLock } from '@lamalibre/lamaste/server';
|
|
44
50
|
import {
|
|
51
|
+
LEGACY_AUTH_VHOST,
|
|
45
52
|
PANEL_DOMAIN_VHOST,
|
|
53
|
+
agentPanelVhostName,
|
|
54
|
+
appVhostName,
|
|
55
|
+
authVhostName,
|
|
46
56
|
installVhost,
|
|
47
57
|
isSiteEnabled,
|
|
58
|
+
legacyTunnelVhostName,
|
|
48
59
|
readInstalledVhost,
|
|
60
|
+
renameVhosts,
|
|
49
61
|
renderAgentPanelVhost,
|
|
50
62
|
renderAuthVhost,
|
|
51
63
|
renderPanelVhost,
|
|
@@ -53,13 +65,12 @@ import {
|
|
|
53
65
|
renderTunnelVhost,
|
|
54
66
|
vhostCertDir,
|
|
55
67
|
} from './nginx.js';
|
|
68
|
+
import { notifyAdminsBestEffort } from './notifications.js';
|
|
56
69
|
import { readSites, readTunnels } from './state.js';
|
|
57
70
|
|
|
58
71
|
/** A subdomain or site id as it may appear in a site name. */
|
|
59
72
|
const SITE_NAME_PART_RE = /^[A-Za-z0-9][A-Za-z0-9-]{0,62}$/;
|
|
60
73
|
|
|
61
|
-
const AUTH_VHOST = 'lamalibre-lamaste-auth';
|
|
62
|
-
|
|
63
74
|
/**
|
|
64
75
|
* Which of a tunnel's bound routes its vhost serves now — the panel's
|
|
65
76
|
* plugins and their hostings decide (`lib/user-surface.js`), loaded when
|
|
@@ -84,11 +95,10 @@ async function servedUserSurface(routes, tunnel) {
|
|
|
84
95
|
* @returns {{ name: string, fqdn: string, config: string } | null}
|
|
85
96
|
*/
|
|
86
97
|
export function expectedTunnelVhost(tunnel, certDir, userSurface = []) {
|
|
87
|
-
if (!managedTunnelVhostName(tunnel)
|
|
88
|
-
|
|
89
|
-
const domain = tunnel.fqdn.slice(tunnel.subdomain.length + 1);
|
|
98
|
+
if (!managedTunnelVhostName(tunnel)) return null;
|
|
99
|
+
const { fqdn, domain } = tunnelHost(tunnel);
|
|
90
100
|
if (tunnel.type === 'panel') {
|
|
91
|
-
return renderAgentPanelVhost(
|
|
101
|
+
return renderAgentPanelVhost(fqdn, domain, tunnel.port, certDir);
|
|
92
102
|
}
|
|
93
103
|
// As createTunnel and updateTunnel write it: the stored access mode
|
|
94
104
|
// (restricted when absent, as Gatekeeper reads it), the plugin route of a
|
|
@@ -97,21 +107,27 @@ export function expectedTunnelVhost(tunnel, certDir, userSurface = []) {
|
|
|
97
107
|
// rendered, and a bound tunnel cannot be made public).
|
|
98
108
|
const accessMode = tunnel.accessMode ?? 'restricted';
|
|
99
109
|
if (accessMode === 'public' && userSurface.length > 0) return null;
|
|
100
|
-
return renderTunnelVhost(accessMode,
|
|
110
|
+
return renderTunnelVhost(accessMode, fqdn, domain, tunnel.port, certDir, {
|
|
101
111
|
...(tunnel.type === 'plugin' && tunnel.pluginRoute ? { pathPrefix: tunnel.pluginRoute } : {}),
|
|
102
112
|
...(tunnel.maxBodySizeMb !== undefined ? { maxBodySizeMb: tunnel.maxBodySizeMb } : {}),
|
|
103
113
|
...(userSurface.length > 0 ? { userSurface } : {}),
|
|
104
114
|
});
|
|
105
115
|
}
|
|
106
116
|
|
|
107
|
-
/**
|
|
117
|
+
/**
|
|
118
|
+
* Site name of a tunnel's vhost — by its hostname — or null for a tunnel
|
|
119
|
+
* without one (internal, or whose state names no `<subdomain>.<domain>`).
|
|
120
|
+
*/
|
|
108
121
|
function managedTunnelVhostName(tunnel) {
|
|
109
|
-
if (tunnel.
|
|
110
|
-
|
|
111
|
-
|
|
122
|
+
if (typeof tunnel.subdomain !== 'string' || !SITE_NAME_PART_RE.test(tunnel.subdomain)) {
|
|
123
|
+
return null;
|
|
124
|
+
}
|
|
125
|
+
const host = vhostTunnelHost(tunnel);
|
|
126
|
+
if (host === null) return null;
|
|
127
|
+
if (tunnel.type === 'panel') return agentPanelVhostName(host.fqdn);
|
|
112
128
|
// Tunnels persisted before `type` existed are app tunnels.
|
|
113
129
|
if (tunnel.type === 'app' || tunnel.type === 'plugin' || tunnel.type === undefined) {
|
|
114
|
-
return
|
|
130
|
+
return appVhostName(host.fqdn);
|
|
115
131
|
}
|
|
116
132
|
return null;
|
|
117
133
|
}
|
|
@@ -295,44 +311,58 @@ export async function reconcileUserSurfaceVhosts(
|
|
|
295
311
|
});
|
|
296
312
|
}
|
|
297
313
|
|
|
298
|
-
const defaultSiteDeps = {
|
|
314
|
+
const defaultSiteDeps = {
|
|
315
|
+
readSites,
|
|
316
|
+
readInstalledVhost,
|
|
317
|
+
installVhost,
|
|
318
|
+
isSiteEnabled,
|
|
319
|
+
notify: notifyAdminsBestEffort,
|
|
320
|
+
};
|
|
299
321
|
|
|
300
322
|
/**
|
|
301
323
|
* Reconcile the vhosts that proxy a browser to the panel or ask Authelia
|
|
302
|
-
* directly: the panel's own (`panel.<
|
|
303
|
-
* (`auth.<domain>`) and every static site
|
|
304
|
-
*
|
|
324
|
+
* directly: the panel's own (`panel.<primary>`), every active domain's auth
|
|
325
|
+
* portal (`auth.<domain>`) and every static site but a plugin's web surface.
|
|
326
|
+
* Call it before the panel listens — then nothing can change a site
|
|
305
327
|
* meanwhile.
|
|
306
328
|
*
|
|
307
329
|
* @param {Parameters<typeof logResult>[0]} log
|
|
308
|
-
* @param {string}
|
|
330
|
+
* @param {ReadonlyArray<{ name: string, primary: boolean }>} domains the active domains
|
|
309
331
|
* @param {typeof defaultSiteDeps} [deps]
|
|
310
332
|
* @returns {Promise<ReturnType<typeof newResult>>}
|
|
311
333
|
*/
|
|
312
|
-
export async function reconcileSiteVhosts(log,
|
|
334
|
+
export async function reconcileSiteVhosts(log, domains, deps = defaultSiteDeps) {
|
|
313
335
|
const result = newResult();
|
|
336
|
+
const primary = domains.find((d) => d.primary)?.name;
|
|
314
337
|
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
338
|
+
if (primary) {
|
|
339
|
+
await reconcileOne(
|
|
340
|
+
{
|
|
341
|
+
name: PANEL_DOMAIN_VHOST,
|
|
342
|
+
label: `panel.${primary}`,
|
|
343
|
+
render: (certDir) => renderPanelVhost(primary, certDir),
|
|
344
|
+
enabled: () => deps.isSiteEnabled(PANEL_DOMAIN_VHOST),
|
|
345
|
+
},
|
|
346
|
+
result,
|
|
347
|
+
deps,
|
|
348
|
+
);
|
|
349
|
+
}
|
|
325
350
|
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
351
|
+
for (const domain of domains) {
|
|
352
|
+
const name = authVhostName(domain.name);
|
|
353
|
+
await reconcileOne(
|
|
354
|
+
{
|
|
355
|
+
name,
|
|
356
|
+
label: `auth.${domain.name}`,
|
|
357
|
+
render: (certDir) => renderAuthVhost(domain.name, certDir, { primary: domain.primary }),
|
|
358
|
+
enabled: () => deps.isSiteEnabled(name),
|
|
359
|
+
},
|
|
360
|
+
result,
|
|
361
|
+
deps,
|
|
362
|
+
);
|
|
363
|
+
}
|
|
364
|
+
|
|
365
|
+
const names = domains.map((d) => d.name);
|
|
336
366
|
|
|
337
367
|
let sites = [];
|
|
338
368
|
try {
|
|
@@ -340,14 +370,29 @@ export async function reconcileSiteVhosts(log, domain, deps = defaultSiteDeps) {
|
|
|
340
370
|
} catch (err) {
|
|
341
371
|
result.failed.push({ vhost: 'sites', error: err instanceof Error ? err.message : String(err) });
|
|
342
372
|
}
|
|
373
|
+
const closed = [];
|
|
343
374
|
for (const site of sites) {
|
|
344
375
|
if (typeof site.id !== 'string' || !SITE_NAME_PART_RE.test(site.id)) continue;
|
|
376
|
+
// A plugin's web surface is its plugin's to render (lib/web-surface.js
|
|
377
|
+
// `reconcileWebSurfaces`, once plugins and hostings can be read).
|
|
378
|
+
if (site.owner) continue;
|
|
379
|
+
|
|
345
380
|
const name = `lamalibre-lamaste-site-${site.id}`;
|
|
346
381
|
await reconcileOne(
|
|
347
382
|
{
|
|
348
383
|
name,
|
|
349
384
|
label: site.fqdn ?? site.id,
|
|
350
|
-
render: (certDir) =>
|
|
385
|
+
render: (certDir) => {
|
|
386
|
+
const rendered = renderStaticSiteVhost(
|
|
387
|
+
site,
|
|
388
|
+
certDir,
|
|
389
|
+
typeof site.fqdn === 'string' ? domainOfHost(site.fqdn, names) : null,
|
|
390
|
+
);
|
|
391
|
+
// Protected, but under none of the relay's domains (possible since
|
|
392
|
+
// 4.6): it renders closed — said once, at the end.
|
|
393
|
+
if (rendered.closed) closed.push(site.fqdn);
|
|
394
|
+
return rendered;
|
|
395
|
+
},
|
|
351
396
|
enabled: () => deps.isSiteEnabled(name),
|
|
352
397
|
// A site still waiting for its DNS or certificate has no vhost yet.
|
|
353
398
|
reportMissing: site.certIssued === true,
|
|
@@ -357,6 +402,71 @@ export async function reconcileSiteVhosts(log, domain, deps = defaultSiteDeps) {
|
|
|
357
402
|
);
|
|
358
403
|
}
|
|
359
404
|
|
|
405
|
+
if (closed.length > 0) {
|
|
406
|
+
log.warn(
|
|
407
|
+
{ sites: closed },
|
|
408
|
+
'protected static sites under none of the relay domains are closed (403)',
|
|
409
|
+
);
|
|
410
|
+
await deps.notify(
|
|
411
|
+
{
|
|
412
|
+
source: 'lamaste',
|
|
413
|
+
level: 'warning',
|
|
414
|
+
message: `Protected static sites under none of this relay's domains answer 403 to everyone: ${closed.join(', ')}. Add their domain, or turn protection off.`,
|
|
415
|
+
},
|
|
416
|
+
log,
|
|
417
|
+
);
|
|
418
|
+
}
|
|
419
|
+
result.closed = closed;
|
|
420
|
+
|
|
360
421
|
logResult(log, 'site', result);
|
|
361
422
|
return result;
|
|
362
423
|
}
|
|
424
|
+
|
|
425
|
+
const defaultRenameDeps = { readTunnels, renameVhosts };
|
|
426
|
+
|
|
427
|
+
/**
|
|
428
|
+
* Rename the vhosts an older version named by subdomain — every tunnel's
|
|
429
|
+
* (`lamalibre-lamaste-app-<subdomain>`, `-agent-panel-<subdomain>`) and the
|
|
430
|
+
* auth portal (`lamalibre-lamaste-auth`, the primary's) — to their names by
|
|
431
|
+
* hostname, in one reload ({@link renameVhosts} in nginx.js: same text, same
|
|
432
|
+
* link state; all of it undone when nginx refuses). Idempotent: a vhost
|
|
433
|
+
* already renamed, or never installed, is left alone. Before the panel
|
|
434
|
+
* listens, under the tunnel lock; a failure is logged and the old names keep
|
|
435
|
+
* serving (the next start tries again).
|
|
436
|
+
*
|
|
437
|
+
* @param {Parameters<typeof logResult>[0]} log
|
|
438
|
+
* @param {string} primary the primary domain
|
|
439
|
+
* @param {typeof defaultRenameDeps} [deps]
|
|
440
|
+
* @returns {Promise<string[]>} the names written
|
|
441
|
+
*/
|
|
442
|
+
export async function renameLegacyVhosts(log, primary, deps = defaultRenameDeps) {
|
|
443
|
+
return withTunnelLock(async () => {
|
|
444
|
+
const renames = [
|
|
445
|
+
{ from: LEGACY_AUTH_VHOST, to: authVhostName(primary), serverName: `auth.${primary}` },
|
|
446
|
+
];
|
|
447
|
+
for (const tunnel of await deps.readTunnels()) {
|
|
448
|
+
const to = managedTunnelVhostName(tunnel);
|
|
449
|
+
if (to === null) continue;
|
|
450
|
+
// Names by subdomain existed only on the primary domain, and an old
|
|
451
|
+
// file is the tunnel's only when it serves the tunnel's hostname — a
|
|
452
|
+
// same-subdomain tunnel of another domain never takes it.
|
|
453
|
+
if (tunnel.fqdn !== `${tunnel.subdomain}.${primary}`) continue;
|
|
454
|
+
renames.push({
|
|
455
|
+
from: legacyTunnelVhostName(tunnel.type, tunnel.subdomain),
|
|
456
|
+
to,
|
|
457
|
+
serverName: tunnel.fqdn,
|
|
458
|
+
});
|
|
459
|
+
}
|
|
460
|
+
try {
|
|
461
|
+
const renamed = await deps.renameVhosts(renames);
|
|
462
|
+
if (renamed.length > 0) log.info({ renamed }, 'Renamed vhosts to their hostnames');
|
|
463
|
+
return renamed;
|
|
464
|
+
} catch (err) {
|
|
465
|
+
log.error(
|
|
466
|
+
{ err: err instanceof Error ? err.message : String(err) },
|
|
467
|
+
'Renaming vhosts to their hostnames failed; the old names keep serving',
|
|
468
|
+
);
|
|
469
|
+
return [];
|
|
470
|
+
}
|
|
471
|
+
});
|
|
472
|
+
}
|