Doorkeeper: `expires_in` keys is missing since 5.4

Created on 12 May 2020  路  20Comments  路  Source: doorkeeper-gem/doorkeeper

Steps to reproduce

Just call /oauth/token with a grant_type to password (what I have tested, maybe other types have the same issue). My specs failed after upgrade. After some research, expires_in is just not sent at all. It does not happen with 5.3.3

Expected behavior

We should receive a json with keys the following keys:

  • access_token
  • token_type
  • expires_in
  • refresh_token
  • created_at

Actual behavior

We receive a json with keys the following keys:

  • access_token
  • token_type
  • expires_in
  • refresh_token
  • created_at

System configuration

Doorkeeper initializer:

# config/initializers/doorkeeper.rb
Doorkeeper.configure do
   access_token_expires_in 2.hours

  # What I have but not necessary 
  access_token_generator '::Doorkeeper::JWT'

  grant_flows %w(password)
end

Ruby version: 2.6.5

Gemfile.lock:


Gemfile.lock content

  remote: https://github.com/benebrice/jsonapi-resources.git
  revision: 318bf85e3644f7086c29c58f4cd82784054501e4
  branch: fix--link-builder-on-root-engine
  specs:
    jsonapi-resources (0.9.11)
      activerecord (>= 4.1)
      concurrent-ruby
      railties (>= 4.1)

PATH
  remote: iso/engines/internal/secret_api
  specs:
    secret_api (0.1.0)
      doorkeeper (~> 5.2)
      jsonapi-resources
      rails (~> 6.0.2)

GEM
  remote: https://rubygems.org/
  specs:
    aasm (5.0.8)
      concurrent-ruby (~> 1.0)
    actioncable (6.0.3)
      actionpack (= 6.0.3)
      nio4r (~> 2.0)
      websocket-driver (>= 0.6.1)
    actionmailbox (6.0.3)
      actionpack (= 6.0.3)
      activejob (= 6.0.3)
      activerecord (= 6.0.3)
      activestorage (= 6.0.3)
      activesupport (= 6.0.3)
      mail (>= 2.7.1)
    actionmailer (6.0.3)
      actionpack (= 6.0.3)
      actionview (= 6.0.3)
      activejob (= 6.0.3)
      mail (~> 2.5, >= 2.5.4)
      rails-dom-testing (~> 2.0)
    actionpack (6.0.3)
      actionview (= 6.0.3)
      activesupport (= 6.0.3)
      rack (~> 2.0, >= 2.0.8)
      rack-test (>= 0.6.3)
      rails-dom-testing (~> 2.0)
      rails-html-sanitizer (~> 1.0, >= 1.2.0)
    actiontext (6.0.3)
      actionpack (= 6.0.3)
      activerecord (= 6.0.3)
      activestorage (= 6.0.3)
      activesupport (= 6.0.3)
      nokogiri (>= 1.8.5)
    actionview (6.0.3)
      activesupport (= 6.0.3)
      builder (~> 3.1)
      erubi (~> 1.4)
      rails-dom-testing (~> 2.0)
      rails-html-sanitizer (~> 1.1, >= 1.2.0)
    active_delivery (0.4.2)
    activejob (6.0.3)
      activesupport (= 6.0.3)
      globalid (>= 0.3.6)
    activemodel (6.0.3)
      activesupport (= 6.0.3)
    activerecord (6.0.3)
      activemodel (= 6.0.3)
      activesupport (= 6.0.3)
    activestorage (6.0.3)
      actionpack (= 6.0.3)
      activejob (= 6.0.3)
      activerecord (= 6.0.3)
      marcel (~> 0.3.1)
    activesupport (6.0.3)
      concurrent-ruby (~> 1.0, >= 1.0.2)
      i18n (>= 0.7, < 2)
      minitest (~> 5.1)
      tzinfo (~> 1.1)
      zeitwerk (~> 2.2, >= 2.2.2)
    acts-as-taggable-on (6.5.0)
      activerecord (>= 5.0, < 6.1)
    addressable (2.7.0)
      public_suffix (>= 2.0.2, < 5.0)
    airbrussh (1.4.0)
      sshkit (>= 1.6.1, != 1.7.0)
    annotate (3.1.1)
      activerecord (>= 3.2, < 7.0)
      rake (>= 10.4, < 14.0)
    ast (2.4.0)
    awesome_print (1.8.0)
    aws-eventstream (1.1.0)
    aws-partitions (1.312.0)
    aws-sdk-core (3.95.0)
      aws-eventstream (~> 1, >= 1.0.2)
      aws-partitions (~> 1, >= 1.239.0)
      aws-sigv4 (~> 1.1)
      jmespath (~> 1.0)
    aws-sdk-kms (1.31.0)
      aws-sdk-core (~> 3, >= 3.71.0)
      aws-sigv4 (~> 1.1)
    aws-sdk-rails (3.1.0)
      aws-sdk-ses (~> 1)
      railties (>= 5.2.0)
    aws-sdk-s3 (1.64.0)
      aws-sdk-core (~> 3, >= 3.83.0)
      aws-sdk-kms (~> 1)
      aws-sigv4 (~> 1.1)
    aws-sdk-ses (1.29.0)
      aws-sdk-core (~> 3, >= 3.71.0)
      aws-sigv4 (~> 1.1)
    aws-sdk-sns (1.23.0)
      aws-sdk-core (~> 3, >= 3.71.0)
      aws-sigv4 (~> 1.1)
    aws-sigv4 (1.1.3)
      aws-eventstream (~> 1.0, >= 1.0.2)
    bcrypt (3.1.13)
    bootsnap (1.4.6)
      msgpack (~> 1.0)
    builder (3.2.4)
    bullet (6.1.0)
      activesupport (>= 3.0.0)
      uniform_notifier (~> 1.11)
    byebug (11.1.3)
    capistrano (3.14.0)
      airbrussh (>= 1.0.0)
      i18n
      rake (>= 10.0.0)
      sshkit (>= 1.9.0)
    capistrano-bundler (1.6.0)
      capistrano (~> 3.1)
    capistrano-multiconfig (3.1.0)
      capistrano (>= 3.7.0)
    capistrano-rails (1.4.0)
      capistrano (~> 3.1)
      capistrano-bundler (~> 1.1)
    capistrano-rake (0.2.0)
      capistrano (>= 3.0)
    capistrano-rvm (0.1.2)
      capistrano (~> 3.0)
      sshkit (~> 1.2)
    capistrano3-puma (4.0.0)
      capistrano (~> 3.7)
      capistrano-bundler
      puma (~> 4.0)
    chronic (0.10.2)
    concurrent-ruby (1.1.6)
    connection_pool (2.2.2)
    crass (1.0.6)
    daemons (1.3.1)
    database_cleaner (1.8.5)
    devise (4.7.1)
      bcrypt (~> 3.0)
      orm_adapter (~> 0.1)
      railties (>= 4.1.0)
      responders
      warden (~> 1.2.3)
    diff-lcs (1.3)
    docile (1.3.2)
    doorkeeper (5.4.0)
      railties (>= 5)
    doorkeeper-jwt (0.4.0)
      jwt (~> 2.1)
    dotenv (2.7.5)
    dotenv-rails (2.7.5)
      dotenv (= 2.7.5)
      railties (>= 3.2, < 6.1)
    erubi (1.9.0)
    eventmachine (1.2.7)
    factory_bot (5.2.0)
      activesupport (>= 4.2.0)
    factory_bot_rails (5.2.0)
      factory_bot (~> 5.2.0)
      railties (>= 4.2.0)
    faker (2.11.0)
      i18n (>= 1.6, < 2)
    faraday (1.0.1)
      multipart-post (>= 1.2, < 3)
    ffi (1.12.2)
    geocoder (1.6.3)
    gitlab (4.14.1)
      httparty (~> 0.14, >= 0.14.0)
      terminal-table (~> 1.5, >= 1.5.1)
    globalid (0.4.2)
      activesupport (>= 4.2.0)
    haml (5.1.2)
      temple (>= 0.8.0)
      tilt
    httparty (0.18.0)
      mime-types (~> 3.0)
      multi_xml (>= 0.5.2)
    i18n (1.8.2)
      concurrent-ruby (~> 1.0)
    image_processing (1.10.3)
      mini_magick (>= 4.9.5, < 5)
      ruby-vips (>= 2.0.17, < 3)
    jaro_winkler (1.5.4)
    jmespath (1.4.0)
    json (2.3.0)
    json-schema (2.8.1)
      addressable (>= 2.4)
    jwt (2.2.1)
    listen (3.1.5)
      rb-fsevent (~> 0.9, >= 0.9.4)
      rb-inotify (~> 0.9, >= 0.9.7)
      ruby_dep (~> 1.2)
    loofah (2.5.0)
      crass (~> 1.0.2)
      nokogiri (>= 1.5.9)
    mail (2.7.1)
      mini_mime (>= 0.1.1)
    mailcatcher (0.2.4)
      eventmachine
      haml
      i18n
      json
      mail
      sinatra
      skinny (>= 0.1.2)
      sqlite3-ruby
      thin
    marcel (0.3.3)
      mimemagic (~> 0.3.2)
    method_source (1.0.0)
    mime-types (3.3.1)
      mime-types-data (~> 3.2015)
    mime-types-data (3.2020.0425)
    mimemagic (0.3.5)
    mini_magick (4.10.1)
    mini_mime (1.0.2)
    mini_portile2 (2.4.0)
    minitest (5.14.0)
    msgpack (1.3.3)
    multi_xml (0.6.0)
    multipart-post (2.1.1)
    mustermann (1.1.1)
      ruby2_keywords (~> 0.0.1)
    net-scp (3.0.0)
      net-ssh (>= 2.6.5, < 7.0.0)
    net-ssh (6.0.2)
    nio4r (2.5.2)
    nokogiri (1.10.9)
      mini_portile2 (~> 2.4.0)
    octokit (4.18.0)
      faraday (>= 0.9)
      sawyer (~> 0.8.0, >= 0.5.3)
    orm_adapter (0.5.0)
    parallel (1.19.1)
    parser (2.7.1.2)
      ast (~> 2.4.0)
    pg (1.2.3)
    pronto (0.10.0)
      gitlab (~> 4.0, >= 4.0.0)
      httparty (>= 0.13.7)
      octokit (~> 4.7, >= 4.7.0)
      rainbow (>= 2.2, < 4.0)
      rugged (~> 0.24, >= 0.23.0)
      thor (~> 0.20.0)
    pronto-rubocop (0.10.0)
      pronto (~> 0.10.0)
      rubocop (~> 0.50, >= 0.49.1)
    public_suffix (4.0.5)
    puma (4.3.3)
      nio4r (~> 2.0)
    rack (2.2.2)
    rack-cors (1.1.1)
      rack (>= 2.0.0)
    rack-protection (2.0.8.1)
      rack
    rack-test (1.1.0)
      rack (>= 1.0, < 3)
    rails (6.0.3)
      actioncable (= 6.0.3)
      actionmailbox (= 6.0.3)
      actionmailer (= 6.0.3)
      actionpack (= 6.0.3)
      actiontext (= 6.0.3)
      actionview (= 6.0.3)
      activejob (= 6.0.3)
      activemodel (= 6.0.3)
      activerecord (= 6.0.3)
      activestorage (= 6.0.3)
      activesupport (= 6.0.3)
      bundler (>= 1.3.0)
      railties (= 6.0.3)
      sprockets-rails (>= 2.0.0)
    rails-dom-testing (2.0.3)
      activesupport (>= 4.2.0)
      nokogiri (>= 1.6)
    rails-html-sanitizer (1.3.0)
      loofah (~> 2.3)
    railties (6.0.3)
      actionpack (= 6.0.3)
      activesupport (= 6.0.3)
      method_source
      rake (>= 0.8.7)
      thor (>= 0.20.3, < 2.0)
    rainbow (3.0.0)
    rake (13.0.1)
    rb-fsevent (0.10.4)
    rb-inotify (0.10.1)
      ffi (~> 1.0)
    redis (4.1.4)
    responders (3.0.0)
      actionpack (>= 5.0)
      railties (>= 5.0)
    rexml (3.2.4)
    rspec-core (3.9.2)
      rspec-support (~> 3.9.3)
    rspec-expectations (3.9.2)
      diff-lcs (>= 1.2.0, < 2.0)
      rspec-support (~> 3.9.0)
    rspec-mocks (3.9.1)
      diff-lcs (>= 1.2.0, < 2.0)
      rspec-support (~> 3.9.0)
    rspec-rails (4.0.0)
      actionpack (>= 4.2)
      activesupport (>= 4.2)
      railties (>= 4.2)
      rspec-core (~> 3.9)
      rspec-expectations (~> 3.9)
      rspec-mocks (~> 3.9)
      rspec-support (~> 3.9)
    rspec-support (3.9.3)
    rswag (2.3.1)
      rswag-api (= 2.3.1)
      rswag-specs (= 2.3.1)
      rswag-ui (= 2.3.1)
    rswag-api (2.3.1)
      railties (>= 3.1, < 7.0)
    rswag-specs (2.3.1)
      activesupport (>= 3.1, < 7.0)
      json-schema (~> 2.2)
      railties (>= 3.1, < 7.0)
    rswag-ui (2.3.1)
      actionpack (>= 3.1, < 7.0)
      railties (>= 3.1, < 7.0)
    rubocop (0.82.0)
      jaro_winkler (~> 1.5.1)
      parallel (~> 1.10)
      parser (>= 2.7.0.1)
      rainbow (>= 2.2.2, < 4.0)
      rexml
      ruby-progressbar (~> 1.7)
      unicode-display_width (>= 1.4.0, < 2.0)
    rubocop-git (0.1.3)
      rubocop (>= 0.24.1)
    rubocop-rspec (1.39.0)
      rubocop (>= 0.68.1)
    ruby-progressbar (1.10.1)
    ruby-vips (2.0.17)
      ffi (~> 1.9)
    ruby2_keywords (0.0.2)
    ruby_dep (1.5.0)
    rugged (0.99.0)
    sawyer (0.8.2)
      addressable (>= 2.3.5)
      faraday (> 0.8, < 2.0)
    seed-fu (2.3.9)
      activerecord (>= 3.1)
      activesupport (>= 3.1)
    shoulda-matchers (4.3.0)
      activesupport (>= 4.2.0)
    sidekiq (6.0.7)
      connection_pool (>= 2.2.2)
      rack (~> 2.0)
      rack-protection (>= 2.0.0)
      redis (>= 4.1.0)
    simplecov (0.18.5)
      docile (~> 1.1)
      simplecov-html (~> 0.11)
    simplecov-html (0.12.2)
    sinatra (2.0.8.1)
      mustermann (~> 1.0)
      rack (~> 2.0)
      rack-protection (= 2.0.8.1)
      tilt (~> 2.0)
    skinny (0.2.2)
      eventmachine (~> 1.0)
      thin
    spring (2.1.0)
    spring-commands-rspec (1.0.4)
      spring (>= 0.9.1)
    spring-watcher-listen (2.0.1)
      listen (>= 2.7, < 4.0)
      spring (>= 1.2, < 3.0)
    sprockets (4.0.0)
      concurrent-ruby (~> 1.0)
      rack (> 1, < 3)
    sprockets-rails (3.2.1)
      actionpack (>= 4.0)
      activesupport (>= 4.0)
      sprockets (>= 3.0.0)
    sqlite3 (1.4.2)
    sqlite3-ruby (1.3.3)
      sqlite3 (>= 1.3.3)
    sshkit (1.21.0)
      net-scp (>= 1.1.2)
      net-ssh (>= 2.8.0)
    temple (0.8.2)
    terminal-table (1.8.0)
      unicode-display_width (~> 1.1, >= 1.1.1)
    thin (1.7.2)
      daemons (~> 1.0, >= 1.0.9)
      eventmachine (~> 1.0, >= 1.0.4)
      rack (>= 1, < 3)
    thor (0.20.3)
    thread_safe (0.3.6)
    tilt (2.0.10)
    timecop (0.9.1)
    tzinfo (1.2.7)
      thread_safe (~> 0.1)
    unicode-display_width (1.7.0)
    uniform_notifier (1.13.0)
    warden (1.2.8)
      rack (>= 2.0.6)
    websocket-driver (0.7.1)
      websocket-extensions (>= 0.1.0)
    websocket-extensions (0.1.4)
    whenever (1.0.0)
      chronic (>= 0.6.3)
    zeitwerk (2.3.0)

PLATFORMS
  ruby

DEPENDENCIES
  aasm
  active_delivery
  acts-as-taggable-on (~> 6.0)
  annotate
  awesome_print
  aws-sdk-rails (~> 3)
  aws-sdk-s3
  aws-sdk-sns
  bootsnap (>= 1.4.2)
  bullet
  byebug
  capistrano (~> 3.11)
  capistrano-bundler
  capistrano-multiconfig (>= 3.0.3)
  capistrano-rails
  capistrano-rake
  capistrano-rvm
  capistrano3-puma
  database_cleaner
  devise
  doorkeeper
  doorkeeper-jwt
  dotenv-rails
  factory_bot_rails
  faker
  geocoder
  haml
  image_processing
  jsonapi-resources!
  listen (>= 3.0.5, < 3.2)
  mailcatcher
  pg
  pronto
  pronto-rubocop
  puma (~> 4.1)
  rack-cors
  rails (~> 6.0.2)
  redis
  rspec-rails
  rswag
  rswag-ui
  rubocop
  rubocop-git
  rubocop-rspec
  secret_api!
  seed-fu
  shoulda-matchers
  sidekiq
  simplecov
  spring
  spring-commands-rspec
  spring-watcher-listen (~> 2.0.0)
  sshkit
  timecop
  tzinfo-data
  whenever

RUBY VERSION
   ruby 2.6.5p114

BUNDLED WITH
   2.0.1

bug? wontfix

All 20 comments

Hi @benebrice . It's super weird because we have specs that insure requires fields in the JSON response for password flow (and others actually):

https://github.com/doorkeeper-gem/doorkeeper/blob/master/spec/controllers/tokens_controller_spec.rb#L43-L45

https://github.com/doorkeeper-gem/doorkeeper/blob/master/spec/requests/flows/password_spec.rb#L43-L45

Maybe your specs related to Doorkeeper::Application instances and informs about other missing fields that was removed after https://github.com/doorkeeper-gem/doorkeeper/security/advisories/GHSA-j7vx-8mqj-cqp9 was closed?

This is weird. I do have an association to Doorkeeper::Application but I don't use it at all here. It's native behaviour. I just changed the root but controller inherits from Doorkeeper::TokensController.
I guess it is not related to GHSA-j7vx-8mqj-cqp9 since I don't have the issue with 5.3.3 right?

Here is my spec (using rswag)

let(:owner) { create(:user) }
  let(:lambda_user) do
    create(:user,
           password: lambda_user_password,
           password_confirmation: lambda_user_password)
  end
  let(:lambda_user_password) { SecureRandom.uuid }
  let(:application) { create(:application, :guest_read_write, owner: owner) }

  let(:client_id) { application.uid }
  let(:client_secret) { application.secret }
  let(:token) do
    create(:access_token,
           resource_owner_id: user.id,
           application_id: application.id,
           use_refresh_token: true,
           scopes: scope)
  end

path '/oauth/token' do
    post 'Generate an access token' do
      tags 'Oauth'
      consumes 'application/vnd.api+json'
      produces 'application/vnd.api+json'
      # Parameters
      parameter name: :params,
                in: :body,
                required: true

      let(:grant_type) { 'password' }
      let(:email) { lambda_user.email }
      let(:password) { lambda_user_password }
      let(:scope) { 'read write' }
      let(:params) do
        { grant_type: grant_type,
          client_id: client_id,
          client_secret: client_secret,
          email: email,
          password: password,
          scope: scope }
      end

      response '200', 'Generate a token' do
        let!(:user) do
          create(:user, :unconfirmed,
                 confirmation_token: confirmation_token)
        end
        let(:confirmation_token) { SecureRandom.uuid }

        schema('$ref' => '#/definitions/AccessToken')
        keys = %w[access_token token_type expires_in refresh_token created_at]
        run_test_with_keys!(keys) do |json|
          it 'has scope' do
            expect(json['scope']).to eq(scope)
          end
        end
      end

      response '200', 'Refresh a token' do
        let!(:user) { create(:user) }
        let(:grant_type) { 'refresh_token' }
        let(:params) do
          { grant_type: grant_type,
            client_id: client_id,
            client_secret: client_secret,
            refresh_token: token.refresh_token }
        end

        schema('$ref' => '#/definitions/AccessToken')
        keys = %w[access_token token_type expires_in refresh_token created_at]
        run_test_with_keys!(keys) do |json|
          it 'has scope' do
            expect(json['scope']).to eq(scope)
          end
        end
      end

      context 'when generating new token' do
        let(:grant_type) { nil }
        let(:scopes) { %w[read write] }

        it_behaves_like 'rswag_error',
                        400,
                        'Missing required parameter: grant_type.' do
          let(:title) { 'Missing required parameter: grant_type.' }
        end
      end
    end
  end

with helper

def run_test_with_keys!(keys, &block)
    run_test! do |response|
      json = JSON.parse(response.body)
      keys.each do |k|
        expect(json).to have_key(k)
      end
      block.call(json) if block_given?
    end
  end

Specs fails when running

keys = %w[access_token token_type expires_in refresh_token created_at]
run_test_with_keys!(keys)

I guess it is not related to GHSA-j7vx-8mqj-cqp9 since I don't have the issue with 5.3.3 right?

I think yes.

From what I can see there is no reason not to have an expires_in in the response. I need to check also changelog to see if we changed something in TokensController behavior or acctess token serialization.

Checked the changelog again and didn't find anything criminal.

Maybe something here https://github.com/doorkeeper-gem/doorkeeper/compare/38b7333c...d5fff38e

Also could you please check inside your test the actual exires_in value of the access token instance? Maybe it's nil and server just compact the response

Hi @benebrice . Did you find the root of the issue?

Nope. I've downgraded to 5.3.3, no more issue. 馃槙

This is super sad :(

It is. I did not take enough time to dig on this step by step on the gem but if this issue happens on the 5.4 but not on 5.3.3 it might be an issue of the gem, hidden somewhere.
I'll let you know as soon as I have debugged this.

The problem is to find it for gem is that we have a lot of specs that checks for this field.. So maybe it's some interesting use case, I don't know

I guess you're right. Rails API + Device + Doorkeeper + Jsonapi-resources, it's not that common yet. Maybe some configuration on my side turned off this on the gem side.

We faced the similar problem with the grant_type: 'refresh_token'.

Maybe it will help but in our case we didn't set expires_in for the factory of the token we wanted to refresh and as you don't send the request, you don't get the expires_in to be set by default.

And I have a related question to @nbulaj. Is that the expected behaviour to use 'parent token' to set attributes of the 'new (refreshed) token'?
I assume that in case if I will change default expires_in to be something else, then this change will force me to invalidate all the tokens or manually update them (never done it tho 馃槃 ), since the refresh_token_request will always get the original value from the parent and not from the config.

Maybe it will help but in our case we didn't set expires_in for the factory of the token we wanted to refresh and as you don't send the request, you don't get the expires_in to be set by default.

That's sounds like what I've posted above:

Also could you please check inside your test the actual expires_in value of the access token instance? Maybe it's nil and server just compact the response

Also I don't sure how Jsonapi-resources serializes data and how it affects on Doorkeeper internals.


@storhet

Is that the expected behaviour to use 'parent token' to set attributes of the 'new (refreshed) token'?

Yes

I assume that in case if I will change default expires_in to be something else,

In this case you 're bring data inconsistency yourself, the same as in #1399 . It's like when you set required scopes for the endpoint like read / write, your application users log in and obtain access tokens, than you just change required scopes to read_repository / write_repository. You need to deal with such cases yourself (create a data migration and update the tokens with a new scopes, etc). So:

I assume that in case if I will change default expires_in to be something else, then this change will force me to invalidate all the tokens or manually update them

Exactly.

Also from RFC6749, p. 1.5. Refresh Token

Refresh tokens are issued to the client by the authorization server and are used to obtain a new access token when the current access token becomes invalid or expires, or to obtain additional access tokens _with identical or narrower scope_ (access tokens may have a shorter lifetime and fewer permissions than authorized by the resource owner).

I'm also seeing this:

Rails (full, not API) 5.2.4.3, Devise 4.7.2, fast_jsonapi 1.5

Works fine on 5.3.3, on 5.4.0 I have a regression: my refresh_token response does not have the 'expires_in' attribute.

      describe 'grant_type refresh_token' do
        let(:user) { create :user, email: '[email protected]', password: '12345678' }
        let(:client_application) { create :client_application }
        let(:refresh_token) do
          client_application.access_tokens.create!(use_refresh_token: true, resource_owner_id: user.id).r  efresh_token
        end

        it 'returns new refresh_token', reqres_title: 'Get new refresh token' do
          post '/oauth/token', params: {
            'grant_type' => 'refresh_token',
            'refresh_token' => refresh_token,
            'client_id' => client_application.uid,
            'client_secret' => client_application.secret
          }

          expect(Doorkeeper::AccessToken.count).to eq 2
          expect(Doorkeeper::AccessToken.second.application_id).to eq client_application.id

          expect(json['access_token'].size).to eq 43
          expect(json['refresh_token'].size).to eq 43
          expect(json['refresh_token'].size).not_to eq refresh_token
          expect(json['token_type']).to eq 'Bearer'
          expect(json['expires_in']).to eq 7200 # FAILS
          expect(json['created_at'].present?).to eq true
          expect(response.status).to eq 200
        end
      end

If it helps, the regression is in 5.4.0.rc1

Looking at some of the PRs, #1366 seems to relate, but I don't see a significant change.

The issue seems to be with

60a0f2705d10dddbf8519f4fef81ced23001f732 (link)

Tests up to commit 40008f8fc459ce8688bcfcc978ce02fe2b9bcc3e (link) are fine, but 60a0f2705d10dddbf8519f4fef81ced23001f732 breaks.

@rishabhsairawat could you please take a look at the above comment? #1366 related

@TheTeaNerd What I changed in #1366 was that Refresh token will use expiry from that of its parent token. So Earlier for refresh token, it was using expiry from the configuration but after #1366 It will use from its parent token.

Looking at your test cases looks like you are not setting deny expiry in your token factory.
@storhet faced the same problem:

We faced the similar problem with the grant_type: 'refresh_token'.
Maybe it will help but in our case we didn't set expires_in for the factory of the token we wanted to refresh and as you don't send the request, you don't get the expires_in to be set by default.

Also, the issue reported by @benebrice is not related to #1366 as that changes doorkeeper behavior only for refresh_token grant type not for any other grant type. @nbulaj I have checked in the doorkeeper code, It already has specs written for token expiry fields.

Thanks @rishabhsairawat.

@benebrice could you please check if comment above resolves your issue?

This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs. Thank you for your contributions.

@nbulaj I finally had time to check it. It's fine if you declare expires_in on the parent. Thanks @rishabhsairawat 馃憣馃徎

# before
let(:token) do
    create(:access_token,
           resource_owner_id: admin.id,
           application_id: application.id,
           use_refresh_token: true,
           scopes: scope)
end

# after
let(:token) do
    create(:access_token,
           resource_owner_id: admin.id,
           application_id: application.id,
           use_refresh_token: true,
           expires_in: 2.hours.to_i,
           scopes: scope)
end
Was this page helpful?
0 / 5 - 0 ratings