@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.
Files changed (270) hide show
  1. package/LICENSE.md +118 -0
  2. package/README.md +114 -0
  3. package/bin/create-lamaste.js +15 -0
  4. package/package.json +54 -0
  5. package/scripts/bundle-vendor.js +110 -0
  6. package/scripts/lamaste-cert-info +62 -0
  7. package/scripts/lamaste-certbot +96 -0
  8. package/scripts/lamaste-priv +693 -0
  9. package/src/index.js +646 -0
  10. package/src/lib/accounts.js +86 -0
  11. package/src/lib/binaries.js +137 -0
  12. package/src/lib/cert-help-page.js +160 -0
  13. package/src/lib/env.js +132 -0
  14. package/src/lib/http-redirect.js +38 -0
  15. package/src/lib/ownership.js +231 -0
  16. package/src/lib/relay-services.js +103 -0
  17. package/src/lib/secrets.js +19 -0
  18. package/src/lib/service-config.js +311 -0
  19. package/src/lib/summary.js +131 -0
  20. package/src/lib/wrappers.js +63 -0
  21. package/src/tasks/gatekeeper.js +233 -0
  22. package/src/tasks/harden.js +293 -0
  23. package/src/tasks/mtls.js +193 -0
  24. package/src/tasks/nginx.js +265 -0
  25. package/src/tasks/node.js +110 -0
  26. package/src/tasks/panel.js +408 -0
  27. package/src/tasks/redeploy.js +438 -0
  28. package/vendor/docs/00-introduction/how-it-works.md +447 -0
  29. package/vendor/docs/00-introduction/quickstart.md +472 -0
  30. package/vendor/docs/00-introduction/what-is-lamaste.md +112 -0
  31. package/vendor/docs/01-concepts/authentication.md +464 -0
  32. package/vendor/docs/01-concepts/authorization.md +242 -0
  33. package/vendor/docs/01-concepts/certificates.md +452 -0
  34. package/vendor/docs/01-concepts/dns-and-domains.md +343 -0
  35. package/vendor/docs/01-concepts/mtls.md +490 -0
  36. package/vendor/docs/01-concepts/nginx-reverse-proxy.md +540 -0
  37. package/vendor/docs/01-concepts/security-model.md +600 -0
  38. package/vendor/docs/01-concepts/tickets.md +414 -0
  39. package/vendor/docs/01-concepts/tunneling.md +367 -0
  40. package/vendor/docs/02-guides/agent-setup.md +194 -0
  41. package/vendor/docs/02-guides/certificate-management.md +341 -0
  42. package/vendor/docs/02-guides/cloud-provisioning.md +406 -0
  43. package/vendor/docs/02-guides/desktop-app-setup.md +226 -0
  44. package/vendor/docs/02-guides/disaster-recovery.md +464 -0
  45. package/vendor/docs/02-guides/first-tunnel.md +230 -0
  46. package/vendor/docs/02-guides/installation.md +393 -0
  47. package/vendor/docs/02-guides/managing-users.md +255 -0
  48. package/vendor/docs/02-guides/onboarding.md +244 -0
  49. package/vendor/docs/02-guides/standalone-plugin-with-tickets.md +375 -0
  50. package/vendor/docs/02-guides/static-sites.md +364 -0
  51. package/vendor/docs/03-architecture/e2e-three-vm-sequences.md +457 -0
  52. package/vendor/docs/03-architecture/installer-flow.md +151 -0
  53. package/vendor/docs/03-architecture/installer.md +445 -0
  54. package/vendor/docs/03-architecture/management-flow.md +288 -0
  55. package/vendor/docs/03-architecture/nginx-configuration.md +830 -0
  56. package/vendor/docs/03-architecture/onboarding-flow.md +164 -0
  57. package/vendor/docs/03-architecture/overview.md +541 -0
  58. package/vendor/docs/03-architecture/panel-client.md +416 -0
  59. package/vendor/docs/03-architecture/panel-server.md +695 -0
  60. package/vendor/docs/03-architecture/state-management.md +529 -0
  61. package/vendor/docs/03-architecture/system-overview.md +167 -0
  62. package/vendor/docs/04-api-reference/certificates.md +1141 -0
  63. package/vendor/docs/04-api-reference/gatekeeper.md +592 -0
  64. package/vendor/docs/04-api-reference/onboarding.md +473 -0
  65. package/vendor/docs/04-api-reference/overview.md +404 -0
  66. package/vendor/docs/04-api-reference/services.md +267 -0
  67. package/vendor/docs/04-api-reference/settings.md +343 -0
  68. package/vendor/docs/04-api-reference/sites.md +716 -0
  69. package/vendor/docs/04-api-reference/system.md +268 -0
  70. package/vendor/docs/04-api-reference/tickets.md +618 -0
  71. package/vendor/docs/04-api-reference/tunnels.md +417 -0
  72. package/vendor/docs/04-api-reference/users.md +333 -0
  73. package/vendor/docs/05-operations/backup-and-restore.md +342 -0
  74. package/vendor/docs/05-operations/monitoring.md +285 -0
  75. package/vendor/docs/05-operations/uninstalling.md +344 -0
  76. package/vendor/docs/05-operations/upgrades.md +270 -0
  77. package/vendor/docs/06-reference/config-files.md +1080 -0
  78. package/vendor/docs/06-reference/glossary.md +528 -0
  79. package/vendor/docs/06-reference/installer-flags.md +260 -0
  80. package/vendor/docs/06-reference/ports-and-services.md +244 -0
  81. package/vendor/docs/06-reference/troubleshooting.md +665 -0
  82. package/vendor/docs/_index.json +233 -0
  83. package/vendor/docs/gatekeeper-design.md +953 -0
  84. package/vendor/docs/package.json +15 -0
  85. package/vendor/docs/todo/lib-cli-desktop-refactor.md +641 -0
  86. package/vendor/gatekeeper/dist/boot.d.ts +1 -0
  87. package/vendor/gatekeeper/dist/boot.d.ts.map +1 -0
  88. package/vendor/gatekeeper/dist/boot.js +17 -0
  89. package/vendor/gatekeeper/dist/boot.js.map +1 -0
  90. package/vendor/gatekeeper/dist/cli/commands/access.d.ts +2 -0
  91. package/vendor/gatekeeper/dist/cli/commands/access.d.ts.map +1 -0
  92. package/vendor/gatekeeper/dist/cli/commands/access.js +33 -0
  93. package/vendor/gatekeeper/dist/cli/commands/access.js.map +1 -0
  94. package/vendor/gatekeeper/dist/cli/commands/grants.d.ts +2 -0
  95. package/vendor/gatekeeper/dist/cli/commands/grants.d.ts.map +1 -0
  96. package/vendor/gatekeeper/dist/cli/commands/grants.js +110 -0
  97. package/vendor/gatekeeper/dist/cli/commands/grants.js.map +1 -0
  98. package/vendor/gatekeeper/dist/cli/commands/groups.d.ts +2 -0
  99. package/vendor/gatekeeper/dist/cli/commands/groups.d.ts.map +1 -0
  100. package/vendor/gatekeeper/dist/cli/commands/groups.js +98 -0
  101. package/vendor/gatekeeper/dist/cli/commands/groups.js.map +1 -0
  102. package/vendor/gatekeeper/dist/cli/index.d.ts +3 -0
  103. package/vendor/gatekeeper/dist/cli/index.d.ts.map +1 -0
  104. package/vendor/gatekeeper/dist/cli/index.js +45 -0
  105. package/vendor/gatekeeper/dist/cli/index.js.map +1 -0
  106. package/vendor/gatekeeper/dist/index.d.ts +9 -0
  107. package/vendor/gatekeeper/dist/index.d.ts.map +1 -0
  108. package/vendor/gatekeeper/dist/index.js +13 -0
  109. package/vendor/gatekeeper/dist/index.js.map +1 -0
  110. package/vendor/gatekeeper/dist/lib/authz.d.ts +16 -0
  111. package/vendor/gatekeeper/dist/lib/authz.d.ts.map +1 -0
  112. package/vendor/gatekeeper/dist/lib/authz.js +42 -0
  113. package/vendor/gatekeeper/dist/lib/authz.js.map +1 -0
  114. package/vendor/gatekeeper/dist/lib/cache-bust.d.ts +15 -0
  115. package/vendor/gatekeeper/dist/lib/cache-bust.d.ts.map +1 -0
  116. package/vendor/gatekeeper/dist/lib/cache-bust.js +19 -0
  117. package/vendor/gatekeeper/dist/lib/cache-bust.js.map +1 -0
  118. package/vendor/gatekeeper/dist/lib/constants.d.ts +82 -0
  119. package/vendor/gatekeeper/dist/lib/constants.d.ts.map +1 -0
  120. package/vendor/gatekeeper/dist/lib/constants.js +79 -0
  121. package/vendor/gatekeeper/dist/lib/constants.js.map +1 -0
  122. package/vendor/gatekeeper/dist/lib/grants.d.ts +32 -0
  123. package/vendor/gatekeeper/dist/lib/grants.d.ts.map +1 -0
  124. package/vendor/gatekeeper/dist/lib/grants.js +314 -0
  125. package/vendor/gatekeeper/dist/lib/grants.js.map +1 -0
  126. package/vendor/gatekeeper/dist/lib/groups.d.ts +10 -0
  127. package/vendor/gatekeeper/dist/lib/groups.d.ts.map +1 -0
  128. package/vendor/gatekeeper/dist/lib/groups.js +247 -0
  129. package/vendor/gatekeeper/dist/lib/groups.js.map +1 -0
  130. package/vendor/gatekeeper/dist/lib/migration.d.ts +17 -0
  131. package/vendor/gatekeeper/dist/lib/migration.d.ts.map +1 -0
  132. package/vendor/gatekeeper/dist/lib/migration.js +79 -0
  133. package/vendor/gatekeeper/dist/lib/migration.js.map +1 -0
  134. package/vendor/gatekeeper/dist/lib/migrations/gatekeeper/0001_groups.sql +7 -0
  135. package/vendor/gatekeeper/dist/lib/migrations/gatekeeper/0002_access_grants.sql +14 -0
  136. package/vendor/gatekeeper/dist/lib/migrations/gatekeeper/0003_access_request_log.sql +9 -0
  137. package/vendor/gatekeeper/dist/lib/migrations/migrations/gatekeeper/0001_groups.sql +7 -0
  138. package/vendor/gatekeeper/dist/lib/migrations/migrations/gatekeeper/0002_access_grants.sql +14 -0
  139. package/vendor/gatekeeper/dist/lib/migrations/migrations/gatekeeper/0003_access_request_log.sql +9 -0
  140. package/vendor/gatekeeper/dist/lib/state-db.d.ts +16 -0
  141. package/vendor/gatekeeper/dist/lib/state-db.d.ts.map +1 -0
  142. package/vendor/gatekeeper/dist/lib/state-db.js +154 -0
  143. package/vendor/gatekeeper/dist/lib/state-db.js.map +1 -0
  144. package/vendor/gatekeeper/dist/lib/templates.d.ts +21 -0
  145. package/vendor/gatekeeper/dist/lib/templates.d.ts.map +1 -0
  146. package/vendor/gatekeeper/dist/lib/templates.js +151 -0
  147. package/vendor/gatekeeper/dist/lib/templates.js.map +1 -0
  148. package/vendor/gatekeeper/dist/lib/types.d.ts +178 -0
  149. package/vendor/gatekeeper/dist/lib/types.d.ts.map +1 -0
  150. package/vendor/gatekeeper/dist/lib/types.js +2 -0
  151. package/vendor/gatekeeper/dist/lib/types.js.map +1 -0
  152. package/vendor/gatekeeper/dist/server/index.d.ts +15 -0
  153. package/vendor/gatekeeper/dist/server/index.d.ts.map +1 -0
  154. package/vendor/gatekeeper/dist/server/index.js +251 -0
  155. package/vendor/gatekeeper/dist/server/index.js.map +1 -0
  156. package/vendor/gatekeeper/dist/server/routes/access-request.d.ts +7 -0
  157. package/vendor/gatekeeper/dist/server/routes/access-request.d.ts.map +1 -0
  158. package/vendor/gatekeeper/dist/server/routes/access-request.js +17 -0
  159. package/vendor/gatekeeper/dist/server/routes/access-request.js.map +1 -0
  160. package/vendor/gatekeeper/dist/server/routes/authz.d.ts +3 -0
  161. package/vendor/gatekeeper/dist/server/routes/authz.d.ts.map +1 -0
  162. package/vendor/gatekeeper/dist/server/routes/authz.js +279 -0
  163. package/vendor/gatekeeper/dist/server/routes/authz.js.map +1 -0
  164. package/vendor/gatekeeper/dist/server/routes/diagnostic.d.ts +13 -0
  165. package/vendor/gatekeeper/dist/server/routes/diagnostic.d.ts.map +1 -0
  166. package/vendor/gatekeeper/dist/server/routes/diagnostic.js +249 -0
  167. package/vendor/gatekeeper/dist/server/routes/diagnostic.js.map +1 -0
  168. package/vendor/gatekeeper/dist/server/routes/grants.d.ts +3 -0
  169. package/vendor/gatekeeper/dist/server/routes/grants.d.ts.map +1 -0
  170. package/vendor/gatekeeper/dist/server/routes/grants.js +112 -0
  171. package/vendor/gatekeeper/dist/server/routes/grants.js.map +1 -0
  172. package/vendor/gatekeeper/dist/server/routes/groups.d.ts +3 -0
  173. package/vendor/gatekeeper/dist/server/routes/groups.d.ts.map +1 -0
  174. package/vendor/gatekeeper/dist/server/routes/groups.js +139 -0
  175. package/vendor/gatekeeper/dist/server/routes/groups.js.map +1 -0
  176. package/vendor/gatekeeper/package.json +49 -0
  177. package/vendor/server/bin/lamaste-server.js +204 -0
  178. package/vendor/server/package.json +31 -0
  179. package/vendor/server/src/commands/certs.js +224 -0
  180. package/vendor/server/src/commands/chisel.js +132 -0
  181. package/vendor/server/src/commands/logs.js +49 -0
  182. package/vendor/server/src/commands/plugins.js +321 -0
  183. package/vendor/server/src/commands/reset-admin.js +478 -0
  184. package/vendor/server/src/commands/restart.js +94 -0
  185. package/vendor/server/src/commands/sites.js +257 -0
  186. package/vendor/server/src/commands/status.js +158 -0
  187. package/vendor/server/src/commands/tunnels.js +365 -0
  188. package/vendor/server/src/commands/uninstall.js +326 -0
  189. package/vendor/server/src/config.js +38 -0
  190. package/vendor/server/src/exec.js +26 -0
  191. package/vendor/server/src/logger.js +39 -0
  192. package/vendor/server/src/ndjson.js +56 -0
  193. package/vendor/server/src/panel-api.js +85 -0
  194. package/vendor/server/src/state.js +45 -0
  195. package/vendor/server-ui/dist/assets/index-B0nWuUyL.js +257 -0
  196. package/vendor/server-ui/dist/assets/index-BqWWFlTU.css +1 -0
  197. package/vendor/server-ui/dist/index.html +13 -0
  198. package/vendor/serverd/package.json +44 -0
  199. package/vendor/serverd/src/boot.js +13 -0
  200. package/vendor/serverd/src/index.js +191 -0
  201. package/vendor/serverd/src/lib/app-error.js +14 -0
  202. package/vendor/serverd/src/lib/authelia.js +85 -0
  203. package/vendor/serverd/src/lib/certbot.js +74 -0
  204. package/vendor/serverd/src/lib/chisel-args.js +6 -0
  205. package/vendor/serverd/src/lib/chisel-reconcile.js +232 -0
  206. package/vendor/serverd/src/lib/chisel-runtime.js +46 -0
  207. package/vendor/serverd/src/lib/chisel-users.js +109 -0
  208. package/vendor/serverd/src/lib/chisel.js +81 -0
  209. package/vendor/serverd/src/lib/config.js +190 -0
  210. package/vendor/serverd/src/lib/constants.js +8 -0
  211. package/vendor/serverd/src/lib/csr-signing.js +331 -0
  212. package/vendor/serverd/src/lib/enrollment.js +302 -0
  213. package/vendor/serverd/src/lib/files.js +19 -0
  214. package/vendor/serverd/src/lib/gatekeeper-client.js +135 -0
  215. package/vendor/serverd/src/lib/invite-page.js +281 -0
  216. package/vendor/serverd/src/lib/ip-utils.js +79 -0
  217. package/vendor/serverd/src/lib/migrations/state/0001_enrollment_tokens.sql +17 -0
  218. package/vendor/serverd/src/lib/migrations/state/0002_tickets.sql +70 -0
  219. package/vendor/serverd/src/lib/migrations/state/0003_plugins.sql +15 -0
  220. package/vendor/serverd/src/lib/migrations/state/0004_agents.sql +19 -0
  221. package/vendor/serverd/src/lib/mtls.js +795 -0
  222. package/vendor/serverd/src/lib/nginx.js +1090 -0
  223. package/vendor/serverd/src/lib/pki-paths.js +41 -0
  224. package/vendor/serverd/src/lib/pki-sign.js +103 -0
  225. package/vendor/serverd/src/lib/plugins.js +538 -0
  226. package/vendor/serverd/src/lib/push-install.js +390 -0
  227. package/vendor/serverd/src/lib/revocation.js +112 -0
  228. package/vendor/serverd/src/lib/services.js +131 -0
  229. package/vendor/serverd/src/lib/session.js +151 -0
  230. package/vendor/serverd/src/lib/state-db.js +130 -0
  231. package/vendor/serverd/src/lib/state.js +140 -0
  232. package/vendor/serverd/src/lib/storage.js +63 -0
  233. package/vendor/serverd/src/lib/system-stats.js +58 -0
  234. package/vendor/serverd/src/lib/tickets.js +1556 -0
  235. package/vendor/serverd/src/lib/totp.js +76 -0
  236. package/vendor/serverd/src/lib/tunnel-deps.js +41 -0
  237. package/vendor/serverd/src/lib/user-access-session.js +142 -0
  238. package/vendor/serverd/src/lib/user-access.js +52 -0
  239. package/vendor/serverd/src/middleware/errors.js +63 -0
  240. package/vendor/serverd/src/middleware/mtls.js +120 -0
  241. package/vendor/serverd/src/middleware/onboarding-guard.js +30 -0
  242. package/vendor/serverd/src/middleware/role-guard.js +58 -0
  243. package/vendor/serverd/src/middleware/twofa-session.js +65 -0
  244. package/vendor/serverd/src/middleware/user-access-session.js +52 -0
  245. package/vendor/serverd/src/routes/enrollment.js +120 -0
  246. package/vendor/serverd/src/routes/health.js +22 -0
  247. package/vendor/serverd/src/routes/invite.js +163 -0
  248. package/vendor/serverd/src/routes/management/agents.js +182 -0
  249. package/vendor/serverd/src/routes/management/certs.js +911 -0
  250. package/vendor/serverd/src/routes/management/gatekeeper-proxy.js +160 -0
  251. package/vendor/serverd/src/routes/management/identity.js +107 -0
  252. package/vendor/serverd/src/routes/management/invitations.js +166 -0
  253. package/vendor/serverd/src/routes/management/logs.js +218 -0
  254. package/vendor/serverd/src/routes/management/plugins.js +560 -0
  255. package/vendor/serverd/src/routes/management/services.js +63 -0
  256. package/vendor/serverd/src/routes/management/settings.js +325 -0
  257. package/vendor/serverd/src/routes/management/sites.js +522 -0
  258. package/vendor/serverd/src/routes/management/storage.js +192 -0
  259. package/vendor/serverd/src/routes/management/system.js +201 -0
  260. package/vendor/serverd/src/routes/management/tickets.js +457 -0
  261. package/vendor/serverd/src/routes/management/tunnels.js +709 -0
  262. package/vendor/serverd/src/routes/management/users.js +377 -0
  263. package/vendor/serverd/src/routes/management.js +36 -0
  264. package/vendor/serverd/src/routes/onboarding/dns.js +101 -0
  265. package/vendor/serverd/src/routes/onboarding/domain.js +42 -0
  266. package/vendor/serverd/src/routes/onboarding/index.js +18 -0
  267. package/vendor/serverd/src/routes/onboarding/provision.js +327 -0
  268. package/vendor/serverd/src/routes/onboarding/status.js +12 -0
  269. package/vendor/serverd/src/routes/plugin-router.js +79 -0
  270. package/vendor/serverd/src/routes/user-access.js +389 -0
@@ -0,0 +1,112 @@
1
+ import { z } from 'zod';
2
+ import { createGrant, listGrants, getGrant, revokeGrant, removeGrantsByPrincipal, } from '../../lib/grants.js';
3
+ const CreateGrantSchema = z.object({
4
+ principalType: z.enum(['user', 'group']),
5
+ principalId: z.string().min(1).max(100),
6
+ resourceType: z.string().min(1).max(100),
7
+ resourceId: z.string().min(1).max(500),
8
+ context: z.record(z.unknown()).optional().default({}),
9
+ });
10
+ export async function grantRoutes(fastify) {
11
+ // POST /api/grants — create grant
12
+ fastify.post('/grants', async (request, reply) => {
13
+ let body;
14
+ try {
15
+ body = CreateGrantSchema.parse(request.body);
16
+ }
17
+ catch (err) {
18
+ return reply
19
+ .code(400)
20
+ .send({ error: 'Invalid request body', details: err.errors });
21
+ }
22
+ try {
23
+ const grant = await createGrant(body);
24
+ return reply.code(201).send({ ok: true, grant });
25
+ }
26
+ catch (err) {
27
+ const e = err;
28
+ return reply.code(e.statusCode ?? 500).send({ error: e.message });
29
+ }
30
+ });
31
+ // GET /api/grants — list grants (with optional query filters)
32
+ fastify.get('/grants', async (request, reply) => {
33
+ const query = request.query;
34
+ const filter = {};
35
+ if (query.principalType === 'user' || query.principalType === 'group') {
36
+ filter.principalType = query.principalType;
37
+ }
38
+ if (query.principalId) {
39
+ filter.principalId = query.principalId;
40
+ }
41
+ if (query.resourceType) {
42
+ filter.resourceType = query.resourceType;
43
+ }
44
+ if (query.resourceId) {
45
+ filter.resourceId = query.resourceId;
46
+ }
47
+ if (query.used === 'true' || query.used === 'false') {
48
+ filter.used = query.used === 'true';
49
+ }
50
+ try {
51
+ const grants = await listGrants(Object.keys(filter).length > 0 ? filter : undefined);
52
+ return { grants };
53
+ }
54
+ catch (err) {
55
+ return reply.code(500).send({ error: err.message });
56
+ }
57
+ });
58
+ // GET /api/grants/:grantId — get grant
59
+ fastify.get('/grants/:grantId', async (request, reply) => {
60
+ const { grantId } = request.params;
61
+ try {
62
+ const grant = await getGrant(grantId);
63
+ if (!grant) {
64
+ return reply.code(404).send({ error: 'Grant not found' });
65
+ }
66
+ return { grant };
67
+ }
68
+ catch (err) {
69
+ return reply.code(500).send({ error: err.message });
70
+ }
71
+ });
72
+ // DELETE /api/grants/:grantId — revoke grant
73
+ fastify.delete('/grants/:grantId', async (request, reply) => {
74
+ const { grantId } = request.params;
75
+ try {
76
+ const grant = await revokeGrant(grantId);
77
+ return { ok: true, grant };
78
+ }
79
+ catch (err) {
80
+ const e = err;
81
+ return reply.code(e.statusCode ?? 500).send({ error: e.message });
82
+ }
83
+ });
84
+ // DELETE /api/grants?principalType=user&principalId=<x> —
85
+ // bulk-revoke every grant belonging to a principal. Used by the panel
86
+ // server to cascade Authelia user deletions across gatekeeper grants
87
+ // (and could be used for group hard-deletes in the future).
88
+ fastify.delete('/grants', async (request, reply) => {
89
+ const query = request.query;
90
+ const principalType = query.principalType;
91
+ const principalId = query.principalId;
92
+ if (principalType !== 'user' && principalType !== 'group') {
93
+ return reply.code(400).send({
94
+ error: 'principalType query parameter must be "user" or "group"',
95
+ });
96
+ }
97
+ if (!principalId || principalId.length === 0 || principalId.length > 100) {
98
+ return reply.code(400).send({
99
+ error: 'principalId query parameter is required (1-100 chars)',
100
+ });
101
+ }
102
+ try {
103
+ const removed = await removeGrantsByPrincipal(principalType, principalId);
104
+ return { ok: true, removed };
105
+ }
106
+ catch (err) {
107
+ const e = err;
108
+ return reply.code(e.statusCode ?? 500).send({ error: e.message });
109
+ }
110
+ });
111
+ }
112
+ //# sourceMappingURL=grants.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"grants.js","sourceRoot":"","sources":["../../../src/server/routes/grants.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,3 @@
1
+ import type { FastifyInstance } from 'fastify';
2
+ export declare function groupRoutes(fastify: FastifyInstance): Promise<void>;
3
+ //# sourceMappingURL=groups.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"groups.d.ts","sourceRoot":"","sources":["../../../src/server/routes/groups.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,eAAe,EAAgC,MAAM,SAAS,CAAC;AAoC7E,wBAAsB,WAAW,CAAC,OAAO,EAAE,eAAe,GAAG,OAAO,CAAC,IAAI,CAAC,CAoHzE"}
@@ -0,0 +1,139 @@
1
+ import { z } from 'zod';
2
+ import { createGroup, listGroups, getGroup, updateGroup, deleteGroup, addMembers, removeMembers, } from '../../lib/groups.js';
3
+ const CreateGroupSchema = z.object({
4
+ name: z
5
+ .string()
6
+ .min(2)
7
+ .max(63)
8
+ .regex(/^[a-z0-9]([a-z0-9-]*[a-z0-9])?$/),
9
+ description: z.string().max(500).optional().default(''),
10
+ createdBy: z.string().max(100).optional(),
11
+ });
12
+ const UpdateGroupSchema = z.object({
13
+ name: z
14
+ .string()
15
+ .min(2)
16
+ .max(63)
17
+ .regex(/^[a-z0-9]([a-z0-9-]*[a-z0-9])?$/)
18
+ .optional(),
19
+ description: z.string().max(500).optional(),
20
+ });
21
+ const AddMembersSchema = z.object({
22
+ usernames: z.array(z.string().min(1).max(100)).min(1).max(50),
23
+ });
24
+ export async function groupRoutes(fastify) {
25
+ // POST /api/groups — create group
26
+ fastify.post('/groups', async (request, reply) => {
27
+ let body;
28
+ try {
29
+ body = CreateGroupSchema.parse(request.body);
30
+ }
31
+ catch (err) {
32
+ return reply
33
+ .code(400)
34
+ .send({ error: 'Invalid request body', details: err.errors });
35
+ }
36
+ try {
37
+ const group = await createGroup(body.name, {
38
+ description: body.description,
39
+ createdBy: body.createdBy,
40
+ });
41
+ return reply.code(201).send({ ok: true, group });
42
+ }
43
+ catch (err) {
44
+ const e = err;
45
+ return reply.code(e.statusCode ?? 500).send({ error: e.message });
46
+ }
47
+ });
48
+ // GET /api/groups — list all groups
49
+ fastify.get('/groups', async (_request, reply) => {
50
+ try {
51
+ const groups = await listGroups();
52
+ return { groups };
53
+ }
54
+ catch (err) {
55
+ return reply.code(500).send({ error: err.message });
56
+ }
57
+ });
58
+ // GET /api/groups/:name — get group
59
+ fastify.get('/groups/:name', async (request, reply) => {
60
+ const { name } = request.params;
61
+ try {
62
+ const group = await getGroup(name);
63
+ if (!group) {
64
+ return reply.code(404).send({ error: `Group "${name}" not found` });
65
+ }
66
+ return { group };
67
+ }
68
+ catch (err) {
69
+ return reply.code(500).send({ error: err.message });
70
+ }
71
+ });
72
+ // PATCH /api/groups/:name — update group
73
+ fastify.patch('/groups/:name', async (request, reply) => {
74
+ const { name } = request.params;
75
+ let body;
76
+ try {
77
+ body = UpdateGroupSchema.parse(request.body);
78
+ }
79
+ catch (err) {
80
+ return reply
81
+ .code(400)
82
+ .send({ error: 'Invalid request body', details: err.errors });
83
+ }
84
+ try {
85
+ const group = await updateGroup(name, body);
86
+ return { ok: true, group };
87
+ }
88
+ catch (err) {
89
+ const e = err;
90
+ return reply.code(e.statusCode ?? 500).send({ error: e.message });
91
+ }
92
+ });
93
+ // DELETE /api/groups/:name — delete group + auto-revoke grants
94
+ fastify.delete('/groups/:name', async (request, reply) => {
95
+ const { name } = request.params;
96
+ try {
97
+ const result = await deleteGroup(name);
98
+ return { ok: true, deletedGrants: result.deletedGrants };
99
+ }
100
+ catch (err) {
101
+ const e = err;
102
+ return reply.code(e.statusCode ?? 500).send({ error: e.message });
103
+ }
104
+ });
105
+ // POST /api/groups/:name/members — add members
106
+ fastify.post('/groups/:name/members', async (request, reply) => {
107
+ const { name } = request.params;
108
+ let body;
109
+ try {
110
+ body = AddMembersSchema.parse(request.body);
111
+ }
112
+ catch (err) {
113
+ return reply
114
+ .code(400)
115
+ .send({ error: 'Invalid request body', details: err.errors });
116
+ }
117
+ try {
118
+ const group = await addMembers(name, body.usernames);
119
+ return { ok: true, group };
120
+ }
121
+ catch (err) {
122
+ const e = err;
123
+ return reply.code(e.statusCode ?? 500).send({ error: e.message });
124
+ }
125
+ });
126
+ // DELETE /api/groups/:name/members/:username — remove member
127
+ fastify.delete('/groups/:name/members/:username', async (request, reply) => {
128
+ const { name, username } = request.params;
129
+ try {
130
+ const group = await removeMembers(name, [username]);
131
+ return { ok: true, group };
132
+ }
133
+ catch (err) {
134
+ const e = err;
135
+ return reply.code(e.statusCode ?? 500).send({ error: e.message });
136
+ }
137
+ });
138
+ }
139
+ //# sourceMappingURL=groups.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"groups.js","sourceRoot":"","sources":["../../../src/server/routes/groups.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,49 @@
1
+ {
2
+ "name": "@lamalibre/lamaste-gatekeeper",
3
+ "version": "4.0.0",
4
+ "description": "Authorization layer for Lamaste — groups, grants, and tunnel access control",
5
+ "type": "module",
6
+ "exports": {
7
+ ".": {
8
+ "types": "./dist/index.d.ts",
9
+ "import": "./dist/index.js"
10
+ },
11
+ "./server": {
12
+ "types": "./dist/server/index.d.ts",
13
+ "import": "./dist/server/index.js"
14
+ },
15
+ "./cli": {
16
+ "types": "./dist/cli/index.d.ts",
17
+ "import": "./dist/cli/index.js"
18
+ }
19
+ },
20
+ "bin": {
21
+ "lamaste-gatekeeper": "dist/cli/index.js"
22
+ },
23
+ "files": [
24
+ "dist"
25
+ ],
26
+ "scripts": {
27
+ "build": "tsc -p tsconfig.json && cp -R src/lib/migrations dist/lib/migrations"
28
+ },
29
+ "engines": {
30
+ "node": ">=22.5.0 <25.0.0"
31
+ },
32
+ "dependencies": {
33
+ "@fastify/rate-limit": "^10.3.0",
34
+ "@lamalibre/lamaste": "*",
35
+ "fastify": "^5.3.3",
36
+ "undici": "^7.8.0",
37
+ "zod": "^3.24.4"
38
+ },
39
+ "devDependencies": {
40
+ "@types/node": "^22.15.18",
41
+ "typescript": "^5.8.3"
42
+ },
43
+ "repository": {
44
+ "type": "git",
45
+ "url": "https://github.com/lamalibre/lamaste.git",
46
+ "directory": "packages/sdks/gatekeeper"
47
+ },
48
+ "license": "SEE LICENSE IN LICENSE.md"
49
+ }
@@ -0,0 +1,204 @@
1
+ #!/usr/bin/env node
2
+
3
+ /**
4
+ * lamaste-server — Server operations CLI for Lamaste.
5
+ *
6
+ * Provides administrative commands for managing a Lamaste server installation.
7
+ * All commands operate on /etc/lamalibre/lamaste/ and require root access on the server.
8
+ *
9
+ * Global flags:
10
+ * --json Output NDJSON for automation / desktop app integration
11
+ *
12
+ * Commands:
13
+ * status Server health, uptime, resource usage
14
+ * logs View server log output (journalctl)
15
+ * restart Restart panel server (and optionally gatekeeper)
16
+ * plugins Manage server-side plugins
17
+ * tunnels Manage tunnels
18
+ * sites Manage static sites
19
+ * certs Certificate status and renewal
20
+ * reset-admin Emergency admin authentication reset
21
+ * uninstall Full server teardown
22
+ */
23
+
24
+ import chalk from 'chalk';
25
+
26
+ /**
27
+ * Extract the --json global flag from argv.
28
+ * @param {string[]} rawArgs
29
+ * @returns {{ json: boolean, args: string[] }}
30
+ */
31
+ function extractGlobalFlags(rawArgs) {
32
+ let json = false;
33
+ const filtered = [];
34
+ for (const arg of rawArgs) {
35
+ if (arg === '--json') {
36
+ json = true;
37
+ } else {
38
+ filtered.push(arg);
39
+ }
40
+ }
41
+ return { json, args: filtered };
42
+ }
43
+
44
+ function printHelp() {
45
+ const b = chalk.bold;
46
+ const c = chalk.cyan;
47
+ const d = chalk.dim;
48
+
49
+ console.log(`
50
+ ${b('lamaste-server')} — server operations CLI for Lamaste
51
+
52
+ ${b('USAGE')}
53
+
54
+ ${c('lamaste-server')} ${d('[--json] <command> [args]')}
55
+
56
+ ${b('COMMANDS')}
57
+
58
+ ${c('status')} Server health, uptime, services, certificate status
59
+ ${c('logs')} View server log output (journalctl wrapper)
60
+ ${c('restart')} Restart panel server and optionally gatekeeper
61
+ ${c('plugins')} Manage server-side plugins (list, install, enable, disable, uninstall)
62
+ ${c('tunnels')} Manage tunnels (list, create, delete, toggle)
63
+ ${c('sites')} Manage static sites (list, create, delete)
64
+ ${c('certs')} Certificate status, renewal, and agent cert listing
65
+ ${c('reset-admin')} Emergency admin reset (reverts to P12, clears 2FA)
66
+ ${c('chisel')} Manage chisel tunnel-server credentials (rotate-credential)
67
+ ${c('uninstall')} Full server teardown (requires confirmation)
68
+
69
+ ${b('GLOBAL FLAGS')}
70
+
71
+ ${c('--json')} Output NDJSON for automation and desktop app integration
72
+
73
+ ${b('EXAMPLES')}
74
+
75
+ ${d('# Check server status')}
76
+ ${c('lamaste-server status')}
77
+
78
+ ${d('# View recent panel logs')}
79
+ ${c('lamaste-server logs --lines 100')}
80
+
81
+ ${d('# Follow logs in real time')}
82
+ ${c('lamaste-server logs --follow')}
83
+
84
+ ${d('# Restart the panel server')}
85
+ ${c('lamaste-server restart')}
86
+
87
+ ${d('# Restart both panel and gatekeeper')}
88
+ ${c('lamaste-server restart --all')}
89
+
90
+ ${d('# List installed plugins')}
91
+ ${c('lamaste-server plugins list')}
92
+
93
+ ${d('# Install a plugin')}
94
+ ${c('lamaste-server plugins install @lamalibre/herd-server')}
95
+
96
+ ${d('# List tunnels')}
97
+ ${c('lamaste-server tunnels list')}
98
+
99
+ ${d('# Create a tunnel')}
100
+ ${c('lamaste-server tunnels create --subdomain myapp --port 3000')}
101
+
102
+ ${d('# Check certificate status')}
103
+ ${c('lamaste-server certs status')}
104
+
105
+ ${d('# Emergency admin reset (run as root on server)')}
106
+ ${d('# The new P12 password is written to /etc/lamalibre/lamaste/pki/.p12-password (mode 0600).')}
107
+ ${d('# In TTY mode the password also prints to STDERR so you can redirect stdout safely.')}
108
+ ${d('# Optional: --password-file <path> writes the password to a custom location too.')}
109
+ ${c('sudo lamaste-server reset-admin')}
110
+
111
+ ${d('# Full server removal')}
112
+ ${c('sudo lamaste-server uninstall')}
113
+ `);
114
+ process.exit(0);
115
+ }
116
+
117
+ async function main() {
118
+ const rawArgs = process.argv.slice(2);
119
+ const { json, args } = extractGlobalFlags(rawArgs);
120
+ const command = args[0];
121
+
122
+ if (!command || command === '--help' || command === '-h') {
123
+ printHelp();
124
+ }
125
+
126
+ switch (command) {
127
+ case 'status': {
128
+ const { runStatus } = await import('../src/commands/status.js');
129
+ await runStatus({ json });
130
+ break;
131
+ }
132
+ case 'logs': {
133
+ const { runLogs } = await import('../src/commands/logs.js');
134
+ await runLogs(args.slice(1), { json });
135
+ break;
136
+ }
137
+ case 'restart': {
138
+ const { runRestart } = await import('../src/commands/restart.js');
139
+ await runRestart(args.slice(1), { json });
140
+ break;
141
+ }
142
+ case 'plugins': {
143
+ const { runPlugins } = await import('../src/commands/plugins.js');
144
+ await runPlugins(args.slice(1), { json });
145
+ break;
146
+ }
147
+ case 'tunnels': {
148
+ const { runTunnels } = await import('../src/commands/tunnels.js');
149
+ await runTunnels(args.slice(1), { json });
150
+ break;
151
+ }
152
+ case 'sites': {
153
+ const { runSites } = await import('../src/commands/sites.js');
154
+ await runSites(args.slice(1), { json });
155
+ break;
156
+ }
157
+ case 'certs': {
158
+ const { runCerts } = await import('../src/commands/certs.js');
159
+ await runCerts(args.slice(1), { json });
160
+ break;
161
+ }
162
+ case 'reset-admin': {
163
+ const { runResetAdmin } = await import('../src/commands/reset-admin.js');
164
+ const subArgs = args.slice(1);
165
+ const pwIdx = subArgs.indexOf('--password-file');
166
+ let passwordFile;
167
+ if (pwIdx !== -1) {
168
+ passwordFile = subArgs[pwIdx + 1];
169
+ if (!passwordFile) {
170
+ console.error(`\n Error: --password-file requires a path argument.\n`);
171
+ process.exit(1);
172
+ }
173
+ }
174
+ await runResetAdmin({ json, passwordFile });
175
+ break;
176
+ }
177
+ case 'chisel': {
178
+ const { runChisel } = await import('../src/commands/chisel.js');
179
+ await runChisel(args.slice(1), { json });
180
+ break;
181
+ }
182
+ case 'uninstall': {
183
+ const { runUninstall } = await import('../src/commands/uninstall.js');
184
+ await runUninstall(args.slice(1), { json });
185
+ break;
186
+ }
187
+ default:
188
+ if (json) {
189
+ process.stdout.write(
190
+ JSON.stringify({ event: 'error', message: `Unknown command: ${command}` }) + '\n',
191
+ );
192
+ } else {
193
+ console.error(`\n Unknown command: ${chalk.red(command)}`);
194
+ console.error(` Run ${chalk.cyan('lamaste-server --help')} for usage.\n`);
195
+ }
196
+ process.exit(1);
197
+ }
198
+ }
199
+
200
+ main().catch((err) => {
201
+ const msg = err instanceof Error ? err.message : String(err);
202
+ process.stderr.write(`\n Fatal error: ${msg}\n\n`);
203
+ process.exit(1);
204
+ });
@@ -0,0 +1,31 @@
1
+ {
2
+ "name": "@lamalibre/lamaste-server",
3
+ "version": "4.0.0",
4
+ "description": "Server operations CLI for Lamaste",
5
+ "type": "module",
6
+ "license": "SEE LICENSE IN LICENSE.md",
7
+ "author": "Code Lama Software",
8
+ "bin": {
9
+ "lamaste-server": "bin/lamaste-server.js"
10
+ },
11
+ "files": [
12
+ "bin",
13
+ "src"
14
+ ],
15
+ "scripts": {
16
+ "lint": "echo 'No lint configured'"
17
+ },
18
+ "dependencies": {
19
+ "@lamalibre/lamaste": "^4.0.0",
20
+ "chalk": "^5.3.0",
21
+ "execa": "^9.0.0"
22
+ },
23
+ "repository": {
24
+ "type": "git",
25
+ "url": "https://github.com/lamalibre/lamaste.git",
26
+ "directory": "packages/server/cli"
27
+ },
28
+ "engines": {
29
+ "node": ">=20.0.0"
30
+ }
31
+ }