+60
-6
modules/home/system/shell.nix
+60
-6
modules/home/system/shell.nix
···
244
244
fi
245
245
246
246
${pkgs.gum}/bin/gum spin --spinner dot --title "Posting to Bluesky..." -- /bin/bash <<EOF
247
+
# Function to resolve DID to PDS endpoint
248
+
resolve_pds() {
249
+
local identifier="\$1"
250
+
local did=""
251
+
252
+
# If identifier is a handle, resolve to DID first
253
+
if [[ ! "\$identifier" =~ ^did: ]]; then
254
+
# Try to resolve handle via DNS first, fallback to bsky.social
255
+
did=\$(${pkgs.curl}/bin/curl -sf "https://bsky.social/xrpc/com.atproto.identity.resolveHandle?handle=\$identifier" | ${pkgs.jq}/bin/jq -r '.did // empty')
256
+
if [[ -z "\$did" ]]; then
257
+
echo "Failed to resolve handle: \$identifier" >&2
258
+
return 1
259
+
fi
260
+
else
261
+
did="\$identifier"
262
+
fi
263
+
264
+
# Resolve DID document
265
+
local pds_endpoint=""
266
+
if [[ "\$did" =~ ^did:plc: ]]; then
267
+
# Resolve via PLC directory
268
+
pds_endpoint=\$(${pkgs.curl}/bin/curl -sf "https://plc.directory/\$did" | ${pkgs.jq}/bin/jq -r '.service[] | select(.type == "AtprotoPersonalDataServer") | .serviceEndpoint' | head -n1)
269
+
elif [[ "\$did" =~ ^did:web: ]]; then
270
+
# Resolve via did:web
271
+
local domain="\''${did#did:web:}"
272
+
pds_endpoint=\$(${pkgs.curl}/bin/curl -sf "https://\$domain/.well-known/did.json" | ${pkgs.jq}/bin/jq -r '.service[] | select(.type == "AtprotoPersonalDataServer") | .serviceEndpoint' | head -n1)
273
+
else
274
+
echo "Unsupported DID method: \$did" >&2
275
+
return 1
276
+
fi
277
+
278
+
if [[ -z "\$pds_endpoint" ]]; then
279
+
echo "Failed to resolve PDS endpoint for: \$did" >&2
280
+
return 1
281
+
fi
282
+
283
+
echo "\$pds_endpoint"
284
+
}
285
+
286
+
# Resolve PDS endpoints for both accounts
287
+
account1_pds=\$(resolve_pds "$ACCOUNT1")
288
+
if [[ -z "\$account1_pds" ]]; then
289
+
echo "Failed to resolve PDS for $ACCOUNT1" >&2
290
+
exit 1
291
+
fi
292
+
293
+
account2_pds=\$(resolve_pds "$ACCOUNT2")
294
+
if [[ -z "\$account2_pds" ]]; then
295
+
echo "Failed to resolve PDS for $ACCOUNT2" >&2
296
+
exit 1
297
+
fi
298
+
247
299
# Generate JWT for ACCOUNT1
248
300
account1_response=\$(${pkgs.curl}/bin/curl -s -X POST \
249
301
-H "Content-Type: application/json" \
···
251
303
"identifier": "'$ACCOUNT1'",
252
304
"password": "'$ACCOUNT1_PASSWORD'"
253
305
}' \
254
-
"https://bsky.social/xrpc/com.atproto.server.createSession")
306
+
"\$account1_pds/xrpc/com.atproto.server.createSession")
255
307
256
308
account1_jwt=\$(echo "\$account1_response" | ${pkgs.jq}/bin/jq -r '.accessJwt')
309
+
account1_did=\$(echo "\$account1_response" | ${pkgs.jq}/bin/jq -r '.did')
257
310
258
311
if [[ -z "\$account1_jwt" || "\$account1_jwt" == "null" ]]; then
259
312
echo "Failed to authenticate account $ACCOUNT1" >&2
···
268
321
"identifier": "'$ACCOUNT2'",
269
322
"password": "'$ACCOUNT2_PASSWORD'"
270
323
}' \
271
-
"https://bsky.social/xrpc/com.atproto.server.createSession")
324
+
"\$account2_pds/xrpc/com.atproto.server.createSession")
272
325
273
326
account2_jwt=\$(echo "\$account2_response" | ${pkgs.jq}/bin/jq -r '.accessJwt')
327
+
account2_did=\$(echo "\$account2_response" | ${pkgs.jq}/bin/jq -r '.did')
274
328
275
329
if [[ -z "\$account2_jwt" || "\$account2_jwt" == "null" ]]; then
276
330
echo "Failed to authenticate account $ACCOUNT2" >&2
···
284
338
-H "Authorization: Bearer \$account1_jwt" \
285
339
-d '{
286
340
"collection": "a.status.update",
287
-
"repo": "'$ACCOUNT1'",
341
+
"repo": "'\$account1_did'",
288
342
"record": {
289
343
"\$type": "a.status.update",
290
344
"text": "'"$message"'",
291
345
"createdAt": "'\$(date -u +"%Y-%m-%dT%H:%M:%SZ")'"
292
346
}
293
347
}' \
294
-
"https://bsky.social/xrpc/com.atproto.repo.createRecord")
348
+
"\$account1_pds/xrpc/com.atproto.repo.createRecord")
295
349
296
350
if [[ \$(echo "\$account1_post_response" | ${pkgs.jq}/bin/jq -r 'has("error")') == "true" ]]; then
297
351
echo "Error posting to $ACCOUNT1:" >&2
···
305
359
-H "Authorization: Bearer \$account2_jwt" \
306
360
-d '{
307
361
"collection": "app.bsky.feed.post",
308
-
"repo": "'$ACCOUNT2'",
362
+
"repo": "'\$account2_did'",
309
363
"record": {
310
364
"\$type": "app.bsky.feed.post",
311
365
"text": "'"$message"'",
312
366
"createdAt": "'\$(date -u +"%Y-%m-%dT%H:%M:%SZ")'"
313
367
}
314
368
}' \
315
-
"https://bsky.social/xrpc/com.atproto.repo.createRecord")
369
+
"\$account2_pds/xrpc/com.atproto.repo.createRecord")
316
370
317
371
if [[ \$(echo "\$account2_post_response" | ${pkgs.jq}/bin/jq -r 'has("error")') == "true" ]]; then
318
372
echo "Error posting to $ACCOUNT2:" >&2
+10
-20
secrets/bluesky.age
+10
-20
secrets/bluesky.age
···
1
1
age-encryption.org/v1
2
2
-> ssh-rsa DqcG0Q
3
-
Pge+V9a56y8YOA2Fz7MaiCSqcX2TeRlz62BoLTdhilyPc1GduRy7cuVDOLEVxa3x
4
-
53qj2JeB4xRpTM8bVzUR4AavOxFLcDaGGe+FbbwvpCIMMECY80KZ9QfDs3X41UIJ
5
-
bjoTn0yPhu+hunNYAAfmuVEZQ6OhG8cfGJKIzGKf2TIksbIlfywGhOruTlugBl8n
6
-
PwK7rS0p2cGRtr4bECchPn5kFqIDERpQEcCZmuh6sGmp54Kmo7aZu3cpzHyl/oM/
7
-
RtChCUTkUu4tGTjc52LdSSWKC8beVN0MLIn0X+Q3yIp9tBZ5ivZR6CX4OGaAEOqq
8
-
BuiMeZt4hh61NoAL5fsF5nEbAogE7WkedJw7qEyUy7YxGAEk+Djo8+CbniVzVCOv
9
-
SmLCNhzbeSUxjp8OR6TWKXNpUG4TQwihzV8ube4eg848U4UOBTGGFvI7OmfoPeLF
10
-
QNATwMOQIAP43UqP01Z13gwKNHLN6x3SIG0lD0m4h9i0icfjv5xi9PLL+bx36OGt
11
-
12
-
-> ssh-rsa DqcG0Q
13
-
H7u1sn3dQfYRkkYWx2MI+1jyAvbWRN7hzonZwpQaojZiyn2pV7CMTtW3E33obKAU
14
-
SGbx5cn8/DWhNRg1/1Mw/d5mTDmesnu/rknOhYpTa1du6jWMymLL40MPD0hDgvNw
15
-
LmKI3cElDqJ+ITHhg3iKwH0OuAeT8iN3c5k9nmaHj7C7r8AClgQUcnt+XloA9YFU
16
-
thulreu9yxc3owKOobzcu8ZdyFDwX4Qyl+lmfzZIFZC1cW8gjPa99cPYua3Ai++A
17
-
myS3sB7xpwdVNK89m1O/qbTQyl9PdqHrkBaknNvpmJ+DPCQTKk7NrtYuioFCyBod
18
-
5+GxmP2qEhwkhWh5hRtI0qjvPxV7YzqUBMbBkafbjBDlyUOmCf8oVrR8sv45pdQw
19
-
7FpyCoquVR5IiEpFDjr8dRRYwbzSxT0BW6f7ZAmIwquPOrhet2ObKRkveyye01QO
20
-
PgNw5P4Xg6f8aKFANI3k6yPrY/2JyoHoqjLVBVov+08jKf5uqRNtLMhjnQ1QHPND
3
+
G6XSVQgjB/AIMCoiFqWwVt8GV6RxDO/IEuRULaAvG2t71MnOBrbhE+30EvPwL3Wv
4
+
3vJf3p9wtkYZao7jJbcGE9jTPIgso5P5G8W4P5/HGqzPZFfyALFRQUBLCGztbUBV
5
+
NsgqWP3YmuuNmFglkeiyOa0DKNCpITIr2nRyDELtkN7t3iif8EGbxqfu9ptUZKVN
6
+
+H3VRAfYfpJJ3f4GYZJU9pu1ygGlBb4KAL6oizy7VHUYHTR98uAWmHh/MSz+gPgM
7
+
GZhsk+j2j/YTDMDsaxxm63gfOIXUSRHVhsFXs0aotr8AyLb8jz4Ui6p0iL4Tor+d
8
+
T/Nv+GPwoMok1mvsxL+72qNhftM5UJ2cGn38m9oNGtUg4BUiBhg6cGK/UmoFO9RT
9
+
jTH68X7ShpUOxhHXZTntSUvhMrvaZf+Bmlt40esAPuA+qnwCOEY28bMH+Eme+EMl
10
+
6X15PzB5OMY+U3gQeL+wnEuHIHOyeyxDnSHvnk0YdXi6A7vRyw1vv78RqxjcSW3e
21
11
22
-
--- T/3m+ZxB3rLlgVKpPtvZTO2yrdNWs6vgFlKYmz4IIaI
23
-
0�Q��\7��s�Hv�*��܌����::��P8�7�r���e�A��&L`��?��x���V2���Dax��mH���.H䂠5LF]g��(Y�8 ��_SȊ��oW햸G�w��j��v�k|����[�EǻM⏙@��й� Z�j�wJ�
12
+
--- CAoxMY3YNS+Gl8JOnNgT1QWW+9KnzrJajWISy1EPSCw
13
+
/��V�@�����B�����q,�GOaL`Mᘛnͣ�;e0��Kw��'9 ew�9��l�����:ԍD��ܡd�|&؉�q�E��ƕ����EI�h�a)�H��f�!���a5�y$ػ��:��B<Ƌt΅���$��;����0ʹ���[�"�