Class: XeroKiwi::Token
- Inherits:
-
Object
- Object
- XeroKiwi::Token
- Defined in:
- lib/xero_kiwi/token.rb
Overview
Immutable value object representing an OAuth2 token pair, plus the surrounding metadata Xero returns at refresh time (id_token, scope, etc).
token = XeroKiwi::Token.new(
access_token: "ya29...",
refresh_token: "1//...",
expires_at: Time.now + 1800
)
token.expired? # => false
token.expiring_soon? # => false (default 60s window)
token.refreshable? # => true
Use .from_oauth_response to build a Token from a raw Xero token-endpoint response — it converts Xero’s ‘expires_in` (seconds-from-now) into an absolute `expires_at` Time, anchored at the moment the request was made.
Constant Summary collapse
- DEFAULT_EXPIRY_WINDOW =
60
Instance Attribute Summary collapse
-
#access_token ⇒ Object
readonly
Returns the value of attribute access_token.
-
#expires_at ⇒ Object
readonly
Returns the value of attribute expires_at.
-
#id_token ⇒ Object
readonly
Returns the value of attribute id_token.
-
#refresh_token ⇒ Object
readonly
Returns the value of attribute refresh_token.
-
#scope ⇒ Object
readonly
Returns the value of attribute scope.
-
#token_type ⇒ Object
readonly
Returns the value of attribute token_type.
Class Method Summary collapse
Instance Method Summary collapse
- #==(other) ⇒ Object (also: #eql?)
-
#expired?(now: Time.now) ⇒ Boolean
True if expires_at is in the past.
-
#expiring_soon?(within: DEFAULT_EXPIRY_WINDOW, now: Time.now) ⇒ Boolean
True if the token expires within ‘within` seconds from `now`.
- #hash ⇒ Object
-
#initialize(access_token:, refresh_token: nil, expires_at: nil, token_type: "Bearer", id_token: nil, scope: nil) ⇒ Token
constructor
A new instance of Token.
- #inspect ⇒ Object
- #refreshable? ⇒ Boolean
- #to_h ⇒ Object
- #valid?(now: Time.now) ⇒ Boolean
Constructor Details
#initialize(access_token:, refresh_token: nil, expires_at: nil, token_type: "Bearer", id_token: nil, scope: nil) ⇒ Token
Returns a new instance of Token.
39 40 41 42 43 44 45 46 47 |
# File 'lib/xero_kiwi/token.rb', line 39 def initialize(access_token:, refresh_token: nil, expires_at: nil, token_type: "Bearer", id_token: nil, scope: nil) @access_token = access_token @refresh_token = refresh_token @expires_at = expires_at @token_type = token_type @id_token = id_token @scope = scope end |
Instance Attribute Details
#access_token ⇒ Object (readonly)
Returns the value of attribute access_token.
23 24 25 |
# File 'lib/xero_kiwi/token.rb', line 23 def access_token @access_token end |
#expires_at ⇒ Object (readonly)
Returns the value of attribute expires_at.
23 24 25 |
# File 'lib/xero_kiwi/token.rb', line 23 def expires_at @expires_at end |
#id_token ⇒ Object (readonly)
Returns the value of attribute id_token.
23 24 25 |
# File 'lib/xero_kiwi/token.rb', line 23 def id_token @id_token end |
#refresh_token ⇒ Object (readonly)
Returns the value of attribute refresh_token.
23 24 25 |
# File 'lib/xero_kiwi/token.rb', line 23 def refresh_token @refresh_token end |
#scope ⇒ Object (readonly)
Returns the value of attribute scope.
23 24 25 |
# File 'lib/xero_kiwi/token.rb', line 23 def scope @scope end |
#token_type ⇒ Object (readonly)
Returns the value of attribute token_type.
23 24 25 |
# File 'lib/xero_kiwi/token.rb', line 23 def token_type @token_type end |
Class Method Details
.from_oauth_response(payload, requested_at: Time.now) ⇒ Object
25 26 27 28 29 30 31 32 33 34 35 36 37 |
# File 'lib/xero_kiwi/token.rb', line 25 def self.from_oauth_response(payload, requested_at: Time.now) payload = payload.transform_keys(&:to_s) expires_in = payload["expires_in"] new( access_token: payload["access_token"], refresh_token: payload["refresh_token"], expires_at: expires_in ? requested_at + expires_in.to_i : nil, token_type: payload["token_type"] || "Bearer", id_token: payload["id_token"], scope: payload["scope"] ) end |
Instance Method Details
#==(other) ⇒ Object Also known as: eql?
87 88 89 |
# File 'lib/xero_kiwi/token.rb', line 87 def ==(other) other.is_a?(Token) && other.to_h == to_h end |
#expired?(now: Time.now) ⇒ Boolean
True if expires_at is in the past. Returns false when expires_at is unknown — without an expiry we have no signal to act on, so callers should fall through to reactive (on-401) handling.
52 53 54 55 56 |
# File 'lib/xero_kiwi/token.rb', line 52 def expired?(now: Time.now) return false if expires_at.nil? now >= expires_at end |
#expiring_soon?(within: DEFAULT_EXPIRY_WINDOW, now: Time.now) ⇒ Boolean
True if the token expires within ‘within` seconds from `now`. Used by the client to decide whether to refresh proactively before a request. The default 60s window is wide enough to absorb network round-trip races without being so wide that we burn refresh tokens unnecessarily.
62 63 64 65 66 |
# File 'lib/xero_kiwi/token.rb', line 62 def expiring_soon?(within: DEFAULT_EXPIRY_WINDOW, now: Time.now) return false if expires_at.nil? now + within >= expires_at end |
#hash ⇒ Object
92 |
# File 'lib/xero_kiwi/token.rb', line 92 def hash = to_h.hash |
#inspect ⇒ Object
94 95 96 97 |
# File 'lib/xero_kiwi/token.rb', line 94 def inspect "#<#{self.class} access_token=#{access_token && "[FILTERED]"} " \ "refreshable=#{refreshable?} expires_at=#{expires_at.inspect}>" end |
#refreshable? ⇒ Boolean
72 73 74 |
# File 'lib/xero_kiwi/token.rb', line 72 def refreshable? !refresh_token.nil? && !refresh_token.empty? end |
#to_h ⇒ Object
76 77 78 79 80 81 82 83 84 85 |
# File 'lib/xero_kiwi/token.rb', line 76 def to_h { access_token: access_token, refresh_token: refresh_token, expires_at: expires_at, token_type: token_type, id_token: id_token, scope: scope } end |
#valid?(now: Time.now) ⇒ Boolean
68 69 70 |
# File 'lib/xero_kiwi/token.rb', line 68 def valid?(now: Time.now) !access_token.nil? && !access_token.empty? && !expired?(now: now) end |