Sha256: 279ec90c2b90eafde2cae1d75750318aa2dde3484681797aa4b0f96710cf0454

Contents?: true

Size: 1.94 KB

Versions: 11

Compression:

Stored size: 1.94 KB

Contents

# frozen_string_literal: true
module ShopifyApp
  class JWT
    class InvalidDestinationError < StandardError; end

    class MismatchedHostsError < StandardError; end

    class InvalidAudienceError < StandardError; end

    WARN_EXCEPTIONS = [
      ::JWT::DecodeError,
      ::JWT::ExpiredSignature,
      ::JWT::ImmatureSignature,
      ::JWT::VerificationError,
      InvalidAudienceError,
      InvalidDestinationError,
      MismatchedHostsError,
    ]

    def initialize(token)
      @token = token
      set_payload
    end

    def shopify_domain
      @payload && ShopifyApp::Utils.sanitize_shop_domain(@payload['dest'])
    end

    def shopify_user_id
      @payload['sub'].to_i if @payload && @payload['sub']
    end

    def expire_at
      @payload['exp'].to_i if @payload && @payload['exp']
    end

    private

    def set_payload
      payload, _ = parse_token_data(ShopifyApp.configuration&.secret, ShopifyApp.configuration&.old_secret)
      @payload = validate_payload(payload)
    rescue *WARN_EXCEPTIONS => error
      Rails.logger.warn("[ShopifyApp::JWT] Failed to validate JWT: [#{error.class}] #{error}")
      nil
    end

    def parse_token_data(secret, old_secret)
      ::JWT.decode(@token, secret, true, { algorithm: 'HS256' })
    rescue ::JWT::VerificationError
      raise unless old_secret

      ::JWT.decode(@token, old_secret, true, { algorithm: 'HS256' })
    end

    def validate_payload(payload)
      dest_host = ShopifyApp::Utils.sanitize_shop_domain(payload['dest'])
      iss_host = ShopifyApp::Utils.sanitize_shop_domain(payload['iss'])
      api_key = ShopifyApp.configuration.api_key

      raise InvalidAudienceError, "'aud' claim does not match api_key" unless payload['aud'] == api_key
      raise InvalidDestinationError, "'dest' claim host not a valid shopify host" unless dest_host
      raise MismatchedHostsError, "'dest' claim host does not match 'iss' claim host" unless dest_host == iss_host

      payload
    end
  end
end

Version data entries

11 entries across 11 versions & 2 rubygems

Version Path
ruby_shopify_app-1.3.3 lib/ruby_shopify_app/session/jwt.rb
ruby_shopify_app-1.3.2 lib/ruby_shopify_app/session/jwt.rb
ruby_shopify_app-1.3.1 lib/ruby_shopify_app/session/jwt.rb
ruby_shopify_app-1.3.0 lib/ruby_shopify_app/session/jwt.rb
ruby_shopify_app-1.2.0 lib/ruby_shopify_app/session/jwt.rb
ruby_shopify_app-1.1.0 lib/ruby_shopify_app/session/jwt.rb
ruby_shopify_app-1.0.0 lib/shopify_app/session/jwt.rb
shopify_app-18.1.3 lib/shopify_app/session/jwt.rb
shopify_app-18.1.2 lib/shopify_app/session/jwt.rb
shopify_app-18.1.1 lib/shopify_app/session/jwt.rb
shopify_app-18.1.0 lib/shopify_app/session/jwt.rb