@striae-org/striae 4.0.0 → 4.0.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.
- package/README.md +1 -1
- package/app/components/actions/case-export/download-handlers.ts +1 -1
- package/app/components/actions/image-manage.ts +2 -1
- package/app/routes/auth/emailActionHandler.tsx +1 -1
- package/app/routes/auth/emailVerification.tsx +1 -1
- package/app/routes/auth/login.tsx +4 -4
- package/app/routes/auth/passwordReset.tsx +1 -1
- package/functions/api/image/[[path]].ts +17 -1
- package/package.json +2 -2
- package/public/.well-known/security.txt +3 -4
- package/scripts/deploy-config.sh +176 -142
- package/worker-configuration.d.ts +7491 -11363
- package/workers/audit-worker/worker-configuration.d.ts +11323 -7448
- package/workers/data-worker/worker-configuration.d.ts +11323 -7448
- package/workers/image-worker/src/image-worker.example.ts +10 -2
- package/workers/image-worker/worker-configuration.d.ts +11322 -7447
- package/workers/keys-worker/src/keys.ts +2 -1
- package/workers/keys-worker/worker-configuration.d.ts +11322 -7447
- package/workers/pdf-worker/worker-configuration.d.ts +11323 -7448
- package/workers/user-worker/worker-configuration.d.ts +11323 -7448
package/README.md
CHANGED
|
@@ -6,7 +6,7 @@ This npm package publishes the Striae application source and deployment scaffold
|
|
|
6
6
|
|
|
7
7
|
## Live Project
|
|
8
8
|
|
|
9
|
-
- Application: [https://
|
|
9
|
+
- Application: [https://striae.app](https://striae.app)
|
|
10
10
|
- Source repository: [https://github.com/striae-org/striae](https://github.com/striae-org/striae)
|
|
11
11
|
- Releases: [https://github.com/striae-org/striae/releases](https://github.com/striae-org/striae/releases)
|
|
12
12
|
- Security policy: [https://github.com/striae-org/striae/security/policy](https://github.com/striae-org/striae/security/policy)
|
|
@@ -975,7 +975,7 @@ forensic procedures and maintain proper documentation.`;
|
|
|
975
975
|
const footer = `
|
|
976
976
|
|
|
977
977
|
Generated by Striae - A Firearms Examiner's Comparison Companion
|
|
978
|
-
https://
|
|
978
|
+
https://striae.app`;
|
|
979
979
|
|
|
980
980
|
return protectForensicData ? baseContent + forensicAddition + footer : baseContent + footer;
|
|
981
981
|
}
|
|
@@ -244,8 +244,9 @@ export const getImageUrl = async (user: User, fileData: FileData, caseNumber: st
|
|
|
244
244
|
try {
|
|
245
245
|
const { accountHash } = await getImageConfig();
|
|
246
246
|
const imageDeliveryUrl = `https://imagedelivery.net/${accountHash}/${fileData.id}/${DEFAULT_VARIANT}`;
|
|
247
|
+
const encodedImageDeliveryUrl = encodeURIComponent(imageDeliveryUrl);
|
|
247
248
|
|
|
248
|
-
const workerResponse = await fetchImageApi(user, `/${
|
|
249
|
+
const workerResponse = await fetchImageApi(user, `/${encodedImageDeliveryUrl}`, {
|
|
249
250
|
method: 'GET',
|
|
250
251
|
headers: {
|
|
251
252
|
'Accept': 'text/plain'
|
|
@@ -283,7 +283,7 @@ export const EmailActionHandler = ({ mode, oobCode, continueUrl, lang }: EmailAc
|
|
|
283
283
|
<Link
|
|
284
284
|
viewTransition
|
|
285
285
|
prefetch="intent"
|
|
286
|
-
to="https://striae.
|
|
286
|
+
to="https://striae.app"
|
|
287
287
|
className={styles.logoLink}
|
|
288
288
|
>
|
|
289
289
|
<div className={styles.logo} />
|
|
@@ -29,7 +29,7 @@ import { evaluatePasswordPolicy } from '~/utils/password-policy';
|
|
|
29
29
|
import { buildActionCodeSettings } from '~/utils/auth-action-settings';
|
|
30
30
|
import { userHasMFA } from '~/utils/mfa';
|
|
31
31
|
|
|
32
|
-
const APP_CANONICAL_ORIGIN = 'https://
|
|
32
|
+
const APP_CANONICAL_ORIGIN = 'https://striae.app';
|
|
33
33
|
const SOCIAL_IMAGE_PATH = '/social-image.png';
|
|
34
34
|
const SOCIAL_IMAGE_ALT = 'Striae forensic annotation and comparison workspace';
|
|
35
35
|
const LOGIN_PATH_ALIASES = new Set(['/auth', '/auth/', '/auth/login', '/auth/login/']);
|
|
@@ -51,8 +51,8 @@ const getCanonicalPath = (pathname: string): string => {
|
|
|
51
51
|
const getAuthMetaContent = (mode: string | null, hasActionCode: boolean): AuthMetaContent => {
|
|
52
52
|
if (!mode && !hasActionCode) {
|
|
53
53
|
return {
|
|
54
|
-
title: 'Striae
|
|
55
|
-
description: 'Sign in to Striae to access your
|
|
54
|
+
title: 'Striae: A Firearms Examiner\'s Comparison Companion',
|
|
55
|
+
description: 'Sign in to Striae to access your comparison annotation workspace, case files, and review tools.',
|
|
56
56
|
robots: 'index,follow,max-image-preview:large,max-snippet:-1,max-video-preview:-1',
|
|
57
57
|
};
|
|
58
58
|
}
|
|
@@ -582,7 +582,7 @@ export const Login = () => {
|
|
|
582
582
|
<Link
|
|
583
583
|
viewTransition
|
|
584
584
|
prefetch="intent"
|
|
585
|
-
to="https://striae.
|
|
585
|
+
to="https://striae.app"
|
|
586
586
|
className={styles.logoLink}>
|
|
587
587
|
<div className={styles.logo} />
|
|
588
588
|
</Link>
|
|
@@ -37,7 +37,23 @@ function extractProxyPath(url: URL): string | null {
|
|
|
37
37
|
}
|
|
38
38
|
|
|
39
39
|
const remainder = url.pathname.slice(routePrefix.length);
|
|
40
|
-
|
|
40
|
+
if (remainder.length === 0) {
|
|
41
|
+
return '/';
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
const normalizedRemainder = remainder.startsWith('/') ? remainder : `/${remainder}`;
|
|
45
|
+
const encodedPath = normalizedRemainder.slice(1);
|
|
46
|
+
|
|
47
|
+
try {
|
|
48
|
+
const decodedPath = decodeURIComponent(encodedPath);
|
|
49
|
+
if (decodedPath.length > 0) {
|
|
50
|
+
return decodedPath.startsWith('/') ? decodedPath : `/${decodedPath}`;
|
|
51
|
+
}
|
|
52
|
+
} catch {
|
|
53
|
+
// Keep legacy behavior for non-encoded paths.
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
return normalizedRemainder;
|
|
41
57
|
}
|
|
42
58
|
|
|
43
59
|
function resolveImageWorkerToken(env: Env): string {
|
package/package.json
CHANGED
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@striae-org/striae",
|
|
3
|
-
"version": "4.0.
|
|
3
|
+
"version": "4.0.1",
|
|
4
4
|
"private": false,
|
|
5
5
|
"description": "Striae is a specialized, cloud-native platform designed to streamline forensic firearms identification by providing an intuitive environment for digital comparison image annotation, authenticated confirmations, and automated report generation.",
|
|
6
6
|
"license": "Apache-2.0",
|
|
7
|
-
"homepage": "https://
|
|
7
|
+
"homepage": "https://striae.app",
|
|
8
8
|
"repository": {
|
|
9
9
|
"type": "git",
|
|
10
10
|
"url": "https://github.com/striae-org/striae.git"
|
|
@@ -1,7 +1,6 @@
|
|
|
1
|
-
Contact: mailto:
|
|
1
|
+
Contact: mailto:security@striae.org
|
|
2
2
|
Contact: https://github.com/striae-org/striae/security/advisories/new
|
|
3
3
|
Expires: 2035-08-15T00:00:00.000Z
|
|
4
|
-
Encryption: https://www.striae.org/.well-known/publickey.info@striae.org.asc
|
|
5
4
|
Preferred-Languages: en
|
|
6
|
-
Canonical: https://
|
|
7
|
-
Policy: https://
|
|
5
|
+
Canonical: https://striae.app/.well-known/security.txt
|
|
6
|
+
Policy: https://striae.org/security
|
package/scripts/deploy-config.sh
CHANGED
|
@@ -181,6 +181,40 @@ normalize_domain_value() {
|
|
|
181
181
|
printf '%s' "$domain"
|
|
182
182
|
}
|
|
183
183
|
|
|
184
|
+
normalize_worker_label_value() {
|
|
185
|
+
local label="$1"
|
|
186
|
+
|
|
187
|
+
label=$(normalize_domain_value "$label")
|
|
188
|
+
label="${label#.}"
|
|
189
|
+
label="${label%.}"
|
|
190
|
+
label=$(printf '%s' "$label" | tr '[:upper:]' '[:lower:]')
|
|
191
|
+
|
|
192
|
+
printf '%s' "$label"
|
|
193
|
+
}
|
|
194
|
+
|
|
195
|
+
normalize_worker_subdomain_value() {
|
|
196
|
+
local subdomain="$1"
|
|
197
|
+
|
|
198
|
+
subdomain=$(normalize_domain_value "$subdomain")
|
|
199
|
+
subdomain="${subdomain#.}"
|
|
200
|
+
subdomain="${subdomain%.}"
|
|
201
|
+
subdomain=$(printf '%s' "$subdomain" | tr '[:upper:]' '[:lower:]')
|
|
202
|
+
|
|
203
|
+
printf '%s' "$subdomain"
|
|
204
|
+
}
|
|
205
|
+
|
|
206
|
+
is_valid_worker_label() {
|
|
207
|
+
local label="$1"
|
|
208
|
+
|
|
209
|
+
[[ "$label" =~ ^[a-z0-9-]+$ ]]
|
|
210
|
+
}
|
|
211
|
+
|
|
212
|
+
is_valid_worker_subdomain() {
|
|
213
|
+
local subdomain="$1"
|
|
214
|
+
|
|
215
|
+
[[ "$subdomain" =~ ^[a-z0-9]([a-z0-9-]*[a-z0-9])?(\.[a-z0-9]([a-z0-9-]*[a-z0-9])?)+$ ]]
|
|
216
|
+
}
|
|
217
|
+
|
|
184
218
|
strip_carriage_returns() {
|
|
185
219
|
printf '%s' "$1" | tr -d '\r'
|
|
186
220
|
}
|
|
@@ -245,54 +279,53 @@ generate_worker_subdomain_label() {
|
|
|
245
279
|
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
|
|
246
280
|
}
|
|
247
281
|
|
|
248
|
-
worker_name_var_for_domain_var() {
|
|
249
|
-
case "$1" in
|
|
250
|
-
KEYS_WORKER_DOMAIN)
|
|
251
|
-
printf '%s' "KEYS_WORKER_NAME"
|
|
252
|
-
;;
|
|
253
|
-
USER_WORKER_DOMAIN)
|
|
254
|
-
printf '%s' "USER_WORKER_NAME"
|
|
255
|
-
;;
|
|
256
|
-
DATA_WORKER_DOMAIN)
|
|
257
|
-
printf '%s' "DATA_WORKER_NAME"
|
|
258
|
-
;;
|
|
259
|
-
AUDIT_WORKER_DOMAIN)
|
|
260
|
-
printf '%s' "AUDIT_WORKER_NAME"
|
|
261
|
-
;;
|
|
262
|
-
IMAGES_WORKER_DOMAIN)
|
|
263
|
-
printf '%s' "IMAGES_WORKER_NAME"
|
|
264
|
-
;;
|
|
265
|
-
PDF_WORKER_DOMAIN)
|
|
266
|
-
printf '%s' "PDF_WORKER_NAME"
|
|
267
|
-
;;
|
|
268
|
-
*)
|
|
269
|
-
printf '%s' ""
|
|
270
|
-
;;
|
|
271
|
-
esac
|
|
272
|
-
}
|
|
273
|
-
|
|
274
282
|
compose_worker_domain() {
|
|
275
283
|
local worker_name=$1
|
|
276
284
|
local worker_subdomain=$2
|
|
277
285
|
|
|
278
|
-
worker_name=$(
|
|
279
|
-
worker_subdomain=$(
|
|
280
|
-
worker_name="${worker_name#.}"
|
|
281
|
-
worker_name="${worker_name%.}"
|
|
282
|
-
worker_subdomain="${worker_subdomain#.}"
|
|
283
|
-
worker_subdomain="${worker_subdomain%.}"
|
|
286
|
+
worker_name=$(normalize_worker_label_value "$worker_name")
|
|
287
|
+
worker_subdomain=$(normalize_worker_subdomain_value "$worker_subdomain")
|
|
284
288
|
|
|
285
289
|
if [ -z "$worker_name" ] || [ -z "$worker_subdomain" ]; then
|
|
286
290
|
return 1
|
|
287
291
|
fi
|
|
288
292
|
|
|
289
|
-
if
|
|
293
|
+
if ! is_valid_worker_label "$worker_name" || ! is_valid_worker_subdomain "$worker_subdomain"; then
|
|
290
294
|
return 1
|
|
291
295
|
fi
|
|
292
296
|
|
|
293
297
|
printf '%s.%s' "$worker_name" "$worker_subdomain"
|
|
294
298
|
}
|
|
295
299
|
|
|
300
|
+
infer_worker_subdomain_from_domain() {
|
|
301
|
+
local worker_name=$1
|
|
302
|
+
local worker_domain=$2
|
|
303
|
+
local worker_subdomain=""
|
|
304
|
+
|
|
305
|
+
worker_name=$(normalize_worker_label_value "$worker_name")
|
|
306
|
+
worker_domain=$(normalize_domain_value "$worker_domain")
|
|
307
|
+
worker_domain=$(printf '%s' "$worker_domain" | tr '[:upper:]' '[:lower:]')
|
|
308
|
+
|
|
309
|
+
if [ -z "$worker_name" ] || [ -z "$worker_domain" ] || is_placeholder "$worker_name" || is_placeholder "$worker_domain"; then
|
|
310
|
+
printf '%s' ""
|
|
311
|
+
return 0
|
|
312
|
+
fi
|
|
313
|
+
|
|
314
|
+
case "$worker_domain" in
|
|
315
|
+
"$worker_name".*)
|
|
316
|
+
worker_subdomain="${worker_domain#${worker_name}.}"
|
|
317
|
+
worker_subdomain=$(normalize_worker_subdomain_value "$worker_subdomain")
|
|
318
|
+
|
|
319
|
+
if is_valid_worker_subdomain "$worker_subdomain"; then
|
|
320
|
+
printf '%s' "$worker_subdomain"
|
|
321
|
+
return 0
|
|
322
|
+
fi
|
|
323
|
+
;;
|
|
324
|
+
esac
|
|
325
|
+
|
|
326
|
+
printf '%s' ""
|
|
327
|
+
}
|
|
328
|
+
|
|
296
329
|
write_env_var() {
|
|
297
330
|
local var_name=$1
|
|
298
331
|
local var_value=$2
|
|
@@ -975,7 +1008,7 @@ prompt_for_secrets() {
|
|
|
975
1008
|
|
|
976
1009
|
current_value=$(strip_carriage_returns "$current_value")
|
|
977
1010
|
|
|
978
|
-
if [ "$var_name" = "PAGES_CUSTOM_DOMAIN" ]
|
|
1011
|
+
if [ "$var_name" = "PAGES_CUSTOM_DOMAIN" ]; then
|
|
979
1012
|
current_value=$(resolve_existing_domain_value "$var_name" "$current_value")
|
|
980
1013
|
fi
|
|
981
1014
|
|
|
@@ -1039,107 +1072,6 @@ prompt_for_secrets() {
|
|
|
1039
1072
|
done
|
|
1040
1073
|
fi
|
|
1041
1074
|
fi
|
|
1042
|
-
elif [[ "$var_name" == *_WORKER_DOMAIN ]]; then
|
|
1043
|
-
local worker_name_var
|
|
1044
|
-
local worker_name_current=""
|
|
1045
|
-
local worker_name_input=""
|
|
1046
|
-
local worker_subdomain_input=""
|
|
1047
|
-
local inferred_subdomain=""
|
|
1048
|
-
local domain_choice=""
|
|
1049
|
-
local composed_domain=""
|
|
1050
|
-
|
|
1051
|
-
worker_name_var=$(worker_name_var_for_domain_var "$var_name")
|
|
1052
|
-
worker_name_current=$(strip_carriage_returns "${!worker_name_var}")
|
|
1053
|
-
|
|
1054
|
-
if [ -n "$worker_name_current" ] && ! is_placeholder "$worker_name_current" && [ -n "$current_value" ] && ! is_placeholder "$current_value"; then
|
|
1055
|
-
case "$current_value" in
|
|
1056
|
-
"$worker_name_current".*)
|
|
1057
|
-
inferred_subdomain="${current_value#${worker_name_current}.}"
|
|
1058
|
-
;;
|
|
1059
|
-
esac
|
|
1060
|
-
fi
|
|
1061
|
-
|
|
1062
|
-
echo -e "${BLUE}$var_name${NC}"
|
|
1063
|
-
echo -e "${YELLOW}$description${NC}"
|
|
1064
|
-
|
|
1065
|
-
while true; do
|
|
1066
|
-
if [ "$update_env" != "true" ] && [ -n "$current_value" ] && ! is_placeholder "$current_value"; then
|
|
1067
|
-
echo -e "${GREEN}Current value: $current_value${NC}"
|
|
1068
|
-
read -p "Press Enter to keep current, or type 'y' to rebuild from worker-name and worker-subdomain: " domain_choice
|
|
1069
|
-
domain_choice=$(strip_carriage_returns "$domain_choice")
|
|
1070
|
-
|
|
1071
|
-
if [ -z "$domain_choice" ]; then
|
|
1072
|
-
new_value=""
|
|
1073
|
-
break
|
|
1074
|
-
fi
|
|
1075
|
-
|
|
1076
|
-
if [ "$domain_choice" != "y" ] && [ "$domain_choice" != "Y" ]; then
|
|
1077
|
-
echo -e "${RED}❌ Please press Enter to keep current or type 'y' to rebuild.${NC}"
|
|
1078
|
-
continue
|
|
1079
|
-
fi
|
|
1080
|
-
fi
|
|
1081
|
-
|
|
1082
|
-
if [ -n "$worker_name_current" ] && ! is_placeholder "$worker_name_current"; then
|
|
1083
|
-
read -p "Prompt: worker-name [$worker_name_current]: " worker_name_input
|
|
1084
|
-
worker_name_input=$(strip_carriage_returns "$worker_name_input")
|
|
1085
|
-
if [ -z "$worker_name_input" ]; then
|
|
1086
|
-
worker_name_input="$worker_name_current"
|
|
1087
|
-
fi
|
|
1088
|
-
else
|
|
1089
|
-
read -p "Prompt: worker-name: " worker_name_input
|
|
1090
|
-
worker_name_input=$(strip_carriage_returns "$worker_name_input")
|
|
1091
|
-
fi
|
|
1092
|
-
|
|
1093
|
-
if [ -z "$worker_name_input" ] || is_placeholder "$worker_name_input"; then
|
|
1094
|
-
echo -e "${RED}❌ worker-name is required and cannot be a placeholder.${NC}"
|
|
1095
|
-
continue
|
|
1096
|
-
fi
|
|
1097
|
-
|
|
1098
|
-
worker_name_input=$(normalize_domain_value "$worker_name_input")
|
|
1099
|
-
worker_name_input="${worker_name_input#.}"
|
|
1100
|
-
worker_name_input="${worker_name_input%.}"
|
|
1101
|
-
|
|
1102
|
-
if [[ "$worker_name_input" == *.* ]] || [[ "$worker_name_input" == */* ]]; then
|
|
1103
|
-
echo -e "${RED}❌ worker-name must be a single hostname label (for example: striae-dev-data).${NC}"
|
|
1104
|
-
continue
|
|
1105
|
-
fi
|
|
1106
|
-
|
|
1107
|
-
if [ -n "$inferred_subdomain" ]; then
|
|
1108
|
-
read -p "Prompt: worker-subdomain [$inferred_subdomain]: " worker_subdomain_input
|
|
1109
|
-
worker_subdomain_input=$(strip_carriage_returns "$worker_subdomain_input")
|
|
1110
|
-
if [ -z "$worker_subdomain_input" ]; then
|
|
1111
|
-
worker_subdomain_input="$inferred_subdomain"
|
|
1112
|
-
fi
|
|
1113
|
-
else
|
|
1114
|
-
read -p "Prompt: worker-subdomain: " worker_subdomain_input
|
|
1115
|
-
worker_subdomain_input=$(strip_carriage_returns "$worker_subdomain_input")
|
|
1116
|
-
fi
|
|
1117
|
-
|
|
1118
|
-
if [ -z "$worker_subdomain_input" ] || is_placeholder "$worker_subdomain_input"; then
|
|
1119
|
-
echo -e "${RED}❌ worker-subdomain is required and cannot be a placeholder.${NC}"
|
|
1120
|
-
continue
|
|
1121
|
-
fi
|
|
1122
|
-
|
|
1123
|
-
worker_subdomain_input=$(normalize_domain_value "$worker_subdomain_input")
|
|
1124
|
-
worker_subdomain_input="${worker_subdomain_input#.}"
|
|
1125
|
-
worker_subdomain_input="${worker_subdomain_input%.}"
|
|
1126
|
-
|
|
1127
|
-
composed_domain=$(compose_worker_domain "$worker_name_input" "$worker_subdomain_input" || echo "")
|
|
1128
|
-
if [ -z "$composed_domain" ]; then
|
|
1129
|
-
echo -e "${RED}❌ Invalid worker-name/worker-subdomain combination.${NC}"
|
|
1130
|
-
continue
|
|
1131
|
-
fi
|
|
1132
|
-
|
|
1133
|
-
if [ -n "$worker_name_var" ]; then
|
|
1134
|
-
write_env_var "$worker_name_var" "$worker_name_input"
|
|
1135
|
-
export "$worker_name_var=$worker_name_input"
|
|
1136
|
-
worker_name_current="$worker_name_input"
|
|
1137
|
-
fi
|
|
1138
|
-
|
|
1139
|
-
new_value="$composed_domain"
|
|
1140
|
-
echo -e "${GREEN}Resulting worker domain: $new_value${NC}"
|
|
1141
|
-
break
|
|
1142
|
-
done
|
|
1143
1075
|
else
|
|
1144
1076
|
# Normal prompt for other variables
|
|
1145
1077
|
echo -e "${BLUE}$var_name${NC}"
|
|
@@ -1175,12 +1107,22 @@ prompt_for_secrets() {
|
|
|
1175
1107
|
continue
|
|
1176
1108
|
fi
|
|
1177
1109
|
|
|
1110
|
+
if [[ "$var_name" == *_WORKER_NAME ]]; then
|
|
1111
|
+
new_value=$(normalize_worker_label_value "$new_value")
|
|
1112
|
+
|
|
1113
|
+
if [ -z "$new_value" ] || ! is_valid_worker_label "$new_value"; then
|
|
1114
|
+
echo -e "${RED}❌ $var_name must use only lowercase letters, numbers, and dashes.${NC}"
|
|
1115
|
+
new_value=""
|
|
1116
|
+
continue
|
|
1117
|
+
fi
|
|
1118
|
+
fi
|
|
1119
|
+
|
|
1178
1120
|
break
|
|
1179
1121
|
done
|
|
1180
1122
|
fi
|
|
1181
1123
|
|
|
1182
1124
|
if [ -n "$new_value" ]; then
|
|
1183
|
-
if [ "$var_name" = "PAGES_CUSTOM_DOMAIN" ]
|
|
1125
|
+
if [ "$var_name" = "PAGES_CUSTOM_DOMAIN" ]; then
|
|
1184
1126
|
new_value=$(normalize_domain_value "$new_value")
|
|
1185
1127
|
fi
|
|
1186
1128
|
|
|
@@ -1190,6 +1132,10 @@ prompt_for_secrets() {
|
|
|
1190
1132
|
export "$var_name=$new_value"
|
|
1191
1133
|
echo -e "${GREEN}✅ $var_name updated${NC}"
|
|
1192
1134
|
elif [ -n "$current_value" ]; then
|
|
1135
|
+
if [[ "$var_name" == *_WORKER_NAME ]]; then
|
|
1136
|
+
current_value=$(normalize_worker_label_value "$current_value")
|
|
1137
|
+
fi
|
|
1138
|
+
|
|
1193
1139
|
# Keep values aligned with .env.example ordering and remove stale duplicates.
|
|
1194
1140
|
write_env_var "$var_name" "$current_value"
|
|
1195
1141
|
export "$var_name=$current_value"
|
|
@@ -1197,6 +1143,31 @@ prompt_for_secrets() {
|
|
|
1197
1143
|
fi
|
|
1198
1144
|
echo ""
|
|
1199
1145
|
}
|
|
1146
|
+
|
|
1147
|
+
set_worker_domain_from_shared_subdomain() {
|
|
1148
|
+
local worker_name_var=$1
|
|
1149
|
+
local worker_domain_var=$2
|
|
1150
|
+
local worker_name_value="${!worker_name_var}"
|
|
1151
|
+
local composed_domain=""
|
|
1152
|
+
|
|
1153
|
+
worker_name_value=$(normalize_worker_label_value "$worker_name_value")
|
|
1154
|
+
|
|
1155
|
+
if [ -z "$worker_name_value" ] || ! is_valid_worker_label "$worker_name_value"; then
|
|
1156
|
+
echo -e "${RED}❌ $worker_name_var must use only lowercase letters, numbers, and dashes.${NC}"
|
|
1157
|
+
exit 1
|
|
1158
|
+
fi
|
|
1159
|
+
|
|
1160
|
+
composed_domain=$(compose_worker_domain "$worker_name_value" "$shared_worker_subdomain" || echo "")
|
|
1161
|
+
|
|
1162
|
+
if [ -z "$composed_domain" ]; then
|
|
1163
|
+
echo -e "${RED}❌ Could not build $worker_domain_var from $worker_name_var and shared worker-subdomain.${NC}"
|
|
1164
|
+
exit 1
|
|
1165
|
+
fi
|
|
1166
|
+
|
|
1167
|
+
write_env_var "$worker_domain_var" "$composed_domain"
|
|
1168
|
+
export "$worker_domain_var=$composed_domain"
|
|
1169
|
+
echo -e "${GREEN}✅ $worker_domain_var set to $composed_domain${NC}"
|
|
1170
|
+
}
|
|
1200
1171
|
|
|
1201
1172
|
echo -e "${BLUE}📊 CLOUDFLARE CORE CONFIGURATION${NC}"
|
|
1202
1173
|
echo "=================================="
|
|
@@ -1225,18 +1196,81 @@ prompt_for_secrets() {
|
|
|
1225
1196
|
|
|
1226
1197
|
echo -e "${BLUE}🔑 WORKER NAMES & DOMAINS${NC}"
|
|
1227
1198
|
echo "========================="
|
|
1199
|
+
echo -e "${YELLOW}Worker names are lowercased automatically and must use only letters, numbers, and dashes.${NC}"
|
|
1200
|
+
echo -e "${YELLOW}Enter one shared worker-subdomain as a hostname (for example: team-name.workers.dev).${NC}"
|
|
1201
|
+
echo -e "${YELLOW}Each worker domain is generated as {worker-name}.{worker-subdomain}.${NC}"
|
|
1202
|
+
|
|
1203
|
+
local shared_worker_subdomain=""
|
|
1204
|
+
local shared_worker_subdomain_default=""
|
|
1205
|
+
local shared_worker_subdomain_input=""
|
|
1206
|
+
|
|
1207
|
+
shared_worker_subdomain_default=$(infer_worker_subdomain_from_domain "$KEYS_WORKER_NAME" "$KEYS_WORKER_DOMAIN")
|
|
1208
|
+
if [ -z "$shared_worker_subdomain_default" ]; then
|
|
1209
|
+
shared_worker_subdomain_default=$(infer_worker_subdomain_from_domain "$USER_WORKER_NAME" "$USER_WORKER_DOMAIN")
|
|
1210
|
+
fi
|
|
1211
|
+
if [ -z "$shared_worker_subdomain_default" ]; then
|
|
1212
|
+
shared_worker_subdomain_default=$(infer_worker_subdomain_from_domain "$DATA_WORKER_NAME" "$DATA_WORKER_DOMAIN")
|
|
1213
|
+
fi
|
|
1214
|
+
if [ -z "$shared_worker_subdomain_default" ]; then
|
|
1215
|
+
shared_worker_subdomain_default=$(infer_worker_subdomain_from_domain "$AUDIT_WORKER_NAME" "$AUDIT_WORKER_DOMAIN")
|
|
1216
|
+
fi
|
|
1217
|
+
if [ -z "$shared_worker_subdomain_default" ]; then
|
|
1218
|
+
shared_worker_subdomain_default=$(infer_worker_subdomain_from_domain "$IMAGES_WORKER_NAME" "$IMAGES_WORKER_DOMAIN")
|
|
1219
|
+
fi
|
|
1220
|
+
if [ -z "$shared_worker_subdomain_default" ]; then
|
|
1221
|
+
shared_worker_subdomain_default=$(infer_worker_subdomain_from_domain "$PDF_WORKER_NAME" "$PDF_WORKER_DOMAIN")
|
|
1222
|
+
fi
|
|
1223
|
+
|
|
1224
|
+
while true; do
|
|
1225
|
+
echo -e "${BLUE}WORKER_SUBDOMAIN${NC}"
|
|
1226
|
+
|
|
1227
|
+
if [ "$update_env" != "true" ] && [ -n "$shared_worker_subdomain_default" ] && ! is_placeholder "$shared_worker_subdomain_default"; then
|
|
1228
|
+
echo -e "${GREEN}Current value: $shared_worker_subdomain_default${NC}"
|
|
1229
|
+
read -p "New value (or press Enter to keep current): " shared_worker_subdomain_input
|
|
1230
|
+
shared_worker_subdomain_input=$(strip_carriage_returns "$shared_worker_subdomain_input")
|
|
1231
|
+
|
|
1232
|
+
if [ -z "$shared_worker_subdomain_input" ]; then
|
|
1233
|
+
shared_worker_subdomain="$shared_worker_subdomain_default"
|
|
1234
|
+
else
|
|
1235
|
+
shared_worker_subdomain="$shared_worker_subdomain_input"
|
|
1236
|
+
fi
|
|
1237
|
+
else
|
|
1238
|
+
read -p "Enter shared worker-subdomain (e.g., team-name.workers.dev): " shared_worker_subdomain_input
|
|
1239
|
+
shared_worker_subdomain_input=$(strip_carriage_returns "$shared_worker_subdomain_input")
|
|
1240
|
+
shared_worker_subdomain="$shared_worker_subdomain_input"
|
|
1241
|
+
fi
|
|
1242
|
+
|
|
1243
|
+
if [ -z "$shared_worker_subdomain" ] || is_placeholder "$shared_worker_subdomain"; then
|
|
1244
|
+
echo -e "${RED}❌ shared worker-subdomain is required and cannot be a placeholder.${NC}"
|
|
1245
|
+
continue
|
|
1246
|
+
fi
|
|
1247
|
+
|
|
1248
|
+
shared_worker_subdomain=$(normalize_worker_subdomain_value "$shared_worker_subdomain")
|
|
1249
|
+
|
|
1250
|
+
if [ -z "$shared_worker_subdomain" ] || ! is_valid_worker_subdomain "$shared_worker_subdomain"; then
|
|
1251
|
+
echo -e "${RED}❌ shared worker-subdomain must be a valid hostname like team-name.workers.dev (letters, numbers, dashes, and dots).${NC}"
|
|
1252
|
+
continue
|
|
1253
|
+
fi
|
|
1254
|
+
|
|
1255
|
+
echo -e "${GREEN}✅ Shared worker-subdomain set to: $shared_worker_subdomain${NC}"
|
|
1256
|
+
echo ""
|
|
1257
|
+
break
|
|
1258
|
+
done
|
|
1259
|
+
|
|
1228
1260
|
prompt_for_var "KEYS_WORKER_NAME" "Keys worker name"
|
|
1229
|
-
prompt_for_var "KEYS_WORKER_DOMAIN" "Keys worker domain (format: {worker-name}.{worker-subdomain})"
|
|
1230
1261
|
prompt_for_var "USER_WORKER_NAME" "User worker name"
|
|
1231
|
-
prompt_for_var "USER_WORKER_DOMAIN" "User worker domain (format: {worker-name}.{worker-subdomain})"
|
|
1232
1262
|
prompt_for_var "DATA_WORKER_NAME" "Data worker name"
|
|
1233
|
-
prompt_for_var "DATA_WORKER_DOMAIN" "Data worker domain (format: {worker-name}.{worker-subdomain})"
|
|
1234
1263
|
prompt_for_var "AUDIT_WORKER_NAME" "Audit worker name"
|
|
1235
|
-
prompt_for_var "AUDIT_WORKER_DOMAIN" "Audit worker domain (format: {worker-name}.{worker-subdomain})"
|
|
1236
1264
|
prompt_for_var "IMAGES_WORKER_NAME" "Images worker name"
|
|
1237
|
-
prompt_for_var "IMAGES_WORKER_DOMAIN" "Images worker domain (format: {worker-name}.{worker-subdomain})"
|
|
1238
1265
|
prompt_for_var "PDF_WORKER_NAME" "PDF worker name"
|
|
1239
|
-
|
|
1266
|
+
|
|
1267
|
+
set_worker_domain_from_shared_subdomain "KEYS_WORKER_NAME" "KEYS_WORKER_DOMAIN"
|
|
1268
|
+
set_worker_domain_from_shared_subdomain "USER_WORKER_NAME" "USER_WORKER_DOMAIN"
|
|
1269
|
+
set_worker_domain_from_shared_subdomain "DATA_WORKER_NAME" "DATA_WORKER_DOMAIN"
|
|
1270
|
+
set_worker_domain_from_shared_subdomain "AUDIT_WORKER_NAME" "AUDIT_WORKER_DOMAIN"
|
|
1271
|
+
set_worker_domain_from_shared_subdomain "IMAGES_WORKER_NAME" "IMAGES_WORKER_DOMAIN"
|
|
1272
|
+
set_worker_domain_from_shared_subdomain "PDF_WORKER_NAME" "PDF_WORKER_DOMAIN"
|
|
1273
|
+
echo ""
|
|
1240
1274
|
|
|
1241
1275
|
echo -e "${BLUE}🗄️ STORAGE CONFIGURATION${NC}"
|
|
1242
1276
|
echo "========================="
|