diff --git a/app/controllers/api/v1/invites_controller.rb b/app/controllers/api/v1/invites_controller.rb index ea17ba74038..7b24cec7918 100644 --- a/app/controllers/api/v1/invites_controller.rb +++ b/app/controllers/api/v1/invites_controller.rb @@ -7,6 +7,7 @@ class Api::V1::InvitesController < Api::BaseController skip_around_action :set_locale before_action :set_invite + before_action :check_valid_usage! before_action :check_enabled_registrations! # Override `current_user` to avoid reading session cookies @@ -22,9 +23,11 @@ class Api::V1::InvitesController < Api::BaseController @invite = Invite.find_by!(code: params[:invite_code]) end - def check_enabled_registrations! - return render json: { error: I18n.t('invites.invalid') }, status: 401 unless @invite.valid_for_use? + def check_valid_usage! + render json: { error: I18n.t('invites.invalid') }, status: 401 unless @invite.valid_for_use? + end + def check_enabled_registrations! raise Mastodon::NotPermittedError unless allowed_registration?(request.remote_ip, @invite) end end diff --git a/spec/requests/invite_spec.rb b/spec/requests/invite_spec.rb index ba046453890..027b0fc738d 100644 --- a/spec/requests/invite_spec.rb +++ b/spec/requests/invite_spec.rb @@ -6,13 +6,49 @@ RSpec.describe 'invites' do let(:invite) { Fabricate(:invite) } context 'when requesting a JSON document' do - it 'returns a JSON document with expected attributes' do - get "/invite/#{invite.code}", headers: { 'Accept' => 'application/activity+json' } + subject { get "/invite/#{invite.code}", headers: { 'Accept' => 'application/activity+json' } } - expect(response).to have_http_status(200) - expect(response.media_type).to eq 'application/json' + context 'when invite is valid' do + it 'returns a JSON document with expected attributes' do + subject - expect(response.parsed_body[:invite_code]).to eq invite.code + expect(response) + .to have_http_status(200) + expect(response.media_type) + .to eq 'application/json' + expect(response.parsed_body) + .to include(invite_code: invite.code) + end + end + + context 'when invite is expired' do + before { invite.update(expires_at: 3.days.ago) } + + it 'returns a JSON document with error details' do + subject + + expect(response) + .to have_http_status(401) + expect(response.media_type) + .to eq 'application/json' + expect(response.parsed_body) + .to include(error: I18n.t('invites.invalid')) + end + end + + context 'when user IP is blocked' do + before { Fabricate :ip_block, severity: :sign_up_block, ip: '127.0.0.1' } + + it 'returns a JSON document with error details' do + subject + + expect(response) + .to have_http_status(403) + expect(response.media_type) + .to eq 'application/json' + expect(response.parsed_body) + .to include(error: /This action is not allowed/) + end end end