@le-space/rootfs 0.6.6 → 0.6.19
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/package.json +1 -1
- package/reference/orbitdb-relay/rootfs/orbitdb-relay-bootstrap-refresh.py +53 -11
- package/reference/orbitdb-relay/rootfs/orbitdb-relay-bootstrap.sh +0 -1
- package/reference/orbitdb-relay/rootfs/orbitdb-relay-configure.sh +12 -6
- package/reference/ucan-store/rootfs/ucan-store-configure.sh +54 -12
- package/reference/ucan-store/rootfs/ucan-store-setup-server.py +14 -0
package/package.json
CHANGED
|
@@ -168,7 +168,8 @@ def json_dumps(payload: object) -> str:
|
|
|
168
168
|
def sign_personal_message(private_key: str, payload: str) -> str:
|
|
169
169
|
message = encode_defunct(text=payload)
|
|
170
170
|
signed = Account.sign_message(message, private_key=private_key)
|
|
171
|
-
|
|
171
|
+
signature = signed.signature.hex()
|
|
172
|
+
return signature if signature.startswith("0x") else f"0x{signature}"
|
|
172
173
|
|
|
173
174
|
|
|
174
175
|
def address_from_private_key(private_key: str) -> str:
|
|
@@ -179,6 +180,21 @@ def signature_payload(chain: str, sender: str, message_type: str, item_hash: str
|
|
|
179
180
|
return "\n".join([chain, sender, message_type, item_hash])
|
|
180
181
|
|
|
181
182
|
|
|
183
|
+
def registration_id_instance_item_hash(registration_id: str | None) -> str | None:
|
|
184
|
+
normalized = str(registration_id or "").strip()
|
|
185
|
+
if not normalized:
|
|
186
|
+
return None
|
|
187
|
+
|
|
188
|
+
parts = [part.strip() for part in normalized.split(":") if part.strip()]
|
|
189
|
+
if not parts:
|
|
190
|
+
return None
|
|
191
|
+
|
|
192
|
+
candidate = parts[-1]
|
|
193
|
+
if len(candidate) == 64 and all(char in "0123456789abcdefABCDEF" for char in candidate):
|
|
194
|
+
return candidate
|
|
195
|
+
return None
|
|
196
|
+
|
|
197
|
+
|
|
182
198
|
def relay_authorization_payload(
|
|
183
199
|
owner_address: str,
|
|
184
200
|
publisher_address: str,
|
|
@@ -186,6 +202,7 @@ def relay_authorization_payload(
|
|
|
186
202
|
registration_id: str | None,
|
|
187
203
|
profile: str | None,
|
|
188
204
|
version: str | None,
|
|
205
|
+
instance_item_hash: str | None,
|
|
189
206
|
issued_at: int,
|
|
190
207
|
) -> dict[str, object]:
|
|
191
208
|
return {
|
|
@@ -195,7 +212,7 @@ def relay_authorization_payload(
|
|
|
195
212
|
"registrationId": registration_id,
|
|
196
213
|
"profile": profile,
|
|
197
214
|
"version": version,
|
|
198
|
-
"instanceItemHash":
|
|
215
|
+
"instanceItemHash": instance_item_hash,
|
|
199
216
|
"issuedAt": issued_at,
|
|
200
217
|
"expiresAt": None,
|
|
201
218
|
}
|
|
@@ -244,6 +261,7 @@ def load_owner_authorization(
|
|
|
244
261
|
return None
|
|
245
262
|
|
|
246
263
|
owner_address = address_from_private_key(owner_private_key)
|
|
264
|
+
instance_item_hash = registration_id_instance_item_hash(registration_id)
|
|
247
265
|
payload = relay_authorization_payload(
|
|
248
266
|
owner_address,
|
|
249
267
|
publisher_address,
|
|
@@ -251,6 +269,7 @@ def load_owner_authorization(
|
|
|
251
269
|
registration_id,
|
|
252
270
|
profile,
|
|
253
271
|
version,
|
|
272
|
+
instance_item_hash,
|
|
254
273
|
issued_at,
|
|
255
274
|
)
|
|
256
275
|
return {
|
|
@@ -260,6 +279,28 @@ def load_owner_authorization(
|
|
|
260
279
|
}
|
|
261
280
|
|
|
262
281
|
|
|
282
|
+
def resolve_owner_address(
|
|
283
|
+
env_values: dict[str, str],
|
|
284
|
+
owner_authorization: dict[str, object] | None,
|
|
285
|
+
) -> str | None:
|
|
286
|
+
if isinstance(owner_authorization, dict):
|
|
287
|
+
payload = owner_authorization.get("payload")
|
|
288
|
+
if isinstance(payload, dict):
|
|
289
|
+
owner_address = str(payload.get("ownerAddress") or "").strip()
|
|
290
|
+
if owner_address:
|
|
291
|
+
return owner_address
|
|
292
|
+
|
|
293
|
+
owner_address = env_values.get("ALEPH_BOOTSTRAP_OWNER_ADDRESS", "").strip()
|
|
294
|
+
if owner_address:
|
|
295
|
+
return owner_address
|
|
296
|
+
|
|
297
|
+
owner_private_key = env_values.get("ALEPH_BOOTSTRAP_OWNER_PRIVATE_KEY", "").strip()
|
|
298
|
+
if owner_private_key:
|
|
299
|
+
return address_from_private_key(owner_private_key)
|
|
300
|
+
|
|
301
|
+
return None
|
|
302
|
+
|
|
303
|
+
|
|
263
304
|
def post_json(url: str, body: dict[str, object]) -> tuple[int, dict]:
|
|
264
305
|
data = json_dumps(body).encode("utf-8")
|
|
265
306
|
request = urllib.request.Request(
|
|
@@ -293,9 +334,11 @@ def build_post_content(
|
|
|
293
334
|
registration_id: str | None,
|
|
294
335
|
profile: str | None,
|
|
295
336
|
version: str | None,
|
|
337
|
+
owner_address: str | None,
|
|
296
338
|
owner_authorization: dict[str, object] | None,
|
|
297
339
|
relay_proof: dict[str, object],
|
|
298
340
|
now_ms: int,
|
|
341
|
+
now_seconds: float,
|
|
299
342
|
ref: str,
|
|
300
343
|
post_type: str,
|
|
301
344
|
) -> dict[str, object]:
|
|
@@ -306,22 +349,20 @@ def build_post_content(
|
|
|
306
349
|
"registrationId": registration_id,
|
|
307
350
|
"profile": profile,
|
|
308
351
|
"version": version,
|
|
309
|
-
"ownerAddress":
|
|
310
|
-
owner_authorization.get("payload", {}).get("ownerAddress")
|
|
311
|
-
if isinstance(owner_authorization, dict)
|
|
312
|
-
else None
|
|
313
|
-
),
|
|
352
|
+
"ownerAddress": owner_address,
|
|
314
353
|
"publisherAddress": sender,
|
|
315
354
|
"authorization": owner_authorization,
|
|
316
355
|
"relayProof": relay_proof,
|
|
317
356
|
"updatedAt": now_ms,
|
|
318
357
|
}
|
|
358
|
+
if browser_multiaddrs:
|
|
359
|
+
content["browserMultiaddrs"] = browser_multiaddrs
|
|
319
360
|
return {
|
|
320
361
|
"type": post_type,
|
|
321
362
|
"address": sender,
|
|
322
363
|
"ref": ref,
|
|
323
364
|
"content": content,
|
|
324
|
-
"time":
|
|
365
|
+
"time": now_seconds,
|
|
325
366
|
}
|
|
326
367
|
|
|
327
368
|
|
|
@@ -550,9 +591,7 @@ def main() -> None:
|
|
|
550
591
|
version,
|
|
551
592
|
now_ms,
|
|
552
593
|
)
|
|
553
|
-
|
|
554
|
-
print(json_dumps({"status": "skipped", "reason": "missing owner authorization"}))
|
|
555
|
-
return
|
|
594
|
+
owner_address = resolve_owner_address(env_values, owner_authorization)
|
|
556
595
|
|
|
557
596
|
proof_payload = relay_proof_payload(
|
|
558
597
|
peer_id,
|
|
@@ -576,9 +615,11 @@ def main() -> None:
|
|
|
576
615
|
registration_id,
|
|
577
616
|
profile,
|
|
578
617
|
version,
|
|
618
|
+
owner_address,
|
|
579
619
|
owner_authorization,
|
|
580
620
|
relay_proof,
|
|
581
621
|
now_ms,
|
|
622
|
+
now_seconds,
|
|
582
623
|
ref,
|
|
583
624
|
post_type,
|
|
584
625
|
)
|
|
@@ -614,6 +655,7 @@ def main() -> None:
|
|
|
614
655
|
"publishedBrowserMultiaddrs": published_browser_multiaddrs or published_multiaddrs,
|
|
615
656
|
"forgottenHashes": previous_hashes,
|
|
616
657
|
"forgetStaleOlderThanSeconds": STALE_RECORD_MAX_AGE_SECONDS,
|
|
658
|
+
"ownerAuthorizationPresent": owner_authorization is not None,
|
|
617
659
|
"forgetResponse": forget_response[1] if forget_response else None,
|
|
618
660
|
"response": response,
|
|
619
661
|
}
|
|
@@ -118,6 +118,5 @@ write_env_var "RELAY_WEBRTC_PORT" "9093"
|
|
|
118
118
|
write_env_var "RELAY_QUIC_PORT" "9094"
|
|
119
119
|
write_env_var "RELAY_DISABLE_WEBRTC" "1"
|
|
120
120
|
write_env_var "RELAY_DISABLE_BOOTSTRAP" "1"
|
|
121
|
-
write_env_var "disableAutoTLS" "1"
|
|
122
121
|
write_env_var "ENABLE_GENERAL_LOGS" "1"
|
|
123
122
|
write_env_var "DEBUG" "'libp2p:websockets:listener'"
|
|
@@ -75,7 +75,13 @@ write_caddyfile() {
|
|
|
75
75
|
auto_https disable_redirects
|
|
76
76
|
}
|
|
77
77
|
|
|
78
|
-
|
|
78
|
+
https://${hostname} {
|
|
79
|
+
tls {
|
|
80
|
+
issuer acme {
|
|
81
|
+
disable_tlsalpn_challenge
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
|
|
79
85
|
# Proxy the full orbitdb-relay HTTP API surface to the metrics/HTTP port.
|
|
80
86
|
# Everything else falls through to the relay WebSocket backend for browser libp2p.
|
|
81
87
|
handle /health {
|
|
@@ -202,11 +208,11 @@ fi
|
|
|
202
208
|
if [ -n "${PROXY_HOSTNAME}" ]; then
|
|
203
209
|
announce+=("/dns4/${PROXY_HOSTNAME}/tcp/443/tls/ws")
|
|
204
210
|
announce+=("/dns6/${PROXY_HOSTNAME}/tcp/443/tls/ws")
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
211
|
+
fi
|
|
212
|
+
|
|
213
|
+
announce+=("/ip4/${PUBLIC_IPV4}/tcp/${WS_PORT}/ws")
|
|
214
|
+
if [ -n "${PUBLIC_IPV6}" ]; then
|
|
215
|
+
announce+=("/ip6/${PUBLIC_IPV6}/tcp/${WS_PORT}/ws")
|
|
210
216
|
fi
|
|
211
217
|
|
|
212
218
|
if [ -n "${WEBRTC_PORT}" ]; then
|
|
@@ -8,6 +8,7 @@ BOOTSTRAP_VALIDATOR="${BOOTSTRAP_VALIDATOR:-/usr/local/sbin/ucan_store_bootstrap
|
|
|
8
8
|
BOOTSTRAP_CRYPTO_VERIFIER="${BOOTSTRAP_CRYPTO_VERIFIER:-/usr/local/sbin/ucan-store-bootstrap-verify.mjs}"
|
|
9
9
|
BOOTSTRAP_VERIFICATION_FILE="${BOOTSTRAP_VERIFICATION_FILE:-/etc/ucan-store/bootstrap-verification.json}"
|
|
10
10
|
SERVICE_NAME="${SERVICE_NAME:-ucan-store.service}"
|
|
11
|
+
BOOTSTRAP_SERVICE="${BOOTSTRAP_SERVICE:-ucan-store-bootstrap.service}"
|
|
11
12
|
CADDY_SERVICE="${CADDY_SERVICE:-caddy.service}"
|
|
12
13
|
CADDYFILE="${CADDYFILE:-/etc/caddy/Caddyfile}"
|
|
13
14
|
SERVICE_PORT="${SERVICE_PORT:-8787}"
|
|
@@ -75,10 +76,19 @@ PY
|
|
|
75
76
|
}
|
|
76
77
|
|
|
77
78
|
write_caddyfile() {
|
|
79
|
+
local service_hostname="${1:-}"
|
|
80
|
+
local proxy_hostname="${2:-}"
|
|
81
|
+
local primary_hostname="${service_hostname}"
|
|
78
82
|
local hostnames=()
|
|
79
83
|
local hostname
|
|
80
84
|
local known
|
|
81
|
-
|
|
85
|
+
|
|
86
|
+
if [ -z "${primary_hostname}" ]; then
|
|
87
|
+
primary_hostname="${proxy_hostname}"
|
|
88
|
+
proxy_hostname=""
|
|
89
|
+
fi
|
|
90
|
+
|
|
91
|
+
for hostname in "${primary_hostname}" "${proxy_hostname}"; do
|
|
82
92
|
if [ -z "${hostname}" ]; then
|
|
83
93
|
continue
|
|
84
94
|
fi
|
|
@@ -100,11 +110,13 @@ write_caddyfile() {
|
|
|
100
110
|
return 0
|
|
101
111
|
fi
|
|
102
112
|
|
|
103
|
-
local
|
|
113
|
+
local http_site_label=""
|
|
104
114
|
local index
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
115
|
+
for ((index = 0; index < ${#hostnames[@]}; index++)); do
|
|
116
|
+
if [ -n "${http_site_label}" ]; then
|
|
117
|
+
http_site_label+=", "
|
|
118
|
+
fi
|
|
119
|
+
http_site_label+="http://${hostnames[${index}]}"
|
|
108
120
|
done
|
|
109
121
|
mkdir -p "$(dirname "${CADDYFILE}")"
|
|
110
122
|
cat > "${CADDYFILE}" <<EOF
|
|
@@ -112,10 +124,31 @@ write_caddyfile() {
|
|
|
112
124
|
auto_https disable_redirects
|
|
113
125
|
}
|
|
114
126
|
|
|
115
|
-
${
|
|
127
|
+
${http_site_label} {
|
|
128
|
+
reverse_proxy 127.0.0.1:${PROXY_PORT}
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
https://${primary_hostname} {
|
|
132
|
+
tls {
|
|
133
|
+
issuer acme {
|
|
134
|
+
disable_tlsalpn_challenge
|
|
135
|
+
}
|
|
136
|
+
}
|
|
137
|
+
|
|
116
138
|
reverse_proxy 127.0.0.1:${PROXY_PORT}
|
|
117
139
|
}
|
|
118
140
|
EOF
|
|
141
|
+
|
|
142
|
+
if [ -n "${proxy_hostname}" ] && [ "${proxy_hostname}" != "${primary_hostname}" ]; then
|
|
143
|
+
cat >> "${CADDYFILE}" <<EOF
|
|
144
|
+
|
|
145
|
+
https://${proxy_hostname} {
|
|
146
|
+
tls internal
|
|
147
|
+
|
|
148
|
+
reverse_proxy 127.0.0.1:${PROXY_PORT}
|
|
149
|
+
}
|
|
150
|
+
EOF
|
|
151
|
+
fi
|
|
119
152
|
}
|
|
120
153
|
|
|
121
154
|
derive_hostname_from_origin() {
|
|
@@ -299,15 +332,19 @@ if [ -n "${WEBAUTHN_ORIGIN}" ]; then
|
|
|
299
332
|
fi
|
|
300
333
|
write_env_var "WEBAUTHN_ORIGIN_FALLBACKS" "${WEBAUTHN_ORIGIN_FALLBACKS}"
|
|
301
334
|
|
|
302
|
-
if [ -z "${SERVICE_DID}" ] && [ -n "${PROXY_HOSTNAME}" ]; then
|
|
303
|
-
SERVICE_DID="$(derive_service_did_from_hostname "${PROXY_HOSTNAME}")"
|
|
304
|
-
fi
|
|
305
|
-
|
|
306
335
|
if [ -z "${SERVICE_ORIGIN}" ] && [ -n "${PROXY_HOSTNAME}" ]; then
|
|
307
336
|
SERVICE_ORIGIN="https://${PROXY_HOSTNAME}"
|
|
308
337
|
fi
|
|
309
338
|
SERVICE_HOSTNAME="$(derive_hostname_from_origin "${SERVICE_ORIGIN}")"
|
|
310
339
|
|
|
340
|
+
if [ -z "${SERVICE_DID}" ]; then
|
|
341
|
+
if [ -n "${SERVICE_HOSTNAME}" ]; then
|
|
342
|
+
SERVICE_DID="$(derive_service_did_from_hostname "${SERVICE_HOSTNAME}")"
|
|
343
|
+
elif [ -n "${PROXY_HOSTNAME}" ]; then
|
|
344
|
+
SERVICE_DID="$(derive_service_did_from_hostname "${PROXY_HOSTNAME}")"
|
|
345
|
+
fi
|
|
346
|
+
fi
|
|
347
|
+
|
|
311
348
|
write_env_var "UCAN_STORE_SERVICE_DID" "${SERVICE_DID}"
|
|
312
349
|
write_env_var "UCAN_STORE_SERVICE_HOSTNAME" "${SERVICE_HOSTNAME}"
|
|
313
350
|
|
|
@@ -323,7 +360,7 @@ if [ -n "${SERVICE_ORIGIN}" ]; then
|
|
|
323
360
|
fi
|
|
324
361
|
|
|
325
362
|
if [ -n "${PROXY_HOSTNAME}" ]; then
|
|
326
|
-
write_caddyfile "${
|
|
363
|
+
write_caddyfile "${SERVICE_HOSTNAME:-}" "${PROXY_HOSTNAME}"
|
|
327
364
|
fi
|
|
328
365
|
|
|
329
366
|
touch "${READY_FILE}"
|
|
@@ -332,7 +369,12 @@ if [ "${START_SERVICE}" = "1" ]; then
|
|
|
332
369
|
systemctl daemon-reload
|
|
333
370
|
systemctl restart "${SERVICE_NAME}"
|
|
334
371
|
if [ -n "${PROXY_HOSTNAME}" ]; then
|
|
335
|
-
systemctl
|
|
372
|
+
systemctl enable "${CADDY_SERVICE}" >/dev/null 2>&1 || true
|
|
373
|
+
if systemctl is-active --quiet "${BOOTSTRAP_SERVICE}"; then
|
|
374
|
+
systemctl reset-failed "${CADDY_SERVICE}" >/dev/null 2>&1 || true
|
|
375
|
+
else
|
|
376
|
+
systemctl restart "${CADDY_SERVICE}"
|
|
377
|
+
fi
|
|
336
378
|
fi
|
|
337
379
|
|
|
338
380
|
PROBED_SERVICE_DID="$(probe_service_did)"
|
|
@@ -12,6 +12,8 @@ ENV_FILE = os.environ.get("ENV_FILE", "/etc/default/ucan-store")
|
|
|
12
12
|
READY_FILE = os.environ.get("READY_FILE", "/etc/default/ucan-store.ready")
|
|
13
13
|
SERVICE_NAME = os.environ.get("SERVICE_NAME", "ucan-store.service")
|
|
14
14
|
BOOTSTRAP_SERVICE = os.environ.get("BOOTSTRAP_SERVICE", "ucan-store-bootstrap.service")
|
|
15
|
+
CADDY_SERVICE = os.environ.get("CADDY_SERVICE", "caddy.service")
|
|
16
|
+
CADDYFILE = os.environ.get("CADDYFILE", "/etc/caddy/Caddyfile")
|
|
15
17
|
CONFIGURE_SCRIPT = "/usr/local/sbin/ucan-store-configure.sh"
|
|
16
18
|
DESCRIBE_SCRIPT = "/usr/local/sbin/ucan-store-describe.py"
|
|
17
19
|
METADATA_FILE = os.environ.get("METADATA_FILE", "/run/ucan-store-setup-metadata.json")
|
|
@@ -49,6 +51,18 @@ def _generate_metadata_files() -> None:
|
|
|
49
51
|
|
|
50
52
|
|
|
51
53
|
def _stop_bootstrap_service() -> None:
|
|
54
|
+
if os.path.exists(CADDYFILE):
|
|
55
|
+
subprocess.run(
|
|
56
|
+
[
|
|
57
|
+
"systemd-run",
|
|
58
|
+
"--unit=ucan-store-caddy-after-bootstrap",
|
|
59
|
+
"--on-active=3",
|
|
60
|
+
"/bin/systemctl",
|
|
61
|
+
"restart",
|
|
62
|
+
CADDY_SERVICE,
|
|
63
|
+
],
|
|
64
|
+
check=False,
|
|
65
|
+
)
|
|
52
66
|
subprocess.run(["systemctl", "stop", BOOTSTRAP_SERVICE], check=False)
|
|
53
67
|
|
|
54
68
|
|