@crombolo/server 0.10.0 → 0.12.1

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 (44) hide show
  1. package/package.json +12 -11
  2. package/src/adapters/audit.ts +186 -0
  3. package/src/adapters/content.ts +2 -0
  4. package/src/adapters/documents.ts +28 -25
  5. package/src/adapters/elements.ts +3 -0
  6. package/src/adapters/health.ts +333 -0
  7. package/src/adapters/media.ts +3 -0
  8. package/src/adapters/members.ts +10 -2
  9. package/src/adapters/references.ts +13 -0
  10. package/src/adapters/relations.ts +48 -0
  11. package/src/adapters/schema-files.ts +41 -11
  12. package/src/adapters/schema-proposals.ts +13 -6
  13. package/src/adapters/search-index.ts +31 -0
  14. package/src/adapters/webhooks.ts +76 -0
  15. package/src/boot-failure.ts +147 -0
  16. package/src/bundle-install.ts +148 -13
  17. package/src/bundles.ts +14 -0
  18. package/src/busy.ts +13 -0
  19. package/src/config.ts +46 -2
  20. package/src/database.ts +9 -7
  21. package/src/delivery-members.ts +387 -0
  22. package/src/editor-types.ts +7 -2
  23. package/src/extensions-notice.ts +3 -2
  24. package/src/form-files.ts +38 -3
  25. package/src/form-submit.ts +62 -5
  26. package/src/form-types.ts +187 -0
  27. package/src/form-workflows.ts +66 -6
  28. package/src/forms.ts +15 -7
  29. package/src/index.ts +12 -0
  30. package/src/jobs.ts +91 -10
  31. package/src/media-files.ts +3 -1
  32. package/src/member-auth.ts +17 -1
  33. package/src/models-builder.ts +12 -8
  34. package/src/ports.ts +57 -2
  35. package/src/schema.ts +58 -11
  36. package/src/secrets.ts +36 -0
  37. package/src/server.ts +388 -29
  38. package/src/setup.ts +288 -0
  39. package/src/status.ts +5 -2
  40. package/src/transfer-dashboard.ts +219 -0
  41. package/src/upgrade-summary.ts +43 -0
  42. package/src/url-settings.ts +91 -0
  43. package/src/webhook-files.ts +138 -0
  44. package/src/webhooks.ts +544 -0
package/src/secrets.ts ADDED
@@ -0,0 +1,36 @@
1
+ /**
2
+ * Secrets kept in the database, sealed with `CROMBOLO_SECRET_KEY`: AES-256-GCM,
3
+ * so a value cannot be read or quietly altered without the key. The key lives
4
+ * only in the environment, so a database dump alone reveals nothing.
5
+ * docs/webhooks.md.
6
+ */
7
+ import { createCipheriv, createDecipheriv, createHash, randomBytes } from 'node:crypto'
8
+
9
+ export const SECRET_KEY_VARIABLE = 'CROMBOLO_SECRET_KEY'
10
+ export const MIN_SECRET_KEY_LENGTH = 32
11
+
12
+ const VERSION = 'v1'
13
+
14
+ /** The configured key, or undefined when it is missing or too short to trust. */
15
+ export function usableSecretKey(value: string | undefined): string | undefined {
16
+ return value && value.length >= MIN_SECRET_KEY_LENGTH ? value : undefined
17
+ }
18
+
19
+ const keyBytes = (key: string) => createHash('sha256').update(key, 'utf8').digest()
20
+
21
+ export function sealSecret(plain: string, key: string): string {
22
+ const iv = randomBytes(12)
23
+ const cipher = createCipheriv('aes-256-gcm', keyBytes(key), iv)
24
+ const body = Buffer.concat([cipher.update(plain, 'utf8'), cipher.final()])
25
+ return `${VERSION}:${Buffer.concat([iv, cipher.getAuthTag(), body]).toString('base64')}`
26
+ }
27
+
28
+ /** Throws when the value was sealed with another key, or has been altered. */
29
+ export function openSecret(sealed: string, key: string): string {
30
+ const [version, encoded] = sealed.split(':', 2)
31
+ if (version !== VERSION || !encoded) throw new Error('Not a sealed secret.')
32
+ const raw = Buffer.from(encoded, 'base64')
33
+ const decipher = createDecipheriv('aes-256-gcm', keyBytes(key), raw.subarray(0, 12))
34
+ decipher.setAuthTag(raw.subarray(12, 28))
35
+ return Buffer.concat([decipher.update(raw.subarray(28)), decipher.final()]).toString('utf8')
36
+ }