Skip to content

Commit 7661a94

Browse files
committed
covered edge case scenarios
1 parent 2355338 commit 7661a94

File tree

2 files changed

+65
-29
lines changed

2 files changed

+65
-29
lines changed

functions/jwt-parser/1.0.0/README.md

Lines changed: 51 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -8,20 +8,21 @@ This function implements JWT payload extraction through a `set` task using jq ex
88

99
**Core JWT Decoding Logic:**
1010
```jq
11-
if (.token | startswith("Bearer ")) then
12-
(.token[7:] | split(".")[1] | @base64d | fromjson)
13-
else
14-
(.token | split(".")[1] | @base64d | fromjson)
15-
end
11+
(if (.token | startswith("Bearer ")) then .token[7:] else .token end) |
12+
split(".") |
13+
if length != 3 then error("Invalid JWT format: must have 3 parts") else .[1] end |
14+
@base64d |
15+
fromjson
1616
```
1717

1818
**Technical Steps:**
1919
1. **Prefix Handling**: Detects and removes "Bearer " prefix if present
2020
2. **Token Splitting**: Splits JWT on "." to isolate header, payload, signature
21-
3. **Payload Extraction**: Selects the middle part (index 1) containing claims
22-
4. **Base64 Decoding**: Uses `@base64d` to decode the base64url payload
23-
5. **JSON Parsing**: Converts decoded string to JSON object with `fromjson`
24-
6. **Optional Claim Navigation**: Uses jq path expressions for specific claim extraction
21+
3. **Format Validation**: Ensures exactly 3 parts (header.payload.signature)
22+
4. **Payload Extraction**: Selects the middle part (index 1) containing claims
23+
5. **Base64 Decoding**: Uses `@base64d` to decode the base64url payload
24+
6. **JSON Parsing**: Converts decoded string to JSON object with `fromjson`
25+
7. **Optional Claim Navigation**: Uses jq path expressions for specific claim extraction
2526

2627
## Usage
2728

@@ -116,21 +117,27 @@ The function processes the **payload** section (index 1 after splitting on ".")
116117

117118
### jq Expression Breakdown
118119

119-
**Primary Expression:**
120+
**JWT Decoding Expression:**
120121
```jq
121-
if (.token | startswith("Bearer ")) then
122-
(.token[7:] | split(".")[1] | @base64d | fromjson)
123-
else
124-
(.token | split(".")[1] | @base64d | fromjson)
125-
end
122+
(if (.token | startswith("Bearer ")) then .token[7:] else .token end) |
123+
split(".") |
124+
if length != 3 then error("Invalid JWT format: must have 3 parts") else .[1] end |
125+
@base64d |
126+
fromjson
126127
```
127128

128129
**Claim Path Expression:**
129130
```jq
130-
if .claimPath then
131-
.claims | getpath(.claimPath | split(".") | map(select(. != "")))
131+
((if (.token | startswith("Bearer ")) then .token[7:] else .token end) |
132+
split(".") |
133+
if length != 3 then error("Invalid JWT format: must have 3 parts") else .[1] end |
134+
@base64d |
135+
fromjson) as $decoded |
136+
if (.claimPath // null) != null then
137+
(.claimPath | split(".") | map(select(. != ""))) as $path |
138+
$decoded | getpath($path)
132139
else
133-
.claims
140+
$decoded
134141
end
135142
```
136143

@@ -157,6 +164,29 @@ The function will fail with jq errors if:
157164
## Implementation Notes
158165

159166
- **No signature verification**: Function extracts claims without cryptographic validation
160-
- **Base64URL decoding**: Uses jq's `@base64d` which handles base64url format
161-
- **Path navigation**: Uses jq's `getpath()` for safe claim extraction
162-
- **Prefix handling**: Automatically detects and strips "Bearer " prefix
167+
- **Base64URL decoding**: Uses jq's `@base64d` which handles base64url format
168+
- **Path navigation**: Uses `getpath()` with string splitting for safe claim extraction
169+
- **Prefix handling**: Conditional logic automatically detects and strips "Bearer " prefix
170+
- **Pipeline processing**: Uses jq pipe operators for clean data transformation flow
171+
- **Null safety**: Uses `has("claimPath")` to check for optional parameter presence
172+
173+
## Technical Validation
174+
175+
### JWT Structure Validation
176+
The function expects standard JWT format: `header.payload.signature`
177+
- **Header**: Algorithm and token type (ignored)
178+
- **Payload**: Base64URL-encoded JSON claims (processed)
179+
- **Signature**: Cryptographic signature (ignored)
180+
181+
### Base64URL Decoding
182+
JWT uses Base64URL encoding (RFC 4648 Section 5):
183+
- Uses `-` and `_` instead of `+` and `/`
184+
- No padding characters required
185+
- jq's `@base64d` handles this automatically
186+
187+
### Claim Path Syntax
188+
Claim paths follow jq object navigation:
189+
- `.sub` - Direct property access
190+
- `.custom.department` - Nested object access
191+
- `.roles[0]` - Array element access
192+
- Path components split on `.` and filtered for non-empty strings

functions/jwt-parser/1.0.0/function.yaml

Lines changed: 14 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -20,14 +20,20 @@ output:
2020
use: set
2121
set:
2222
claims: >-
23-
if (.token | startswith("Bearer ")) then
24-
(.token[7:] | split(".")[1] | @base64d | fromjson)
25-
else
26-
(.token | split(".")[1] | @base64d | fromjson)
27-
end
23+
(if (.token | startswith("Bearer ")) then .token[7:] else .token end) |
24+
split(".") |
25+
if length != 3 then error("Invalid JWT format: must have 3 parts") else .[1] end |
26+
@base64d |
27+
fromjson
2828
result: >-
29-
if .claimPath then
30-
.claims | getpath(.claimPath | split(".") | map(select(. != "")))
29+
((if (.token | startswith("Bearer ")) then .token[7:] else .token end) |
30+
split(".") |
31+
if length != 3 then error("Invalid JWT format: must have 3 parts") else .[1] end |
32+
@base64d |
33+
fromjson) as $decoded |
34+
if (.claimPath // null) != null then
35+
(.claimPath | split(".") | map(select(. != ""))) as $path |
36+
$decoded | getpath($path)
3137
else
32-
.claims
38+
$decoded
3339
end

0 commit comments

Comments
 (0)