AtlatestRepositorysigil-jwt
1
(import (sigil test)2
(sigil jwt)3
(sigil math)4
(sigil time))6
;; ============================================================7
;; jwt-encode8
;; ============================================================10
(test-group "jwt-encode"11
(test "produces 3 dot-separated parts"12
(let ((token (jwt-encode '((sub . "user1")) "secret")))13
(assert-true (string? token))14
;; Count dots15
(let ((parts (let loop ((s token) (parts '()) (current ""))16
(if (= (string-length s) 0)17
(reverse (cons current parts))18
(if (char=? (string-ref s 0) #\.)19
(loop (substring s 1 (string-length s))20
(cons current parts)21
"")22
(loop (substring s 1 (string-length s))23
parts24
(string-append current (string (string-ref s 0)))))))))25
(assert-equal 3 (length parts))))))27
;; ============================================================28
;; jwt-decode roundtrip29
;; ============================================================31
(test-group "jwt-decode"32
(test "roundtrip encode/decode recovers claims"33
(let* ((claims '((sub . "user123") (role . "admin")))34
(token (jwt-encode claims "my-secret"))35
(decoded (jwt-decode token "my-secret")))36
(assert-true (dict? decoded))37
(assert-equal "user123" (dict-ref decoded sub:))38
(assert-equal "admin" (dict-ref decoded role:))))40
(test "wrong secret returns #f"41
(let* ((token (jwt-encode '((sub . "user")) "correct-secret"))42
(decoded (jwt-decode token "wrong-secret")))43
(assert-false decoded)))45
(test "malformed token returns #f"46
(assert-false (jwt-decode "not.a.valid-token" "secret"))47
(assert-false (jwt-decode "onlyonepart" "secret"))))49
;; ============================================================50
;; Expiration51
;; ============================================================53
(test-group "expiration"54
(test "expired token rejected"55
(let* ((claims (list (cons 'sub "user")56
(cons 'exp (- (floor (current-second)) 3600))))57
(token (jwt-encode claims "secret"))58
(decoded (jwt-decode token "secret")))59
(assert-false decoded)))61
(test "valid future token accepted"62
(let* ((claims (list (cons 'sub "user")63
(cons 'exp (+ (floor (current-second)) 3600))))64
(token (jwt-encode claims "secret"))65
(decoded (jwt-decode token "secret")))66
(assert-true (dict? decoded))67
(assert-equal "user" (dict-ref decoded sub:)))))69
;; ============================================================70
;; jwt-decode-unsafe71
;; ============================================================73
(test-group "jwt-decode-unsafe"74
(test "decodes without verifying signature"75
(let* ((token (jwt-encode '((sub . "peek")) "secret"))76
(decoded (jwt-decode-unsafe token)))77
(assert-true (dict? decoded))78
(assert-equal "peek" (dict-ref decoded sub:)))))80
(run-tests)