Class: JwtAuthCognito::JwtValidator

Inherits:
Object
  • Object
show all
Defined in:
lib/jwt_auth_cognito/jwt_validator.rb

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(config = JwtAuthCognito.configuration) ⇒ JwtValidator

Returns a new instance of JwtValidator.



7
8
9
10
11
# File 'lib/jwt_auth_cognito/jwt_validator.rb', line 7

def initialize(config = JwtAuthCognito.configuration)
  @config = config
  @jwks_service = JwksService.new(config)
  @blacklist_service = TokenBlacklistService.new(config)
end

Class Method Details

.create_cognito_validator(config = nil) ⇒ Object

Create a convenience factory method



128
129
130
131
132
133
134
135
136
137
138
# File 'lib/jwt_auth_cognito/jwt_validator.rb', line 128

def self.create_cognito_validator(config = nil)
  if config
    old_config = JwtAuthCognito.configuration
    JwtAuthCognito.configure { |c| c = config }
    validator = new
    JwtAuthCognito.instance_variable_set(:@configuration, old_config)
    validator
  else
    new
  end
end

Instance Method Details

#calculate_secret_hash(identifier) ⇒ Object

Calculate secret hash for Cognito operations (when client secret is configured)



97
98
99
# File 'lib/jwt_auth_cognito/jwt_validator.rb', line 97

def calculate_secret_hash(identifier)
  @config.calculate_secret_hash(identifier)
end

#decode_token(token) ⇒ Object



72
73
74
75
76
# File 'lib/jwt_auth_cognito/jwt_validator.rb', line 72

def decode_token(token)
  JWT.decode(token, nil, false).first
rescue JWT::DecodeError => e
  { error: "Failed to decode token: #{e.message}" }
end

#extract_token_from_header(authorization_header) ⇒ Object

Utility methods inspired by Node.js package



65
66
67
68
69
70
# File 'lib/jwt_auth_cognito/jwt_validator.rb', line 65

def extract_token_from_header(authorization_header)
  return nil unless authorization_header
  
  match = authorization_header.match(/\ABearer (.+)\z/)
  match ? match[1] : nil
end

#get_time_to_expiry(token) ⇒ Object



116
117
118
119
120
121
122
123
124
125
# File 'lib/jwt_auth_cognito/jwt_validator.rb', line 116

def get_time_to_expiry(token)
  payload = decode_token(token)
  return nil if payload.is_a?(Hash) && payload[:error]

  exp = payload["exp"]
  return nil unless exp

  seconds = exp - Time.now.to_i
  seconds > 0 ? seconds : 0
end

#get_token_info(token) ⇒ Object



78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
# File 'lib/jwt_auth_cognito/jwt_validator.rb', line 78

def get_token_info(token)
  payload = decode_token(token)
  return payload if payload.is_a?(Hash) && payload[:error]

  {
    sub: payload["sub"],
    username: payload["cognito:username"] || payload["username"],
    email: payload["email"],
    token_use: payload["token_use"],
    client_id: payload["aud"],
    issued_at: payload["iat"] ? Time.at(payload["iat"]) : nil,
    expires_at: payload["exp"] ? Time.at(payload["exp"]) : nil,
    not_before: payload["nbf"] ? Time.at(payload["nbf"]) : nil,
    jti: payload["jti"],
    has_client_secret: @config.has_client_secret?
  }
end

#has_client_secret?Boolean

Check if client secret is configured

Returns:

  • (Boolean)


102
103
104
# File 'lib/jwt_auth_cognito/jwt_validator.rb', line 102

def has_client_secret?
  @config.has_client_secret?
end

#is_token_expired?(token) ⇒ Boolean

Returns:

  • (Boolean)


106
107
108
109
110
111
112
113
114
# File 'lib/jwt_auth_cognito/jwt_validator.rb', line 106

def is_token_expired?(token)
  payload = decode_token(token)
  return true if payload.is_a?(Hash) && payload[:error]

  exp = payload["exp"]
  return false unless exp

  Time.now.to_i >= exp
end

#revoke_token(token, user_id: nil) ⇒ Object



56
57
58
# File 'lib/jwt_auth_cognito/jwt_validator.rb', line 56

def revoke_token(token, user_id: nil)
  @blacklist_service.add_to_blacklist(token, user_id: user_id)
end

#revoke_user_tokens(user_id) ⇒ Object



60
61
62
# File 'lib/jwt_auth_cognito/jwt_validator.rb', line 60

def revoke_user_tokens(user_id)
  @blacklist_service.invalidate_user_tokens(user_id)
end

#validate_access_token(token) ⇒ Object



32
33
34
35
36
37
38
39
40
# File 'lib/jwt_auth_cognito/jwt_validator.rb', line 32

def validate_access_token(token)
  result = validate_token(token)
  
  if result[:valid] && result[:payload]["token_use"] != "access"
    return { valid: false, error: "Token is not an access token" }
  end
  
  result
end

#validate_id_token(token) ⇒ Object



42
43
44
45
46
47
48
49
50
# File 'lib/jwt_auth_cognito/jwt_validator.rb', line 42

def validate_id_token(token)
  result = validate_token(token)
  
  if result[:valid] && result[:payload]["token_use"] != "id"
    return { valid: false, error: "Token is not an ID token" }
  end
  
  result
end

#validate_multiple_tokens(tokens) ⇒ Object



52
53
54
# File 'lib/jwt_auth_cognito/jwt_validator.rb', line 52

def validate_multiple_tokens(tokens)
  tokens.map { |token| validate_token(token) }
end

#validate_token(token, options = {}) ⇒ Object



13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
# File 'lib/jwt_auth_cognito/jwt_validator.rb', line 13

def validate_token(token, options = {})
  @config.validate!
  
  # Check blacklist first
  if @blacklist_service.is_blacklisted?(token)
    return { valid: false, error: "Token has been revoked" }
  end

  # Choose validation method based on configuration
  case @config.validation_mode
  when :secure
    validate_token_secure(token, options)
  when :basic
    validate_token_basic(token, options)
  else
    raise ConfigurationError, "Invalid validation_mode: #{@config.validation_mode}"
  end
end