File: encode.rb

package info (click to toggle)
ruby-jwt 2.7.1-1
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid, trixie
  • size: 736 kB
  • sloc: ruby: 4,326; makefile: 4
file content (79 lines) | stat: -rw-r--r-- 1,667 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
# frozen_string_literal: true

require_relative 'algos'
require_relative 'claims_validator'

# JWT::Encode module
module JWT
  # Encoding logic for JWT
  class Encode
    ALG_KEY = 'alg'

    def initialize(options)
      @payload          = options[:payload]
      @key              = options[:key]
      @algorithm        = resolve_algorithm(options[:algorithm])
      @headers          = options[:headers].transform_keys(&:to_s)
      @headers[ALG_KEY] = @algorithm.alg
    end

    def segments
      validate_claims!
      combine(encoded_header_and_payload, encoded_signature)
    end

    private

    def resolve_algorithm(algorithm)
      return algorithm if Algos.implementation?(algorithm)

      Algos.create(algorithm)
    end

    def encoded_header
      @encoded_header ||= encode_header
    end

    def encoded_payload
      @encoded_payload ||= encode_payload
    end

    def encoded_signature
      @encoded_signature ||= encode_signature
    end

    def encoded_header_and_payload
      @encoded_header_and_payload ||= combine(encoded_header, encoded_payload)
    end

    def encode_header
      encode_data(@headers)
    end

    def encode_payload
      encode_data(@payload)
    end

    def signature
      @algorithm.sign(data: encoded_header_and_payload, signing_key: @key)
    end

    def validate_claims!
      return unless @payload.is_a?(Hash)

      ClaimsValidator.new(@payload).validate!
    end

    def encode_signature
      ::JWT::Base64.url_encode(signature)
    end

    def encode_data(data)
      ::JWT::Base64.url_encode(JWT::JSON.generate(data))
    end

    def combine(*parts)
      parts.join('.')
    end
  end
end