@striae-org/striae 6.1.8 → 7.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 (45) hide show
  1. package/.env.example +0 -26
  2. package/app/components/actions/image-manage.ts +17 -67
  3. package/functions/api/audit/[[path]].ts +9 -24
  4. package/functions/api/data/[[path]].ts +9 -24
  5. package/functions/api/image/[[path]].ts +14 -30
  6. package/functions/api/pdf/[[path]].ts +9 -24
  7. package/functions/api/user/[[path]].ts +20 -36
  8. package/package.json +9 -10
  9. package/scripts/deploy-all.sh +29 -10
  10. package/scripts/deploy-config/modules/env-utils.sh +0 -68
  11. package/scripts/deploy-config/modules/prompt.sh +4 -110
  12. package/scripts/deploy-config/modules/scaffolding.sh +5 -0
  13. package/scripts/deploy-config/modules/validation.sh +1 -19
  14. package/scripts/deploy-pages-secrets.sh +0 -9
  15. package/scripts/deploy-worker-secrets.sh +2 -8
  16. package/tsconfig.json +1 -4
  17. package/workers/audit-worker/package.json +2 -2
  18. package/workers/audit-worker/src/audit-worker.ts +0 -5
  19. package/workers/audit-worker/src/config.ts +1 -6
  20. package/workers/audit-worker/src/types.ts +0 -1
  21. package/workers/audit-worker/wrangler.jsonc.example +2 -6
  22. package/workers/data-worker/package.json +3 -3
  23. package/workers/data-worker/src/config.ts +1 -6
  24. package/workers/data-worker/src/data-worker.ts +1 -6
  25. package/workers/data-worker/src/types.ts +0 -1
  26. package/workers/data-worker/wrangler.jsonc.example +2 -4
  27. package/workers/image-worker/package.json +2 -2
  28. package/workers/image-worker/src/handlers/delete-image.ts +0 -5
  29. package/workers/image-worker/src/handlers/mint-signed-url.ts +0 -5
  30. package/workers/image-worker/src/handlers/serve-image.ts +1 -2
  31. package/workers/image-worker/src/handlers/upload-image.ts +0 -5
  32. package/workers/image-worker/src/security/signed-url.ts +2 -2
  33. package/workers/image-worker/src/types.ts +0 -1
  34. package/workers/image-worker/wrangler.jsonc.example +2 -1
  35. package/workers/pdf-worker/package.json +2 -2
  36. package/workers/pdf-worker/src/pdf-worker.ts +0 -8
  37. package/workers/pdf-worker/wrangler.jsonc.example +2 -1
  38. package/workers/user-worker/package.json +2 -2
  39. package/workers/user-worker/src/auth.ts +0 -7
  40. package/workers/user-worker/src/types.ts +0 -2
  41. package/workers/user-worker/src/user-worker.ts +1 -3
  42. package/workers/user-worker/wrangler.jsonc.example +2 -1
  43. package/wrangler.toml.example +22 -2
  44. package/worker-configuration.d.ts +0 -7509
  45. package/workers/image-worker/src/auth.ts +0 -7
@@ -79,7 +79,7 @@ echo -e "${GREEN}✅ Preflight checks passed${NC}"
79
79
  echo ""
80
80
 
81
81
  # Step 1: Configuration Setup
82
- echo -e "${PURPLE}Step 1/6: Configuration Setup${NC}"
82
+ echo -e "${PURPLE}Step 1/7: Configuration Setup${NC}"
83
83
  echo "------------------------------"
84
84
  echo -e "${YELLOW}⚙️ Setting up configuration files and replacing placeholders...${NC}"
85
85
  if ! bash "$SCRIPT_DIR/deploy-config.sh"; then
@@ -92,7 +92,7 @@ run_config_checkpoint
92
92
  echo ""
93
93
 
94
94
  # Step 2: Install Worker Dependencies
95
- echo -e "${PURPLE}Step 2/6: Installing Worker Dependencies${NC}"
95
+ echo -e "${PURPLE}Step 2/7: Installing Worker Dependencies${NC}"
96
96
  echo "----------------------------------------"
97
97
  echo -e "${YELLOW}📦 Installing npm dependencies for all workers...${NC}"
98
98
  if ! bash "$SCRIPT_DIR/install-workers.sh"; then
@@ -102,8 +102,26 @@ fi
102
102
  echo -e "${GREEN}✅ All worker dependencies installed successfully${NC}"
103
103
  echo ""
104
104
 
105
- # Step 3: Deploy Workers
106
- echo -e "${PURPLE}Step 3/6: Deploying Workers${NC}"
105
+ # Step 3: Generate Wrangler Types
106
+ echo -e "${PURPLE}Step 3/7: Generating Wrangler Types${NC}"
107
+ echo "-------------------------------------"
108
+ echo -e "${YELLOW}📝 Running wrangler types in root and all worker directories...${NC}"
109
+ if ! npx wrangler types; then
110
+ echo -e "${RED}❌ Root wrangler types generation failed!${NC}"
111
+ exit 1
112
+ fi
113
+ for WORKER in audit-worker data-worker image-worker pdf-worker user-worker; do
114
+ echo -e "${YELLOW} → Generating types for ${WORKER}...${NC}"
115
+ if ! (cd "workers/$WORKER" && npx wrangler types); then
116
+ echo -e "${RED}❌ wrangler types failed for ${WORKER}!${NC}"
117
+ exit 1
118
+ fi
119
+ done
120
+ echo -e "${GREEN}✅ Wrangler types generated successfully${NC}"
121
+ echo ""
122
+
123
+ # Step 4: Deploy Workers
124
+ echo -e "${PURPLE}Step 4/7: Deploying Workers${NC}"
107
125
  echo "----------------------------"
108
126
  echo -e "${YELLOW}🔧 Deploying all 5 Cloudflare Workers...${NC}"
109
127
  if ! npm run deploy-workers; then
@@ -113,8 +131,8 @@ fi
113
131
  echo -e "${GREEN}✅ All workers deployed successfully${NC}"
114
132
  echo ""
115
133
 
116
- # Step 4: Deploy Worker Secrets
117
- echo -e "${PURPLE}Step 4/6: Deploying Worker Secrets${NC}"
134
+ # Step 5: Deploy Worker Secrets
135
+ echo -e "${PURPLE}Step 5/7: Deploying Worker Secrets${NC}"
118
136
  echo "-----------------------------------"
119
137
  echo -e "${YELLOW}🔐 Deploying worker environment variables...${NC}"
120
138
  if ! bash "$SCRIPT_DIR/deploy-worker-secrets.sh"; then
@@ -124,8 +142,8 @@ fi
124
142
  echo -e "${GREEN}✅ Worker secrets deployed successfully${NC}"
125
143
  echo ""
126
144
 
127
- # Step 5: Deploy Pages Secrets
128
- echo -e "${PURPLE}Step 5/6: Deploying Pages Secrets${NC}"
145
+ # Step 6: Deploy Pages Secrets
146
+ echo -e "${PURPLE}Step 6/7: Deploying Pages Secrets${NC}"
129
147
  echo "----------------------------------"
130
148
  echo -e "${YELLOW}🔐 Deploying Pages environment variables...${NC}"
131
149
  if ! bash "$SCRIPT_DIR/deploy-pages-secrets.sh"; then
@@ -135,8 +153,8 @@ fi
135
153
  echo -e "${GREEN}✅ Pages secrets deployed successfully${NC}"
136
154
  echo ""
137
155
 
138
- # Step 6: Deploy Pages
139
- echo -e "${PURPLE}Step 6/6: Deploying Pages${NC}"
156
+ # Step 7: Deploy Pages
157
+ echo -e "${PURPLE}Step 7/7: Deploying Pages${NC}"
140
158
  echo "--------------------------"
141
159
  echo -e "${YELLOW}🌐 Building and deploying Pages...${NC}"
142
160
  if ! npm run deploy-pages; then
@@ -153,6 +171,7 @@ echo "=========================================="
153
171
  echo ""
154
172
  echo -e "${BLUE}Deployed Components:${NC}"
155
173
  echo " ✅ Worker dependencies (npm install)"
174
+ echo " ✅ Wrangler types (root + all workers)"
156
175
  echo " ✅ 5 Cloudflare Workers"
157
176
  echo " ✅ Worker environment variables"
158
177
  echo " ✅ Pages environment variables"
@@ -56,29 +56,12 @@ normalize_worker_label_value() {
56
56
  printf '%s' "$label"
57
57
  }
58
58
 
59
- normalize_worker_subdomain_value() {
60
- local subdomain="$1"
61
-
62
- subdomain=$(normalize_domain_value "$subdomain")
63
- subdomain="${subdomain#.}"
64
- subdomain="${subdomain%.}"
65
- subdomain=$(printf '%s' "$subdomain" | tr '[:upper:]' '[:lower:]')
66
-
67
- printf '%s' "$subdomain"
68
- }
69
-
70
59
  is_valid_worker_label() {
71
60
  local label="$1"
72
61
 
73
62
  [[ "$label" =~ ^[a-z0-9-]+$ ]]
74
63
  }
75
64
 
76
- is_valid_worker_subdomain() {
77
- local subdomain="$1"
78
-
79
- [[ "$subdomain" =~ ^[a-z0-9]([a-z0-9-]*[a-z0-9])?(\.[a-z0-9]([a-z0-9-]*[a-z0-9])?)+$ ]]
80
- }
81
-
82
65
  strip_carriage_returns() {
83
66
  printf '%s' "$1" | tr -d '\r'
84
67
  }
@@ -196,57 +179,6 @@ confirm_key_pair_regeneration() {
196
179
  return 1
197
180
  }
198
181
 
199
- generate_worker_subdomain_label() {
200
- node -e "const { randomInt } = require('crypto'); const alphabet = 'abcdefghijklmnopqrstuvwxyz0123456789'; let value = ''; for (let index = 0; index < 10; index += 1) { value += alphabet[randomInt(alphabet.length)]; } process.stdout.write(value);" 2>/dev/null
201
- }
202
-
203
- compose_worker_domain() {
204
- local worker_name=$1
205
- local worker_subdomain=$2
206
-
207
- worker_name=$(normalize_worker_label_value "$worker_name")
208
- worker_subdomain=$(normalize_worker_subdomain_value "$worker_subdomain")
209
-
210
- if [ -z "$worker_name" ] || [ -z "$worker_subdomain" ]; then
211
- return 1
212
- fi
213
-
214
- if ! is_valid_worker_label "$worker_name" || ! is_valid_worker_subdomain "$worker_subdomain"; then
215
- return 1
216
- fi
217
-
218
- printf '%s.%s' "$worker_name" "$worker_subdomain"
219
- }
220
-
221
- infer_worker_subdomain_from_domain() {
222
- local worker_name=$1
223
- local worker_domain=$2
224
- local worker_subdomain=""
225
-
226
- worker_name=$(normalize_worker_label_value "$worker_name")
227
- worker_domain=$(normalize_domain_value "$worker_domain")
228
- worker_domain=$(printf '%s' "$worker_domain" | tr '[:upper:]' '[:lower:]')
229
-
230
- if [ -z "$worker_name" ] || [ -z "$worker_domain" ] || is_placeholder "$worker_name" || is_placeholder "$worker_domain"; then
231
- printf '%s' ""
232
- return 0
233
- fi
234
-
235
- case "$worker_domain" in
236
- "$worker_name".*)
237
- worker_subdomain="${worker_domain#${worker_name}.}"
238
- worker_subdomain=$(normalize_worker_subdomain_value "$worker_subdomain")
239
-
240
- if is_valid_worker_subdomain "$worker_subdomain"; then
241
- printf '%s' "$worker_subdomain"
242
- return 0
243
- fi
244
- ;;
245
- esac
246
-
247
- printf '%s' ""
248
- }
249
-
250
182
  write_env_var() {
251
183
  local var_name=$1
252
184
  local var_value=$2
@@ -23,7 +23,7 @@ prompt_for_secrets() {
23
23
  is_auto_generated_secret_var() {
24
24
  local var_name=$1
25
25
  case "$var_name" in
26
- USER_DB_AUTH|R2_KEY_SECRET|PDF_WORKER_AUTH|IMAGES_API_TOKEN|IMAGE_SIGNED_URL_SECRET)
26
+ IMAGE_SIGNED_URL_SECRET)
27
27
  return 0
28
28
  ;;
29
29
  *)
@@ -36,18 +36,6 @@ prompt_for_secrets() {
36
36
  local var_name=$1
37
37
  local value=$2
38
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
- PDF_WORKER_AUTH)
46
- [ "$value" = "your_custom_pdf_worker_auth_token_here" ]
47
- ;;
48
- IMAGES_API_TOKEN)
49
- [ "$value" = "your_cloudflare_images_api_token_here" ]
50
- ;;
51
39
  IMAGE_SIGNED_URL_SECRET)
52
40
  [ "$value" = "your_image_signed_url_secret_here" ]
53
41
  ;;
@@ -214,42 +202,11 @@ prompt_for_secrets() {
214
202
  echo ""
215
203
  }
216
204
 
217
- set_worker_domain_from_shared_subdomain() {
218
- local worker_name_var=$1
219
- local worker_domain_var=$2
220
- local worker_name_value="${!worker_name_var}"
221
- local composed_domain=""
222
-
223
- worker_name_value=$(normalize_worker_label_value "$worker_name_value")
224
-
225
- if [ -z "$worker_name_value" ] || ! is_valid_worker_label "$worker_name_value"; then
226
- echo -e "${RED}❌ $worker_name_var must use only lowercase letters, numbers, and dashes.${NC}"
227
- exit 1
228
- fi
229
-
230
- composed_domain=$(compose_worker_domain "$worker_name_value" "$shared_worker_subdomain" || echo "")
231
-
232
- if [ -z "$composed_domain" ]; then
233
- echo -e "${RED}❌ Could not build $worker_domain_var from $worker_name_var and shared worker-subdomain.${NC}"
234
- exit 1
235
- fi
236
-
237
- write_env_var "$worker_domain_var" "$composed_domain"
238
- export "$worker_domain_var=$composed_domain"
239
- echo -e "${GREEN}✅ $worker_domain_var set to $composed_domain${NC}"
240
- }
241
-
242
205
  echo -e "${BLUE}📊 CLOUDFLARE CORE CONFIGURATION${NC}"
243
206
  echo "=================================="
244
207
  prompt_for_var "ACCOUNT_ID" "Your Cloudflare Account ID"
245
208
 
246
- echo -e "${BLUE}🔐 SHARED AUTHENTICATION & STORAGE${NC}"
247
- echo "==================================="
248
- prompt_for_var "USER_DB_AUTH" "Custom user database authentication token (generate with: openssl rand -hex 16)"
249
- prompt_for_var "R2_KEY_SECRET" "Custom R2 storage authentication token (generate with: openssl rand -hex 16)"
250
- prompt_for_var "IMAGES_API_TOKEN" "Image worker API token (shared between workers)"
251
-
252
- echo -e "${BLUE}🔥 FIREBASE AUTH CONFIGURATION${NC}"
209
+ echo -e "${BLUE} FIREBASE AUTH CONFIGURATION${NC}"
253
210
  echo "==============================="
254
211
  prompt_for_var "API_KEY" "Firebase API key"
255
212
  prompt_for_var "AUTH_DOMAIN" "Firebase auth domain (project-id.firebaseapp.com)"
@@ -264,77 +221,15 @@ prompt_for_secrets() {
264
221
  prompt_for_var "PAGES_PROJECT_NAME" "Your Cloudflare Pages project name"
265
222
  prompt_for_var "PAGES_CUSTOM_DOMAIN" "Your custom domain (e.g., striae.org) - DO NOT include https://"
266
223
 
267
- echo -e "${BLUE}🔑 WORKER NAMES & DOMAINS${NC}"
268
- echo "========================="
224
+ echo -e "${BLUE}🔑 WORKER NAMES${NC}"
225
+ echo "==============="
269
226
  echo -e "${YELLOW}Worker names are lowercased automatically and must use only letters, numbers, and dashes.${NC}"
270
- echo -e "${YELLOW}Enter one shared worker-subdomain as a hostname (for example: team-name.workers.dev).${NC}"
271
- echo -e "${YELLOW}Each worker domain is generated as {worker-name}.{worker-subdomain}.${NC}"
272
-
273
- local shared_worker_subdomain=""
274
- local shared_worker_subdomain_default=""
275
- local shared_worker_subdomain_input=""
276
-
277
- shared_worker_subdomain_default=$(infer_worker_subdomain_from_domain "$USER_WORKER_NAME" "$USER_WORKER_DOMAIN")
278
- if [ -z "$shared_worker_subdomain_default" ]; then
279
- shared_worker_subdomain_default=$(infer_worker_subdomain_from_domain "$DATA_WORKER_NAME" "$DATA_WORKER_DOMAIN")
280
- fi
281
- if [ -z "$shared_worker_subdomain_default" ]; then
282
- shared_worker_subdomain_default=$(infer_worker_subdomain_from_domain "$AUDIT_WORKER_NAME" "$AUDIT_WORKER_DOMAIN")
283
- fi
284
- if [ -z "$shared_worker_subdomain_default" ]; then
285
- shared_worker_subdomain_default=$(infer_worker_subdomain_from_domain "$IMAGES_WORKER_NAME" "$IMAGES_WORKER_DOMAIN")
286
- fi
287
- if [ -z "$shared_worker_subdomain_default" ]; then
288
- shared_worker_subdomain_default=$(infer_worker_subdomain_from_domain "$PDF_WORKER_NAME" "$PDF_WORKER_DOMAIN")
289
- fi
290
-
291
- while true; do
292
- echo -e "${BLUE}WORKER_SUBDOMAIN${NC}"
293
-
294
- if [ "$update_env" != "true" ] && [ -n "$shared_worker_subdomain_default" ] && ! is_placeholder "$shared_worker_subdomain_default"; then
295
- echo -e "${GREEN}Current value: $shared_worker_subdomain_default${NC}"
296
- read -p "New value (or press Enter to keep current): " shared_worker_subdomain_input
297
- shared_worker_subdomain_input=$(strip_carriage_returns "$shared_worker_subdomain_input")
298
-
299
- if [ -z "$shared_worker_subdomain_input" ]; then
300
- shared_worker_subdomain="$shared_worker_subdomain_default"
301
- else
302
- shared_worker_subdomain="$shared_worker_subdomain_input"
303
- fi
304
- else
305
- read -p "Enter shared worker-subdomain (e.g., team-name.workers.dev): " shared_worker_subdomain_input
306
- shared_worker_subdomain_input=$(strip_carriage_returns "$shared_worker_subdomain_input")
307
- shared_worker_subdomain="$shared_worker_subdomain_input"
308
- fi
309
-
310
- if [ -z "$shared_worker_subdomain" ] || is_placeholder "$shared_worker_subdomain"; then
311
- echo -e "${RED}❌ shared worker-subdomain is required and cannot be a placeholder.${NC}"
312
- continue
313
- fi
314
-
315
- shared_worker_subdomain=$(normalize_worker_subdomain_value "$shared_worker_subdomain")
316
-
317
- if [ -z "$shared_worker_subdomain" ] || ! is_valid_worker_subdomain "$shared_worker_subdomain"; then
318
- echo -e "${RED}❌ shared worker-subdomain must be a valid hostname like team-name.workers.dev (letters, numbers, dashes, and dots).${NC}"
319
- continue
320
- fi
321
-
322
- echo -e "${GREEN}✅ Shared worker-subdomain set to: $shared_worker_subdomain${NC}"
323
- echo ""
324
- break
325
- done
326
227
 
327
228
  prompt_for_var "USER_WORKER_NAME" "User worker name"
328
229
  prompt_for_var "DATA_WORKER_NAME" "Data worker name"
329
230
  prompt_for_var "AUDIT_WORKER_NAME" "Audit worker name"
330
231
  prompt_for_var "IMAGES_WORKER_NAME" "Images worker name"
331
232
  prompt_for_var "PDF_WORKER_NAME" "PDF worker name"
332
-
333
- set_worker_domain_from_shared_subdomain "USER_WORKER_NAME" "USER_WORKER_DOMAIN"
334
- set_worker_domain_from_shared_subdomain "DATA_WORKER_NAME" "DATA_WORKER_DOMAIN"
335
- set_worker_domain_from_shared_subdomain "AUDIT_WORKER_NAME" "AUDIT_WORKER_DOMAIN"
336
- set_worker_domain_from_shared_subdomain "IMAGES_WORKER_NAME" "IMAGES_WORKER_DOMAIN"
337
- set_worker_domain_from_shared_subdomain "PDF_WORKER_NAME" "PDF_WORKER_DOMAIN"
338
233
  echo ""
339
234
 
340
235
  echo -e "${BLUE}🗄️ STORAGE CONFIGURATION${NC}"
@@ -346,7 +241,6 @@ prompt_for_secrets() {
346
241
 
347
242
  echo -e "${BLUE}🔐 SERVICE-SPECIFIC SECRETS${NC}"
348
243
  echo "============================"
349
- prompt_for_var "PDF_WORKER_AUTH" "PDF worker authentication token (generate with: openssl rand -hex 16)"
350
244
  prompt_for_var "IMAGE_SIGNED_URL_SECRET" "Image signed URL secret (generate with: openssl rand -base64 48 | tr '+/' '-_' | tr -d '=')"
351
245
 
352
246
  # Auto-derive IMAGE_SIGNED_URL_BASE_URL from PAGES_CUSTOM_DOMAIN if not yet set or still
@@ -185,6 +185,11 @@ update_wrangler_configs() {
185
185
  if [ -f "wrangler.toml" ]; then
186
186
  echo -e "${YELLOW} Updating wrangler.toml...${NC}"
187
187
  sed -i "s/\"PAGES_PROJECT_NAME\"/\"$PAGES_PROJECT_NAME\"/g" wrangler.toml
188
+ sed -i "s/USER_WORKER_NAME/$USER_WORKER_NAME/g" wrangler.toml
189
+ sed -i "s/DATA_WORKER_NAME/$DATA_WORKER_NAME/g" wrangler.toml
190
+ sed -i "s/AUDIT_WORKER_NAME/$AUDIT_WORKER_NAME/g" wrangler.toml
191
+ sed -i "s/IMAGES_WORKER_NAME/$IMAGES_WORKER_NAME/g" wrangler.toml
192
+ sed -i "s/PDF_WORKER_NAME/$PDF_WORKER_NAME/g" wrangler.toml
188
193
  echo -e "${GREEN} ✅ main wrangler.toml configuration updated${NC}"
189
194
  fi
190
195
 
@@ -75,11 +75,6 @@ required_vars=(
75
75
  # Core Cloudflare Configuration
76
76
  "ACCOUNT_ID"
77
77
 
78
- # Shared Authentication & Storage
79
- "USER_DB_AUTH"
80
- "R2_KEY_SECRET"
81
- "IMAGES_API_TOKEN"
82
-
83
78
  # Firebase Auth Configuration
84
79
  "API_KEY"
85
80
  "AUTH_DOMAIN"
@@ -102,13 +97,6 @@ required_vars=(
102
97
  "IMAGES_WORKER_NAME"
103
98
  "PDF_WORKER_NAME"
104
99
 
105
- # Worker Domains (required for proxy/env secrets and worker fallbacks)
106
- "USER_WORKER_DOMAIN"
107
- "DATA_WORKER_DOMAIN"
108
- "AUDIT_WORKER_DOMAIN"
109
- "IMAGES_WORKER_DOMAIN"
110
- "PDF_WORKER_DOMAIN"
111
-
112
100
  # Storage Configuration (required for config replacement)
113
101
  "DATA_BUCKET_NAME"
114
102
  "AUDIT_BUCKET_NAME"
@@ -116,7 +104,6 @@ required_vars=(
116
104
  "KV_STORE_ID"
117
105
 
118
106
  # Worker-Specific Secrets (required for deployment)
119
- "PDF_WORKER_AUTH"
120
107
  "IMAGE_SIGNED_URL_SECRET"
121
108
  "BROWSER_API_TOKEN"
122
109
  "MANIFEST_SIGNING_PRIVATE_KEY"
@@ -212,11 +199,6 @@ validate_env_value_formats() {
212
199
  echo -e "${YELLOW}🔍 Validating environment value formats...${NC}"
213
200
 
214
201
  validate_domain_var "PAGES_CUSTOM_DOMAIN"
215
- validate_domain_var "USER_WORKER_DOMAIN"
216
- validate_domain_var "DATA_WORKER_DOMAIN"
217
- validate_domain_var "AUDIT_WORKER_DOMAIN"
218
- validate_domain_var "IMAGES_WORKER_DOMAIN"
219
- validate_domain_var "PDF_WORKER_DOMAIN"
220
202
 
221
203
  if ! [[ "$KV_STORE_ID" =~ ^([0-9a-fA-F]{32}|[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12})$ ]]; then
222
204
  echo -e "${RED}❌ Error: KV_STORE_ID must be a 32-character hex namespace ID (or UUID format)${NC}"
@@ -313,7 +295,7 @@ validate_generated_configs() {
313
295
  assert_contains_literal "app/config/firebase.ts" "$MEASUREMENT_ID" "MEASUREMENT_ID missing in app/config/firebase.ts"
314
296
 
315
297
  local placeholder_pattern
316
- placeholder_pattern="(\"(ACCOUNT_ID|PAGES_PROJECT_NAME|PAGES_CUSTOM_DOMAIN|USER_WORKER_NAME|DATA_WORKER_NAME|AUDIT_WORKER_NAME|IMAGES_WORKER_NAME|PDF_WORKER_NAME|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|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)\")"
298
+ placeholder_pattern="(\"(ACCOUNT_ID|PAGES_PROJECT_NAME|PAGES_CUSTOM_DOMAIN|USER_WORKER_NAME|DATA_WORKER_NAME|AUDIT_WORKER_NAME|IMAGES_WORKER_NAME|PDF_WORKER_NAME|DATA_BUCKET_NAME|AUDIT_BUCKET_NAME|FILES_BUCKET_NAME|KV_STORE_ID|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)\")"
317
299
 
318
300
  local files_to_scan=(
319
301
  "wrangler.toml"
@@ -151,16 +151,7 @@ if [ -z "$PAGES_PROJECT_NAME" ] || is_placeholder "$PAGES_PROJECT_NAME"; then
151
151
  fi
152
152
 
153
153
  required_pages_secrets=(
154
- "AUDIT_WORKER_DOMAIN"
155
- "DATA_WORKER_DOMAIN"
156
- "IMAGES_API_TOKEN"
157
- "IMAGES_WORKER_DOMAIN"
158
- "PDF_WORKER_AUTH"
159
- "PDF_WORKER_DOMAIN"
160
154
  "PROJECT_ID"
161
- "R2_KEY_SECRET"
162
- "USER_DB_AUTH"
163
- "USER_WORKER_DOMAIN"
164
155
  )
165
156
 
166
157
  echo -e "${YELLOW}🔍 Validating required Pages secret values...${NC}"
@@ -97,8 +97,6 @@ load_required_admin_service_credentials
97
97
 
98
98
  build_user_worker_secret_list() {
99
99
  local secrets=(
100
- "USER_DB_AUTH"
101
- "R2_KEY_SECRET"
102
100
  "PROJECT_ID"
103
101
  "FIREBASE_SERVICE_ACCOUNT_EMAIL"
104
102
  "FIREBASE_SERVICE_ACCOUNT_PRIVATE_KEY"
@@ -149,9 +147,7 @@ build_user_worker_secret_list() {
149
147
  }
150
148
 
151
149
  build_audit_worker_secret_list() {
152
- local secrets=(
153
- "R2_KEY_SECRET"
154
- )
150
+ local secrets=()
155
151
 
156
152
  if [ -n "${DATA_AT_REST_ENCRYPTION_ENABLED:-}" ]; then
157
153
  secrets+=("DATA_AT_REST_ENCRYPTION_ENABLED")
@@ -230,7 +226,6 @@ set_worker_secrets() {
230
226
 
231
227
  build_data_worker_secret_list() {
232
228
  local secrets=(
233
- "R2_KEY_SECRET"
234
229
  "MANIFEST_SIGNING_PRIVATE_KEY"
235
230
  "MANIFEST_SIGNING_KEY_ID"
236
231
  "EXPORT_ENCRYPTION_PRIVATE_KEY"
@@ -274,7 +269,6 @@ build_data_worker_secret_list() {
274
269
 
275
270
  build_images_worker_secret_list() {
276
271
  local secrets=(
277
- "IMAGES_API_TOKEN"
278
272
  "DATA_AT_REST_ENCRYPTION_PUBLIC_KEY"
279
273
  "DATA_AT_REST_ENCRYPTION_KEY_ID"
280
274
  "IMAGE_SIGNED_URL_SECRET"
@@ -365,7 +359,7 @@ fi
365
359
 
366
360
  # PDF Worker
367
361
  if ! set_worker_secrets "PDF Worker" "workers/pdf-worker" \
368
- "PDF_WORKER_AUTH" "ACCOUNT_ID" "BROWSER_API_TOKEN"; then
362
+ "ACCOUNT_ID" "BROWSER_API_TOKEN"; then
369
363
  echo -e "${YELLOW}⚠️ Skipping PDF Worker (not configured)${NC}"
370
364
  fi
371
365
 
package/tsconfig.json CHANGED
@@ -7,10 +7,7 @@
7
7
  "**/.client/**/*.ts",
8
8
  "**/.client/**/*.tsx",
9
9
  ".react-router/types/**/*"
10
- ],
11
- "exclude": [
12
- "tests/e2e"
13
- ],
10
+ ],
14
11
  "compilerOptions": {
15
12
  "lib": [
16
13
  "DOM",
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "audit-worker",
3
- "version": "6.1.8",
3
+ "version": "7.0.0",
4
4
  "private": true,
5
5
  "scripts": {
6
6
  "deploy": "wrangler deploy",
@@ -8,6 +8,6 @@
8
8
  "start": "wrangler dev"
9
9
  },
10
10
  "devDependencies": {
11
- "wrangler": "^4.84.0"
11
+ "wrangler": "^4.84.1"
12
12
  }
13
13
  }
@@ -1,4 +1,3 @@
1
- import { hasValidHeader } from './config';
2
1
  import { handleAuditRequest } from './handlers/audit-routes';
3
2
  import type { CreateResponse, Env } from './types';
4
3
 
@@ -9,10 +8,6 @@ const createWorkerResponse: CreateResponse = (data, status: number = 200): Respo
9
8
 
10
9
  export default {
11
10
  async fetch(request: Request, env: Env): Promise<Response> {
12
- if (!hasValidHeader(request, env)) {
13
- return createWorkerResponse({ error: 'Forbidden' }, 403);
14
- }
15
-
16
11
  try {
17
12
  const url = new URL(request.url);
18
13
  const pathname = url.pathname;
@@ -1,7 +1,2 @@
1
- import type { Env } from './types';
2
-
3
1
  export const DATA_AT_REST_ENCRYPTION_ALGORITHM = 'RSA-OAEP-AES-256-GCM';
4
- export const DATA_AT_REST_ENCRYPTION_VERSION = '1.0';
5
-
6
- export const hasValidHeader = (request: Request, env: Env): boolean =>
7
- request.headers.get('X-Custom-Auth-Key') === env.R2_KEY_SECRET;
2
+ export const DATA_AT_REST_ENCRYPTION_VERSION = '1.0';
@@ -1,5 +1,4 @@
1
1
  export interface Env {
2
- R2_KEY_SECRET: string;
3
2
  STRIAE_AUDIT: R2Bucket;
4
3
  DATA_AT_REST_ENCRYPTION_ENABLED?: string;
5
4
  DATA_AT_REST_ENCRYPTION_PRIVATE_KEY?: string;
@@ -1,13 +1,9 @@
1
1
  {
2
- // Required secrets: R2_KEY_SECRET
3
- // Optional data-at-rest secrets/vars:
4
- // - DATA_AT_REST_ENCRYPTION_ENABLED=true
5
- // - DATA_AT_REST_ENCRYPTION_PRIVATE_KEY (required for decrypting encrypted records)
6
- // - DATA_AT_REST_ENCRYPTION_PUBLIC_KEY and DATA_AT_REST_ENCRYPTION_KEY_ID (required when encrypt-on-write is enabled)
7
2
  "name": "AUDIT_WORKER_NAME",
8
3
  "account_id": "ACCOUNT_ID",
9
4
  "main": "src/audit-worker.ts",
10
- "compatibility_date": "2026-04-20",
5
+ "workers_dev": false,
6
+ "compatibility_date": "2026-04-21",
11
7
  "compatibility_flags": [
12
8
  "nodejs_compat"
13
9
  ],
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "data-worker",
3
- "version": "6.1.8",
3
+ "version": "7.0.0",
4
4
  "private": true,
5
5
  "scripts": {
6
6
  "deploy": "wrangler deploy",
@@ -8,7 +8,7 @@
8
8
  "start": "wrangler dev"
9
9
  },
10
10
  "devDependencies": {
11
- "@cloudflare/vitest-pool-workers": "^0.14.8",
12
- "wrangler": "^4.84.0"
11
+ "@cloudflare/vitest-pool-workers": "^0.14.9",
12
+ "wrangler": "^4.84.1"
13
13
  }
14
14
  }
@@ -1,11 +1,6 @@
1
- import type { Env } from './types';
2
-
3
1
  export const SIGN_MANIFEST_PATH = '/api/forensic/sign-manifest';
4
2
  export const SIGN_CONFIRMATION_PATH = '/api/forensic/sign-confirmation';
5
3
  export const SIGN_AUDIT_EXPORT_PATH = '/api/forensic/sign-audit-export';
6
4
  export const DECRYPT_EXPORT_PATH = '/api/forensic/decrypt-export';
7
5
  export const DATA_AT_REST_ENCRYPTION_ALGORITHM = 'RSA-OAEP-AES-256-GCM';
8
- export const DATA_AT_REST_ENCRYPTION_VERSION = '1.0';
9
-
10
- export const hasValidHeader = (request: Request, env: Env): boolean =>
11
- request.headers.get('X-Custom-Auth-Key') === env.R2_KEY_SECRET;
6
+ export const DATA_AT_REST_ENCRYPTION_VERSION = '1.0';
@@ -2,8 +2,7 @@ import {
2
2
  DECRYPT_EXPORT_PATH,
3
3
  SIGN_AUDIT_EXPORT_PATH,
4
4
  SIGN_CONFIRMATION_PATH,
5
- SIGN_MANIFEST_PATH,
6
- hasValidHeader
5
+ SIGN_MANIFEST_PATH
7
6
  } from './config';
8
7
  import { handleDecryptExport } from './handlers/decrypt-export';
9
8
  import {
@@ -21,10 +20,6 @@ const createWorkerResponse: CreateResponse = (data, status: number = 200): Respo
21
20
 
22
21
  export default {
23
22
  async fetch(request: Request, env: Env): Promise<Response> {
24
- if (!hasValidHeader(request, env)) {
25
- return createWorkerResponse({ error: 'Forbidden' }, 403);
26
- }
27
-
28
23
  try {
29
24
  const url = new URL(request.url);
30
25
  const pathname = url.pathname;
@@ -1,5 +1,4 @@
1
1
  export interface Env {
2
- R2_KEY_SECRET: string;
3
2
  STRIAE_DATA: R2Bucket;
4
3
  MANIFEST_SIGNING_PRIVATE_KEY: string;
5
4
  MANIFEST_SIGNING_KEY_ID: string;
@@ -1,11 +1,9 @@
1
1
  {
2
- // Required secrets: R2_KEY_SECRET, MANIFEST_SIGNING_PRIVATE_KEY, MANIFEST_SIGNING_KEY_ID, EXPORT_ENCRYPTION_PRIVATE_KEY, EXPORT_ENCRYPTION_KEY_ID
3
- // - DATA_AT_REST_ENCRYPTION_PRIVATE_KEY (required for decrypting encrypted records)
4
- // - DATA_AT_REST_ENCRYPTION_PUBLIC_KEY and DATA_AT_REST_ENCRYPTION_KEY_ID (required when encrypt-on-write is enabled)
5
2
  "name": "DATA_WORKER_NAME",
6
3
  "account_id": "ACCOUNT_ID",
7
4
  "main": "src/data-worker.ts",
8
- "compatibility_date": "2026-04-20",
5
+ "workers_dev": false,
6
+ "compatibility_date": "2026-04-21",
9
7
  "compatibility_flags": [
10
8
  "nodejs_compat"
11
9
  ],
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "image-worker",
3
- "version": "6.1.8",
3
+ "version": "7.0.0",
4
4
  "private": true,
5
5
  "scripts": {
6
6
  "deploy": "wrangler deploy",
@@ -8,6 +8,6 @@
8
8
  "start": "wrangler dev"
9
9
  },
10
10
  "devDependencies": {
11
- "wrangler": "^4.84.0"
11
+ "wrangler": "^4.84.1"
12
12
  }
13
13
  }
@@ -1,4 +1,3 @@
1
- import { hasValidToken } from '../auth';
2
1
  import type { CreateImageWorkerResponse, Env } from '../types';
3
2
  import { parseFileId } from '../utils/path-utils';
4
3
 
@@ -7,10 +6,6 @@ export async function handleImageDelete(
7
6
  env: Env,
8
7
  createJsonResponse: CreateImageWorkerResponse
9
8
  ): Promise<Response> {
10
- if (!hasValidToken(request, env)) {
11
- return createJsonResponse({ error: 'Unauthorized' }, 403);
12
- }
13
-
14
9
  const fileId = parseFileId(new URL(request.url).pathname);
15
10
  if (!fileId) {
16
11
  return createJsonResponse({ error: 'Image ID is required' }, 400);