@simplens/onboard 1.0.4 → 1.0.6

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 (46) hide show
  1. package/README.md +43 -9
  2. package/dist/__tests__/infra-prompts.test.js +3 -1
  3. package/dist/__tests__/infra-prompts.test.js.map +1 -1
  4. package/dist/__tests__/infra.test.js +13 -0
  5. package/dist/__tests__/infra.test.js.map +1 -1
  6. package/dist/__tests__/validators.test.js +21 -1
  7. package/dist/__tests__/validators.test.js.map +1 -1
  8. package/dist/config/constants.d.ts.map +1 -1
  9. package/dist/config/constants.js +0 -1
  10. package/dist/config/constants.js.map +1 -1
  11. package/dist/env-config.d.ts +1 -1
  12. package/dist/env-config.d.ts.map +1 -1
  13. package/dist/env-config.js +46 -6
  14. package/dist/env-config.js.map +1 -1
  15. package/dist/index.js +135 -19
  16. package/dist/index.js.map +1 -1
  17. package/dist/infra.d.ts +12 -3
  18. package/dist/infra.d.ts.map +1 -1
  19. package/dist/infra.js +95 -23
  20. package/dist/infra.js.map +1 -1
  21. package/dist/services.d.ts +12 -0
  22. package/dist/services.d.ts.map +1 -1
  23. package/dist/services.js +50 -0
  24. package/dist/services.js.map +1 -1
  25. package/dist/templates.d.ts +5 -1
  26. package/dist/templates.d.ts.map +1 -1
  27. package/dist/templates.js +66 -1
  28. package/dist/templates.js.map +1 -1
  29. package/dist/types/domain.d.ts +6 -0
  30. package/dist/types/domain.d.ts.map +1 -1
  31. package/dist/validators.d.ts +9 -0
  32. package/dist/validators.d.ts.map +1 -1
  33. package/dist/validators.js +38 -0
  34. package/dist/validators.js.map +1 -1
  35. package/package.json +1 -1
  36. package/src/__tests__/infra-prompts.test.ts +3 -1
  37. package/src/__tests__/infra.test.ts +15 -0
  38. package/src/__tests__/validators.test.ts +27 -1
  39. package/src/config/constants.ts +0 -1
  40. package/src/env-config.ts +51 -6
  41. package/src/index.ts +145 -18
  42. package/src/infra.ts +120 -24
  43. package/src/services.ts +72 -0
  44. package/src/templates.ts +70 -1
  45. package/src/types/domain.ts +6 -0
  46. package/src/validators.ts +51 -0
package/src/templates.ts CHANGED
@@ -127,8 +127,11 @@ export const APP_COMPOSE_TEMPLATE = `services:
127
127
  - 3000:3000
128
128
  env_file:
129
129
  - .env
130
+ environment:
131
+ SIMPLENS_CONFIG_PATH: \${SIMPLENS_CONFIG_PATH:-/app/simplens.config.yaml}
130
132
  volumes:
131
133
  - plugin-data:/app/.plugins
134
+ - logs-data:/app/logs
132
135
  - ./simplens.config.yaml:/app/simplens.config.yaml:ro
133
136
  command: [ "node", "dist/api/server.js" ]
134
137
  restart: unless-stopped
@@ -143,6 +146,8 @@ export const APP_COMPOSE_TEMPLATE = `services:
143
146
  image: ghcr.io/simplenotificationsystem/simplens-core:\${CORE_VERSION:-latest}
144
147
  env_file:
145
148
  - .env
149
+ volumes:
150
+ - logs-data:/app/logs
146
151
  command: [ "node", "dist/workers/worker.js" ]
147
152
  restart: unless-stopped
148
153
 
@@ -150,8 +155,11 @@ export const APP_COMPOSE_TEMPLATE = `services:
150
155
  image: ghcr.io/simplenotificationsystem/simplens-core:\${CORE_VERSION:-latest}
151
156
  env_file:
152
157
  - .env
158
+ environment:
159
+ SIMPLENS_CONFIG_PATH: \${SIMPLENS_CONFIG_PATH:-/app/simplens.config.yaml}
153
160
  volumes:
154
161
  - plugin-data:/app/.plugins
162
+ - logs-data:/app/logs
155
163
  - ./simplens.config.yaml:/app/simplens.config.yaml:ro
156
164
  command: [ "node", "dist/processors/unified/unified.processor.js" ]
157
165
  depends_on:
@@ -163,6 +171,8 @@ export const APP_COMPOSE_TEMPLATE = `services:
163
171
  image: ghcr.io/simplenotificationsystem/simplens-core:\${CORE_VERSION:-latest}
164
172
  env_file:
165
173
  - .env
174
+ volumes:
175
+ - logs-data:/app/logs
166
176
  command: [ "node", "dist/processors/delayed/delayed.processor.js" ]
167
177
  restart: unless-stopped
168
178
 
@@ -170,6 +180,8 @@ export const APP_COMPOSE_TEMPLATE = `services:
170
180
  image: ghcr.io/simplenotificationsystem/simplens-core:\${CORE_VERSION:-latest}
171
181
  env_file:
172
182
  - .env
183
+ volumes:
184
+ - logs-data:/app/logs
173
185
  command: [ "node", "dist/workers/recovery/recovery.service.js" ]
174
186
  restart: unless-stopped
175
187
 
@@ -185,11 +197,11 @@ export const APP_COMPOSE_TEMPLATE = `services:
185
197
  API_BASE_URL: http://api:\${PORT:-3000}
186
198
  WEBHOOK_HOST: dashboard
187
199
  WEBHOOK_PORT: \${DASHBOARD_PORT:-3002}
188
- NEXT_PUBLIC_BASE_PATH: \${BASE_PATH:-}
189
200
  restart: unless-stopped
190
201
 
191
202
  volumes:
192
203
  plugin-data:
204
+ logs-data:
193
205
 
194
206
  networks:
195
207
  default:
@@ -207,3 +219,60 @@ export const APP_NGINX_SERVICE_TEMPLATE = ` nginx:
207
219
  - api
208
220
  - dashboard
209
221
  restart: unless-stopped`;
222
+
223
+ export const APP_NGINX_SSL_SERVICE_TEMPLATE = ` nginx:
224
+ image: nginx:alpine
225
+ container_name: nginx
226
+ ports:
227
+ - "80:80"
228
+ - "443:443"
229
+ volumes:
230
+ - "./nginx.conf:/etc/nginx/conf.d/default.conf:ro"
231
+ - certbot-etc:/etc/letsencrypt
232
+ - certbot-www:/var/www/certbot
233
+ depends_on:
234
+ - api
235
+ - dashboard
236
+ restart: unless-stopped`;
237
+
238
+ export const APP_CERTBOT_SERVICES_TEMPLATE = ` certbot:
239
+ image: certbot/certbot:latest
240
+ container_name: certbot
241
+ volumes:
242
+ - certbot-etc:/etc/letsencrypt
243
+ - certbot-www:/var/www/certbot
244
+ command: sh -c "trap exit TERM; while :; do sleep 86400; done"
245
+ restart: unless-stopped
246
+
247
+ certbot-renew:
248
+ image: docker:cli
249
+ container_name: certbot-renew
250
+ volumes:
251
+ - /var/run/docker.sock:/var/run/docker.sock
252
+ depends_on:
253
+ - certbot
254
+ - nginx
255
+ command: sh -c "while :; do sleep 12h; docker exec certbot certbot renew --webroot -w /var/www/certbot --quiet && docker exec nginx nginx -s reload || true; done"
256
+ restart: unless-stopped`;
257
+
258
+ export const INFRA_CERTBOT_SERVICES_TEMPLATE = ` certbot:
259
+ image: certbot/certbot:latest
260
+ container_name: certbot
261
+ volumes:
262
+ - certbot-etc:/etc/letsencrypt
263
+ - certbot-www:/var/www/certbot
264
+ command: sh -c "trap exit TERM; while :; do sleep 86400; done"
265
+ restart: unless-stopped
266
+
267
+ certbot-renew:
268
+ image: docker:cli
269
+ container_name: certbot-renew
270
+ volumes:
271
+ - /var/run/docker.sock:/var/run/docker.sock
272
+ depends_on:
273
+ - certbot
274
+ - nginx
275
+ command: sh -c "while :; do sleep 12h; docker exec certbot certbot renew --webroot -w /var/www/certbot --quiet && docker exec nginx nginx -s reload || true; done"
276
+ restart: unless-stopped`;
277
+
278
+ export const INFRA_CERTBOT_VOLUMES = ['certbot-etc', 'certbot-www'] as const;
@@ -52,6 +52,12 @@ export interface SetupOptions {
52
52
  targetDir: string;
53
53
  /** Dashboard base path (empty string means root) */
54
54
  basePath: string;
55
+ /** Whether SSL automation with Certbot is enabled */
56
+ enableSsl?: boolean;
57
+ /** Public domain for SSL certificate */
58
+ sslDomain?: string;
59
+ /** Registration email for Let's Encrypt */
60
+ sslEmail?: string;
55
61
  }
56
62
 
57
63
  /**
package/src/validators.ts CHANGED
@@ -10,6 +10,57 @@ import { VALIDATION } from './config/constants.js';
10
10
 
11
11
  export type OSType = 'windows' | 'linux' | 'darwin';
12
12
 
13
+ /**
14
+ * Validate a public domain used for ACME/Certbot.
15
+ * Accepts FQDN only (no protocol, path, query, port, or wildcard).
16
+ */
17
+ export function validatePublicDomain(input: string): true | string {
18
+ const value = input.trim().toLowerCase();
19
+
20
+ if (!value) {
21
+ return 'Domain is required';
22
+ }
23
+
24
+ if (
25
+ value.includes('://') ||
26
+ value.includes('/') ||
27
+ value.includes('?') ||
28
+ value.includes('#') ||
29
+ value.includes(':') ||
30
+ value.includes('*')
31
+ ) {
32
+ return 'Enter only a domain name (example: app.example.com)';
33
+ }
34
+
35
+ // RFC-ish practical FQDN validation
36
+ const domainRegex =
37
+ /^(?=.{1,253}$)(?:[a-z0-9](?:[a-z0-9-]{0,61}[a-z0-9])?\.)+[a-z]{2,63}$/;
38
+
39
+ if (!domainRegex.test(value)) {
40
+ return 'Invalid domain format (example: app.example.com)';
41
+ }
42
+
43
+ return true;
44
+ }
45
+
46
+ /**
47
+ * Validate email format for Let's Encrypt registration.
48
+ */
49
+ export function validateEmailAddress(input: string): true | string {
50
+ const value = input.trim();
51
+
52
+ if (!value) {
53
+ return 'Email is required';
54
+ }
55
+
56
+ const emailRegex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
57
+ if (!emailRegex.test(value)) {
58
+ return 'Invalid email format (example: admin@example.com)';
59
+ }
60
+
61
+ return true;
62
+ }
63
+
13
64
  /**
14
65
  * Checks if Docker is installed on the system by running `docker --version`.
15
66
  *