doorkeeper-gem / doorkeeper

Doorkeeper is an OAuth 2 provider for Ruby on Rails / Grape.
https://doorkeeper.gitbook.io/guides/
MIT License
5.32k stars 1.07k forks source link

uninitialized constant for access_token_model when using custom_access_token_attributes config #1647

Closed matthewheathoyster closed 1 year ago

matthewheathoyster commented 1 year ago

I am trying to configure custom_access_token_attributes in doorkeeper.rb to look for a custom attribute of company_id, but Doorkeeper config fails to constantize my custom model classes when this option is enabled. When the option is disabled, everything works perfectly: Doorkeeper can find my custom model classes, this only happens when that config option is enabled.

We auto-load the relevant models from a backend/modules folder like so, from an initializers/autoloaded_paths.rb file in Rails config/:

Rails.autoloaders.main.tap do |loader|
  loader.push_dir("#{Rails.root}/backend/modules")
  loader.collapse("#{Rails.root}/backend/modules/*/models")
end

So a model like backend/modules/public_api/models/oauth_access_grant.rb would be available as PublicAPI::OauthAccessGrant. Rails correctly constantizes that class when fully loaded, but Doorkeeper can't seem to look it up properly when custom_access_token_attributes is set in doorkeeper.rb

Is this because those classes simply aren't auto-loaded and available at the time Doorkeeper runs? Is there a best practice way of making those custom classes available to Doorkeeper?

The backtrace is:

backtrace content ``` NameError: uninitialized constant PublicAPI Object.const_get(camel_cased_word) ^^^^^^^^^^ Did you mean? PublicSuffix /Users/matthew/code/anywhere/vendor/nix/gems/ruby/3.1.0/gems/activesupport-7.0.4.3/lib/active_support/inflector/methods.rb:280:in `constantize' /Users/matthew/code/anywhere/vendor/nix/gems/ruby/3.1.0/gems/activesupport-7.0.4.3/lib/active_support/core_ext/string/inflections.rb:74:in `constantize' /Users/matthew/code/anywhere/vendor/nix/gems/ruby/3.1.0/gems/doorkeeper-5.6.5/lib/doorkeeper/config.rb:434:in `access_token_model' /Users/matthew/code/anywhere/vendor/nix/gems/ruby/3.1.0/gems/doorkeeper-5.6.5/lib/doorkeeper/config/validations.rb:59:in `block in validate_custom_access_token_attributes' /Users/matthew/code/anywhere/vendor/nix/gems/ruby/3.1.0/gems/doorkeeper-5.6.5/lib/doorkeeper/config/validations.rb:58:in `each' /Users/matthew/code/anywhere/vendor/nix/gems/ruby/3.1.0/gems/doorkeeper-5.6.5/lib/doorkeeper/config/validations.rb:58:in `validate_custom_access_token_attributes' /Users/matthew/code/anywhere/vendor/nix/gems/ruby/3.1.0/gems/doorkeeper-5.6.5/lib/doorkeeper/config/validations.rb:14:in `validate!' /Users/matthew/code/anywhere/vendor/nix/gems/ruby/3.1.0/gems/doorkeeper-5.6.5/lib/doorkeeper/config/abstract_builder.rb:23:in `build' /Users/matthew/code/anywhere/vendor/nix/gems/ruby/3.1.0/gems/doorkeeper-5.6.5/lib/doorkeeper.rb:121:in `configure' /Users/matthew/code/anywhere/config/initializers/doorkeeper.rb:3:in `
' /Users/matthew/code/anywhere/vendor/nix/gems/ruby/3.1.0/gems/bootsnap-1.11.1/lib/bootsnap/load_path_cache/core_ext/kernel_require.rb:39:in `load' /Users/matthew/code/anywhere/vendor/nix/gems/ruby/3.1.0/gems/bootsnap-1.11.1/lib/bootsnap/load_path_cache/core_ext/kernel_require.rb:39:in `load' /Users/matthew/code/anywhere/vendor/nix/gems/ruby/3.1.0/gems/railties-7.0.4.3/lib/rails/engine.rb:667:in `block in load_config_initializer' /Users/matthew/code/anywhere/vendor/nix/gems/ruby/3.1.0/gems/activesupport-7.0.4.3/lib/active_support/notifications.rb:208:in `instrument' /Users/matthew/code/anywhere/vendor/nix/gems/ruby/3.1.0/gems/railties-7.0.4.3/lib/rails/engine.rb:666:in `load_config_initializer' /Users/matthew/code/anywhere/vendor/nix/gems/ruby/3.1.0/gems/railties-7.0.4.3/lib/rails/engine.rb:620:in `block (2 levels) in ' /Users/matthew/code/anywhere/vendor/nix/gems/ruby/3.1.0/gems/railties-7.0.4.3/lib/rails/engine.rb:619:in `each' /Users/matthew/code/anywhere/vendor/nix/gems/ruby/3.1.0/gems/railties-7.0.4.3/lib/rails/engine.rb:619:in `block in ' /Users/matthew/code/anywhere/vendor/nix/gems/ruby/3.1.0/gems/railties-7.0.4.3/lib/rails/initializable.rb:32:in `instance_exec' /Users/matthew/code/anywhere/vendor/nix/gems/ruby/3.1.0/gems/railties-7.0.4.3/lib/rails/initializable.rb:32:in `run' /Users/matthew/code/anywhere/vendor/nix/gems/ruby/3.1.0/gems/railties-7.0.4.3/lib/rails/initializable.rb:61:in `block in run_initializers' /Users/matthew/code/anywhere/vendor/nix/gems/ruby/3.1.0/gems/railties-7.0.4.3/lib/rails/initializable.rb:50:in `each' /Users/matthew/code/anywhere/vendor/nix/gems/ruby/3.1.0/gems/railties-7.0.4.3/lib/rails/initializable.rb:50:in `tsort_each_child' /Users/matthew/code/anywhere/vendor/nix/gems/ruby/3.1.0/gems/railties-7.0.4.3/lib/rails/initializable.rb:60:in `run_initializers' /Users/matthew/code/anywhere/vendor/nix/gems/ruby/3.1.0/gems/railties-7.0.4.3/lib/rails/application.rb:372:in `initialize!' /Users/matthew/code/anywhere/config/environment.rb:7:in `
' /Users/matthew/code/anywhere/vendor/nix/gems/ruby/3.1.0/gems/bootsnap-1.11.1/lib/bootsnap/load_path_cache/core_ext/kernel_require.rb:30:in `require' /Users/matthew/code/anywhere/vendor/nix/gems/ruby/3.1.0/gems/bootsnap-1.11.1/lib/bootsnap/load_path_cache/core_ext/kernel_require.rb:30:in `require' /Users/matthew/code/anywhere/vendor/nix/gems/ruby/3.1.0/gems/zeitwerk-2.6.6/lib/zeitwerk/kernel.rb:38:in `require' /Users/matthew/code/anywhere/vendor/nix/gems/ruby/3.1.0/gems/railties-7.0.4.3/lib/rails/application.rb:348:in `require_environment!' /Users/matthew/code/anywhere/vendor/nix/gems/ruby/3.1.0/gems/railties-7.0.4.3/lib/rails/application.rb:511:in `block in run_tasks_blocks' /Users/matthew/code/anywhere/vendor/nix/gems/ruby/3.1.0/gems/sentry-ruby-core-5.2.1/lib/sentry/rake.rb:24:in `execute' ```

System configuration

Doorkeeper initializer:

doorkeeper.rb content ```ruby # config/initializers/doorkeeper.rb # frozen_string_literal: true Doorkeeper.configure do # Change the ORM that doorkeeper will use (requires ORM extensions installed). # Check the list of supported ORMs here: https://github.com/doorkeeper-gem/doorkeeper#orms orm :active_record # This block will be called to check whether the resource owner is authenticated or not. resource_owner_authenticator do current_user || warden.authenticate!(scope: :user) # Put your resource owner authentication logic here. # Example implementation: # User.find_by(id: session[:user_id]) || redirect_to(new_user_session_url) end # If you didn't skip applications controller from Doorkeeper routes in your application routes.rb # file then you need to declare this block in order to restrict access to the web interface for # adding oauth authorized applications. In other case it will return 403 Forbidden response # every time somebody will try to access the admin web interface. # # admin_authenticator do # # Put your admin authentication logic here. # # Example implementation: # # if current_user # head :forbidden unless current_user.admin? # else # redirect_to sign_in_url # end # end # You can use your own model classes if you need to extend (or even override) default # Doorkeeper models such as `Application`, `AccessToken` and `AccessGrant. # # Be default Doorkeeper ActiveRecord ORM uses it's own classes: # # access_token_class "Doorkeeper::AccessToken" # access_grant_class "Doorkeeper::AccessGrant" # application_class "Doorkeeper::Application" # # Don't forget to include Doorkeeper ORM mixins into your custom models: # # * ::Doorkeeper::Orm::ActiveRecord::Mixins::AccessToken - for access token # * ::Doorkeeper::Orm::ActiveRecord::Mixins::AccessGrant - for access grant # * ::Doorkeeper::Orm::ActiveRecord::Mixins::Application - for application (OAuth2 clients) # # For example: # # access_token_class "MyAccessToken" # # class MyAccessToken < ApplicationRecord # include ::Doorkeeper::Orm::ActiveRecord::Mixins::AccessToken # # self.table_name = "hey_i_wanna_my_name" # # def destroy_me! # destroy # end # end access_grant_class "PublicAPI::OauthAccessGrant" access_token_class "PublicAPI::OauthAccessToken" application_class "PublicAPI::OauthApplication" # Enables polymorphic Resource Owner association for Access Tokens and Access Grants. # By default this option is disabled. # # Make sure you properly setup you database and have all the required columns (run # `bundle exec rails generate doorkeeper:enable_polymorphic_resource_owner` and execute Rails # migrations). # # If this option enabled, Doorkeeper will store not only Resource Owner primary key # value, but also it's type (class name). See "Polymorphic Associations" section of # Rails guides: https://guides.rubyonrails.org/association_basics.html#polymorphic-associations # # [NOTE] If you apply this option on already existing project don't forget to manually # update `resource_owner_type` column in the database and fix migration template as it will # set NOT NULL constraint for Access Grants table. # # use_polymorphic_resource_owner # If you are planning to use Doorkeeper in Rails 5 API-only application, then you might # want to use API mode that will skip all the views management and change the way how # Doorkeeper responds to a requests. # api_only # Enforce token request content type to application/x-www-form-urlencoded. # It is not enabled by default to not break prior versions of the gem. # enforce_content_type # Authorization Code expiration time (default: 10 minutes). # # authorization_code_expires_in 10.minutes # Access token expiration time (default: 2 hours). # If you want to disable expiration, set this to `nil`. # # access_token_expires_in 2.hours # Assign custom TTL for access tokens. Will be used instead of access_token_expires_in # option if defined. In case the block returns `nil` value Doorkeeper fallbacks to # +access_token_expires_in+ configuration option value. If you really need to issue a # non-expiring access token (which is not recommended) then you need to return # Float::INFINITY from this block. # # `context` has the following properties available: # # * `client` - the OAuth client application (see Doorkeeper::OAuth::Client) # * `grant_type` - the grant type of the request (see Doorkeeper::OAuth) # * `scopes` - the requested scopes (see Doorkeeper::OAuth::Scopes) # * `resource_owner` - authorized resource owner instance (if present) # # custom_access_token_expires_in do |context| # context.client.additional_settings.implicit_oauth_expiration # end # Use a custom class for generating the access token. # See https://doorkeeper.gitbook.io/guides/configuration/other-configurations#custom-access-token-generator # # access_token_generator '::Doorkeeper::JWT' # The controller +Doorkeeper::ApplicationController+ inherits from. # Defaults to +ActionController::Base+ unless +api_only+ is set, which changes the default to # +ActionController::API+. The return value of this option must be a stringified class name. # See https://doorkeeper.gitbook.io/guides/configuration/other-configurations#custom-controllers # # base_controller 'ApplicationController' # Reuse access token for the same resource owner within an application (disabled by default). # # This option protects your application from creating new tokens before old **valid** one becomes # expired so your database doesn't bloat. Keep in mind that when this option is enabled Doorkeeper # doesn't update existing token expiration time, it will create a new token instead if no active matching # token found for the application, resources owner and/or set of scopes. # Rationale: https://github.com/doorkeeper-gem/doorkeeper/issues/383 # # You can not enable this option together with +hash_token_secrets+. # # reuse_access_token # In case you enabled `reuse_access_token` option Doorkeeper will try to find matching # token using `matching_token_for` Access Token API that searches for valid records # in batches in order not to pollute the memory with all the database records. By default # Doorkeeper uses batch size of 10 000 records. You can increase or decrease this value # depending on your needs and server capabilities. # # token_lookup_batch_size 10_000 # Set a limit for token_reuse if using reuse_access_token option # # This option limits token_reusability to some extent. # If not set then access_token will be reused unless it expires. # Rationale: https://github.com/doorkeeper-gem/doorkeeper/issues/1189 # # This option should be a percentage(i.e. (0,100]) # # token_reuse_limit 100 # Only allow one valid access token obtained via client credentials # per client. If a new access token is obtained before the old one # expired, the old one gets revoked (disabled by default) # # When enabling this option, make sure that you do not expect multiple processes # using the same credentials at the same time (e.g. web servers spanning # multiple machines and/or processes). # # revoke_previous_client_credentials_token # Hash access and refresh tokens before persisting them. # This will disable the possibility to use +reuse_access_token+ # since plain values can no longer be retrieved. # # Note: If you are already a user of doorkeeper and have existing tokens # in your installation, they will be invalid without adding 'fallback: :plain'. # # hash_token_secrets # By default, token secrets will be hashed using the # +Doorkeeper::Hashing::SHA256+ strategy. # # If you wish to use another hashing implementation, you can override # this strategy as follows: # # hash_token_secrets using: '::Doorkeeper::Hashing::MyCustomHashImpl' # # Keep in mind that changing the hashing function will invalidate all existing # secrets, if there are any. # Hash application secrets before persisting them. # # hash_application_secrets # # By default, applications will be hashed # with the +Doorkeeper::SecretStoring::SHA256+ strategy. # # If you wish to use bcrypt for application secret hashing, uncomment # this line instead: # # hash_application_secrets using: '::Doorkeeper::SecretStoring::BCrypt' # When the above option is enabled, and a hashed token or secret is not found, # you can allow to fall back to another strategy. For users upgrading # doorkeeper and wishing to enable hashing, you will probably want to enable # the fallback to plain tokens. # # This will ensure that old access tokens and secrets # will remain valid even if the hashing above is enabled. # # This can be done by adding 'fallback: plain', e.g. : # # hash_application_secrets using: '::Doorkeeper::SecretStoring::BCrypt', fallback: :plain # Issue access tokens with refresh token (disabled by default), you may also # pass a block which accepts `context` to customize when to give a refresh # token or not. Similar to +custom_access_token_expires_in+, `context` has # the following properties: # # `client` - the OAuth client application (see Doorkeeper::OAuth::Client) # `grant_type` - the grant type of the request (see Doorkeeper::OAuth) # `scopes` - the requested scopes (see Doorkeeper::OAuth::Scopes) # use_refresh_token # Provide support for an owner to be assigned to each registered application (disabled by default) # Optional parameter confirmation: true (default: false) if you want to enforce ownership of # a registered application # NOTE: you must also run the rails g doorkeeper:application_owner generator # to provide the necessary support # enable_application_owner confirmation: true # Define access token scopes for your provider # For more information go to # https://doorkeeper.gitbook.io/guides/ruby-on-rails/scopes # # default_scopes :public # optional_scopes :write, :update default_scopes :read # Allows to restrict only certain scopes for grant_type. # By default, all the scopes will be available for all the grant types. # # Keys to this hash should be the name of grant_type and # values should be the array of scopes for that grant type. # Note: scopes should be from configured_scopes (i.e. default or optional) # # scopes_by_grant_type password: [:write], client_credentials: [:update] # Forbids creating/updating applications with arbitrary scopes that are # not in configuration, i.e. +default_scopes+ or +optional_scopes+. # (disabled by default) # # enforce_configured_scopes # Change the way client credentials are retrieved from the request object. # By default it retrieves first from the `HTTP_AUTHORIZATION` header, then # falls back to the `:client_id` and `:client_secret` params from the `params` object. # Check out https://github.com/doorkeeper-gem/doorkeeper/wiki/Changing-how-clients-are-authenticated # for more information on customization # # client_credentials :from_basic, :from_params # Change the way access token is authenticated from the request object. # By default it retrieves first from the `HTTP_AUTHORIZATION` header, then # falls back to the `:access_token` or `:bearer_token` params from the `params` object. # Check out https://github.com/doorkeeper-gem/doorkeeper/wiki/Changing-how-clients-are-authenticated # for more information on customization # # access_token_methods :from_bearer_authorization, :from_access_token_param, :from_bearer_param # Forces the usage of the HTTPS protocol in non-native redirect uris (enabled # by default in non-development environments). OAuth2 delegates security in # communication to the HTTPS protocol so it is wise to keep this enabled. # # Callable objects such as proc, lambda, block or any object that responds to # #call can be used in order to allow conditional checks (to allow non-SSL # redirects to localhost for example). # # force_ssl_in_redirect_uri !Rails.env.development? # # force_ssl_in_redirect_uri { |uri| uri.host != 'localhost' } # Specify what redirect URI's you want to block during Application creation. # Any redirect URI is allowed by default. # # You can use this option in order to forbid URI's with 'javascript' scheme # for example. # # forbid_redirect_uri { |uri| uri.scheme.to_s.downcase == 'javascript' } # Allows to set blank redirect URIs for Applications in case Doorkeeper configured # to use URI-less OAuth grant flows like Client Credentials or Resource Owner # Password Credentials. The option is on by default and checks configured grant # types, but you **need** to manually drop `NOT NULL` constraint from `redirect_uri` # column for `oauth_applications` database table. # # You can completely disable this feature with: # # allow_blank_redirect_uri false # # Or you can define your custom check: # # allow_blank_redirect_uri do |grant_flows, client| # client.superapp? # end allow_blank_redirect_uri false # Specify how authorization errors should be handled. # By default, doorkeeper renders json errors when access token # is invalid, expired, revoked or has invalid scopes. # # If you want to render error response yourself (i.e. rescue exceptions), # set +handle_auth_errors+ to `:raise` and rescue Doorkeeper::Errors::InvalidToken # or following specific errors: # # Doorkeeper::Errors::TokenForbidden, Doorkeeper::Errors::TokenExpired, # Doorkeeper::Errors::TokenRevoked, Doorkeeper::Errors::TokenUnknown # # handle_auth_errors :raise # Customize token introspection response. # Allows to add your own fields to default one that are required by the OAuth spec # for the introspection response. It could be `sub`, `aud` and so on. # This configuration option can be a proc, lambda or any Ruby object responds # to `.call` method and result of it's invocation must be a Hash. # # custom_introspection_response do |token, context| # { # "sub": "Z5O3upPC88QrAjx00dis", # "aud": "https://protected.example.net/resource", # "username": User.find(token.resource_owner_id).username # } # end # # or # # custom_introspection_response CustomIntrospectionResponder # Specify what grant flows are enabled in array of Strings. The valid # strings and the flows they enable are: # # "authorization_code" => Authorization Code Grant Flow # "implicit" => Implicit Grant Flow # "password" => Resource Owner Password Credentials Grant Flow # "client_credentials" => Client Credentials Grant Flow # # If not specified, Doorkeeper enables authorization_code and # client_credentials. # # implicit and password grant flows have risks that you should understand # before enabling: # https://datatracker.ietf.org/doc/html/rfc6819#section-4.4.2 # https://datatracker.ietf.org/doc/html/rfc6819#section-4.4.3 # grant_flows %w[authorization_code] # Allows to customize OAuth grant flows that +each+ application support. # You can configure a custom block (or use a class respond to `#call`) that must # return `true` in case Application instance supports requested OAuth grant flow # during the authorization request to the server. This configuration +doesn't+ # set flows per application, it only allows to check if application supports # specific grant flow. # # For example you can add an additional database column to `oauth_applications` table, # say `t.array :grant_flows, default: []`, and store allowed grant flows that can # be used with this application there. Then when authorization requested Doorkeeper # will call this block to check if specific Application (passed with client_id and/or # client_secret) is allowed to perform the request for the specific grant type # (authorization, password, client_credentials, etc). # # Example of the block: # # ->(flow, client) { client.grant_flows.include?(flow) } # # In case this option invocation result is `false`, Doorkeeper server returns # :unauthorized_client error and stops the request. # # @param allow_grant_flow_for_client [Proc] Block or any object respond to #call # @return [Boolean] `true` if allow or `false` if forbid the request # # allow_grant_flow_for_client do |grant_flow, client| # # `grant_flows` is an Array column with grant # # flows that application supports # # client.grant_flows.include?(grant_flow) # end # If you need arbitrary Resource Owner-Client authorization you can enable this option # and implement the check your need. Config option must respond to #call and return # true in case resource owner authorized for the specific application or false in other # cases. # # Be default all Resource Owners are authorized to any Client (application). # # authorize_resource_owner_for_client do |client, resource_owner| # resource_owner.admin? || client.owners_allowlist.include?(resource_owner) # end # Allows additional data fields to be sent while granting access to an application, # and for this additional data to be included in subsequently generated access tokens. # The 'authorizations/new' page will need to be overridden to include this additional data # in the request params when granting access. The access grant and access token models # will both need to respond to these additional data fields, and have a database column # to store them in. # # Example: # You have a multi-tenanted platform and want to be able to grant access to a specific # tenant, rather than all the tenants a user has access to. You can use this config # option to specify that a ':tenant_id' will be passed when authorizing. This tenant_id # will be included in the access tokens. When a request is made with one of these access # tokens, you can check that the requested data belongs to the specified tenant. # # Default value is an empty Array: [] # custom_access_token_attributes [:tenant_id] custom_access_token_attributes [:company_id] # Hook into the strategies' request & response life-cycle in case your # application needs advanced customization or logging: # # before_successful_strategy_response do |request| # puts "BEFORE HOOK FIRED! #{request}" # end # # after_successful_strategy_response do |request, response| # puts "AFTER HOOK FIRED! #{request}, #{response}" # end # Hook into Authorization flow in order to implement Single Sign Out # or add any other functionality. Inside the block you have an access # to `controller` (authorizations controller instance) and `context` # (Doorkeeper::OAuth::Hooks::Context instance) which provides pre auth # or auth objects with issued token based on hook type (before or after). # # before_successful_authorization do |controller, context| # Rails.logger.info(controller.request.params.inspect) # # Rails.logger.info(context.pre_auth.inspect) # end # # after_successful_authorization do |controller, context| # controller.session[:logout_urls] << # Doorkeeper::Application # .find_by(controller.request.params.slice(:redirect_uri)) # .logout_uri # # Rails.logger.info(context.auth.inspect) # Rails.logger.info(context.issued_token) # end # Under some circumstances you might want to have applications auto-approved, # so that the user skips the authorization step. # For example if dealing with a trusted application. # # skip_authorization do |resource_owner, client| # client.superapp? or resource_owner.admin? # end # Configure custom constraints for the Token Introspection request. # By default this configuration option allows to introspect a token by another # token of the same application, OR to introspect the token that belongs to # authorized client (from authenticated client) OR when token doesn't # belong to any client (public token). Otherwise requester has no access to the # introspection and it will return response as stated in the RFC. # # Block arguments: # # @param token [Doorkeeper::AccessToken] # token to be introspected # # @param authorized_client [Doorkeeper::Application] # authorized client (if request is authorized using Basic auth with # Client Credentials for example) # # @param authorized_token [Doorkeeper::AccessToken] # Bearer token used to authorize the request # # In case the block returns `nil` or `false` introspection responses with 401 status code # when using authorized token to introspect, or you'll get 200 with { "active": false } body # when using authorized client to introspect as stated in the # RFC 7662 section 2.2. Introspection Response. # # Using with caution: # Keep in mind that these three parameters pass to block can be nil as following case: # `authorized_client` is nil if and only if `authorized_token` is present, and vice versa. # `token` will be nil if and only if `authorized_token` is present. # So remember to use `&` or check if it is present before calling method on # them to make sure you doesn't get NoMethodError exception. # # You can define your custom check: # # allow_token_introspection do |token, authorized_client, authorized_token| # if authorized_token # # customize: require `introspection` scope # authorized_token.application == token&.application || # authorized_token.scopes.include?("introspection") # elsif token.application # # `protected_resource` is a new database boolean column, for example # authorized_client == token.application || authorized_client.protected_resource? # else # # public token (when token.application is nil, token doesn't belong to any application) # true # end # end # # Or you can completely disable any token introspection: # # allow_token_introspection false # # If you need to block the request at all, then configure your routes.rb or web-server # like nginx to forbid the request. allow_token_introspection false # WWW-Authenticate Realm (default: "Doorkeeper"). # # realm "Doorkeeper" end ```

Ruby version: 3.1.0

Gemfile.lock:

Gemfile.lock content ``` GIT remote: https://github.com/heartcombo/devise.git revision: 025b1c873491908b346e4d394f54481ec18fb02c specs: devise (4.8.1) bcrypt (~> 3.0) orm_adapter (~> 0.1) railties (>= 4.1.0) responders warden (~> 1.2.3) GIT remote: https://github.com/oysterhr/hellosign-api.git revision: 280481725850274de6d3f777bb6ae568d5fd9276 specs: hellosign-api (1.0.7) faraday (>= 2.0.0) faraday-multipart (>= 1.0.0) mime-types (>= 3.0.0) multi_json (>= 1.0.0) PATH remote: engines/brain specs: brain (0.1.0) activejob airrecord (~> 1.0, >= 1.0.11) countries money-rails oyster-action pg rails (~> 7.0.4.3) strong_migrations PATH remote: engines/codat specs: codat (0.1.0) argo hairtrigger net-smtp oyster-action oyster-events rails (~> 7.0.2) strong_migrations PATH remote: engines/dealer specs: dealer (0.1.0) aasm (~> 5.0, >= 5.2.0) docusign_esign (~> 3.0, >= 3.19.0) faraday (>= 2.0) faraday-retry oyster-action oyster-common oyster-events paper_trail pdf-reader (~> 2.10) pg rails (~> 7.0.2) strong_migrations PATH remote: engines/expensify specs: expensify (0.1.0) argo oyster-action oyster-events rails (~> 7.0.2) sidekiq (~> 6.4.1) sidekiq-unique-jobs strong_migrations PATH remote: engines/iam specs: iam (0.1.0) oso-cloud (~> 1.0.0) pg rails (~> 7.0.4) PATH remote: engines/oyster-events specs: oyster-events (0.1.0) oyster-action rails (>= 7.0.2) rails_event_store ruby_event_store-rspec PATH remote: gems/argo specs: argo (0.1.0) activesupport webmock PATH remote: gems/oyster-action specs: oyster-action (0.1.0) activesupport PATH remote: gems/oyster-common specs: oyster-common (0.1.0) activemodel activesupport zeitwerk PATH remote: gems/sage-decision specs: sage-decision (0.1.0) activesupport rubytree GEM remote: https://******@gems.contribsys.com/ specs: sidekiq-pro (5.3.1) sidekiq (>= 6.3.0) GEM remote: https://rubygems.org/ specs: Ascii85 (1.1.0) aasm (5.2.0) concurrent-ruby (~> 1.0) actioncable (7.0.4.3) actionpack (= 7.0.4.3) activesupport (= 7.0.4.3) nio4r (~> 2.0) websocket-driver (>= 0.6.1) actionmailbox (7.0.4.3) actionpack (= 7.0.4.3) activejob (= 7.0.4.3) activerecord (= 7.0.4.3) activestorage (= 7.0.4.3) activesupport (= 7.0.4.3) mail (>= 2.7.1) net-imap net-pop net-smtp actionmailer (7.0.4.3) actionpack (= 7.0.4.3) actionview (= 7.0.4.3) activejob (= 7.0.4.3) activesupport (= 7.0.4.3) mail (~> 2.5, >= 2.5.4) net-imap net-pop net-smtp rails-dom-testing (~> 2.0) actionpack (7.0.4.3) actionview (= 7.0.4.3) activesupport (= 7.0.4.3) rack (~> 2.0, >= 2.2.0) rack-test (>= 0.6.3) rails-dom-testing (~> 2.0) rails-html-sanitizer (~> 1.0, >= 1.2.0) actiontext (7.0.4.3) actionpack (= 7.0.4.3) activerecord (= 7.0.4.3) activestorage (= 7.0.4.3) activesupport (= 7.0.4.3) globalid (>= 0.6.0) nokogiri (>= 1.8.5) actionview (7.0.4.3) activesupport (= 7.0.4.3) builder (~> 3.1) erubi (~> 1.4) rails-dom-testing (~> 2.0) rails-html-sanitizer (~> 1.1, >= 1.2.0) activejob (7.0.4.3) activesupport (= 7.0.4.3) globalid (>= 0.3.6) activemodel (7.0.4.3) activesupport (= 7.0.4.3) activerecord (7.0.4.3) activemodel (= 7.0.4.3) activesupport (= 7.0.4.3) activestorage (7.0.4.3) actionpack (= 7.0.4.3) activejob (= 7.0.4.3) activerecord (= 7.0.4.3) activesupport (= 7.0.4.3) marcel (~> 1.0) mini_mime (>= 1.1.0) activesupport (7.0.4.3) concurrent-ruby (~> 1.0, >= 1.0.2) i18n (>= 1.6, < 2) minitest (>= 5.1) tzinfo (~> 2.0) addressable (2.8.1) public_suffix (>= 2.0.2, < 6.0) administrate (0.17.0) actionpack (>= 5.0) actionview (>= 5.0) activerecord (>= 5.0) datetime_picker_rails (~> 0.0.7) jquery-rails (>= 4.0) kaminari (>= 1.0) momentjs-rails (~> 2.8) sassc-rails (~> 2.1) selectize-rails (~> 0.6) administrate-field-active_storage (0.4.1) administrate (>= 0.2.2) rails (>= 7.0) administrate-field-enum (0.0.9) administrate (~> 0.12) administrate-field-jsonb (0.4.6) administrate (< 1.0.0) rails (>= 4.2) administrate-field-nested_has_many (1.3.0) administrate (> 0.8, < 1) cocoon (~> 1.2, >= 1.2.11) afm (0.2.2) after_commit_everywhere (0.1.5) activerecord (>= 4.2) aggregate_root (2.4.1) ruby_event_store (= 2.4.1) airrecord (1.0.11) faraday (>= 1.0, < 3.0) faraday-net_http_persistent net-http-persistent akami (1.3.1) gyoku (>= 0.4.0) nokogiri analytics-ruby (2.0.13) arkency-command_bus (0.4.1) concurrent-ruby ast (2.4.2) awesome_print (1.8.0) aws-eventstream (1.1.0) aws-partitions (1.418.0) aws-sdk-core (3.111.2) aws-eventstream (~> 1, >= 1.0.2) aws-partitions (~> 1, >= 1.239.0) aws-sigv4 (~> 1.1) jmespath (~> 1.0) aws-sdk-kms (1.41.0) aws-sdk-core (~> 3, >= 3.109.0) aws-sigv4 (~> 1.1) aws-sdk-s3 (1.87.0) aws-sdk-core (~> 3, >= 3.109.0) aws-sdk-kms (~> 1) aws-sigv4 (~> 1.1) aws-sigv4 (1.2.2) aws-eventstream (~> 1, >= 1.0.2) backport (1.2.0) bcrypt (3.1.16) benchmark (0.2.0) bindex (0.8.1) bootsnap (1.11.1) msgpack (~> 1.2) brpoplpush-redis_script (0.1.3) concurrent-ruby (~> 1.0, >= 1.0.5) redis (>= 1.0, < 6) builder (3.2.4) bundle-audit (0.1.0) bundler-audit bundler-audit (0.9.1) bundler (>= 1.2.0, < 3) thor (~> 1.0) byebug (11.1.3) capybara (3.37.1) addressable matrix mini_mime (>= 0.1.3) nokogiri (~> 1.8) rack (>= 1.6.0) rack-test (>= 0.6.3) regexp_parser (>= 1.5, < 3.0) xpath (~> 3.2) capybara-lockstep (1.2.1) activesupport (>= 3.2) capybara (>= 2.0) ruby2_keywords selenium-webdriver (>= 3) childprocess (4.1.0) cocoon (1.2.15) code_owners (2.0.1) pathspec rake coderay (1.1.3) combine_pdf (1.0.22) matrix ruby-rc4 (>= 0.1.5) concurrent-ruby (1.2.0) config (3.1.0) deep_merge (~> 1.2, >= 1.2.1) dry-validation (~> 1.0, >= 1.0.0) connection_pool (2.3.0) cookiejar (0.3.3) countries (5.3.0) unaccent (~> 0.3) crack (0.4.5) rexml crass (1.0.6) datadog_api_client (2.1.0) httparty (~> 0.20, >= 0.20.0) zeitwerk (~> 2.6, >= 2.6.0) datetime_picker_rails (0.0.7) momentjs-rails (>= 2.8.1) db-query-matchers (0.11.0) activesupport (>= 4.0, < 7.1) rspec (>= 3.0) ddtrace (1.5.0) debase-ruby_core_source (>= 0.10.16, <= 0.10.17) libdatadog (~> 0.7.0.1.1) libddwaf (~> 1.3.0.2.0) msgpack debase-ruby_core_source (0.10.17) deep_merge (1.2.1) devise-pwned_password (0.1.9) devise (~> 4) pwned (~> 2.0.0) diff-lcs (1.5.0) digest (3.1.0) docile (1.3.5) docusign_esign (3.19.0) addressable (~> 2.7, >= 2.7.0) json (~> 2.1, >= 2.1.0) jwt (~> 2.2, >= 2.2.1) typhoeus (~> 1.0, >= 1.0.1) dogstatsd-ruby (5.5.0) domain_name (0.5.20190701) unf (>= 0.0.5, < 1.0.0) doorkeeper (5.6.5) railties (>= 5) dotenv (2.7.6) dotenv-rails (2.7.6) dotenv (= 2.7.6) railties (>= 3.2) down (5.3.1) addressable (~> 2.8) dry-cli (0.7.0) dry-configurable (0.13.0) concurrent-ruby (~> 1.0) dry-core (~> 0.6) dry-container (0.9.0) concurrent-ruby (~> 1.0) dry-configurable (~> 0.13, >= 0.13.0) dry-core (0.7.1) concurrent-ruby (~> 1.0) dry-inflector (0.2.1) dry-initializer (3.0.4) dry-logic (1.2.0) concurrent-ruby (~> 1.0) dry-core (~> 0.5, >= 0.5) dry-schema (1.8.0) concurrent-ruby (~> 1.0) dry-configurable (~> 0.13, >= 0.13.0) dry-core (~> 0.5, >= 0.5) dry-initializer (~> 3.0) dry-logic (~> 1.0) dry-types (~> 1.5) dry-types (1.5.1) concurrent-ruby (~> 1.0) dry-container (~> 0.3) dry-core (~> 0.5, >= 0.5) dry-inflector (~> 0.1, >= 0.1.2) dry-logic (~> 1.0, >= 1.0.2) dry-validation (1.7.0) concurrent-ruby (~> 1.0) dry-container (~> 0.7, >= 0.7.1) dry-core (~> 0.5, >= 0.5) dry-initializer (~> 3.0) dry-schema (~> 1.8, >= 1.8.0) e2mmap (0.1.0) em-http-request (1.1.7) addressable (>= 2.3.4) cookiejar (!= 0.3.1) em-socksify (>= 0.3) eventmachine (>= 1.0.3) http_parser.rb (>= 0.6.0) em-socksify (0.3.2) eventmachine (>= 1.0.0.beta.4) em-synchrony (1.0.6) eventmachine (>= 1.0.0.beta.1) erubi (1.11.0) et-orbi (1.2.6) tzinfo ethon (0.15.0) ffi (>= 1.15.0) eventmachine (1.2.7) eventmachine_httpserver (0.2.1) factory_bot (6.2.0) activesupport (>= 5.0.0) factory_bot_rails (6.2.0) factory_bot (~> 6.2.0) railties (>= 5.0.0) faker (2.20.0) i18n (>= 1.8.11, < 2) faraday (2.5.2) faraday-net_http (>= 2.0, < 3.1) ruby2_keywords (>= 0.0.4) faraday-multipart (1.0.4) multipart-post (~> 2) faraday-net_http (3.0.2) faraday-net_http_persistent (2.1.0) faraday (~> 2.5) net-http-persistent (~> 4.0) faraday-retry (2.0.0) faraday (~> 2.0) fast_excel (0.4.0) ffi (> 1.9, < 2) ffi (1.15.5) ffi-compiler (1.0.1) ffi (>= 1.0.0) rake formatador (1.1.0) fugit (1.5.2) et-orbi (~> 1.1, >= 1.1.8) raabro (~> 1.4) globalid (1.0.1) activesupport (>= 5.0) gon (6.4.0) actionpack (>= 3.0.20) i18n (>= 0.7) multi_json request_store (>= 1.0) good_migrations (0.2.1) activerecord (>= 3.1) railties (>= 3.1) google-protobuf (3.21.7) graphql (2.0.14) graphql-batch (0.5.1) graphql (>= 1.10, < 3) promise.rb (~> 0.7.2) graphql-pagination (2.0.1) graphql (~> 2.0) graphql-rails_logger (1.2.3) actionpack (> 5.0) activesupport (> 5.0) railties (> 5.0) rouge (~> 3.0) guard (2.18.0) formatador (>= 0.2.4) listen (>= 2.7, < 4.0) lumberjack (>= 1.0.12, < 2.0) nenv (~> 0.1) notiffany (~> 0.0) pry (>= 0.13.0) shellany (~> 0.0) thor (>= 0.18.1) guard-compat (1.2.1) guard-rspec (4.7.3) guard (~> 2.1) guard-compat (~> 1.1) rspec (>= 2.99.0, < 4.0) guard-rubocop (1.5.0) guard (~> 2.0) rubocop (< 2.0) gyoku (1.4.0) builder (>= 2.1.2) rexml (~> 3.0) hairtrigger (0.2.25) activerecord (>= 5.0, < 8) ruby2ruby (~> 2.4) ruby_parser (~> 3.10) hashdiff (1.0.1) hashery (2.1.2) hashie (5.0.0) http (5.1.0) addressable (~> 2.8) http-cookie (~> 1.0) http-form_data (~> 2.2) llhttp-ffi (~> 0.4.0) http-cookie (1.0.5) domain_name (~> 0.5) http-form_data (2.3.0) http_parser.rb (0.6.0) httparty (0.21.0) mini_mime (>= 1.0.0) multi_xml (>= 0.5.2) httpi (3.0.1) rack hubspot-api-client (14.5.2) json (~> 2.1, >= 2.1.0) require_all (~> 3.0.0) typhoeus (~> 1.4.0) humanize (2.5.1) i18n (1.12.0) concurrent-ruby (~> 1.0) ibandit (1.9.0) i18n ice_nine (0.11.2) image_processing (1.12.2) mini_magick (>= 4.9.5, < 5) ruby-vips (>= 2.0.17, < 3) inflection (1.0.0) intercom-rails (0.4.2) activesupport (> 3.0) jaro_winkler (1.5.4) jmespath (1.6.1) jquery-rails (4.5.0) rails-dom-testing (>= 1, < 3) railties (>= 4.2.0) thor (>= 0.14, < 2.0) json (2.6.2) json-schema (2.8.1) addressable (>= 2.4) jwt (2.6.0) kaminari (1.2.2) activesupport (>= 4.1.0) kaminari-actionview (= 1.2.2) kaminari-activerecord (= 1.2.2) kaminari-core (= 1.2.2) kaminari-actionview (1.2.2) actionview kaminari-core (= 1.2.2) kaminari-activerecord (1.2.2) activerecord kaminari-core (= 1.2.2) kaminari-core (1.2.2) knapsack (4.0.0) rake kramdown (2.4.0) rexml kramdown-parser-gfm (1.1.0) kramdown (~> 2.0) language_server-protocol (3.17.0.3) launchdarkly-server-sdk (6.4.0) concurrent-ruby (~> 1.1) http (>= 4.4.0, < 6.0.0) json (~> 2.3) ld-eventsource (= 2.2.1) semantic (~> 1.6) ld-eventsource (2.2.1) concurrent-ruby (~> 1.0) http (>= 4.4.1, < 6.0.0) libdatadog (0.7.0.1.1) libddwaf (1.3.0.2.0) ffi (~> 1.0) licensed (3.9.1) bundler (>= 1.10) json (>= 2.6.2) licensee (>= 9.15.2, < 10.0.0) parallel (>= 0.18.0) pathname-common_prefix (~> 0.0.1) reverse_markdown (>= 1, < 3) ruby-xxHash (~> 0.4) thor (>= 0.19) tomlrb (>= 1.2, < 3.0) licensee (9.15.3) dotenv (~> 2.0) octokit (>= 4.20, < 7.0) reverse_markdown (>= 1, < 3) rugged (>= 0.24, < 2.0) thor (>= 0.19, < 2.0) listen (3.7.1) rb-fsevent (~> 0.10, >= 0.10.3) rb-inotify (~> 0.9, >= 0.9.10) llhttp-ffi (0.4.0) ffi-compiler (~> 1.0) rake (~> 13.0) lograge (0.11.2) actionpack (>= 4) activesupport (>= 4) railties (>= 4) request_store (~> 1.0) loofah (2.19.1) crass (~> 1.0.2) nokogiri (>= 1.5.9) lumberjack (1.2.8) mail (2.7.1) mini_mime (>= 0.1.1) marcel (1.0.2) matrix (0.4.2) method_source (1.0.0) mime-types (3.4.1) mime-types-data (~> 3.2015) mime-types-data (3.2022.0105) mini_magick (4.11.0) mini_mime (1.1.2) mini_portile2 (2.8.1) minitest (5.16.3) momentjs-rails (2.29.1.1) railties (>= 3.1) monetize (1.12.0) money (~> 6.12) money (6.16.0) i18n (>= 0.6.4, <= 2) money-rails (1.15.0) activesupport (>= 3.0) monetize (~> 1.9) money (~> 6.13) railties (>= 3.0) msgpack (1.6.0) multi_json (1.15.0) multi_xml (0.6.0) multipart-post (2.2.3) mustermann (3.0.0) ruby2_keywords (~> 0.0.1) nenv (0.3.0) net-http-persistent (4.0.1) connection_pool (~> 2.2) net-imap (0.2.3) digest net-protocol strscan net-pop (0.1.1) digest net-protocol timeout net-protocol (0.1.3) timeout net-smtp (0.3.1) digest net-protocol timeout netsuite (0.9.2) savon (>= 2.3.0, != 2.13.0) nio4r (2.5.8) nokogiri (1.13.10) mini_portile2 (~> 2.8.0) racc (~> 1.4) nori (2.6.0) notiffany (0.1.3) nenv (~> 0.1) shellany (~> 0.0) oauth2 (1.4.11) faraday (>= 0.17.3, < 3.0) jwt (>= 1.0, < 3.0) multi_json (~> 1.3) multi_xml (~> 0.5) rack (>= 1.2, < 4) octokit (6.0.1) faraday (>= 1, < 3) sawyer (~> 0.9) omniauth (2.1.1) hashie (>= 3.4.6) rack (>= 2.2.3) rack-protection omniauth-google-oauth2 (0.8.1) jwt (>= 2.0) oauth2 (~> 1.1) omniauth (>= 1.1.1) omniauth-oauth2 (>= 1.6) omniauth-oauth2 (1.7.1) oauth2 (~> 1.4) omniauth (>= 1.9, < 3) omniauth-okta (2.0.0) omniauth (~> 2.0) omniauth-oauth2 (~> 1.7, >= 1.7.1) omniauth-rails_csrf_protection (1.0.0) actionpack (>= 4.2) omniauth (~> 2.0) orm_adapter (0.5.0) oso-cloud (1.0.0) faraday (~> 2.5.2) faraday-retry (~> 2.0.0) paper_trail (12.3.0) activerecord (>= 5.2) request_store (~> 1.1) parallel (1.22.1) parallel_tests (3.8.1) parallel paranoia (2.6.0) activerecord (>= 5.1, < 7.1) parser (3.2.1.1) ast (~> 2.4.1) pathname-common_prefix (0.0.1) pathspec (1.1.3) pdf-core (0.9.0) pdf-inspector (1.3.0) pdf-reader (>= 1.0, < 3.0.a) pdf-reader (2.10.0) Ascii85 (~> 1.0) afm (~> 0.2.1) hashery (~> 2.0) ruby-rc4 ttfunk pg (1.3.4) phone (1.2.3) plaid (17.2.0) faraday (>= 1.0.1, < 3.0) faraday-multipart (>= 1.0.1, < 2.0) possessive (1.0.1) postmark (1.22.0) json postmark-rails (0.22.0) actionmailer (>= 3.0.0) postmark (>= 1.21.3, < 2.0) prawn (2.4.0) pdf-core (~> 0.9.0) ttfunk (~> 1.7) prawn-table (0.2.2) prawn (>= 1.3.0, < 3.0.0) promise.rb (0.7.4) pry (0.13.1) coderay (~> 1.1) method_source (~> 1.0) pry-byebug (3.9.0) byebug (~> 11.0) pry (~> 0.13.0) pry-rails (0.3.9) pry (>= 0.10.4) public_suffix (5.0.1) puffing-billy (3.0.2) addressable (~> 2.5) em-http-request (~> 1.1, >= 1.1.0) em-synchrony eventmachine (~> 1.2) eventmachine_httpserver http_parser.rb (~> 0.6.0) multi_json puma (5.6.4) nio4r (~> 2.0) pwned (2.0.2) raabro (1.4.0) racc (1.6.2) rack (2.2.6.4) rack-attack (6.6.1) rack (>= 1.0, < 3) rack-cors (1.1.1) rack (>= 2.0.0) rack-protection (3.0.4) rack rack-proxy (0.7.4) rack rack-test (2.0.2) rack (>= 1.3) rack-timeout (0.6.0) rails (7.0.4.3) actioncable (= 7.0.4.3) actionmailbox (= 7.0.4.3) actionmailer (= 7.0.4.3) actionpack (= 7.0.4.3) actiontext (= 7.0.4.3) actionview (= 7.0.4.3) activejob (= 7.0.4.3) activemodel (= 7.0.4.3) activerecord (= 7.0.4.3) activestorage (= 7.0.4.3) activesupport (= 7.0.4.3) bundler (>= 1.15.0) railties (= 7.0.4.3) rails-controller-testing (1.0.5) actionpack (>= 5.0.1.rc1) actionview (>= 5.0.1.rc1) activesupport (>= 5.0.1.rc1) rails-dom-testing (2.0.3) activesupport (>= 4.2.0) nokogiri (>= 1.6) rails-html-sanitizer (1.4.4) loofah (~> 2.19, >= 2.19.1) rails_event_store (2.4.1) activejob (>= 3.0) activemodel (>= 3.0) activesupport (>= 3.0) aggregate_root (= 2.4.1) arkency-command_bus (>= 0.4) rails_event_store_active_record (= 2.4.1) ruby_event_store (= 2.4.1) ruby_event_store-browser (= 2.4.1) rails_event_store_active_record (2.4.1) activerecord (>= 6.0) ruby_event_store (= 2.4.1) railties (7.0.4.3) actionpack (= 7.0.4.3) activesupport (= 7.0.4.3) method_source rake (>= 12.2) thor (~> 1.0) zeitwerk (~> 2.5) rainbow (3.1.1) rake (13.0.6) rb-fsevent (0.11.1) rb-inotify (0.10.1) ffi (~> 1.0) redis (4.8.0) redis-namespace (1.8.2) redis (>= 3.0.4) regexp_parser (2.7.0) request_store (1.5.1) rack (>= 1.4) require_all (3.0.0) responders (3.0.1) actionpack (>= 5.0) railties (>= 5.0) reverse_markdown (2.1.1) nokogiri rexml (3.2.5) roo (2.9.0) nokogiri (~> 1) rubyzip (>= 1.3.0, < 3.0.0) rouge (3.30.0) rspec (3.11.0) rspec-core (~> 3.11.0) rspec-expectations (~> 3.11.0) rspec-mocks (~> 3.11.0) rspec-core (3.11.0) rspec-support (~> 3.11.0) rspec-expectations (3.11.0) diff-lcs (>= 1.2.0, < 2.0) rspec-support (~> 3.11.0) rspec-github (2.3.1) rspec-core (~> 3.0) rspec-github-actions-formatter (0.2.0) rspec-mocks (3.11.0) diff-lcs (>= 1.2.0, < 2.0) rspec-support (~> 3.11.0) rspec-rails (5.1.1) actionpack (>= 5.2) activesupport (>= 5.2) railties (>= 5.2) rspec-core (~> 3.10) rspec-expectations (~> 3.10) rspec-mocks (~> 3.10) rspec-support (~> 3.10) rspec-retry (0.6.2) rspec-core (> 3.3) rspec-support (3.11.0) rspec_junit_formatter (0.5.1) rspec-core (>= 2, < 4, != 2.12.0) rubocop (1.44.1) json (~> 2.3) parallel (~> 1.10) parser (>= 3.2.0.0) rainbow (>= 2.2.2, < 4.0) regexp_parser (>= 1.8, < 3.0) rexml (>= 3.2.5, < 4.0) rubocop-ast (>= 1.24.1, < 2.0) ruby-progressbar (~> 1.7) unicode-display_width (>= 2.4.0, < 3.0) rubocop-ast (1.27.0) parser (>= 3.2.1.0) rubocop-performance (1.15.2) rubocop (>= 1.7.0, < 2.0) rubocop-ast (>= 0.4.0) rubocop-rails (2.14.2) activesupport (>= 4.2.0) rack (>= 1.1) rubocop (>= 1.7.0, < 2.0) rubocop-rspec (2.10.0) rubocop (~> 1.19) ruby-calendarific (1.0.1) ruby-progressbar (1.13.0) ruby-rc4 (0.1.5) ruby-vips (2.1.4) ffi (~> 1.12) ruby-xxHash (0.4.0.2) ruby2_keywords (0.0.5) ruby2ruby (2.4.4) ruby_parser (~> 3.1) sexp_processor (~> 4.6) rubyXL (3.4.24) nokogiri (>= 1.10.8) rubyzip (>= 1.3.0) ruby_event_store (2.4.1) concurrent-ruby (~> 1.0, >= 1.1.6) ruby_event_store-browser (2.4.1) ruby_event_store (= 2.4.1) sinatra ruby_event_store-rspec (2.4.1) rspec (~> 3.0) ruby_parser (3.19.0) sexp_processor (~> 4.16) rubytree (2.0.0) json (~> 2.0, > 2.3.1) rubyzip (2.3.2) rufus-scheduler (3.8.1) fugit (~> 1.1, >= 1.1.6) rugged (1.5.0.1) sassc (2.4.0) ffi (~> 1.9) sassc-rails (2.1.2) railties (>= 4.0.0) sassc (>= 2.0) sprockets (> 3.0) sprockets-rails tilt savon (2.14.0) akami (~> 1.2) builder (>= 2.1.2) gyoku (~> 1.2) httpi (>= 2.4.5) mail (~> 2.5) nokogiri (>= 1.8.1) nori (~> 2.4) wasabi (~> 3.4) sawyer (0.9.2) addressable (>= 2.3.5) faraday (>= 0.17.3, < 3) scenic (1.6.0) activerecord (>= 4.0.0) railties (>= 4.0.0) scientist (1.6.3) selectize-rails (0.12.6) selenium-webdriver (4.6.1) childprocess (>= 0.5, < 5.0) rexml (~> 3.2, >= 3.2.5) rubyzip (>= 1.2.2, < 3.0) websocket (~> 1.0) semantic (1.6.1) sentry-rails (5.2.1) railties (>= 5.0) sentry-ruby-core (~> 5.2.1) sentry-ruby (5.2.1) concurrent-ruby (~> 1.0, >= 1.0.2) sentry-ruby-core (= 5.2.1) sentry-ruby-core (5.2.1) concurrent-ruby sentry-sidekiq (5.2.1) sentry-ruby-core (~> 5.2.1) sidekiq (>= 3.0) sexp_processor (4.16.0) shellany (0.0.1) shoulda-matchers (5.1.0) activesupport (>= 5.2.0) sidekiq (6.4.2) connection_pool (>= 2.2.2) rack (~> 2.0) redis (>= 4.2.0) sidekiq-failures (1.0.1) sidekiq (>= 4.0.0) sidekiq-scheduler (3.1.1) e2mmap redis (>= 3, < 5) rufus-scheduler (~> 3.2) sidekiq (>= 3) thwait tilt (>= 1.4.0) sidekiq-unique-jobs (7.1.29) brpoplpush-redis_script (> 0.1.1, <= 2.0.0) concurrent-ruby (~> 1.0, >= 1.0.5) redis (< 5.0) sidekiq (>= 5.0, < 7.0) thor (>= 0.20, < 3.0) simplecov (0.21.2) docile (~> 1.1) simplecov-html (~> 0.11) simplecov_json_formatter (~> 0.1) simplecov-html (0.12.3) simplecov_json_formatter (0.1.2) sinatra (3.0.4) mustermann (~> 3.0) rack (~> 2.2, >= 2.2.4) rack-protection (= 3.0.4) tilt (~> 2.0) slack-notifier (2.4.0) solargraph (0.47.2) backport (~> 1.2) benchmark bundler (>= 1.17.2) diff-lcs (~> 1.4) e2mmap jaro_winkler (~> 1.5) kramdown (~> 2.3) kramdown-parser-gfm (~> 1.1) parser (~> 3.0) reverse_markdown (>= 1.0.5, < 3) rubocop (>= 0.52) thor (~> 1.0) tilt (~> 2.0) yard (~> 0.9, >= 0.9.24) spring (3.1.1) spring-commands-rspec (1.0.4) spring (>= 0.9.1) sprockets (4.1.1) concurrent-ruby (~> 1.0) rack (> 1, < 3) sprockets-rails (3.4.2) actionpack (>= 5.2) activesupport (>= 5.2) sprockets (>= 3.0.0) standard (1.24.3) language_server-protocol (~> 3.17.0.2) rubocop (= 1.44.1) rubocop-performance (= 1.15.2) stripe (5.30.0) strong_migrations (1.1.0) activerecord (>= 5.2) strscan (3.0.3) thor (1.2.1) thwait (0.2.0) e2mmap tilt (2.0.11) timeout (0.3.0) tomlrb (2.0.3) ttfunk (1.7.0) typhoeus (1.4.0) ethon (>= 0.9.0) tzinfo (2.0.5) concurrent-ruby (~> 1.0) tzinfo-data (1.2022.3) tzinfo (>= 1.0.0) unaccent (0.4.0) unf (0.1.4) unf_ext unf_ext (0.0.8.2) unicode-display_width (2.4.2) vcr (6.1.0) vite_rails (3.0.13) railties (>= 5.1, < 8) vite_ruby (~> 3.0, >= 3.2.2) vite_ruby (3.2.13) dry-cli (~> 0.7.0) rack-proxy (~> 0.6, >= 0.6.1) zeitwerk (~> 2.2) warden (1.2.9) rack (>= 2.0.9) wasabi (3.8.0) addressable httpi (~> 3.0) nokogiri (>= 1.4.2) web-console (4.2.0) actionview (>= 6.0.0) activemodel (>= 6.0.0) bindex (>= 0.4.0) railties (>= 6.0.0) webdrivers (5.2.0) nokogiri (~> 1.6) rubyzip (>= 1.3.0) selenium-webdriver (~> 4.0) webmock (3.18.1) addressable (>= 2.8.0) crack (>= 0.3.2) hashdiff (>= 0.4.0, < 2.0.0) webrick (1.7.0) websocket (1.2.9) websocket-driver (0.7.5) websocket-extensions (>= 0.1.0) websocket-extensions (0.1.5) wisper (2.0.1) wisper-rspec (1.1.0) write_xlsx (1.09.3) rubyzip (>= 1.0.0) zip-zip xpath (3.2.0) nokogiri (~> 1.8) yard (0.9.28) webrick (~> 1.7.0) zeitwerk (2.6.6) zendesk_api (1.38.0.rc1) faraday (> 2.0.0) faraday-multipart hashie (>= 3.5.2, < 6.0.0) inflection mini_mime multipart-post (~> 2.0) zip-zip (0.3) rubyzip (>= 1.0.0) PLATFORMS ruby DEPENDENCIES aasm (~> 5.0, >= 5.2.0) administrate administrate-field-active_storage administrate-field-enum administrate-field-jsonb administrate-field-nested_has_many after_commit_everywhere (~> 0.1, >= 0.1.5) analytics-ruby (~> 2.0.0) argo! awesome_print aws-sdk-s3 bootsnap (>= 1.4.2) brain! bundle-audit byebug capybara (>= 3.37.1) capybara-lockstep codat! code_owners combine_pdf config connection_pool countries datadog_api_client (~> 2.1.0) db-query-matchers ddtrace (~> 1.0) dealer! devise! devise-pwned_password dogstatsd-ruby doorkeeper dotenv-rails down expensify! factory_bot_rails faker faraday (~> 2.0) fast_excel fugit gon good_migrations google-protobuf (~> 3.21) graphql graphql-batch graphql-pagination graphql-rails_logger guard guard-rspec guard-rubocop hairtrigger hellosign-api! httparty hubspot-api-client humanize iam! ibandit (~> 1.9.0) ice_nine (~> 0.11.2) image_processing intercom-rails json-schema (~> 2.8) jwt kaminari-activerecord knapsack launchdarkly-server-sdk licensed lograge mail matrix money money-rails multipart-post (~> 2.1) net-imap net-pop net-smtp netsuite omniauth (>= 2.1.0) omniauth-google-oauth2 omniauth-okta omniauth-rails_csrf_protection oyster-action! oyster-common! oyster-events! paper_trail parallel_tests paranoia parser pdf-inspector pg (>= 0.18, < 2.0) phone plaid possessive (~> 1.0, >= 1.0.1) postmark-rails prawn prawn-table pry-byebug pry-rails puffing-billy puma (~> 5.6) rack-attack rack-cors rack-timeout rails (~> 7.0.4, >= 7.0.4.3) rails-controller-testing rails_event_store rainbow redis redis-namespace roo (~> 2.9.0) rspec-github rspec-github-actions-formatter rspec-rails (~> 5.1.1) rspec-retry rspec_junit_formatter rubocop rubocop-rails rubocop-rspec (~> 2.8) ruby-calendarific (~> 1.0) rubyXL (>= 3.4.24, < 4.0) rubyzip sage-decision! scenic scientist selenium-webdriver sentry-rails (~> 5.2.1) sentry-ruby (~> 5.2.0) sentry-sidekiq (~> 5.2.1) shoulda-matchers sidekiq-failures sidekiq-pro! sidekiq-scheduler sidekiq-unique-jobs (~> 7.1.29) simplecov slack-notifier solargraph spring (~> 3.1) spring-commands-rspec standard (~> 1.10) stripe (~> 5.30.0) strong_migrations tzinfo-data vcr vite_rails web-console (>= 4.2.0) webdrivers webmock (>= 3.18.1) wisper (~> 2.0.1) wisper-rspec (~> 1.1) write_xlsx (~> 1.09) zendesk_api (= 1.38.0.rc1) RUBY VERSION ruby 3.1.2p20 BUNDLED WITH 2.3.7 ```
justinko commented 1 year ago

I've had to add this to get around the error:

Doorkeeper::Config::Validations.prepend(Module.new do
  def validate_custom_access_token_attributes; end
end)
raivil commented 1 year ago

Seems the same/related to https://github.com/doorkeeper-gem/doorkeeper/issues/1642

nbulaj commented 1 year ago

Should be fixed with 5.6.6 release @matthewheath