@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.
Files changed (178) hide show
  1. package/package.json +2 -2
  2. package/scripts/bundle-vendor.js +20 -3
  3. package/scripts/lamaste-priv +56 -5
  4. package/scripts/pin-release.js +98 -0
  5. package/src/index.js +8 -1
  6. package/src/lib/env.js +19 -0
  7. package/src/lib/service-config.js +7 -0
  8. package/src/tasks/redeploy.js +8 -0
  9. package/vendor/docs/00-introduction/how-it-works.md +2 -2
  10. package/vendor/docs/00-introduction/quickstart.md +5 -5
  11. package/vendor/docs/00-introduction/what-is-lamaste.md +5 -5
  12. package/vendor/docs/01-concepts/authentication.md +6 -2
  13. package/vendor/docs/01-concepts/authorization.md +4 -0
  14. package/vendor/docs/01-concepts/certificates.md +3 -3
  15. package/vendor/docs/01-concepts/dns-and-domains.md +9 -0
  16. package/vendor/docs/01-concepts/mtls.md +2 -2
  17. package/vendor/docs/01-concepts/security-model.md +28 -3
  18. package/vendor/docs/01-concepts/tickets.md +2 -2
  19. package/vendor/docs/01-concepts/tunneling.md +4 -4
  20. package/vendor/docs/02-guides/agent-setup.md +5 -5
  21. package/vendor/docs/02-guides/certificate-management.md +2 -2
  22. package/vendor/docs/02-guides/cloud-provisioning.md +3 -3
  23. package/vendor/docs/02-guides/desktop-app-setup.md +10 -10
  24. package/vendor/docs/02-guides/installation.md +3 -3
  25. package/vendor/docs/02-guides/managing-users.md +5 -11
  26. package/vendor/docs/02-guides/onboarding.md +2 -2
  27. package/vendor/docs/02-guides/second-domain.md +82 -0
  28. package/vendor/docs/02-guides/standalone-plugin-with-tickets.md +2 -2
  29. package/vendor/docs/02-guides/static-sites.md +4 -0
  30. package/vendor/docs/03-architecture/installer-flow.md +2 -2
  31. package/vendor/docs/03-architecture/installer.md +4 -4
  32. package/vendor/docs/03-architecture/management-flow.md +1 -1
  33. package/vendor/docs/03-architecture/nginx-configuration.md +80 -12
  34. package/vendor/docs/03-architecture/overview.md +5 -5
  35. package/vendor/docs/03-architecture/panel-client.md +6 -6
  36. package/vendor/docs/03-architecture/panel-server.md +2 -2
  37. package/vendor/docs/03-architecture/state-management.md +3 -3
  38. package/vendor/docs/03-architecture/system-overview.md +1 -1
  39. package/vendor/docs/04-api-reference/agent-hosted-plugins.md +116 -37
  40. package/vendor/docs/04-api-reference/app-host.md +3 -3
  41. package/vendor/docs/04-api-reference/domains.md +192 -0
  42. package/vendor/docs/04-api-reference/gatekeeper.md +54 -8
  43. package/vendor/docs/04-api-reference/lifecycle-hooks.md +4 -4
  44. package/vendor/docs/04-api-reference/onboarding.md +1 -1
  45. package/vendor/docs/04-api-reference/overview.md +9 -0
  46. package/vendor/docs/04-api-reference/registry-and-oidc.md +26 -13
  47. package/vendor/docs/04-api-reference/sites.md +9 -0
  48. package/vendor/docs/04-api-reference/tunnels.md +35 -28
  49. package/vendor/docs/04-api-reference/users.md +41 -29
  50. package/vendor/docs/05-operations/backup-and-restore.md +1 -1
  51. package/vendor/docs/05-operations/uninstalling.md +1 -1
  52. package/vendor/docs/05-operations/upgrades.md +15 -6
  53. package/vendor/docs/06-reference/config-files.md +19 -15
  54. package/vendor/docs/06-reference/glossary.md +3 -3
  55. package/vendor/docs/06-reference/installer-flags.md +13 -13
  56. package/vendor/docs/06-reference/ports-and-services.md +1 -1
  57. package/vendor/docs/06-reference/troubleshooting.md +8 -8
  58. package/vendor/docs/_index.json +105 -19
  59. package/vendor/docs/external-members-design.md +816 -0
  60. package/vendor/docs/gatekeeper-design.md +8 -8
  61. package/vendor/docs/identity-directory-design.md +3 -3
  62. package/vendor/docs/multi-domain-relay-design.md +836 -0
  63. package/vendor/docs/package.json +1 -1
  64. package/vendor/docs/todo/lib-cli-desktop-refactor.md +27 -27
  65. package/vendor/gatekeeper/dist/index.d.ts +3 -3
  66. package/vendor/gatekeeper/dist/index.d.ts.map +1 -1
  67. package/vendor/gatekeeper/dist/index.js +2 -2
  68. package/vendor/gatekeeper/dist/index.js.map +1 -1
  69. package/vendor/gatekeeper/dist/lib/authz.d.ts +9 -0
  70. package/vendor/gatekeeper/dist/lib/authz.d.ts.map +1 -1
  71. package/vendor/gatekeeper/dist/lib/authz.js +31 -0
  72. package/vendor/gatekeeper/dist/lib/authz.js.map +1 -1
  73. package/vendor/gatekeeper/dist/lib/constants.d.ts +5 -2
  74. package/vendor/gatekeeper/dist/lib/constants.d.ts.map +1 -1
  75. package/vendor/gatekeeper/dist/lib/constants.js +5 -2
  76. package/vendor/gatekeeper/dist/lib/constants.js.map +1 -1
  77. package/vendor/gatekeeper/dist/lib/grants.d.ts.map +1 -1
  78. package/vendor/gatekeeper/dist/lib/grants.js +20 -13
  79. package/vendor/gatekeeper/dist/lib/grants.js.map +1 -1
  80. package/vendor/gatekeeper/dist/lib/migrations/gatekeeper/0004_unconsume_access_grants.sql +8 -0
  81. package/vendor/gatekeeper/dist/lib/secret.d.ts +6 -0
  82. package/vendor/gatekeeper/dist/lib/secret.d.ts.map +1 -0
  83. package/vendor/gatekeeper/dist/lib/secret.js +12 -0
  84. package/vendor/gatekeeper/dist/lib/secret.js.map +1 -0
  85. package/vendor/gatekeeper/dist/lib/templates.d.ts +20 -0
  86. package/vendor/gatekeeper/dist/lib/templates.d.ts.map +1 -1
  87. package/vendor/gatekeeper/dist/lib/templates.js +80 -14
  88. package/vendor/gatekeeper/dist/lib/templates.js.map +1 -1
  89. package/vendor/gatekeeper/dist/lib/tunnels.d.ts +3 -6
  90. package/vendor/gatekeeper/dist/lib/tunnels.d.ts.map +1 -1
  91. package/vendor/gatekeeper/dist/lib/tunnels.js +4 -16
  92. package/vendor/gatekeeper/dist/lib/tunnels.js.map +1 -1
  93. package/vendor/gatekeeper/dist/lib/types.d.ts +0 -19
  94. package/vendor/gatekeeper/dist/lib/types.d.ts.map +1 -1
  95. package/vendor/gatekeeper/dist/server/index.d.ts +6 -1
  96. package/vendor/gatekeeper/dist/server/index.d.ts.map +1 -1
  97. package/vendor/gatekeeper/dist/server/index.js +56 -11
  98. package/vendor/gatekeeper/dist/server/index.js.map +1 -1
  99. package/vendor/gatekeeper/dist/server/routes/authz.d.ts.map +1 -1
  100. package/vendor/gatekeeper/dist/server/routes/authz.js +325 -55
  101. package/vendor/gatekeeper/dist/server/routes/authz.js.map +1 -1
  102. package/vendor/gatekeeper/dist/server/routes/diagnostic.d.ts.map +1 -1
  103. package/vendor/gatekeeper/dist/server/routes/diagnostic.js +5 -2
  104. package/vendor/gatekeeper/dist/server/routes/diagnostic.js.map +1 -1
  105. package/vendor/gatekeeper/package.json +2 -2
  106. package/vendor/server/bin/lamaste-server.js +7 -0
  107. package/vendor/server/package.json +2 -2
  108. package/vendor/server/src/commands/domains.js +214 -0
  109. package/vendor/server/src/commands/plugin-identity.js +2 -16
  110. package/vendor/server/src/commands/plugin-web-surface.js +269 -0
  111. package/vendor/server/src/commands/plugins.js +175 -14
  112. package/vendor/server/src/commands/registry-credential.js +10 -3
  113. package/vendor/server/src/commands/sites.js +18 -1
  114. package/vendor/server/src/commands/status.js +19 -0
  115. package/vendor/server/src/commands/tunnels.js +4 -1
  116. package/vendor/server/src/commands/users.js +8 -19
  117. package/vendor/server/src/domains.js +92 -0
  118. package/vendor/server/src/fail.js +21 -0
  119. package/vendor/server/src/oidc-client-grants.js +63 -0
  120. package/vendor/server/src/panel-api.js +15 -0
  121. package/vendor/server/src/plugin-approval.js +80 -1
  122. package/vendor/server/src/plugin-web-surface.js +307 -0
  123. package/vendor/server-ui/dist/assets/index-B8Tv_ocF.js +84 -0
  124. package/vendor/server-ui/dist/assets/index-Cb-ADsbB.css +1 -0
  125. package/vendor/server-ui/dist/index.html +2 -2
  126. package/vendor/serverd/package.json +2 -2
  127. package/vendor/serverd/src/index.js +50 -19
  128. package/vendor/serverd/src/lib/app-error.js +24 -0
  129. package/vendor/serverd/src/lib/audience.js +12 -3
  130. package/vendor/serverd/src/lib/authelia.js +341 -35
  131. package/vendor/serverd/src/lib/chisel-runtime.js +18 -6
  132. package/vendor/serverd/src/lib/chisel.js +10 -2
  133. package/vendor/serverd/src/lib/directory.js +67 -52
  134. package/vendor/serverd/src/lib/domains.js +1792 -0
  135. package/vendor/serverd/src/lib/gatekeeper-client.js +34 -7
  136. package/vendor/serverd/src/lib/hook-pipelines.js +8 -3
  137. package/vendor/serverd/src/lib/identity-sync.js +35 -0
  138. package/vendor/serverd/src/lib/migrations/state/0015_plugin_web_surface.sql +14 -0
  139. package/vendor/serverd/src/lib/migrations/state/0016_domains.sql +53 -0
  140. package/vendor/serverd/src/lib/migrations/state/0017_membership_kind.sql +15 -0
  141. package/vendor/serverd/src/lib/migrations/state/0018_domain_group_keys.sql +23 -0
  142. package/vendor/serverd/src/lib/nginx.js +576 -131
  143. package/vendor/serverd/src/lib/owned-groups.js +326 -0
  144. package/vendor/serverd/src/lib/plugin-domain.js +86 -0
  145. package/vendor/serverd/src/lib/plugin-hooks.js +40 -11
  146. package/vendor/serverd/src/lib/plugin-lifecycle.js +129 -5
  147. package/vendor/serverd/src/lib/plugin-oidc.js +144 -42
  148. package/vendor/serverd/src/lib/plugin-packages.js +74 -2
  149. package/vendor/serverd/src/lib/plugins.js +82 -9
  150. package/vendor/serverd/src/lib/registry-credential.js +39 -6
  151. package/vendor/serverd/src/lib/services.js +9 -1
  152. package/vendor/serverd/src/lib/state.js +29 -0
  153. package/vendor/serverd/src/lib/tunnel-deps.js +2 -4
  154. package/vendor/serverd/src/lib/user-surface.js +77 -31
  155. package/vendor/serverd/src/lib/users-lock.js +23 -0
  156. package/vendor/serverd/src/lib/vhost-reconcile.js +151 -41
  157. package/vendor/serverd/src/lib/web-surface.js +783 -0
  158. package/vendor/serverd/src/middleware/user-access-session.js +11 -4
  159. package/vendor/serverd/src/routes/invite.js +15 -5
  160. package/vendor/serverd/src/routes/management/domains.js +154 -0
  161. package/vendor/serverd/src/routes/management/gatekeeper-proxy.js +44 -8
  162. package/vendor/serverd/src/routes/management/identity.js +21 -7
  163. package/vendor/serverd/src/routes/management/invitations.js +33 -4
  164. package/vendor/serverd/src/routes/management/plugin-web-surface.js +151 -0
  165. package/vendor/serverd/src/routes/management/plugins.js +6 -2
  166. package/vendor/serverd/src/routes/management/registry-credential.js +86 -57
  167. package/vendor/serverd/src/routes/management/sites.js +188 -71
  168. package/vendor/serverd/src/routes/management/tunnels.js +37 -22
  169. package/vendor/serverd/src/routes/management/users.js +184 -64
  170. package/vendor/serverd/src/routes/management.js +4 -0
  171. package/vendor/serverd/src/routes/onboarding/dns.js +3 -17
  172. package/vendor/serverd/src/routes/onboarding/provision.js +22 -13
  173. package/vendor/serverd/src/routes/user-access.js +13 -1
  174. package/vendor/gatekeeper/dist/lib/migrations/migrations/gatekeeper/0001_groups.sql +0 -7
  175. package/vendor/gatekeeper/dist/lib/migrations/migrations/gatekeeper/0002_access_grants.sql +0 -14
  176. package/vendor/gatekeeper/dist/lib/migrations/migrations/gatekeeper/0003_access_request_log.sql +0 -9
  177. package/vendor/server-ui/dist/assets/index-D-fer5ef.css +0 -1
  178. package/vendor/server-ui/dist/assets/index-DSaDPJaw.js +0 -84
@@ -225,26 +225,53 @@ function groupOf(raw) {
225
225
  }
226
226
 
227
227
  /**
228
- * Every grant on plugin `route` (`resourceType: 'plugin'`, `resourceId:
229
- * <route>`) — with roles or without.
228
+ * Every grant on one resource (`resourceType`, `resourceId`).
230
229
  *
231
- * @param {string} route
230
+ * @param {string} resourceType
231
+ * @param {string} resourceId
232
+ * @returns {Promise<{ ok: true, grants: GatekeeperGrant[] } | Extract<GatekeeperResult, { ok: false }>>}
233
+ */
234
+ export function listResourceGrants(resourceType, resourceId) {
235
+ return listGrantsMatching({ resourceType, resourceId });
236
+ }
237
+
238
+ /**
239
+ * Every grant on resources of `resourceType` (`tunnel`, `site`,
240
+ * `oidc-client`, …).
241
+ *
242
+ * @param {string} resourceType
232
243
  * @returns {Promise<{ ok: true, grants: GatekeeperGrant[] } | Extract<GatekeeperResult, { ok: false }>>}
233
244
  */
234
- export async function listPluginGrants(route) {
235
- const qs = new URLSearchParams({ resourceType: 'plugin', resourceId: route }).toString();
245
+ export function listGrantsOfType(resourceType) {
246
+ return listGrantsMatching({ resourceType });
247
+ }
248
+
249
+ /** The grants matching `filter` (its fields are Gatekeeper's query filters). */
250
+ async function listGrantsMatching(filter) {
251
+ const qs = new URLSearchParams(filter).toString();
236
252
  const result = await gatekeeperRequest('GET', `/api/grants?${qs}`);
237
253
  if (!result.ok) return result;
238
254
  if (!isRecord(result.data) || !Array.isArray(result.data.grants)) return malformed('its grants');
239
255
  const grants = result.data.grants.map(grantOf);
240
256
  if (grants.some((g) => g === null)) return malformed('its grants');
241
- // Gatekeeper filters by the query; a grant on anything else is not this plugin's.
257
+ // Gatekeeper filters by the query; a grant on anything else is not one asked for.
242
258
  return {
243
259
  ok: true,
244
- grants: grants.filter((g) => g.resourceType === 'plugin' && g.resourceId === route),
260
+ grants: grants.filter((g) => Object.entries(filter).every(([key, value]) => g[key] === value)),
245
261
  };
246
262
  }
247
263
 
264
+ /**
265
+ * Every grant on plugin `route` (`resourceType: 'plugin'`, `resourceId:
266
+ * <route>`) — with roles or without.
267
+ *
268
+ * @param {string} route
269
+ * @returns {Promise<{ ok: true, grants: GatekeeperGrant[] } | Extract<GatekeeperResult, { ok: false }>>}
270
+ */
271
+ export function listPluginGrants(route) {
272
+ return listResourceGrants('plugin', route);
273
+ }
274
+
248
275
  /**
249
276
  * Every Lamaste group with its members.
250
277
  *
@@ -871,8 +871,10 @@ export async function runUninstallPipeline(op, ctx, { force = false } = {}) {
871
871
  /**
872
872
  * The install pipeline around an upgrade of the relay package (the agent
873
873
  * half is already running; its stages go through the tunnel). `apply` is
874
- * Lamaste's step — install the new package and its hook module; `revert`
875
- * restores the previous ones. Agent and relay stages see `phase: "upgrade"`.
874
+ * Lamaste's step — install the new package and its hook module; `serve`,
875
+ * when given, is the last step (the new version's web tree served, once
876
+ * every stage passed);
877
+ * `revert` restores the previous ones. Agent and relay stages see `phase: "upgrade"`.
876
878
  *
877
879
  * A hosted plugin whose agent half Lamaste installs gets the new version of
878
880
  * it first (after the agent's pre stage): the agent's helper installs it
@@ -880,7 +882,7 @@ export async function runUninstallPipeline(op, ctx, { force = false } = {}) {
880
882
  * tunnel. A failure after that switch activates the version that ran
881
883
  * before (`ctx.previousAgentHalfVersion`).
882
884
  */
883
- export async function runUpgradePipeline(op, ctx, { apply, revert, hosted }) {
885
+ export async function runUpgradePipeline(op, ctx, { apply, serve, revert, hosted }) {
884
886
  let applied = false;
885
887
  try {
886
888
  if (hosted) {
@@ -906,6 +908,9 @@ export async function runUpgradePipeline(op, ctx, { apply, revert, hosted }) {
906
908
  await agentStageOrSkip(op, ctx, 'install:post-tunnel', 'upgrade', 'tunnel');
907
909
  await relayStageOrSkip(op, ctx, 'install:post-tunnel', 'upgrade');
908
910
  }
911
+ // What the new version serves its users from the relay (its web tree):
912
+ // the last step, once every stage passed — a failure still reverts.
913
+ if (serve) await op.step('serve the new web tree', serve);
909
914
  } catch (err) {
910
915
  op.warn(`Reverting: ${String(err.message ?? err).slice(0, 300)}`);
911
916
  try {
@@ -77,6 +77,7 @@ import {
77
77
  } from './audience.js';
78
78
  import { getConfig } from './config.js';
79
79
  import { clearPendingPrincipals, getDirectoryId, reconcileDirectory } from './directory.js';
80
+ import { ensurePrimaryDomain, syncDomainAccess } from './domains.js';
80
81
  import { installedVersionApproved } from './plugin-hooks.js';
81
82
  import { findPlugin, findPluginByRoute, readPlugins } from './plugins.js';
82
83
  import { retainedIdentityPositions } from './retained-data.js';
@@ -859,6 +860,9 @@ async function syncDuePlugins(logger) {
859
860
  let tickTimer = null;
860
861
  let ticking = false;
861
862
 
863
+ /** The OIDC sync failure the tick last logged — logged again only when it changes. */
864
+ let lastOidcSyncError = null;
865
+
862
866
  /**
863
867
  * One tick: reconcile the directory with users.yml (once onboarding is
864
868
  * done), clear the Gatekeeper principals of removed users still pending,
@@ -875,6 +879,37 @@ export async function identityTick(logger) {
875
879
  } catch (err) {
876
880
  logger?.warn({ err: err.message }, 'Could not reconcile the user directory');
877
881
  }
882
+ // Who may reach each domain, as the directory now says: users adopted
883
+ // or removed outside Lamaste, and a rendering a failure left behind.
884
+ try {
885
+ await ensurePrimaryDomain({ logger });
886
+ await syncDomainAccess({ logger });
887
+ } catch (err) {
888
+ logger?.warn({ err: err.message }, 'Could not render domain access');
889
+ }
890
+ // users.yml touched once a minute: a reload Authelia skipped (its
891
+ // cooldown) or that a restart of the panel cut short is never missing
892
+ // for longer, and a hand edit gets Lamaste's groups back.
893
+ try {
894
+ const { touchUsersFile } = await import('./authelia.js');
895
+ await touchUsersFile();
896
+ } catch (err) {
897
+ logger?.warn({ err: err.message }, 'Could not touch users.yml');
898
+ }
899
+ // The OIDC provider too, as the plugins and the members now say: a
900
+ // plugin moved to another domain whose sync failed is healed here.
901
+ // Compare-first, so a steady relay writes nothing.
902
+ try {
903
+ const { syncOidcClients } = await import('./plugin-oidc.js');
904
+ await syncOidcClients(logger);
905
+ lastOidcSyncError = null;
906
+ } catch (err) {
907
+ // Once per distinct failure, not every minute.
908
+ if (err.message !== lastOidcSyncError) {
909
+ logger?.warn({ err: err.message }, 'Could not sync the OIDC clients');
910
+ }
911
+ lastOidcSyncError = err.message;
912
+ }
878
913
  }
879
914
  await clearPendingPrincipals({ logger });
880
915
  await recomputeAudiences({ logger });
@@ -0,0 +1,14 @@
1
+ -- A plugin's web surface (4.6, slice 7).
2
+ --
3
+ -- user_surface is the manifest's `userSurface` block as the installed
4
+ -- version declares it (JSON; NULL when it declares none): its `web` names
5
+ -- the default subdomain and access mode Lamaste offers for the plugin's own
6
+ -- site and the directory of the server package that holds the shell.
7
+ --
8
+ -- web_tree_sha256 is the digest of that directory's web tree (core
9
+ -- `webTreeManifest`), read from the installed package: it enters the
10
+ -- approval digest, and the relay serves a copy of the tree only when the
11
+ -- copy's own digest equals it. NULL when the version declares no web
12
+ -- surface.
13
+ ALTER TABLE plugins ADD COLUMN user_surface TEXT;
14
+ ALTER TABLE plugins ADD COLUMN web_tree_sha256 TEXT;
@@ -0,0 +1,53 @@
1
+ -- The relay's base domains and who is a member of each (the multi-domain
2
+ -- relay, packages/core/docs/multi-domain-relay-design.md; lib/domains.js).
3
+ --
4
+ -- One domain is the primary: the panel's (panel.json `domain`), inserted at
5
+ -- the first start after onboarding together with every user the directory
6
+ -- holds as its members (lib/domains.js `ensurePrimaryDomain`) — an upgraded
7
+ -- single-domain relay keeps letting everyone in.
8
+
9
+ -- A base domain:
10
+ -- name lower case, two labels at least; domains never overlap
11
+ -- is_primary 1 for exactly one row: the panel's domain
12
+ -- status pending (added, auth.<domain> not yet issued) | active
13
+ -- (its sign-in, session cookie and members rendered)
14
+ CREATE TABLE domains (
15
+ name TEXT PRIMARY KEY,
16
+ is_primary INTEGER NOT NULL DEFAULT 0 CHECK (is_primary IN (0, 1)),
17
+ status TEXT NOT NULL CHECK (status IN ('pending', 'active')),
18
+ created_at TEXT NOT NULL,
19
+ activated_at TEXT,
20
+ CHECK (is_primary = 0 OR status = 'active'),
21
+ CHECK ((status = 'active') = (activated_at IS NOT NULL))
22
+ );
23
+ CREATE UNIQUE INDEX domains_one_primary ON domains (is_primary) WHERE is_primary = 1;
24
+
25
+ -- Who may reach a domain: one row per domain and user, by user id (a
26
+ -- re-created username is a new user with no membership). Rows go when the
27
+ -- user is deleted or the domain removed; a disabled user keeps theirs but
28
+ -- is never rendered as a member. Changes take the directory's store-wide
29
+ -- sequence, as plugin audiences do.
30
+ CREATE TABLE domain_members (
31
+ domain TEXT NOT NULL REFERENCES domains (name),
32
+ user_id TEXT NOT NULL REFERENCES directory_users (user_id),
33
+ added_at TEXT NOT NULL,
34
+ added_by TEXT NOT NULL,
35
+ seq INTEGER NOT NULL DEFAULT 0,
36
+ PRIMARY KEY (domain, user_id)
37
+ );
38
+ CREATE INDEX domain_members_user ON domain_members (user_id);
39
+
40
+ CREATE TRIGGER domain_members_stamp_insert AFTER INSERT ON domain_members
41
+ BEGIN
42
+ UPDATE directory_counter SET seq = seq + 1 WHERE id = 1;
43
+ UPDATE domain_members SET seq = (SELECT seq FROM directory_counter WHERE id = 1)
44
+ WHERE domain = NEW.domain AND user_id = NEW.user_id;
45
+ END;
46
+ CREATE TRIGGER domain_members_stamp_delete AFTER DELETE ON domain_members
47
+ BEGIN
48
+ UPDATE directory_counter SET seq = seq + 1 WHERE id = 1;
49
+ END;
50
+
51
+ -- The domain a plugin belongs to — its OIDC clients' `{domain}` and sign-in,
52
+ -- its user and web surfaces, its audience. NULL: the primary domain.
53
+ ALTER TABLE plugins ADD COLUMN domain TEXT;
@@ -0,0 +1,15 @@
1
+ -- The kind of a domain membership (packages/core/docs/external-members-design.md;
2
+ -- lib/domains.js): a `member` reaches what the domain gives its members, an
3
+ -- `external` member only what names them (a grant, a site's listed users, an
4
+ -- OIDC client granted to them). Every membership from before is a member.
5
+ ALTER TABLE domain_members ADD COLUMN kind TEXT NOT NULL DEFAULT 'member'
6
+ CHECK (kind IN ('member', 'external'));
7
+
8
+ -- A change of kind takes the directory's store-wide sequence, as an insert does.
9
+ CREATE TRIGGER domain_members_stamp_kind AFTER UPDATE OF kind ON domain_members
10
+ WHEN OLD.kind IS NOT NEW.kind
11
+ BEGIN
12
+ UPDATE directory_counter SET seq = seq + 1 WHERE id = 1;
13
+ UPDATE domain_members SET seq = (SELECT seq FROM directory_counter WHERE id = 1)
14
+ WHERE domain = NEW.domain AND user_id = NEW.user_id;
15
+ END;
@@ -0,0 +1,23 @@
1
+ -- Opaque names for the Authelia groups Lamaste owns
2
+ -- (packages/core/docs/external-members-design.md, security review): a
3
+ -- domain's members and external members are `lamaste:m:<key>` and
4
+ -- `lamaste:x:<key>`, with a random key per domain, so an OIDC relying party
5
+ -- that asks for the `groups` claim learns no domain's name. The panel gives
6
+ -- a new domain its key when it inserts it; the trigger is the fallback, and
7
+ -- existing domains get one here.
8
+ ALTER TABLE domains ADD COLUMN group_key TEXT;
9
+ UPDATE domains SET group_key = lower(hex(randomblob(8))) WHERE group_key IS NULL;
10
+ CREATE UNIQUE INDEX domains_group_key ON domains(group_key);
11
+ CREATE TRIGGER domains_group_key_fill AFTER INSERT ON domains
12
+ WHEN NEW.group_key IS NULL
13
+ BEGIN
14
+ UPDATE domains SET group_key = lower(hex(randomblob(8))) WHERE name = NEW.name;
15
+ END;
16
+
17
+ -- Domains removed from the relay: hostnames under them are still Lamaste's
18
+ -- groups (a host group left on a user is stripped at the next rendering,
19
+ -- never taken for an administrator's group).
20
+ CREATE TABLE retired_domains (
21
+ name TEXT PRIMARY KEY,
22
+ removed_at TEXT NOT NULL
23
+ );