Class: Pluggy::ApiKey
- Inherits:
-
Object
- Object
- Pluggy::ApiKey
- Defined in:
- lib/pluggy/api_key.rb
Overview
An apiKey from POST /auth, with its expiry.
Pluggy documents a 2-hour lifetime, but the token is a JWT, so read the
exp claim instead of assuming: it costs nothing, needs no dependency, and
self-corrects if Pluggy ever changes the TTL. No signature verification --
we are only reading the clock on a token we were just handed.
Constant Summary collapse
- FALLBACK_TTL =
Used only when
expcannot be read (an opaque token, or a shape change). 2 * 60 * 60
- SKEW =
Renew slightly early so a request can't expire in flight.
60
Instance Attribute Summary collapse
-
#expires_at ⇒ Object
readonly
Returns the value of attribute expires_at.
-
#token ⇒ Object
readonly
Returns the value of attribute token.
Class Method Summary collapse
-
.jwt_expiry(token) ⇒ Object
Decode a base64url JWT payload and read
exp.
Instance Method Summary collapse
- #expired?(now = Time.now) ⇒ Boolean
-
#initialize(token, expires_at: nil) ⇒ ApiKey
constructor
A new instance of ApiKey.
- #inspect ⇒ Object
- #to_s ⇒ Object
Constructor Details
#initialize(token, expires_at: nil) ⇒ ApiKey
Returns a new instance of ApiKey.
22 23 24 25 26 27 |
# File 'lib/pluggy/api_key.rb', line 22 def initialize(token, expires_at: nil) raise ArgumentError, "apiKey cannot be empty" if token.nil? || token.to_s.empty? @token = token.to_s @expires_at = expires_at || self.class.jwt_expiry(@token) || (Time.now + FALLBACK_TTL) end |
Instance Attribute Details
#expires_at ⇒ Object (readonly)
Returns the value of attribute expires_at.
20 21 22 |
# File 'lib/pluggy/api_key.rb', line 20 def expires_at @expires_at end |
#token ⇒ Object (readonly)
Returns the value of attribute token.
20 21 22 |
# File 'lib/pluggy/api_key.rb', line 20 def token @token end |
Class Method Details
.jwt_expiry(token) ⇒ Object
Decode a base64url JWT payload and read exp.
Deliberately does not require "base64": it is a bundled, not a default, gem from Ruby 3.4 on, so requiring it can fail under Bundler. String#unpack1("m0") is core and does the same job.
44 45 46 47 48 49 50 51 52 53 54 55 |
# File 'lib/pluggy/api_key.rb', line 44 def self.jwt_expiry(token) segment = token.split(".")[1] return nil unless segment padded = segment.tr("-_", "+/") padded += "=" * ((4 - (padded.length % 4)) % 4) exp = JSON.parse(padded.unpack1("m0"))["exp"] exp.is_a?(Numeric) ? Time.at(exp) : nil rescue StandardError nil end |
Instance Method Details
#expired?(now = Time.now) ⇒ Boolean
29 30 31 |
# File 'lib/pluggy/api_key.rb', line 29 def expired?(now = Time.now) now >= (@expires_at - SKEW) end |
#inspect ⇒ Object
35 36 37 |
# File 'lib/pluggy/api_key.rb', line 35 def inspect "#<Pluggy::ApiKey ***#{@token[-6..]} expires_at=#{@expires_at.iso8601}>" end |
#to_s ⇒ Object
33 |
# File 'lib/pluggy/api_key.rb', line 33 def to_s = @token |