Skip to content

Commit

Permalink
feat: Add function to decode JWT tokens
Browse files Browse the repository at this point in the history
  • Loading branch information
kpatryk committed Nov 29, 2024
1 parent ce77a86 commit 7068c10
Show file tree
Hide file tree
Showing 3 changed files with 76 additions and 30 deletions.
30 changes: 0 additions & 30 deletions functions/utils/convert.sh
Original file line number Diff line number Diff line change
@@ -1,33 +1,3 @@
decode_base64() {
local input="$1"
local decoded="$input"
local temp

if [ -z "$input" ]; then
echo "Error: input is empty." >&2
return 1
fi

while true; do
if temp=$(echo -n "$decoded" | base64 -d 2>/dev/null) && [ -n "$temp" ]; then
if [ "$temp" = "$decoded" ]; then
break
fi

if echo -n "$temp" | LC_ALL=C grep -q '[^[:print:][:space:]]'; then
break
fi

decoded="$temp"
else
break
fi
done

printf '%s' "$decoded"
printf '\n'
}

# convert myVar to my-var
convert_camel_case_to_kebab_case() {
echo "$1" | sed -r 's/([a-z0-9])([A-Z])/\1-\2/g' | tr '[:upper:]' '[:lower:]'
Expand Down
75 changes: 75 additions & 0 deletions functions/utils/decode.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
decode_base64_url() {
# Replace URL-safe characters with standard Base64 characters.
local input=$1
input=${input//-/+}
input=${input//_/\/}

# Pad with '=' if necessary
local mod4=$((${#input} % 4))
if ((mod4 != 0)); then
input="${input}$(printf '%0.s=' $(seq $((4 - mod4))))"
fi

echo "$input" | base64 -d 2>/dev/null
}

decode_jwt() {
if [[ -z "$1" ]]; then
echo -e "Usage: decode_jwt <jwt>\nSplits and decodes a JSON Web Token."
return
fi

local jwt=$1
local delimiter_count

delimiter_count=$(grep -o '\.' <<<"$jwt" | wc -l)
if [[ "$delimiter_count" -ne 2 ]]; then
echo "Error: Invalid JWT format. A JWT must contain exactly two dots."
return 1
fi

IFS='.' read -r header payload signature <<<"$jwt"
if [[ -z "$header" || -z "$payload" || -z "$signature" ]]; then
echo "Error: JWT parts cannot be empty."
return 1
fi

echo "Header:"
decode_base64_url "$header" | jq .

echo "Payload:"
decode_base64_url "$payload" | jq .

echo "Signature (Base64Url):"
echo "$signature"
}

decode_base64() {
local input="$1"
local decoded="$input"
local temp

if [ -z "$input" ]; then
echo "Error: input is empty." >&2
return 1
fi

while true; do
if temp=$(echo -n "$decoded" | base64 -d 2>/dev/null) && [ -n "$temp" ]; then
if [ "$temp" = "$decoded" ]; then
break
fi

if echo -n "$temp" | LC_ALL=C grep -q '[^[:print:][:space:]]'; then
break
fi

decoded="$temp"
else
break
fi
done

printf '%s' "$decoded"
printf '\n'
}
1 change: 1 addition & 0 deletions tests/functions/utils/test_convert.bats
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

repo_root=$(git rev-parse --show-toplevel)

load "$repo_root/functions/utils/decode.sh"
load "$repo_root/functions/utils/convert.sh"

@test "decode_base64" {
Expand Down

0 comments on commit 7068c10

Please sign in to comment.