#!/bin/sh
# Validate environment
if ! command -v msgbus > /dev/null; then
printf "missing msgbus command. Use: go install git.mills.io/prologic/msgbus/cmd/msgbus@latest"
exit 1
fi
if ! command -v salty > /dev/null; then
printf "missing salty command. Use: go install go.mills.io/salty/cmd/salty@latest"
exit 1
fi
if ! command -v salty-keygen > /dev/null; then
printf "missing salty-keygen command. Use: go install go.mills.io/salty/cmd/salty-keygen@latest"
exit 1
fi
if [ -z "$SALTY_IDENTITY" ]; then
export SALTY_IDENTITY="$HOME/.config/salty/$USER.key"
fi
get_user () {
user=$(grep user: "$SALTY_IDENTITY" | awk '{print $3}')
if [ -z "$user" ]; then
user="$USER"
fi
echo "$user"
}
stream () {
if [ -z "$SALTY_IDENTITY" ]; then
echo "SALTY_IDENTITY not set"
exit 2
fi
jq -r '.payload' | base64 -d | salty -i "$SALTY_IDENTITY" -d
}
lookup () {
if [ $# -lt 1 ]; then
printf "Usage: %s nick@domain\n" "$(basename "$0")"
exit 1
fi
user="$1"
nick="$(echo "$user" | awk -F@ '{ print $1 }')"
domain="$(echo "$user" | awk -F@ '{ print $2 }')"
curl -qsSL "https://$domain/.well-known/salty/${nick}.json"
}
readmsgs () {
topic="$1"
if [ -z "$topic" ]; then
topic=$(get_user)
fi
export SALTY_IDENTITY="$HOME/.config/salty/$topic.key"
if [ ! -f "$SALTY_IDENTITY" ]; then
echo "identity file missing for user $topic" >&2
exit 1
fi
msgbus sub "$topic" "$0"
}
sendmsg () {
if [ $# -lt 2 ]; then
printf "Usage: %s nick@domain.tld <message>\n" "$(basename "$0")"
exit 0
fi
if [ -z "$SALTY_IDENTITY" ]; then
echo "SALTY_IDENTITY not set"
exit 2
fi
user="$1"
message="$2"
salty_json="$(mktemp /tmp/salty.XXXXXX)"
lookup "$user" > "$salty_json"
endpoint="$(jq -r '.endpoint' < "$salty_json")"
topic="$(jq -r '.topic' < "$salty_json")"
key="$(jq -r '.key' < "$salty_json")"
rm "$salty_json"
message="[$(date +%FT%TZ)] <$(get_user)> $message"
echo "$message" \
| salty -i "$SALTY_IDENTITY" -r "$key" \
| msgbus -u "$endpoint" pub "$topic"
}
make_user () {
mkdir -p "$HOME/.config/salty"
if [ $# -lt 1 ]; then
user=$USER
else
user=$1
fi
identity_file="$HOME/.config/salty/$user.key"
if [ -f "$identity_file" ]; then
printf "user key exists!"
exit 1
fi
# Check for msgbus env.. probably can make it fallback to looking for a config file?
if [ -z "$MSGBUS_URI" ]; then
printf "missing MSGBUS_URI in environment"
exit 1
fi
salty-keygen -o "$identity_file"
echo "# user: $user" >> "$identity_file"
pubkey=$(grep key: "$identity_file" | awk '{print $4}')
cat <<- EOF
Create this file in your webserver well-known folder. https://hostname.tld/.well-known/salty/$user.json
{
"endpoint": "$MSGBUS_URI",
"topic": "$user",
"key": "$pubkey"
}
EOF
}
# check if streaming
if [ ! -t 1 ]; then
stream
exit 0
fi
# Show Help
if [ $# -lt 1 ]; then
printf "Commands: send read lookup"
exit 0
fi
CMD=$1
shift
case $CMD in
send)
sendmsg "$@"
;;
read)
readmsgs "$@"
;;
lookup)
lookup "$@"
;;
make-user)
make_user "$@"
;;
esac
ssh client, because that's me, no-matter where I am. The only exception to this rule is I usually create a separate key for any "work" / " company" I am a part of.
@prologic@twtxt.net I have seen single use keys that are signed by a central PKI .. Keybase has one that uses a chatbot to generate the keys on the fly.
It just comes down to your threat model :)
ssh client, because that's me, no-matter where I am. The only exception to this rule is I usually create a separate key for any "work" / " company" I am a part of.
@prologic@twtxt.net for shame! lol me too.
I would HIGHLY recommend reading up on the keybase architecture. They designed device key system for real time chat that is e2e secure. https://book.keybase.io/security
A property of ec keys is deriving new keys that can be determined to be “on curve.” bitcoin has some BIPs that derive single use keys for every transaction connected to a wallet. And be derived as either public or private chains. https://qvault.io/security/bip-32-watch-only-wallets/
@prologic@twtxt.net yarn builds in 1.18!
Consensus Time
⌘ Read more
@prologic@twtxt.net Re: Chat system, What if the base specification included a system for per-user arbitrary JSON storage on the server? Kind of like XEP-0049, but expanded upon. Two kinds of objects: public and private. Public objects can be queried by anyone, private objects cannot and must be encrypted with the user’s private key. Public keys could be stored there, as well as anything else defined by extensions. Roster, user block list, avatar, etc.
@prologic@twtxt.net hmm so each individual feed on your pod sub’s my feed? Wouldn’t that flood your server for each post?
This repository contains all the Incident Response Playbooks and Workflows of Company’s SOC [https://gitlab.com/syntax-ir/playbooks]
Deviled Eggs
⌘ Read more
False Dichotomy
⌘ Read more
Recovery run: 6.12 miles, 00:11:28 average pace, 01:10:08 duration
Recovery run
#running
Qua
⌘ Read more
I Shouldn’t Complain
⌘ Read more
@prologic@prologic://twtxt.net/user/prologic/twtxt.txt The news first broke several days ago, but I didn’t see photo confirmation until today. I might have just been late :P
The An-225 Mriya, the world’s largest aircraft, has been destroyed. https://www.airlinerwatch.com/2022/02/has-worlds-most-iconic-aircraft-225.html
Outlet Denier
⌘ Read more
One down! More to go.
BREAKING: Russian billionaire Alisher Usmanov’s super yacht, one of the biggest in the world, seized in Germany - Forbes
Party Quadrants
⌘ Read more
For the Sake of Simplicity
⌘ Read more
#makeartnotwar #GLSL #shaders code at https://www.shadertoy.com/view/fs2fRm if you want to use it

Google no longer allows in-app donations that don’t go through Google Play. https://github.com/streetcomplete/StreetComplete/issues/3768
Greek Letters
⌘ Read more
Recovery run: 4.08 miles, 00:11:29 average pace, 00:46:51 duration
Recovery run
#running
Rounding
⌘ Read more
Ostorlab is going open-source, releasing our scanning engine, vulnerability detectors, and analyzers https://blog.ostorlab.co/ostorlab-open-source.html
Headline Words
⌘ Read more
There is no place like home.

what’s your super power?!: 3.03 miles, 00:08:51 average pace, 00:26:51 duration
what’s your super power?!
#running
Chorded Keyboard
⌘ Read more
Recovery run (with Beth): 3.17 miles, 00:12:52 average pace, 00:40:45 duration
Recovery run (with Beth)
#running
Data Trap
⌘ Read more
Health Stats
⌘ Read more
Zettelkasten app built in Teliva, a platform for sandboxed, hackable text-mode apps: https://archive.org/details/akkartik-teliva-2022-02-10
Rest and Fluids
⌘ Read more
Look at you all using naked links!
Try https://twtxt.net!
#Wordle 235 4/6*
⬛🟨🟨⬛⬛
🟨🟨⬛⬛⬛
⬛⬛🟨🟨🟩
🟩🟩🟩🟩🟩
@david@netbros.com Do you always link that?
updated our introduction to uxn e-books with a new table formatting and some minor corrections | https://compudanzas.net/publications.html
