Skip to content

Instantly share code, notes, and snippets.

@robconery
Created November 14, 2023 01:43
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save robconery/78ed337a4a049057aafa560de7b0af1c to your computer and use it in GitHub Desktop.
Save robconery/78ed337a4a049057aafa560de7b0af1c to your computer and use it in GitHub Desktop.
# Admin API key goes here
KEY="[FIND ME IN THE ADMIN SETTINGS]"
# Split the key into ID and SECRET
TMPIFS=$IFS
IFS=':' read ID SECRET <<< "$KEY"
IFS=$TMPIFS
# Prepare header and payload
NOW=$(date +'%s')
FIVE_MINS=$(($NOW + 300))
HEADER="{\"alg\": \"HS256\",\"typ\": \"JWT\", \"kid\": \"$ID\"}"
PAYLOAD="{\"iat\":$NOW,\"exp\":$FIVE_MINS,\"aud\": \"/v3/admin/\"}"
# Helper function for perfoming base64 URL encoding
base64_url_encode() {
declare input=${1:-$(</dev/stdin)}
# Use `tr` to URL encode the output from base64.
printf '%s' "${input}" | base64 | tr -d '=' | tr '+' '-' | tr '/' '_'
}
# Prepare the token body
header_base64=$(base64_url_encode "$HEADER")
payload_base64=$(base64_url_encode "$PAYLOAD")
header_payload="${header_base64}.${payload_base64}"
# Create the signature
signature=$(printf '%s' "${header_payload}" | openssl dgst -binary -sha256 -mac HMAC -macopt hexkey:$SECRET | base64_url_encode)
# Concat payload and signature into a valid JWT token
TOKEN="${header_payload}.${signature}"
echo "${TOKEN}"
rm [path to your zipped theme]/theme.zip
zip -qr -X theme.zip [path to your theme] -x "*.git*"
curl -X POST -F 'file=@theme.zip' -H "Authorization: Ghost ${TOKEN}" [BLOG URL]/ghost/api/v3/admin/themes/upload/
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment