module Roda::RodaPlugins::RouteCsrf::InstanceMethods

def csrf_invalid_message(opts)

Returns nil if the CSRF token is valid.
Returns error message string if the CSRF token is not valid.
def csrf_invalid_message(opts)
  opts = opts.empty? ? csrf_options : csrf_options.merge(opts)
  method = request.request_method
  unless opts[:check_request_methods].include?(method)
    return
  end
  unless encoded_token = opts[:token]
    encoded_token = case opts[:check_header]
    when :only
      env[opts[:env_header]]
    when true
      return (csrf_invalid_message(opts.merge(:check_header=>false)) && csrf_invalid_message(opts.merge(:check_header=>:only)))
    else
      @_request.params[opts[:field]]
    end
  end
  unless encoded_token.is_a?(String)
    return "encoded token is not a string"
  end
  if (rack_csrf_key = opts[:upgrade_from_rack_csrf_key]) && (rack_csrf_value = session[rack_csrf_key]) && csrf_compare(rack_csrf_value, encoded_token)
    return
  end
  # 31 byte random initialization vector
  # 32 byte HMAC
  # 63 bytes total
  # 84 bytes when base64 encoded
  unless encoded_token.bytesize == 84
    return "encoded token length is not 84"
  end
  begin
    submitted_hmac = Base64.strict_decode64(encoded_token)
  rescue ArgumentError
    return "encoded token is not valid base64"
  end
  random_data = submitted_hmac.slice!(0...31)
  if csrf_compare(csrf_hmac(random_data, method, @_request.path), submitted_hmac)
    return
  end
  if opts[:require_request_specific_tokens]
    "decoded token is not valid for request method and path"
  else
    unless csrf_compare(csrf_hmac(random_data, '', ''), submitted_hmac)
      "decoded token is not valid for either request method and path or for blank method and path"
    end
  end
end