@striae-org/striae 5.2.0 → 5.3.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 (105) hide show
  1. package/.env.example +36 -33
  2. package/README.md +5 -46
  3. package/app/components/actions/case-export/core-export.ts +2 -174
  4. package/app/components/actions/case-export/download-handlers.ts +83 -750
  5. package/app/components/actions/case-export/index.ts +6 -30
  6. package/app/components/actions/case-export/metadata-helpers.ts +0 -78
  7. package/app/components/actions/case-export/types-constants.ts +0 -43
  8. package/app/components/actions/case-import/confirmation-import.ts +13 -14
  9. package/app/components/actions/case-import/zip-processing.ts +92 -12
  10. package/app/components/actions/generate-pdf.ts +3 -2
  11. package/app/components/audit/user-audit-viewer.tsx +0 -19
  12. package/app/components/audit/viewer/audit-viewer-header.tsx +0 -33
  13. package/app/components/navbar/case-modals/archive-case-modal.tsx +1 -1
  14. package/app/components/navbar/navbar.tsx +1 -1
  15. package/app/components/sidebar/case-import/case-import.module.css +35 -0
  16. package/app/components/sidebar/case-import/components/CasePreviewSection.tsx +59 -3
  17. package/app/components/sidebar/case-import/components/ConfirmationDialog.tsx +2 -4
  18. package/app/components/sidebar/case-import/components/ConfirmationPreviewSection.tsx +1 -1
  19. package/app/components/sidebar/notes/class-details-shared.ts +2 -2
  20. package/app/components/toast/toast.module.css +36 -0
  21. package/app/components/toast/toast.tsx +6 -2
  22. package/app/components/user/manage-profile.tsx +4 -3
  23. package/app/config-example/config.json +1 -2
  24. package/app/root.tsx +0 -7
  25. package/app/routes/_index.tsx +1 -1
  26. package/app/routes/auth/login.example.tsx +22 -103
  27. package/app/routes/auth/route.ts +1 -1
  28. package/app/routes/striae/striae.tsx +53 -59
  29. package/app/services/firebase/index.ts +0 -3
  30. package/app/types/export.ts +1 -2
  31. package/app/utils/auth/index.ts +0 -1
  32. package/app/utils/data/permissions.ts +3 -2
  33. package/package.json +10 -17
  34. package/public/_headers +0 -4
  35. package/public/_routes.json +0 -1
  36. package/worker-configuration.d.ts +20 -17
  37. package/workers/audit-worker/src/audit-worker.example.ts +9 -806
  38. package/workers/audit-worker/src/config.ts +7 -0
  39. package/workers/audit-worker/src/crypto/data-at-rest.ts +410 -0
  40. package/workers/audit-worker/src/handlers/audit-routes.ts +125 -0
  41. package/workers/audit-worker/src/storage/audit-storage.ts +99 -0
  42. package/workers/audit-worker/src/types.ts +56 -0
  43. package/workers/audit-worker/worker-configuration.d.ts +1 -1
  44. package/workers/audit-worker/wrangler.jsonc.example +1 -1
  45. package/workers/data-worker/src/config.ts +11 -0
  46. package/workers/data-worker/src/data-worker.example.ts +21 -942
  47. package/workers/data-worker/src/handlers/decrypt-export.ts +118 -0
  48. package/workers/data-worker/src/handlers/signing.ts +174 -0
  49. package/workers/data-worker/src/handlers/storage-routes.ts +129 -0
  50. package/workers/data-worker/src/registry/key-registry.ts +368 -0
  51. package/workers/data-worker/src/types.ts +46 -0
  52. package/workers/data-worker/worker-configuration.d.ts +1 -1
  53. package/workers/data-worker/wrangler.jsonc.example +1 -1
  54. package/workers/image-worker/worker-configuration.d.ts +1 -1
  55. package/workers/image-worker/wrangler.jsonc.example +1 -1
  56. package/workers/pdf-worker/worker-configuration.d.ts +2 -3
  57. package/workers/pdf-worker/wrangler.jsonc.example +1 -1
  58. package/workers/user-worker/src/auth.ts +30 -0
  59. package/workers/user-worker/src/cleanup/account-deletion.ts +337 -0
  60. package/workers/user-worker/src/config.ts +4 -0
  61. package/workers/user-worker/src/encryption-utils.ts +25 -0
  62. package/workers/user-worker/src/firebase/admin.ts +152 -0
  63. package/workers/user-worker/src/handlers/user-routes.ts +242 -0
  64. package/workers/user-worker/src/registry/user-kv.ts +172 -0
  65. package/workers/user-worker/src/storage/user-records.ts +34 -0
  66. package/workers/user-worker/src/types.ts +106 -0
  67. package/workers/user-worker/src/user-worker.example.ts +18 -964
  68. package/workers/user-worker/worker-configuration.d.ts +4 -2
  69. package/workers/user-worker/wrangler.jsonc.example +12 -1
  70. package/wrangler.toml.example +1 -1
  71. package/app/components/actions/case-export/data-processing.ts +0 -223
  72. package/app/components/sidebar/case-export/case-export.module.css +0 -418
  73. package/app/components/sidebar/case-export/case-export.tsx +0 -310
  74. package/app/types/exceljs-bare.d.ts +0 -9
  75. package/app/utils/auth/auth.ts +0 -11
  76. package/public/.well-known/security.txt +0 -6
  77. package/public/favicon.ico +0 -0
  78. package/public/icon-256.png +0 -0
  79. package/public/icon-512.png +0 -0
  80. package/public/manifest.json +0 -39
  81. package/public/shortcut.png +0 -0
  82. package/public/social-image.png +0 -0
  83. package/public/vendor/exceljs.LICENSE +0 -22
  84. package/public/vendor/exceljs.bare.min.js +0 -45
  85. package/scripts/deploy-all.sh +0 -166
  86. package/scripts/deploy-config/modules/env-utils.sh +0 -322
  87. package/scripts/deploy-config/modules/keys.sh +0 -404
  88. package/scripts/deploy-config/modules/prompt.sh +0 -372
  89. package/scripts/deploy-config/modules/scaffolding.sh +0 -336
  90. package/scripts/deploy-config/modules/validation.sh +0 -365
  91. package/scripts/deploy-config.sh +0 -236
  92. package/scripts/deploy-pages-secrets.sh +0 -231
  93. package/scripts/deploy-pages.sh +0 -34
  94. package/scripts/deploy-primershear-emails.sh +0 -167
  95. package/scripts/deploy-worker-secrets.sh +0 -374
  96. package/scripts/dev.cjs +0 -23
  97. package/scripts/install-workers.sh +0 -88
  98. package/scripts/run-eslint.cjs +0 -43
  99. package/scripts/update-compatibility-dates.cjs +0 -124
  100. package/scripts/update-markdown-versions.cjs +0 -43
  101. package/workers/keys-worker/package.json +0 -18
  102. package/workers/keys-worker/src/keys.example.ts +0 -67
  103. package/workers/keys-worker/src/keys.ts +0 -67
  104. package/workers/keys-worker/worker-configuration.d.ts +0 -7447
  105. package/workers/keys-worker/wrangler.jsonc.example +0 -15
@@ -1,372 +0,0 @@
1
- #!/bin/bash
2
-
3
- prompt_for_secrets() {
4
- echo -e "\n${BLUE}🔐 Environment Variables Setup${NC}"
5
- echo "=============================="
6
- echo -e "${YELLOW}Please provide values for the following environment variables.${NC}"
7
- echo -e "${YELLOW}Press Enter to keep existing values (if any).${NC}"
8
- echo ""
9
-
10
- # Create or backup existing .env
11
- if [ -f ".env" ] && [ "$update_env" != "true" ]; then
12
- cp .env .env.backup
13
- echo -e "${GREEN}📄 Existing .env backed up to .env.backup${NC}"
14
- fi
15
-
16
- # Copy .env.example to .env if it doesn't exist
17
- if [ ! -f ".env" ]; then
18
- cp .env.example .env
19
- echo -e "${GREEN}📄 Created .env from .env.example${NC}"
20
- fi
21
-
22
- # Function to prompt for a variable
23
- is_auto_generated_secret_var() {
24
- local var_name=$1
25
- case "$var_name" in
26
- USER_DB_AUTH|R2_KEY_SECRET|KEYS_AUTH|PDF_WORKER_AUTH|IMAGES_API_TOKEN|IMAGE_SIGNED_URL_SECRET)
27
- return 0
28
- ;;
29
- *)
30
- return 1
31
- ;;
32
- esac
33
- }
34
-
35
- is_secret_placeholder_value() {
36
- local var_name=$1
37
- local value=$2
38
- case "$var_name" in
39
- USER_DB_AUTH)
40
- [ "$value" = "your_custom_user_db_auth_token_here" ]
41
- ;;
42
- R2_KEY_SECRET)
43
- [ "$value" = "your_custom_r2_secret_here" ]
44
- ;;
45
- KEYS_AUTH)
46
- [ "$value" = "your_custom_keys_auth_token_here" ]
47
- ;;
48
- PDF_WORKER_AUTH)
49
- [ "$value" = "your_custom_pdf_worker_auth_token_here" ]
50
- ;;
51
- IMAGES_API_TOKEN)
52
- [ "$value" = "your_cloudflare_images_api_token_here" ]
53
- ;;
54
- IMAGE_SIGNED_URL_SECRET)
55
- [ "$value" = "your_image_signed_url_secret_here" ]
56
- ;;
57
- *)
58
- return 1
59
- ;;
60
- esac
61
- }
62
-
63
- generate_secret_value() {
64
- local var_name=$1
65
- case "$var_name" in
66
- IMAGE_SIGNED_URL_SECRET)
67
- openssl rand -base64 48 2>/dev/null | tr '+/' '-_' | tr -d '='
68
- ;;
69
- *)
70
- openssl rand -hex 32 2>/dev/null
71
- ;;
72
- esac
73
- }
74
-
75
- prompt_for_var() {
76
- local var_name=$1
77
- local description=$2
78
- local current_value="${!var_name}"
79
- local new_value=""
80
- local allow_keep="false"
81
-
82
- current_value=$(strip_carriage_returns "$current_value")
83
-
84
- if [ "$var_name" = "PAGES_CUSTOM_DOMAIN" ]; then
85
- current_value=$(resolve_existing_domain_value "$var_name" "$current_value")
86
- fi
87
-
88
- # Auto-generate selected secrets - but allow keeping current.
89
- if is_auto_generated_secret_var "$var_name"; then
90
- echo -e "${BLUE}$var_name${NC}"
91
- echo -e "${YELLOW}$description${NC}"
92
-
93
- if [ "$update_env" != "true" ] && [ -n "$current_value" ] && ! is_placeholder "$current_value" && ! is_secret_placeholder_value "$var_name" "$current_value"; then
94
- # Current value exists and is not a placeholder
95
- echo -e "${GREEN}Current value: [HIDDEN]${NC}"
96
- read -p "Generate new secret? (press Enter to keep current, or type 'y' to generate): " gen_choice
97
- gen_choice=$(strip_carriage_returns "$gen_choice")
98
-
99
- if [ "$gen_choice" = "y" ] || [ "$gen_choice" = "Y" ]; then
100
- new_value=$(generate_secret_value "$var_name" || echo "")
101
- if [ -n "$new_value" ]; then
102
- echo -e "${GREEN}✅ $var_name auto-generated${NC}"
103
- else
104
- while true; do
105
- echo -e "${RED}❌ Failed to auto-generate, please enter manually:${NC}"
106
- read -p "Enter value: " new_value
107
- new_value=$(strip_carriage_returns "$new_value")
108
- if [ -z "$new_value" ]; then
109
- echo -e "${RED}❌ A value is required.${NC}"
110
- continue
111
- fi
112
- if is_placeholder "$new_value"; then
113
- echo -e "${RED}❌ Placeholder values are not allowed.${NC}"
114
- new_value=""
115
- continue
116
- fi
117
- break
118
- done
119
- fi
120
- else
121
- # User wants to keep current value
122
- new_value=""
123
- fi
124
- else
125
- # No current value or placeholder value - auto-generate
126
- echo -e "${YELLOW}Auto-generating secret...${NC}"
127
- new_value=$(generate_secret_value "$var_name" || echo "")
128
- if [ -n "$new_value" ]; then
129
- echo -e "${GREEN}✅ $var_name auto-generated${NC}"
130
- else
131
- while true; do
132
- echo -e "${RED}❌ Failed to auto-generate, please enter manually:${NC}"
133
- read -p "Enter value: " new_value
134
- new_value=$(strip_carriage_returns "$new_value")
135
- if [ -z "$new_value" ]; then
136
- echo -e "${RED}❌ A value is required.${NC}"
137
- continue
138
- fi
139
- if is_placeholder "$new_value"; then
140
- echo -e "${RED}❌ Placeholder values are not allowed.${NC}"
141
- new_value=""
142
- continue
143
- fi
144
- break
145
- done
146
- fi
147
- fi
148
- else
149
- # Normal prompt for other variables
150
- echo -e "${BLUE}$var_name${NC}"
151
- echo -e "${YELLOW}$description${NC}"
152
- if [ "$update_env" != "true" ] && [ -n "$current_value" ] && ! is_placeholder "$current_value"; then
153
- allow_keep="true"
154
- if [ "$var_name" = "FIREBASE_SERVICE_ACCOUNT_PRIVATE_KEY" ]; then
155
- echo -e "${GREEN}Current value: [HIDDEN]${NC}"
156
- else
157
- echo -e "${GREEN}Current value: $current_value${NC}"
158
- fi
159
- fi
160
-
161
- while true; do
162
- if [ "$allow_keep" = "true" ]; then
163
- read -p "New value (or press Enter to keep current): " new_value
164
- new_value=$(strip_carriage_returns "$new_value")
165
- if [ -z "$new_value" ]; then
166
- break
167
- fi
168
- else
169
- read -p "Enter value: " new_value
170
- new_value=$(strip_carriage_returns "$new_value")
171
- if [ -z "$new_value" ]; then
172
- echo -e "${RED}❌ A value is required.${NC}"
173
- continue
174
- fi
175
- fi
176
-
177
- if is_placeholder "$new_value"; then
178
- echo -e "${RED}❌ Placeholder values are not allowed.${NC}"
179
- new_value=""
180
- continue
181
- fi
182
-
183
- if [[ "$var_name" == *_WORKER_NAME ]]; then
184
- new_value=$(normalize_worker_label_value "$new_value")
185
-
186
- if [ -z "$new_value" ] || ! is_valid_worker_label "$new_value"; then
187
- echo -e "${RED}❌ $var_name must use only lowercase letters, numbers, and dashes.${NC}"
188
- new_value=""
189
- continue
190
- fi
191
- fi
192
-
193
- break
194
- done
195
- fi
196
-
197
- if [ -n "$new_value" ]; then
198
- if [ "$var_name" = "PAGES_CUSTOM_DOMAIN" ]; then
199
- new_value=$(normalize_domain_value "$new_value")
200
- fi
201
-
202
- # Update the .env file
203
- write_env_var "$var_name" "$new_value"
204
-
205
- export "$var_name=$new_value"
206
- echo -e "${GREEN}✅ $var_name updated${NC}"
207
- elif [ -n "$current_value" ]; then
208
- if [[ "$var_name" == *_WORKER_NAME ]]; then
209
- current_value=$(normalize_worker_label_value "$current_value")
210
- fi
211
-
212
- # Keep values aligned with .env.example ordering and remove stale duplicates.
213
- write_env_var "$var_name" "$current_value"
214
- export "$var_name=$current_value"
215
- echo -e "${GREEN}✅ Keeping current value for $var_name${NC}"
216
- fi
217
- echo ""
218
- }
219
-
220
- set_worker_domain_from_shared_subdomain() {
221
- local worker_name_var=$1
222
- local worker_domain_var=$2
223
- local worker_name_value="${!worker_name_var}"
224
- local composed_domain=""
225
-
226
- worker_name_value=$(normalize_worker_label_value "$worker_name_value")
227
-
228
- if [ -z "$worker_name_value" ] || ! is_valid_worker_label "$worker_name_value"; then
229
- echo -e "${RED}❌ $worker_name_var must use only lowercase letters, numbers, and dashes.${NC}"
230
- exit 1
231
- fi
232
-
233
- composed_domain=$(compose_worker_domain "$worker_name_value" "$shared_worker_subdomain" || echo "")
234
-
235
- if [ -z "$composed_domain" ]; then
236
- echo -e "${RED}❌ Could not build $worker_domain_var from $worker_name_var and shared worker-subdomain.${NC}"
237
- exit 1
238
- fi
239
-
240
- write_env_var "$worker_domain_var" "$composed_domain"
241
- export "$worker_domain_var=$composed_domain"
242
- echo -e "${GREEN}✅ $worker_domain_var set to $composed_domain${NC}"
243
- }
244
-
245
- echo -e "${BLUE}📊 CLOUDFLARE CORE CONFIGURATION${NC}"
246
- echo "=================================="
247
- prompt_for_var "ACCOUNT_ID" "Your Cloudflare Account ID"
248
-
249
- echo -e "${BLUE}🔐 SHARED AUTHENTICATION & STORAGE${NC}"
250
- echo "==================================="
251
- prompt_for_var "USER_DB_AUTH" "Custom user database authentication token (generate with: openssl rand -hex 16)"
252
- prompt_for_var "R2_KEY_SECRET" "Custom R2 storage authentication token (generate with: openssl rand -hex 16)"
253
- prompt_for_var "IMAGES_API_TOKEN" "Image worker API token (shared between workers)"
254
-
255
- echo -e "${BLUE}🔥 FIREBASE AUTH CONFIGURATION${NC}"
256
- echo "==============================="
257
- prompt_for_var "API_KEY" "Firebase API key"
258
- prompt_for_var "AUTH_DOMAIN" "Firebase auth domain (project-id.firebaseapp.com)"
259
- prompt_for_var "STORAGE_BUCKET" "Firebase storage bucket"
260
- prompt_for_var "MESSAGING_SENDER_ID" "Firebase messaging sender ID"
261
- prompt_for_var "APP_ID" "Firebase app ID"
262
- prompt_for_var "MEASUREMENT_ID" "Firebase measurement ID (optional)"
263
- echo -e "${GREEN}Using PROJECT_ID and service account values from app/config/admin-service.json${NC}"
264
-
265
- echo -e "${BLUE}📄 PAGES CONFIGURATION${NC}"
266
- echo "======================"
267
- prompt_for_var "PAGES_PROJECT_NAME" "Your Cloudflare Pages project name"
268
- prompt_for_var "PAGES_CUSTOM_DOMAIN" "Your custom domain (e.g., striae.org) - DO NOT include https://"
269
-
270
- echo -e "${BLUE}🔑 WORKER NAMES & DOMAINS${NC}"
271
- echo "========================="
272
- echo -e "${YELLOW}Worker names are lowercased automatically and must use only letters, numbers, and dashes.${NC}"
273
- echo -e "${YELLOW}Enter one shared worker-subdomain as a hostname (for example: team-name.workers.dev).${NC}"
274
- echo -e "${YELLOW}Each worker domain is generated as {worker-name}.{worker-subdomain}.${NC}"
275
-
276
- local shared_worker_subdomain=""
277
- local shared_worker_subdomain_default=""
278
- local shared_worker_subdomain_input=""
279
-
280
- shared_worker_subdomain_default=$(infer_worker_subdomain_from_domain "$KEYS_WORKER_NAME" "$KEYS_WORKER_DOMAIN")
281
- if [ -z "$shared_worker_subdomain_default" ]; then
282
- shared_worker_subdomain_default=$(infer_worker_subdomain_from_domain "$USER_WORKER_NAME" "$USER_WORKER_DOMAIN")
283
- fi
284
- if [ -z "$shared_worker_subdomain_default" ]; then
285
- shared_worker_subdomain_default=$(infer_worker_subdomain_from_domain "$DATA_WORKER_NAME" "$DATA_WORKER_DOMAIN")
286
- fi
287
- if [ -z "$shared_worker_subdomain_default" ]; then
288
- shared_worker_subdomain_default=$(infer_worker_subdomain_from_domain "$AUDIT_WORKER_NAME" "$AUDIT_WORKER_DOMAIN")
289
- fi
290
- if [ -z "$shared_worker_subdomain_default" ]; then
291
- shared_worker_subdomain_default=$(infer_worker_subdomain_from_domain "$IMAGES_WORKER_NAME" "$IMAGES_WORKER_DOMAIN")
292
- fi
293
- if [ -z "$shared_worker_subdomain_default" ]; then
294
- shared_worker_subdomain_default=$(infer_worker_subdomain_from_domain "$PDF_WORKER_NAME" "$PDF_WORKER_DOMAIN")
295
- fi
296
-
297
- while true; do
298
- echo -e "${BLUE}WORKER_SUBDOMAIN${NC}"
299
-
300
- if [ "$update_env" != "true" ] && [ -n "$shared_worker_subdomain_default" ] && ! is_placeholder "$shared_worker_subdomain_default"; then
301
- echo -e "${GREEN}Current value: $shared_worker_subdomain_default${NC}"
302
- read -p "New value (or press Enter to keep current): " shared_worker_subdomain_input
303
- shared_worker_subdomain_input=$(strip_carriage_returns "$shared_worker_subdomain_input")
304
-
305
- if [ -z "$shared_worker_subdomain_input" ]; then
306
- shared_worker_subdomain="$shared_worker_subdomain_default"
307
- else
308
- shared_worker_subdomain="$shared_worker_subdomain_input"
309
- fi
310
- else
311
- read -p "Enter shared worker-subdomain (e.g., team-name.workers.dev): " shared_worker_subdomain_input
312
- shared_worker_subdomain_input=$(strip_carriage_returns "$shared_worker_subdomain_input")
313
- shared_worker_subdomain="$shared_worker_subdomain_input"
314
- fi
315
-
316
- if [ -z "$shared_worker_subdomain" ] || is_placeholder "$shared_worker_subdomain"; then
317
- echo -e "${RED}❌ shared worker-subdomain is required and cannot be a placeholder.${NC}"
318
- continue
319
- fi
320
-
321
- shared_worker_subdomain=$(normalize_worker_subdomain_value "$shared_worker_subdomain")
322
-
323
- if [ -z "$shared_worker_subdomain" ] || ! is_valid_worker_subdomain "$shared_worker_subdomain"; then
324
- echo -e "${RED}❌ shared worker-subdomain must be a valid hostname like team-name.workers.dev (letters, numbers, dashes, and dots).${NC}"
325
- continue
326
- fi
327
-
328
- echo -e "${GREEN}✅ Shared worker-subdomain set to: $shared_worker_subdomain${NC}"
329
- echo ""
330
- break
331
- done
332
-
333
- prompt_for_var "KEYS_WORKER_NAME" "Keys worker name"
334
- prompt_for_var "USER_WORKER_NAME" "User worker name"
335
- prompt_for_var "DATA_WORKER_NAME" "Data worker name"
336
- prompt_for_var "AUDIT_WORKER_NAME" "Audit worker name"
337
- prompt_for_var "IMAGES_WORKER_NAME" "Images worker name"
338
- prompt_for_var "PDF_WORKER_NAME" "PDF worker name"
339
-
340
- set_worker_domain_from_shared_subdomain "KEYS_WORKER_NAME" "KEYS_WORKER_DOMAIN"
341
- set_worker_domain_from_shared_subdomain "USER_WORKER_NAME" "USER_WORKER_DOMAIN"
342
- set_worker_domain_from_shared_subdomain "DATA_WORKER_NAME" "DATA_WORKER_DOMAIN"
343
- set_worker_domain_from_shared_subdomain "AUDIT_WORKER_NAME" "AUDIT_WORKER_DOMAIN"
344
- set_worker_domain_from_shared_subdomain "IMAGES_WORKER_NAME" "IMAGES_WORKER_DOMAIN"
345
- set_worker_domain_from_shared_subdomain "PDF_WORKER_NAME" "PDF_WORKER_DOMAIN"
346
- echo ""
347
-
348
- echo -e "${BLUE}🗄️ STORAGE CONFIGURATION${NC}"
349
- echo "========================="
350
- prompt_for_var "DATA_BUCKET_NAME" "Your R2 bucket name for case data storage"
351
- prompt_for_var "AUDIT_BUCKET_NAME" "Your R2 bucket name for audit logs (separate from data bucket)"
352
- prompt_for_var "FILES_BUCKET_NAME" "Your R2 bucket name for encrypted files storage"
353
- prompt_for_var "KV_STORE_ID" "Your KV namespace ID (UUID format)"
354
-
355
- echo -e "${BLUE}🔐 SERVICE-SPECIFIC SECRETS${NC}"
356
- echo "============================"
357
- prompt_for_var "KEYS_AUTH" "Keys worker authentication token (generate with: openssl rand -hex 16)"
358
- prompt_for_var "PDF_WORKER_AUTH" "PDF worker authentication token (generate with: openssl rand -hex 16)"
359
- prompt_for_var "IMAGE_SIGNED_URL_SECRET" "Image signed URL secret (generate with: openssl rand -base64 48 | tr '+/' '-_' | tr -d '=')"
360
- prompt_for_var "BROWSER_API_TOKEN" "Cloudflare Browser Rendering API token (for PDF Worker)"
361
-
362
- configure_manifest_signing_credentials
363
- configure_export_encryption_credentials
364
- configure_user_kv_encryption_credentials
365
- configure_data_at_rest_encryption_credentials
366
-
367
- # Reload the updated .env file
368
- source .env
369
-
370
- echo -e "${GREEN}🎉 Environment variables setup completed!${NC}"
371
- echo -e "${BLUE}📄 All values saved to .env file${NC}"
372
- }