Skip to content

Instantly share code, notes, and snippets.

@tondrej
Last active March 15, 2024 19:39
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save tondrej/2f68873281f962843402c0b7da0530f7 to your computer and use it in GitHub Desktop.
Save tondrej/2f68873281f962843402c0b7da0530f7 to your computer and use it in GitHub Desktop.
Merge/sync local KeepassXC database with Dropbox
#!/bin/bash
DROPBOX_PATH=/Apps/Keepass2Android/main.kdbx
KDBX_DROPBOX=~/Documents/keepass/dropbox/main.kdbx
KDBX_LOCAL=~/Documents/keepass/main.kdbx
YUBIKEY_SERIALNO=9851170
YUBIKEY_SLOT=2
# 1. obtain dropbox API credentials from local keepassxc database
APP_KEY=$(keepassxc-cli show --yubikey $YUBIKEY_SLOT:$YUBIKEY_SERIALNO --no-password "$KDBX_LOCAL" Dropbox --attributes "API key")
STATUS=$?
if [ $STATUS -ne 0 ]; then
echo Error reading Dropbox API key
exit $STATUS
fi
APP_SECRET=$(keepassxc-cli show --yubikey $YUBIKEY_SLOT:$YUBIKEY_SERIALNO --no-password "$KDBX_LOCAL" Dropbox --attributes "API secret")
STATUS=$?
if [ $STATUS -ne 0 ]; then
echo Error reading Dropbox API secret
exit $STATUS
fi
REFRESH_TOKEN=$(keepassxc-cli show --yubikey $YUBIKEY_SLOT:$YUBIKEY_SERIALNO --no-password "$KDBX_LOCAL" Dropbox --attributes "API refresh token")
STATUS=$?
if [ $STATUS -ne 0 ]; then
echo Error reading Dropbox API refresh token
exit $STATUS
fi
# 2. refresh token
REFRESH_RESPONSE=$(curl https://api.dropbox.com/oauth2/token --silent --data grant_type=refresh_token --data refresh_token=$REFRESH_TOKEN --user $APP_KEY:$APP_SECRET)
STATUS=$?
if [ $STATUS -ne 0 ]; then
echo Error refreshing Dropbox API token
exit $STATUS
fi
DROPBOX_TOKEN=$(echo $REFRESH_RESPONSE | grep -oP '"access_token"\s*:\s*"\K[^"]*')
STATUS=$?
if [ $STATUS -ne 0 ]; then
echo Error parsing refresh token response
exit $STATUS
fi
# 3. download current keepassxc database from Dropbox
curl -X POST https://content.dropboxapi.com/2/files/download \
--silent \
--header "Authorization: Bearer $DROPBOX_TOKEN" \
--header "Dropbox-API-Arg: {\"path\":\"$DROPBOX_PATH\"}" \
--output "$KDBX_DROPBOX"
STATUS=$?
if [ $STATUS -ne 0 ]; then
echo Error downloading KeepassXC database
exit $STATUS
fi
# 3. merge into local database
keepassxc-cli merge \
--yubikey $YUBIKEY_SLOT:$YUBIKEY_SERIALNO \
--no-password \
--yubikey-from $YUBIKEY_SLOT:$YUBIKEY_SERIALNO \
--no-password-from \
"$KDBX_LOCAL" \
"$KDBX_DROPBOX"
STATUS=$?
if [ $STATUS -ne 0 ]; then
echo Error merging KeepassXC database
exit $STATUS
fi
# 4. upload merged database to Dropbox
curl -X POST https://content.dropboxapi.com/2/files/upload \
--silent \
--header "Authorization: Bearer $DROPBOX_TOKEN" \
--header "Content-Type: application/octet-stream" \
--header "Dropbox-API-Arg: {\"path\":\"$DROPBOX_PATH\",\"mode\":{\".tag\":\"overwrite\"},\"autorename\":false}" \
--upload-file "$KDBX_LOCAL"
STATUS=$?
if [ $STATUS -ne 0 ]; then
echo Error uploading KeepassXC database
exit $STATUS
fi
@tondrej
Copy link
Author

tondrej commented Jan 5, 2023

MacOS' grep doesn't support -P so use ggrep (gnu grep) brew install grep

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment