@lamalibre/create-lamaste 4.4.1 → 4.5.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 +200 -16
- package/src/index.js +1 -0
- package/src/lib/backend-cookie.js +65 -0
- package/src/lib/ip-panel-vhost.js +208 -0
- package/src/lib/service-config.js +5 -3
- package/src/tasks/nginx.js +18 -135
- package/src/tasks/redeploy.js +39 -1
- 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 +1 -1
- package/vendor/docs/01-concepts/authorization.md +66 -48
- 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 +70 -33
- 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 +113 -25
- 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 +4 -4
- package/vendor/docs/03-architecture/management-flow.md +3 -1
- package/vendor/docs/03-architecture/nginx-configuration.md +165 -18
- package/vendor/docs/03-architecture/overview.md +13 -17
- package/vendor/docs/03-architecture/panel-client.md +6 -6
- package/vendor/docs/03-architecture/panel-server.md +3 -2
- package/vendor/docs/03-architecture/state-management.md +4 -8
- package/vendor/docs/03-architecture/system-overview.md +1 -1
- package/vendor/docs/04-api-reference/agent-hosted-plugins.md +291 -22
- package/vendor/docs/04-api-reference/app-host.md +3 -3
- package/vendor/docs/04-api-reference/gatekeeper.md +60 -5
- package/vendor/docs/04-api-reference/lifecycle-hooks.md +14 -12
- package/vendor/docs/04-api-reference/onboarding.md +1 -1
- package/vendor/docs/04-api-reference/registry-and-oidc.md +3 -3
- package/vendor/docs/04-api-reference/tunnels.md +67 -29
- package/vendor/docs/04-api-reference/users.md +241 -45
- package/vendor/docs/05-operations/backup-and-restore.md +35 -26
- package/vendor/docs/05-operations/monitoring.md +39 -0
- package/vendor/docs/05-operations/uninstalling.md +2 -1
- package/vendor/docs/05-operations/upgrades.md +15 -6
- package/vendor/docs/06-reference/config-files.md +82 -188
- 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 +25 -26
- package/vendor/docs/06-reference/troubleshooting.md +8 -8
- package/vendor/docs/gatekeeper-design.md +10 -8
- package/vendor/docs/identity-directory-design.md +48 -14
- 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 +2 -1
- package/vendor/gatekeeper/dist/index.d.ts.map +1 -1
- package/vendor/gatekeeper/dist/index.js +2 -0
- package/vendor/gatekeeper/dist/index.js.map +1 -1
- package/vendor/gatekeeper/dist/lib/grants.d.ts +6 -0
- package/vendor/gatekeeper/dist/lib/grants.d.ts.map +1 -1
- package/vendor/gatekeeper/dist/lib/grants.js +6 -1
- package/vendor/gatekeeper/dist/lib/grants.js.map +1 -1
- package/vendor/gatekeeper/dist/lib/groups.d.ts +5 -0
- package/vendor/gatekeeper/dist/lib/groups.d.ts.map +1 -1
- package/vendor/gatekeeper/dist/lib/groups.js +5 -1
- package/vendor/gatekeeper/dist/lib/groups.js.map +1 -1
- package/vendor/gatekeeper/dist/lib/principals.d.ts +29 -0
- package/vendor/gatekeeper/dist/lib/principals.d.ts.map +1 -0
- package/vendor/gatekeeper/dist/lib/principals.js +67 -0
- package/vendor/gatekeeper/dist/lib/principals.js.map +1 -0
- package/vendor/gatekeeper/dist/lib/tunnels.d.ts +13 -0
- package/vendor/gatekeeper/dist/lib/tunnels.d.ts.map +1 -0
- package/vendor/gatekeeper/dist/lib/tunnels.js +68 -0
- package/vendor/gatekeeper/dist/lib/tunnels.js.map +1 -0
- package/vendor/gatekeeper/dist/lib/types.d.ts +19 -0
- package/vendor/gatekeeper/dist/lib/types.d.ts.map +1 -1
- package/vendor/gatekeeper/dist/server/index.d.ts.map +1 -1
- package/vendor/gatekeeper/dist/server/index.js +22 -48
- package/vendor/gatekeeper/dist/server/index.js.map +1 -1
- package/vendor/gatekeeper/dist/server/routes/authz.d.ts +15 -1
- package/vendor/gatekeeper/dist/server/routes/authz.d.ts.map +1 -1
- package/vendor/gatekeeper/dist/server/routes/authz.js +250 -103
- 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 +61 -4
- package/vendor/gatekeeper/dist/server/routes/diagnostic.js.map +1 -1
- package/vendor/gatekeeper/dist/server/routes/principals.d.ts +3 -0
- package/vendor/gatekeeper/dist/server/routes/principals.d.ts.map +1 -0
- package/vendor/gatekeeper/dist/server/routes/principals.js +27 -0
- package/vendor/gatekeeper/dist/server/routes/principals.js.map +1 -0
- package/vendor/gatekeeper/package.json +2 -2
- package/vendor/server/bin/lamaste-server.js +15 -1
- package/vendor/server/package.json +2 -2
- package/vendor/server/src/commands/plugin-identity.js +335 -0
- package/vendor/server/src/commands/plugins.js +99 -11
- package/vendor/server/src/commands/registry-credential.js +2 -1
- package/vendor/server/src/commands/tunnels.js +102 -2
- package/vendor/server/src/commands/uninstall.js +3 -1
- package/vendor/server/src/commands/users.js +358 -0
- package/vendor/server/src/plugin-approval.js +107 -5
- package/vendor/server/src/plugin-identity.js +382 -0
- package/vendor/server-ui/dist/assets/index-D-fer5ef.css +1 -0
- package/vendor/server-ui/dist/assets/index-DSaDPJaw.js +84 -0
- package/vendor/server-ui/dist/index.html +2 -2
- package/vendor/serverd/package.json +2 -2
- package/vendor/serverd/src/index.js +25 -1
- package/vendor/serverd/src/lib/audience.js +576 -0
- package/vendor/serverd/src/lib/authelia.js +78 -7
- package/vendor/serverd/src/lib/config.js +68 -43
- package/vendor/serverd/src/lib/directory.js +1113 -0
- package/vendor/serverd/src/lib/entitlements.js +517 -0
- package/vendor/serverd/src/lib/gatekeeper-client.js +215 -10
- package/vendor/serverd/src/lib/hook-pipelines.js +13 -0
- package/vendor/serverd/src/lib/identity-sync.js +905 -0
- package/vendor/serverd/src/lib/migrations/state/0013_identity_directory.sql +158 -0
- package/vendor/serverd/src/lib/migrations/state/0014_identity_ledger.sql +20 -0
- package/vendor/serverd/src/lib/mtls.js +6 -2
- package/vendor/serverd/src/lib/nginx.js +279 -48
- package/vendor/serverd/src/lib/plugin-hooks.js +98 -45
- package/vendor/serverd/src/lib/plugin-hosting.js +33 -5
- package/vendor/serverd/src/lib/plugin-lifecycle.js +100 -9
- package/vendor/serverd/src/lib/plugins.js +59 -4
- package/vendor/serverd/src/lib/registry-credential.js +9 -6
- package/vendor/serverd/src/lib/request-logging.js +19 -0
- package/vendor/serverd/src/lib/retained-data.js +50 -4
- package/vendor/serverd/src/lib/state.js +18 -0
- package/vendor/serverd/src/lib/tunnel-hooks.js +4 -1
- package/vendor/serverd/src/lib/user-access-session.js +21 -11
- package/vendor/serverd/src/lib/user-caller.js +67 -0
- package/vendor/serverd/src/lib/user-surface.js +733 -0
- package/vendor/serverd/src/lib/vhost-reconcile.js +136 -34
- package/vendor/serverd/src/middleware/user-access-session.js +9 -0
- package/vendor/serverd/src/routes/agent-forwarder.js +4 -2
- package/vendor/serverd/src/routes/invite.js +53 -12
- package/vendor/serverd/src/routes/management/gatekeeper-proxy.js +107 -16
- package/vendor/serverd/src/routes/management/identity-directory.js +79 -0
- package/vendor/serverd/src/routes/management/invitations.js +78 -68
- package/vendor/serverd/src/routes/management/plugin-identity.js +221 -0
- package/vendor/serverd/src/routes/management/registry-credential.js +1 -1
- package/vendor/serverd/src/routes/management/tunnels.js +98 -2
- package/vendor/serverd/src/routes/management/users.js +290 -208
- package/vendor/serverd/src/routes/management.js +4 -0
- package/vendor/serverd/src/routes/onboarding/provision.js +14 -1
- package/vendor/serverd/src/routes/user-access.js +17 -4
- package/vendor/serverd/src/routes/user-surface.js +69 -0
- package/vendor/server-ui/dist/assets/index-25wo_8av.css +0 -1
- package/vendor/server-ui/dist/assets/index-roDHz3dM.js +0 -84
|
@@ -0,0 +1,158 @@
|
|
|
1
|
+
-- The user directory and each plugin's audience (4.5, slice 6).
|
|
2
|
+
--
|
|
3
|
+
-- Authelia's users.yml stays its credential file; this directory gives every
|
|
4
|
+
-- user a stable id the panel tells plugins about, and keeps what the panel
|
|
5
|
+
-- last knew of a user after the user is gone (lib/directory.js). The panel
|
|
6
|
+
-- never writes users.yml from here: it reconciles this directory against the
|
|
7
|
+
-- file after its own writes, at start and every minute — read only.
|
|
8
|
+
|
|
9
|
+
-- This directory's identity: a UUID v4 made once, when the store is created.
|
|
10
|
+
-- A store that is replaced (a fresh state.db) has another id, which tells an
|
|
11
|
+
-- agent half that its cursor no longer means anything (it replays from 0).
|
|
12
|
+
CREATE TABLE directory_meta (
|
|
13
|
+
id INTEGER PRIMARY KEY CHECK (id = 1),
|
|
14
|
+
directory_id TEXT NOT NULL,
|
|
15
|
+
created_at TEXT NOT NULL
|
|
16
|
+
);
|
|
17
|
+
INSERT INTO directory_meta (id, directory_id, created_at)
|
|
18
|
+
SELECT 1,
|
|
19
|
+
substr(h, 1, 8) || '-' || substr(h, 9, 4) || '-4' || substr(h, 14, 3) || '-' ||
|
|
20
|
+
substr('89ab', 1 + (random() & 3), 1) || substr(h, 18, 3) || '-' || substr(h, 21, 12),
|
|
21
|
+
strftime('%Y-%m-%dT%H:%M:%fZ', 'now')
|
|
22
|
+
FROM (SELECT lower(hex(randomblob(16))) AS h);
|
|
23
|
+
|
|
24
|
+
-- The store-wide sequence the audience triggers stamp changes with. It only
|
|
25
|
+
-- grows: a cursor on it never sees a number twice, across every plugin.
|
|
26
|
+
CREATE TABLE directory_counter (
|
|
27
|
+
id INTEGER PRIMARY KEY CHECK (id = 1),
|
|
28
|
+
seq INTEGER NOT NULL
|
|
29
|
+
);
|
|
30
|
+
INSERT INTO directory_counter (id, seq) VALUES (1, 0);
|
|
31
|
+
|
|
32
|
+
-- One row per user the directory ever knew, never deleted:
|
|
33
|
+
-- user_id UUID v4, made when the username first appeared
|
|
34
|
+
-- username, display_name, email
|
|
35
|
+
-- as users.yml last had them (display_name / email NULL
|
|
36
|
+
-- when it had none); all three NULL once erased
|
|
37
|
+
-- status active | disabled (Authelia's `disabled: true`) | removed
|
|
38
|
+
-- removed_reason deleted (through Lamaste) | deleted-outside (gone from
|
|
39
|
+
-- users.yml without Lamaste) — set exactly when removed
|
|
40
|
+
-- removed_at when the user was removed
|
|
41
|
+
-- erased_at when an administrator erased the tombstone
|
|
42
|
+
-- principal_cleared_at
|
|
43
|
+
-- when Gatekeeper removed everything it held under the
|
|
44
|
+
-- removed user's username — the grants naming it and its
|
|
45
|
+
-- group memberships (Gatekeeper keys users by username,
|
|
46
|
+
-- which a later user may reuse). NULL on a removed row:
|
|
47
|
+
-- pending, retried every minute; the username is not given
|
|
48
|
+
-- to a new user, and no username with a pending cleanup
|
|
49
|
+
-- holds a role, until it is set. Set before an erasure
|
|
50
|
+
-- scrubs the username it needs.
|
|
51
|
+
-- version 1 at creation, +1 on every change of the row
|
|
52
|
+
-- A username names at most one user that is not removed; a removed user
|
|
53
|
+
-- keeps it (history stays readable) until erased, and a username that comes
|
|
54
|
+
-- back is a new user with a new id.
|
|
55
|
+
CREATE TABLE directory_users (
|
|
56
|
+
user_id TEXT PRIMARY KEY,
|
|
57
|
+
username TEXT,
|
|
58
|
+
display_name TEXT,
|
|
59
|
+
email TEXT,
|
|
60
|
+
status TEXT NOT NULL CHECK (status IN ('active', 'disabled', 'removed')),
|
|
61
|
+
removed_reason TEXT CHECK (removed_reason IS NULL OR removed_reason IN ('deleted', 'deleted-outside')),
|
|
62
|
+
removed_at TEXT,
|
|
63
|
+
erased_at TEXT,
|
|
64
|
+
principal_cleared_at TEXT,
|
|
65
|
+
version INTEGER NOT NULL CHECK (version >= 1),
|
|
66
|
+
created_at TEXT NOT NULL,
|
|
67
|
+
updated_at TEXT NOT NULL,
|
|
68
|
+
CHECK ((status = 'removed') = (removed_reason IS NOT NULL)),
|
|
69
|
+
CHECK ((status = 'removed') = (removed_at IS NOT NULL)),
|
|
70
|
+
CHECK (status = 'removed' OR username IS NOT NULL),
|
|
71
|
+
CHECK (erased_at IS NULL OR (status = 'removed' AND username IS NULL
|
|
72
|
+
AND display_name IS NULL AND email IS NULL)),
|
|
73
|
+
CHECK (principal_cleared_at IS NULL OR status = 'removed'),
|
|
74
|
+
CHECK (erased_at IS NULL OR principal_cleared_at IS NOT NULL)
|
|
75
|
+
);
|
|
76
|
+
CREATE UNIQUE INDEX directory_users_username ON directory_users (username)
|
|
77
|
+
WHERE status <> 'removed';
|
|
78
|
+
-- The removed users whose Gatekeeper principal is still to be cleared.
|
|
79
|
+
CREATE INDEX directory_users_principal_pending ON directory_users (username)
|
|
80
|
+
WHERE status = 'removed' AND principal_cleared_at IS NULL;
|
|
81
|
+
|
|
82
|
+
-- Each plugin's audience as last delivered (lib/audience.js): one row per
|
|
83
|
+
-- plugin and user who was ever a member, the change the feed carries for
|
|
84
|
+
-- them (the AudienceChange body without `seq`: an `upsert` with the member,
|
|
85
|
+
-- or a `remove` with its reason and, but for `erased`, the last known
|
|
86
|
+
-- declared attributes), its version (+1 whenever the change differs) and the
|
|
87
|
+
-- `seq` the triggers below stamp. Rows are written only when the change
|
|
88
|
+
-- differs; users who were never members have none. The plugin's ledger: kept
|
|
89
|
+
-- while any agent keeps data of the plugin (see 0014).
|
|
90
|
+
CREATE TABLE plugin_audience (
|
|
91
|
+
plugin TEXT NOT NULL,
|
|
92
|
+
user_id TEXT NOT NULL REFERENCES directory_users (user_id),
|
|
93
|
+
change TEXT NOT NULL,
|
|
94
|
+
version INTEGER NOT NULL CHECK (version >= 1),
|
|
95
|
+
seq INTEGER NOT NULL DEFAULT 0,
|
|
96
|
+
updated_at TEXT NOT NULL,
|
|
97
|
+
PRIMARY KEY (plugin, user_id)
|
|
98
|
+
);
|
|
99
|
+
CREATE INDEX plugin_audience_seq ON plugin_audience (plugin, seq);
|
|
100
|
+
|
|
101
|
+
-- A new row, and a row whose change was rewritten, take the next store-wide
|
|
102
|
+
-- seq. Only an UPDATE that names `change` stamps: the stamp itself updates
|
|
103
|
+
-- `seq` alone, so it does not fire again.
|
|
104
|
+
CREATE TRIGGER plugin_audience_stamp_insert AFTER INSERT ON plugin_audience
|
|
105
|
+
BEGIN
|
|
106
|
+
UPDATE directory_counter SET seq = seq + 1 WHERE id = 1;
|
|
107
|
+
UPDATE plugin_audience SET seq = (SELECT seq FROM directory_counter WHERE id = 1)
|
|
108
|
+
WHERE plugin = NEW.plugin AND user_id = NEW.user_id;
|
|
109
|
+
END;
|
|
110
|
+
CREATE TRIGGER plugin_audience_stamp_update AFTER UPDATE OF change ON plugin_audience
|
|
111
|
+
BEGIN
|
|
112
|
+
UPDATE directory_counter SET seq = seq + 1 WHERE id = 1;
|
|
113
|
+
UPDATE plugin_audience SET seq = (SELECT seq FROM directory_counter WHERE id = 1)
|
|
114
|
+
WHERE plugin = NEW.plugin AND user_id = NEW.user_id;
|
|
115
|
+
END;
|
|
116
|
+
|
|
117
|
+
-- What the panel knows of each plugin's agent half and its feed
|
|
118
|
+
-- (lib/identity-sync.js):
|
|
119
|
+
-- directory_id the directory the half follows, as it last answered
|
|
120
|
+
-- cursor the seq it has applied up to, as it last answered
|
|
121
|
+
-- ready_version the plugin version installed when the half last
|
|
122
|
+
-- applied every change up to the head after a complete
|
|
123
|
+
-- replay — user callers go to the half only while it is
|
|
124
|
+
-- the installed version
|
|
125
|
+
-- last_sync_at the last sync that ended with the half up to date
|
|
126
|
+
-- last_reconcile_at the last full replay (a reset or the daily reconcile);
|
|
127
|
+
-- cleared when one starts, so one cut short is owed
|
|
128
|
+
-- last_mismatches what the last daily reconcile found (null otherwise)
|
|
129
|
+
-- last_error why the last sync did not finish (or was not tried)
|
|
130
|
+
-- Removed when its hosting is removed (the half of a later hosting is sent
|
|
131
|
+
-- everything, and is ready only once it has applied it) and with the
|
|
132
|
+
-- plugin's ledger (0014); kept when the plugin stops declaring identity.
|
|
133
|
+
CREATE TABLE plugin_identity_sync (
|
|
134
|
+
plugin TEXT PRIMARY KEY,
|
|
135
|
+
directory_id TEXT,
|
|
136
|
+
cursor INTEGER,
|
|
137
|
+
ready_version TEXT,
|
|
138
|
+
last_sync_at TEXT,
|
|
139
|
+
last_reconcile_at TEXT,
|
|
140
|
+
last_mismatches INTEGER,
|
|
141
|
+
last_error TEXT,
|
|
142
|
+
updated_at TEXT NOT NULL
|
|
143
|
+
);
|
|
144
|
+
|
|
145
|
+
-- Who erased a removed user, and when. The erasure itself is the scrubbed
|
|
146
|
+
-- directory row; each plugin acknowledges it when its half's cursor passes
|
|
147
|
+
-- the `remove/erased` change of its audience.
|
|
148
|
+
CREATE TABLE directory_erasures (
|
|
149
|
+
user_id TEXT PRIMARY KEY REFERENCES directory_users (user_id),
|
|
150
|
+
requested_at TEXT NOT NULL,
|
|
151
|
+
requested_by TEXT NOT NULL
|
|
152
|
+
);
|
|
153
|
+
|
|
154
|
+
-- The manifest's `identity` block as normalized (core
|
|
155
|
+
-- `normalizeIdentityBlock`: roles by id, attributes sorted, the default
|
|
156
|
+
-- applied), NULL when the plugin declares none. It enters the approval
|
|
157
|
+
-- digest when present.
|
|
158
|
+
ALTER TABLE plugins ADD COLUMN identity TEXT;
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
-- Erasure obligations outlive a plugin's feed (4.5, slice 6).
|
|
2
|
+
--
|
|
3
|
+
-- plugin_audience (0013) is each plugin's ledger of everyone its agent
|
|
4
|
+
-- halves were ever sent, and so of the erasures it owes. It stays when the
|
|
5
|
+
-- plugin is uninstalled or stops declaring identity — its data stays on an
|
|
6
|
+
-- agent — and goes only once no data of the plugin is left anywhere: the
|
|
7
|
+
-- plugin is not installed and no agent retains its data (lib/audience.js
|
|
8
|
+
-- `dropIdentityLedgerIfNoData`). Erasing a user rewrites the user's row in
|
|
9
|
+
-- every ledger, so a plugin that comes back replays the erasure.
|
|
10
|
+
--
|
|
11
|
+
-- Data an agent retains (retained_agent_data, 0010) is an agent half's data
|
|
12
|
+
-- directory, its identity projection included. What that projection had
|
|
13
|
+
-- applied when the data was retained — the directory it followed and its
|
|
14
|
+
-- cursor, as the half last answered — is recorded with it: the erasures of
|
|
15
|
+
-- the plugin's ledger stamped after that cursor are pending on that agent
|
|
16
|
+
-- until the data is purged, or taken back by a hosting whose half replays
|
|
17
|
+
-- them. NULL when the relay knew no position (the half had never answered):
|
|
18
|
+
-- every erasure of the ledger is pending there.
|
|
19
|
+
ALTER TABLE retained_agent_data ADD COLUMN identity_directory_id TEXT;
|
|
20
|
+
ALTER TABLE retained_agent_data ADD COLUMN identity_cursor INTEGER;
|
|
@@ -854,16 +854,20 @@ export async function revokeAgentCert(label, logger) {
|
|
|
854
854
|
|
|
855
855
|
// 7. Detach the agent from its tunnels, so a later enrollment that reuses
|
|
856
856
|
// the label inherits nothing. Runs after the credential removal, whose
|
|
857
|
-
// chisel restart already ended the agent's sessions.
|
|
857
|
+
// chisel restart already ended the agent's sessions. A released tunnel
|
|
858
|
+
// bound as a plugin's user surface serves none of it from now on: its
|
|
859
|
+
// vhost loses those locations.
|
|
858
860
|
if (!label.startsWith(PLUGIN_AGENT_CN_PREFIX)) {
|
|
859
861
|
try {
|
|
860
|
-
await releaseAgentTunnels({
|
|
862
|
+
const { releasedIds } = await releaseAgentTunnels({
|
|
861
863
|
agentLabel: label,
|
|
862
864
|
nginx: tunnelNginxDeps,
|
|
863
865
|
chisel: tunnelChiselDeps,
|
|
864
866
|
state: tunnelStateDeps,
|
|
865
867
|
logger,
|
|
866
868
|
});
|
|
869
|
+
const { refreshTunnelUserSurfaceVhosts } = await import('./user-surface.js');
|
|
870
|
+
await refreshTunnelUserSurfaceVhosts(releasedIds, logger);
|
|
867
871
|
} catch (err) {
|
|
868
872
|
logger.error(
|
|
869
873
|
{ err, label },
|