@striae-org/striae 5.0.0 → 5.1.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 (30) hide show
  1. package/.env.example +5 -2
  2. package/app/components/actions/case-export/download-handlers.ts +6 -7
  3. package/app/components/actions/case-manage.ts +10 -11
  4. package/app/components/actions/generate-pdf.ts +43 -1
  5. package/app/components/actions/image-manage.ts +13 -45
  6. package/app/routes/striae/hooks/use-striae-reset-helpers.ts +4 -0
  7. package/app/routes/striae/striae.tsx +15 -4
  8. package/app/utils/data/operations/case-operations.ts +13 -1
  9. package/app/utils/data/operations/confirmation-summary-operations.ts +38 -1
  10. package/app/utils/data/operations/file-annotation-operations.ts +13 -1
  11. package/package.json +2 -2
  12. package/scripts/deploy-config.sh +149 -6
  13. package/scripts/deploy-pages-secrets.sh +0 -6
  14. package/scripts/deploy-worker-secrets.sh +66 -5
  15. package/scripts/encrypt-r2-backfill.mjs +376 -0
  16. package/worker-configuration.d.ts +13 -7
  17. package/workers/audit-worker/package.json +1 -4
  18. package/workers/audit-worker/src/audit-worker.example.ts +522 -61
  19. package/workers/audit-worker/wrangler.jsonc.example +5 -0
  20. package/workers/data-worker/package.json +1 -4
  21. package/workers/data-worker/src/data-worker.example.ts +280 -2
  22. package/workers/data-worker/src/encryption-utils.ts +145 -1
  23. package/workers/data-worker/wrangler.jsonc.example +4 -0
  24. package/workers/image-worker/package.json +1 -4
  25. package/workers/image-worker/src/encryption-utils.ts +217 -0
  26. package/workers/image-worker/src/image-worker.example.ts +196 -127
  27. package/workers/image-worker/wrangler.jsonc.example +7 -0
  28. package/workers/keys-worker/package.json +1 -4
  29. package/workers/pdf-worker/package.json +1 -4
  30. package/workers/user-worker/package.json +1 -4
@@ -334,7 +334,7 @@ write_env_var() {
334
334
  var_value=$(strip_carriage_returns "$var_value")
335
335
  env_file_value="$var_value"
336
336
 
337
- if [ "$var_name" = "FIREBASE_SERVICE_ACCOUNT_PRIVATE_KEY" ] || [ "$var_name" = "MANIFEST_SIGNING_PRIVATE_KEY" ] || [ "$var_name" = "MANIFEST_SIGNING_PUBLIC_KEY" ] || [ "$var_name" = "EXPORT_ENCRYPTION_PRIVATE_KEY" ] || [ "$var_name" = "EXPORT_ENCRYPTION_PUBLIC_KEY" ]; then
337
+ if [ "$var_name" = "FIREBASE_SERVICE_ACCOUNT_PRIVATE_KEY" ] || [ "$var_name" = "MANIFEST_SIGNING_PRIVATE_KEY" ] || [ "$var_name" = "MANIFEST_SIGNING_PUBLIC_KEY" ] || [ "$var_name" = "EXPORT_ENCRYPTION_PRIVATE_KEY" ] || [ "$var_name" = "EXPORT_ENCRYPTION_PUBLIC_KEY" ] || [ "$var_name" = "DATA_AT_REST_ENCRYPTION_PRIVATE_KEY" ] || [ "$var_name" = "DATA_AT_REST_ENCRYPTION_PUBLIC_KEY" ]; then
338
338
  # Store as a quoted string so sourced .env preserves escaped newline markers (\n)
339
339
  env_file_value=${env_file_value//\"/\\\"}
340
340
  env_file_value="\"$env_file_value\""
@@ -590,6 +590,147 @@ configure_export_encryption_credentials() {
590
590
  echo ""
591
591
  }
592
592
 
593
+ generate_data_at_rest_encryption_key_pair() {
594
+ local private_key_file
595
+ local public_key_file
596
+ private_key_file=$(mktemp)
597
+ public_key_file=$(mktemp)
598
+
599
+ if ! node -e "const { generateKeyPairSync } = require('crypto'); const fs = require('fs'); const pair = generateKeyPairSync('rsa', { modulusLength: 2048, publicKeyEncoding: { type: 'spki', format: 'pem' }, privateKeyEncoding: { type: 'pkcs8', format: 'pem' } }); fs.writeFileSync(process.argv[1], pair.privateKey, 'utf8'); fs.writeFileSync(process.argv[2], pair.publicKey, 'utf8');" "$private_key_file" "$public_key_file"; then
600
+ rm -f "$private_key_file" "$public_key_file"
601
+ return 1
602
+ fi
603
+
604
+ local private_key_pem
605
+ local public_key_pem
606
+ private_key_pem=$(cat "$private_key_file")
607
+ public_key_pem=$(cat "$public_key_file")
608
+ rm -f "$private_key_file" "$public_key_file"
609
+
610
+ private_key_pem="${private_key_pem//$'\r'/}"
611
+ public_key_pem="${public_key_pem//$'\r'/}"
612
+
613
+ DATA_AT_REST_ENCRYPTION_PRIVATE_KEY="${private_key_pem//$'\n'/\\n}"
614
+ DATA_AT_REST_ENCRYPTION_PUBLIC_KEY="${public_key_pem//$'\n'/\\n}"
615
+
616
+ export DATA_AT_REST_ENCRYPTION_PRIVATE_KEY
617
+ export DATA_AT_REST_ENCRYPTION_PUBLIC_KEY
618
+
619
+ write_env_var "DATA_AT_REST_ENCRYPTION_PRIVATE_KEY" "$DATA_AT_REST_ENCRYPTION_PRIVATE_KEY"
620
+ write_env_var "DATA_AT_REST_ENCRYPTION_PUBLIC_KEY" "$DATA_AT_REST_ENCRYPTION_PUBLIC_KEY"
621
+
622
+ return 0
623
+ }
624
+
625
+ configure_data_at_rest_encryption_credentials() {
626
+ echo -e "${BLUE}🗃️ DATA-AT-REST ENCRYPTION CONFIGURATION${NC}"
627
+ echo "========================================"
628
+
629
+ local current_enabled="${DATA_AT_REST_ENCRYPTION_ENABLED:-}"
630
+ local normalized_enabled=""
631
+ local enable_choice=""
632
+
633
+ current_enabled=$(strip_carriage_returns "$current_enabled")
634
+ normalized_enabled=$(printf '%s' "$current_enabled" | tr '[:upper:]' '[:lower:]')
635
+
636
+ if [ -z "$normalized_enabled" ] || is_placeholder "$normalized_enabled"; then
637
+ DATA_AT_REST_ENCRYPTION_ENABLED="false"
638
+ elif [ "$normalized_enabled" = "1" ] || [ "$normalized_enabled" = "true" ] || [ "$normalized_enabled" = "yes" ] || [ "$normalized_enabled" = "on" ]; then
639
+ DATA_AT_REST_ENCRYPTION_ENABLED="true"
640
+ else
641
+ DATA_AT_REST_ENCRYPTION_ENABLED="false"
642
+ fi
643
+
644
+ if [ "$update_env" != "true" ]; then
645
+ read -p "Enable data-at-rest encryption for new writes? (y/N, Enter keeps current): " enable_choice
646
+ enable_choice=$(strip_carriage_returns "$enable_choice")
647
+ case "$enable_choice" in
648
+ y|Y|yes|YES)
649
+ DATA_AT_REST_ENCRYPTION_ENABLED="true"
650
+ ;;
651
+ n|N|no|NO)
652
+ DATA_AT_REST_ENCRYPTION_ENABLED="false"
653
+ ;;
654
+ "")
655
+ ;;
656
+ *)
657
+ echo -e "${YELLOW}⚠️ Unrecognized choice '$enable_choice'; keeping current setting${NC}"
658
+ ;;
659
+ esac
660
+ fi
661
+
662
+ export DATA_AT_REST_ENCRYPTION_ENABLED
663
+ write_env_var "DATA_AT_REST_ENCRYPTION_ENABLED" "$DATA_AT_REST_ENCRYPTION_ENABLED"
664
+ echo -e "${GREEN}✅ DATA_AT_REST_ENCRYPTION_ENABLED: $DATA_AT_REST_ENCRYPTION_ENABLED${NC}"
665
+
666
+ local should_generate="false"
667
+ local regenerate_choice=""
668
+
669
+ if [ "$update_env" = "true" ]; then
670
+ should_generate="true"
671
+ elif [ -z "$DATA_AT_REST_ENCRYPTION_PRIVATE_KEY" ] || is_placeholder "$DATA_AT_REST_ENCRYPTION_PRIVATE_KEY" || [ -z "$DATA_AT_REST_ENCRYPTION_PUBLIC_KEY" ] || is_placeholder "$DATA_AT_REST_ENCRYPTION_PUBLIC_KEY"; then
672
+ should_generate="true"
673
+ else
674
+ echo -e "${GREEN}Current data-at-rest encryption key pair: [HIDDEN]${NC}"
675
+ read -p "Generate new data-at-rest encryption key pair? (press Enter to keep current, or type 'y' to regenerate): " regenerate_choice
676
+ regenerate_choice=$(strip_carriage_returns "$regenerate_choice")
677
+ if [ "$regenerate_choice" = "y" ] || [ "$regenerate_choice" = "Y" ]; then
678
+ should_generate="true"
679
+ fi
680
+ fi
681
+
682
+ if [ "$should_generate" = "true" ]; then
683
+ echo -e "${YELLOW}Generating data-at-rest encryption RSA key pair...${NC}"
684
+ if generate_data_at_rest_encryption_key_pair; then
685
+ echo -e "${GREEN}✅ Data-at-rest encryption key pair generated${NC}"
686
+ else
687
+ echo -e "${RED}❌ Error: Failed to generate data-at-rest encryption key pair${NC}"
688
+ exit 1
689
+ fi
690
+ else
691
+ echo -e "${GREEN}✅ Keeping current data-at-rest encryption key pair${NC}"
692
+ fi
693
+
694
+ if [ -z "$DATA_AT_REST_ENCRYPTION_KEY_ID" ] || is_placeholder "$DATA_AT_REST_ENCRYPTION_KEY_ID" || [ "$should_generate" = "true" ]; then
695
+ local generated_key_id
696
+ generated_key_id=$(generate_worker_subdomain_label)
697
+ if [ -z "$generated_key_id" ] || [ ${#generated_key_id} -ne 10 ]; then
698
+ echo -e "${RED}❌ Error: Failed to generate DATA_AT_REST_ENCRYPTION_KEY_ID${NC}"
699
+ exit 1
700
+ fi
701
+ DATA_AT_REST_ENCRYPTION_KEY_ID="$generated_key_id"
702
+ export DATA_AT_REST_ENCRYPTION_KEY_ID
703
+ write_env_var "DATA_AT_REST_ENCRYPTION_KEY_ID" "$DATA_AT_REST_ENCRYPTION_KEY_ID"
704
+ echo -e "${GREEN}✅ DATA_AT_REST_ENCRYPTION_KEY_ID generated: $DATA_AT_REST_ENCRYPTION_KEY_ID${NC}"
705
+ else
706
+ echo -e "${GREEN}✅ DATA_AT_REST_ENCRYPTION_KEY_ID: $DATA_AT_REST_ENCRYPTION_KEY_ID${NC}"
707
+ fi
708
+
709
+ echo ""
710
+ }
711
+
712
+ validate_data_at_rest_encryption_settings() {
713
+ local enabled_normalized
714
+ enabled_normalized=$(printf '%s' "${DATA_AT_REST_ENCRYPTION_ENABLED:-false}" | tr '[:upper:]' '[:lower:]')
715
+
716
+ if [ "$enabled_normalized" = "1" ] || [ "$enabled_normalized" = "true" ] || [ "$enabled_normalized" = "yes" ] || [ "$enabled_normalized" = "on" ]; then
717
+ if [ -z "$DATA_AT_REST_ENCRYPTION_PRIVATE_KEY" ] || is_placeholder "$DATA_AT_REST_ENCRYPTION_PRIVATE_KEY"; then
718
+ echo -e "${RED}❌ Error: DATA_AT_REST_ENCRYPTION_PRIVATE_KEY is required when DATA_AT_REST_ENCRYPTION_ENABLED is true${NC}"
719
+ exit 1
720
+ fi
721
+
722
+ if [ -z "$DATA_AT_REST_ENCRYPTION_PUBLIC_KEY" ] || is_placeholder "$DATA_AT_REST_ENCRYPTION_PUBLIC_KEY"; then
723
+ echo -e "${RED}❌ Error: DATA_AT_REST_ENCRYPTION_PUBLIC_KEY is required when DATA_AT_REST_ENCRYPTION_ENABLED is true${NC}"
724
+ exit 1
725
+ fi
726
+
727
+ if [ -z "$DATA_AT_REST_ENCRYPTION_KEY_ID" ] || is_placeholder "$DATA_AT_REST_ENCRYPTION_KEY_ID"; then
728
+ echo -e "${RED}❌ Error: DATA_AT_REST_ENCRYPTION_KEY_ID is required when DATA_AT_REST_ENCRYPTION_ENABLED is true${NC}"
729
+ exit 1
730
+ fi
731
+ fi
732
+ }
733
+
593
734
  # Validate required variables
594
735
  required_vars=(
595
736
  # Core Cloudflare Configuration
@@ -634,15 +775,14 @@ required_vars=(
634
775
  # Storage Configuration (required for config replacement)
635
776
  "DATA_BUCKET_NAME"
636
777
  "AUDIT_BUCKET_NAME"
778
+ "FILES_BUCKET_NAME"
637
779
  "KV_STORE_ID"
638
780
 
639
781
  # Worker-Specific Secrets (required for deployment)
640
782
  "KEYS_AUTH"
641
783
  "PDF_WORKER_AUTH"
642
784
  "ACCOUNT_HASH"
643
- "API_TOKEN"
644
785
  "BROWSER_API_TOKEN"
645
- "HMAC_KEY"
646
786
  "MANIFEST_SIGNING_PRIVATE_KEY"
647
787
  "MANIFEST_SIGNING_KEY_ID"
648
788
  "MANIFEST_SIGNING_PUBLIC_KEY"
@@ -824,6 +964,7 @@ validate_generated_configs() {
824
964
 
825
965
  assert_contains_literal "workers/data-worker/wrangler.jsonc" "$DATA_BUCKET_NAME" "DATA_BUCKET_NAME missing in data worker config"
826
966
  assert_contains_literal "workers/audit-worker/wrangler.jsonc" "$AUDIT_BUCKET_NAME" "AUDIT_BUCKET_NAME missing in audit worker config"
967
+ assert_contains_literal "workers/image-worker/wrangler.jsonc" "$FILES_BUCKET_NAME" "FILES_BUCKET_NAME missing in image worker config"
827
968
  assert_contains_literal "workers/user-worker/wrangler.jsonc" "$KV_STORE_ID" "KV_STORE_ID missing in user worker config"
828
969
 
829
970
  assert_contains_literal "app/config/config.json" "https://$PAGES_CUSTOM_DOMAIN" "PAGES_CUSTOM_DOMAIN missing in app/config/config.json"
@@ -848,7 +989,7 @@ validate_generated_configs() {
848
989
  assert_contains_literal "workers/user-worker/src/user-worker.ts" "https://$PAGES_CUSTOM_DOMAIN" "PAGES_CUSTOM_DOMAIN missing in user-worker source"
849
990
 
850
991
  local placeholder_pattern
851
- placeholder_pattern="(\"(ACCOUNT_ID|PAGES_PROJECT_NAME|PAGES_CUSTOM_DOMAIN|KEYS_WORKER_NAME|USER_WORKER_NAME|DATA_WORKER_NAME|AUDIT_WORKER_NAME|IMAGES_WORKER_NAME|PDF_WORKER_NAME|KEYS_WORKER_DOMAIN|USER_WORKER_DOMAIN|DATA_WORKER_DOMAIN|AUDIT_WORKER_DOMAIN|IMAGES_WORKER_DOMAIN|PDF_WORKER_DOMAIN|DATA_BUCKET_NAME|AUDIT_BUCKET_NAME|KV_STORE_ID|ACCOUNT_HASH|MANIFEST_SIGNING_KEY_ID|MANIFEST_SIGNING_PUBLIC_KEY|EXPORT_ENCRYPTION_KEY_ID|EXPORT_ENCRYPTION_PUBLIC_KEY|YOUR_FIREBASE_API_KEY|YOUR_FIREBASE_AUTH_DOMAIN|YOUR_FIREBASE_PROJECT_ID|YOUR_FIREBASE_STORAGE_BUCKET|YOUR_FIREBASE_MESSAGING_SENDER_ID|YOUR_FIREBASE_APP_ID|YOUR_FIREBASE_MEASUREMENT_ID)\"|'(PAGES_CUSTOM_DOMAIN|DATA_WORKER_DOMAIN|IMAGES_WORKER_DOMAIN)')"
992
+ placeholder_pattern="(\"(ACCOUNT_ID|PAGES_PROJECT_NAME|PAGES_CUSTOM_DOMAIN|KEYS_WORKER_NAME|USER_WORKER_NAME|DATA_WORKER_NAME|AUDIT_WORKER_NAME|IMAGES_WORKER_NAME|PDF_WORKER_NAME|KEYS_WORKER_DOMAIN|USER_WORKER_DOMAIN|DATA_WORKER_DOMAIN|AUDIT_WORKER_DOMAIN|IMAGES_WORKER_DOMAIN|PDF_WORKER_DOMAIN|DATA_BUCKET_NAME|AUDIT_BUCKET_NAME|FILES_BUCKET_NAME|KV_STORE_ID|ACCOUNT_HASH|MANIFEST_SIGNING_KEY_ID|MANIFEST_SIGNING_PUBLIC_KEY|EXPORT_ENCRYPTION_KEY_ID|EXPORT_ENCRYPTION_PUBLIC_KEY|YOUR_FIREBASE_API_KEY|YOUR_FIREBASE_AUTH_DOMAIN|YOUR_FIREBASE_PROJECT_ID|YOUR_FIREBASE_STORAGE_BUCKET|YOUR_FIREBASE_MESSAGING_SENDER_ID|YOUR_FIREBASE_APP_ID|YOUR_FIREBASE_MEASUREMENT_ID)\"|'(PAGES_CUSTOM_DOMAIN|DATA_WORKER_DOMAIN|IMAGES_WORKER_DOMAIN)')"
852
993
 
853
994
  local files_to_scan=(
854
995
  "wrangler.toml"
@@ -880,6 +1021,7 @@ run_validation_checkpoint() {
880
1021
  validate_required_vars
881
1022
  validate_env_value_formats
882
1023
  validate_env_file_entries
1024
+ validate_data_at_rest_encryption_settings
883
1025
  validate_generated_configs
884
1026
  }
885
1027
 
@@ -1385,6 +1527,7 @@ prompt_for_secrets() {
1385
1527
  echo "========================="
1386
1528
  prompt_for_var "DATA_BUCKET_NAME" "Your R2 bucket name for case data storage"
1387
1529
  prompt_for_var "AUDIT_BUCKET_NAME" "Your R2 bucket name for audit logs (separate from data bucket)"
1530
+ prompt_for_var "FILES_BUCKET_NAME" "Your R2 bucket name for encrypted files storage"
1388
1531
  prompt_for_var "KV_STORE_ID" "Your KV namespace ID (UUID format)"
1389
1532
 
1390
1533
  echo -e "${BLUE}🔐 SERVICE-SPECIFIC SECRETS${NC}"
@@ -1392,12 +1535,11 @@ prompt_for_secrets() {
1392
1535
  prompt_for_var "KEYS_AUTH" "Keys worker authentication token (generate with: openssl rand -hex 16)"
1393
1536
  prompt_for_var "PDF_WORKER_AUTH" "PDF worker authentication token (generate with: openssl rand -hex 16)"
1394
1537
  prompt_for_var "ACCOUNT_HASH" "Cloudflare Images Account Hash"
1395
- prompt_for_var "API_TOKEN" "Cloudflare Images API token (for Images Worker)"
1396
1538
  prompt_for_var "BROWSER_API_TOKEN" "Cloudflare Browser Rendering API token (for PDF Worker)"
1397
- prompt_for_var "HMAC_KEY" "Cloudflare Images HMAC signing key"
1398
1539
 
1399
1540
  configure_manifest_signing_credentials
1400
1541
  configure_export_encryption_credentials
1542
+ configure_data_at_rest_encryption_credentials
1401
1543
 
1402
1544
  # Reload the updated .env file
1403
1545
  source .env
@@ -1462,6 +1604,7 @@ update_wrangler_configs() {
1462
1604
  echo -e "${YELLOW} Updating image-worker/wrangler.jsonc...${NC}"
1463
1605
  sed -i "s/\"IMAGES_WORKER_NAME\"/\"$IMAGES_WORKER_NAME\"/g" workers/image-worker/wrangler.jsonc
1464
1606
  sed -i "s/\"ACCOUNT_ID\"/\"$ACCOUNT_ID\"/g" workers/image-worker/wrangler.jsonc
1607
+ sed -i "s/\"FILES_BUCKET_NAME\"/\"$FILES_BUCKET_NAME\"/g" workers/image-worker/wrangler.jsonc
1465
1608
  echo -e "${GREEN} ✅ image-worker configuration updated${NC}"
1466
1609
  fi
1467
1610
 
@@ -172,12 +172,6 @@ deploy_pages_environment_secrets() {
172
172
  set_pages_secret "$secret" "$secret_value" "$pages_env"
173
173
  done
174
174
 
175
- local optional_api_token
176
- optional_api_token=$(get_optional_value "API_TOKEN")
177
- if [ -n "$optional_api_token" ]; then
178
- set_pages_secret "API_TOKEN" "$optional_api_token" "$pages_env"
179
- fi
180
-
181
175
  local optional_primershear_emails
182
176
  optional_primershear_emails=$(get_optional_value "PRIMERSHEAR_EMAILS")
183
177
  if [ -n "$optional_primershear_emails" ]; then
@@ -95,6 +95,30 @@ load_required_admin_service_credentials() {
95
95
 
96
96
  load_required_admin_service_credentials
97
97
 
98
+ build_audit_worker_secret_list() {
99
+ local secrets=(
100
+ "R2_KEY_SECRET"
101
+ )
102
+
103
+ if [ -n "${DATA_AT_REST_ENCRYPTION_ENABLED:-}" ]; then
104
+ secrets+=("DATA_AT_REST_ENCRYPTION_ENABLED")
105
+ fi
106
+
107
+ if [ -n "${DATA_AT_REST_ENCRYPTION_PRIVATE_KEY:-}" ]; then
108
+ secrets+=("DATA_AT_REST_ENCRYPTION_PRIVATE_KEY")
109
+ fi
110
+
111
+ if [ -n "${DATA_AT_REST_ENCRYPTION_PUBLIC_KEY:-}" ]; then
112
+ secrets+=("DATA_AT_REST_ENCRYPTION_PUBLIC_KEY")
113
+ fi
114
+
115
+ if [ -n "${DATA_AT_REST_ENCRYPTION_KEY_ID:-}" ]; then
116
+ secrets+=("DATA_AT_REST_ENCRYPTION_KEY_ID")
117
+ fi
118
+
119
+ printf '%s\n' "${secrets[@]}"
120
+ }
121
+
98
122
  # Function to set worker secrets
99
123
  set_worker_secrets() {
100
124
  local worker_name=$1
@@ -143,6 +167,34 @@ set_worker_secrets() {
143
167
  popd > /dev/null
144
168
  }
145
169
 
170
+ build_data_worker_secret_list() {
171
+ local secrets=(
172
+ "R2_KEY_SECRET"
173
+ "MANIFEST_SIGNING_PRIVATE_KEY"
174
+ "MANIFEST_SIGNING_KEY_ID"
175
+ "EXPORT_ENCRYPTION_PRIVATE_KEY"
176
+ "EXPORT_ENCRYPTION_KEY_ID"
177
+ )
178
+
179
+ if [ -n "${DATA_AT_REST_ENCRYPTION_ENABLED:-}" ]; then
180
+ secrets+=("DATA_AT_REST_ENCRYPTION_ENABLED")
181
+ fi
182
+
183
+ if [ -n "${DATA_AT_REST_ENCRYPTION_PRIVATE_KEY:-}" ]; then
184
+ secrets+=("DATA_AT_REST_ENCRYPTION_PRIVATE_KEY")
185
+ fi
186
+
187
+ if [ -n "${DATA_AT_REST_ENCRYPTION_PUBLIC_KEY:-}" ]; then
188
+ secrets+=("DATA_AT_REST_ENCRYPTION_PUBLIC_KEY")
189
+ fi
190
+
191
+ if [ -n "${DATA_AT_REST_ENCRYPTION_KEY_ID:-}" ]; then
192
+ secrets+=("DATA_AT_REST_ENCRYPTION_KEY_ID")
193
+ fi
194
+
195
+ printf '%s\n' "${secrets[@]}"
196
+ }
197
+
146
198
  # Deploy secrets to each worker
147
199
  echo -e "\n${BLUE}🔐 Deploying secrets to workers...${NC}"
148
200
 
@@ -168,8 +220,12 @@ elif [ $workers_configured -lt $total_workers ]; then
168
220
  fi
169
221
 
170
222
  # Audit Worker
171
- if ! set_worker_secrets "Audit Worker" "workers/audit-worker" \
172
- "R2_KEY_SECRET"; then
223
+ audit_worker_secrets=()
224
+ while IFS= read -r secret; do
225
+ audit_worker_secrets+=("$secret")
226
+ done < <(build_audit_worker_secret_list)
227
+
228
+ if ! set_worker_secrets "Audit Worker" "workers/audit-worker" "${audit_worker_secrets[@]}"; then
173
229
  echo -e "${YELLOW}⚠️ Skipping Audit Worker (not configured)${NC}"
174
230
  fi
175
231
 
@@ -186,14 +242,18 @@ if ! set_worker_secrets "User Worker" "workers/user-worker" \
186
242
  fi
187
243
 
188
244
  # Data Worker
189
- if ! set_worker_secrets "Data Worker" "workers/data-worker" \
190
- "R2_KEY_SECRET" "MANIFEST_SIGNING_PRIVATE_KEY" "MANIFEST_SIGNING_KEY_ID" "EXPORT_ENCRYPTION_PRIVATE_KEY" "EXPORT_ENCRYPTION_KEY_ID"; then
245
+ data_worker_secrets=()
246
+ while IFS= read -r secret; do
247
+ data_worker_secrets+=("$secret")
248
+ done < <(build_data_worker_secret_list)
249
+
250
+ if ! set_worker_secrets "Data Worker" "workers/data-worker" "${data_worker_secrets[@]}"; then
191
251
  echo -e "${YELLOW}⚠️ Skipping Data Worker (not configured)${NC}"
192
252
  fi
193
253
 
194
254
  # Images Worker
195
255
  if ! set_worker_secrets "Images Worker" "workers/image-worker" \
196
- "ACCOUNT_ID" "API_TOKEN" "HMAC_KEY"; then
256
+ "IMAGES_API_TOKEN" "DATA_AT_REST_ENCRYPTION_PRIVATE_KEY" "DATA_AT_REST_ENCRYPTION_PUBLIC_KEY" "DATA_AT_REST_ENCRYPTION_KEY_ID"; then
197
257
  echo -e "${YELLOW}⚠️ Skipping Images Worker (not configured)${NC}"
198
258
  fi
199
259
 
@@ -210,6 +270,7 @@ echo " - Copy wrangler.jsonc.example to wrangler.jsonc in each worker director
210
270
  echo " - Configure KV namespace ID in workers/user-worker/wrangler.jsonc"
211
271
  echo " - Configure R2 bucket name in workers/data-worker/wrangler.jsonc"
212
272
  echo " - Configure R2 bucket name in workers/audit-worker/wrangler.jsonc"
273
+ echo " - Configure R2 bucket name in workers/image-worker/wrangler.jsonc"
213
274
  echo " - Update ACCOUNT_ID and custom domains in all worker configurations"
214
275
 
215
276
  echo -e "\n${BLUE}📝 For manual deployment, use these commands:${NC}"