From bc320d6cec5900fa2fd9d3a46480e242111caaca Mon Sep 17 00:00:00 2001 From: Eugen Rochko Date: Sat, 12 Mar 2022 04:14:25 +0100 Subject: [PATCH] Fix `POST /api/v1/emails/confirmations` not being available after sign-up (#17743) --- .../api/v1/emails/confirmations_controller.rb | 4 +- .../emails/confirmations_controller_spec.rb | 64 +++++++++++++++++++ 2 files changed, 66 insertions(+), 2 deletions(-) create mode 100644 spec/controllers/api/v1/emails/confirmations_controller_spec.rb diff --git a/app/controllers/api/v1/emails/confirmations_controller.rb b/app/controllers/api/v1/emails/confirmations_controller.rb index f1d9954d0..3faaea2fb 100644 --- a/app/controllers/api/v1/emails/confirmations_controller.rb +++ b/app/controllers/api/v1/emails/confirmations_controller.rb @@ -1,7 +1,7 @@ # frozen_string_literal: true class Api::V1::Emails::ConfirmationsController < Api::BaseController - before_action :doorkeeper_authorize! + before_action -> { doorkeeper_authorize! :write, :'write:accounts' } before_action :require_user_owned_by_application! before_action :require_user_not_confirmed! @@ -19,6 +19,6 @@ class Api::V1::Emails::ConfirmationsController < Api::BaseController end def require_user_not_confirmed! - render json: { error: 'This method is only available while the e-mail is awaiting confirmation' }, status: :forbidden if current_user.confirmed? || current_user.unconfirmed_email.blank? + render json: { error: 'This method is only available while the e-mail is awaiting confirmation' }, status: :forbidden unless !current_user.confirmed? || current_user.unconfirmed_email.present? end end diff --git a/spec/controllers/api/v1/emails/confirmations_controller_spec.rb b/spec/controllers/api/v1/emails/confirmations_controller_spec.rb new file mode 100644 index 000000000..15ac31cbc --- /dev/null +++ b/spec/controllers/api/v1/emails/confirmations_controller_spec.rb @@ -0,0 +1,64 @@ +require 'rails_helper' + +RSpec.describe Api::V1::Emails::ConfirmationsController, type: :controller do + let(:confirmed_at) { nil } + let(:user) { Fabricate(:user, confirmed_at: confirmed_at) } + let(:app) { Fabricate(:application) } + let(:token) { Fabricate(:accessible_access_token, resource_owner_id: user.id, scopes: scopes, application: app) } + let(:scopes) { 'write' } + + describe '#create' do + context 'with an oauth token' do + before do + allow(controller).to receive(:doorkeeper_token) { token } + end + + context 'from a random app' do + it 'returns http forbidden' do + post :create + expect(response).to have_http_status(:forbidden) + end + end + + context 'from an app that created the account' do + before do + user.update(created_by_application: token.application) + end + + context 'when the account is already confirmed' do + let(:confirmed_at) { Time.now.utc } + + it 'returns http forbidden' do + post :create + expect(response).to have_http_status(:forbidden) + end + + context 'but user changed e-mail and has not confirmed it' do + before do + user.update(email: 'foo@bar.com') + end + + it 'returns http success' do + post :create + expect(response).to have_http_status(:success) + end + end + end + + context 'when the account is unconfirmed' do + it 'returns http success' do + post :create + expect(response).to have_http_status(:success) + end + end + end + end + + context 'without an oauth token' do + it 'returns http unauthorized' do + post :create + expect(response).to have_http_status(:unauthorized) + end + end + end +end