Initial commit
This commit is contained in:
267
app/api/v2/resource/phones.rb
Normal file
267
app/api/v2/resource/phones.rb
Normal file
@@ -0,0 +1,267 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
module API::V2
|
||||
module Resource
|
||||
class Phones < Grape::API
|
||||
rescue_from(Twilio::REST::RestError) do |error|
|
||||
Rails.logger.error "Twilio Client Error: #{error.message}"
|
||||
error!({ errors: [twilio_dictionary_error(error.code)] }, 422)
|
||||
end
|
||||
|
||||
helpers do
|
||||
def validate_phone!(phone_number, landline = nil)
|
||||
phone_number = Phone.international(phone_number)
|
||||
|
||||
error!({ errors: ['resource.phone.invalid_num'] }, 400) \
|
||||
unless Phone.valid?(phone_number)
|
||||
|
||||
error!({ errors: ['resource.phone.number_exist'] }, 400) \
|
||||
if Phone.verified.find_by_number(phone_number) && landline.blank?
|
||||
|
||||
# check phone is landline
|
||||
error!({ errors: ['resource.phone.number_not_landline'] }, 400) \
|
||||
if landline.present? && phone_number[2] == '9'
|
||||
end
|
||||
end
|
||||
|
||||
desc 'mobile related routes'
|
||||
resource :mobiles do
|
||||
desc 'Returns list of user\'s phones',
|
||||
failure: [
|
||||
{ code: 401, message: 'Invalid bearer token' },
|
||||
],
|
||||
success: Entities::Phone
|
||||
get do
|
||||
present current_user.phones, with: Entities::Phone
|
||||
end
|
||||
|
||||
desc 'Add new mobile',
|
||||
failure: [
|
||||
{ code: 400, message: 'Required params are empty' },
|
||||
{ code: 401, message: 'Invalid bearer token' },
|
||||
{ code: 404, message: 'Record is not found' },
|
||||
{ code: 422, message: 'Validation errors' }
|
||||
],
|
||||
success: { code: 200, message: 'New phone was added' }
|
||||
params do
|
||||
requires :phone_number,
|
||||
type: String,
|
||||
allow_blank: false,
|
||||
desc: 'Phone number with country code(in iran +98)'
|
||||
optional :channel,
|
||||
type: String,
|
||||
default: 'sms',
|
||||
values: { value: -> { Phone::TWILIO_CHANNELS }, message: 'resource.phone.invalid_channel'},
|
||||
desc: 'The verification method to use(this param is for legacy structure must be sms)'
|
||||
end
|
||||
post do
|
||||
error!({ errors: ['kyc_follow_steps'] }, 403) if current_user.kyc_info.dig(:step) < 2
|
||||
|
||||
error!({ errors: ['resource.phone.code_doesnt_expired'] }, 422) if current_user.read_cache('register-mobile')
|
||||
declared_params = declared(params)
|
||||
validate_phone!(declared_params[:phone_number])
|
||||
phone_number = Phone.international(declared_params[:phone_number])
|
||||
# label = current_user.labels.find_by(key: 'access_phone', value: 'verified')
|
||||
# error!({ errors: ['resource.phone.exists'] }, 422) if label.present?
|
||||
if current_user.mobile('pending').present?
|
||||
current_user.mobile('pending').update(number: phone_number)
|
||||
else
|
||||
current_user.phones.create(number: phone_number, category: 'mobile')
|
||||
end
|
||||
# code_error!(phone.errors.details, 422) if phone.errors.any?
|
||||
error!({ errors: ['resource.phone.cant_send_message'] }, 422) unless KaveNegarSmsService.send_confirmation(current_user)
|
||||
status 200
|
||||
end
|
||||
|
||||
desc 'Resend activation code for mobile sms',
|
||||
failure: [
|
||||
{ code: 400, message: 'Required params are empty' },
|
||||
{ code: 401, message: 'Invalid bearer token' },
|
||||
{ code: 404, message: 'Record is not found' },
|
||||
{ code: 422, message: 'Validation errors' }
|
||||
],
|
||||
success: { code: 200, message: 'Activation code was resend' }
|
||||
params do
|
||||
requires :phone_number,
|
||||
type: String,
|
||||
allow_blank: false,
|
||||
desc: 'Phone number with country code( in iran +98 )'
|
||||
optional :channel,
|
||||
type: String,
|
||||
default: 'sms',
|
||||
values: { value: -> { Phone::TWILIO_CHANNELS }, message: 'resource.phone.invalid_channel'},
|
||||
desc: 'The verification method to use(this param is for legacy structure must be sms)'
|
||||
end
|
||||
# TODO you can delete this api and use above
|
||||
post '/send_code' do
|
||||
error!({ errors: ['resource.phone.code_doesnt_expired'] }, 422) if current_user.read_cache('register-mobile')
|
||||
declared_params = declared(params)
|
||||
validate_phone!(declared_params[:phone_number])
|
||||
|
||||
phone_number = Phone.international(declared_params[:phone_number])
|
||||
phone = current_user.phones.find_by_number(phone_number)
|
||||
error!({ errors: ['resource.phone.doesnt_exist'] }, 404) unless phone
|
||||
|
||||
KaveNegarSmsService.send_confirmation(current_user)
|
||||
status 200
|
||||
end
|
||||
|
||||
desc 'Verify a mobile(enter code and verify number)',
|
||||
failure: [
|
||||
{ code: 400, message: 'Required params are empty' },
|
||||
{ code: 401, message: 'Invalid bearer token' },
|
||||
{ code: 404, message: 'Record is not found' }
|
||||
],
|
||||
success: API::V2::Entities::UserWithFullInfo
|
||||
params do
|
||||
requires :phone_number,
|
||||
type: String,
|
||||
allow_blank: false,
|
||||
desc: 'phone number with country code(in iran with +98)'
|
||||
requires :verification_code,
|
||||
type: String,
|
||||
allow_blank: false,
|
||||
desc: 'Verification code from sms(this param is for legacy structure must be sms)'
|
||||
end
|
||||
post '/verify' do
|
||||
declared_params = declared(params)
|
||||
validate_phone!(declared_params[:phone_number])
|
||||
error!({ errors: ['resource.phone.doesnt_exist'] }, 404) unless current_user.mobile('pending')
|
||||
|
||||
unless TOTPServiceAction.new('register-mobile').validate?(current_user.uid, declared(params)[:verification_code])
|
||||
error!({ errors: ['resource.phone.verification_invalid'] }, 400)
|
||||
end
|
||||
current_user.delete_cache('register-mobile')
|
||||
pending_mobile = current_user.mobile('pending')
|
||||
last_verified_mobile = current_user.mobile('verified')
|
||||
if last_verified_mobile&.step == 'owner_phone'
|
||||
if pending_mobile.check_owner_ship
|
||||
last_verified_mobile.update(state: 'replaced')
|
||||
pending_mobile.update(validated_at: Time.current, state: 'verified', step: 'owner_phone')
|
||||
else
|
||||
pending_mobile.update(state: 'rejected')
|
||||
end
|
||||
elsif last_verified_mobile&.step == 'access_phone'
|
||||
last_verified_mobile.update(state: 'replaced')
|
||||
pending_mobile.update(validated_at: Time.current, step: 'access_phone', state: 'verified')
|
||||
else
|
||||
pending_mobile.update(validated_at: Time.current, step: 'access_phone', state: 'verified')
|
||||
end
|
||||
|
||||
|
||||
present current_user, with: API::V2::Entities::UserWithFullInfo
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
desc 'landline related routes'
|
||||
resource :phones do
|
||||
|
||||
desc 'Add new phone',
|
||||
failure: [
|
||||
{ code: 400, message: 'Required params are empty' },
|
||||
{ code: 401, message: 'Invalid bearer token' },
|
||||
{ code: 404, message: 'Record is not found' },
|
||||
{ code: 422, message: 'Validation errors' }
|
||||
],
|
||||
success: { code: 200, message: 'New phone was added' }
|
||||
params do
|
||||
requires :phone_number,
|
||||
type: String,
|
||||
allow_blank: false,
|
||||
desc: 'Phone number with country code(in iran +98)'
|
||||
optional :channel,
|
||||
type: String,
|
||||
default: 'call',
|
||||
values: { value: -> { Phone::TWILIO_CHANNELS }, message: 'resource.phone.invalid_channel'},
|
||||
desc: 'The verification method to use'
|
||||
end
|
||||
post do
|
||||
error!({ errors: ['resource.phone.code_doesnt_expired'] }, 422) if current_user.read_cache('register-phone')
|
||||
|
||||
error!({ errors: ['kyc_follow_steps'] }, 403) if current_user.kyc_info.dig(:step) < 6
|
||||
|
||||
declared_params = declared(params)
|
||||
validate_phone!(declared_params[:phone_number], true)
|
||||
phone_number = Phone.international(declared_params[:phone_number])
|
||||
phone = current_user.phones.find_by(category: :landline, step: 'telephone', state: 'pending')
|
||||
label = current_user.labels.find_by(key: 'telephone', value: 'verified')
|
||||
# TODO can edit for updating feature
|
||||
error!({ errors: ['resource.phone.exists'] }, 422) if label.present?
|
||||
|
||||
if phone.present?
|
||||
phone.update(number: phone_number)
|
||||
else
|
||||
current_user.phones.create(number: phone_number, category: :landline, step: 'telephone')
|
||||
end
|
||||
# code_error!(phone.errors.details, 422) if phone.errors.any?
|
||||
KaveNegarSmsService.send_call_confirmation(current_user)
|
||||
end
|
||||
|
||||
desc 'Resend activation code in call',
|
||||
failure: [
|
||||
{ code: 400, message: 'Required params are empty' },
|
||||
{ code: 401, message: 'Invalid bearer token' },
|
||||
{ code: 404, message: 'Record is not found' },
|
||||
{ code: 422, message: 'Validation errors' }
|
||||
],
|
||||
success: { code: 200, message: 'Activation code was resend' }
|
||||
params do
|
||||
requires :phone_number,
|
||||
type: String,
|
||||
allow_blank: false,
|
||||
desc: 'Phone number with country code'
|
||||
optional :channel,
|
||||
type: String,
|
||||
default: 'call',
|
||||
values: { value: -> { Phone::TWILIO_CHANNELS }, message: 'resource.phone.invalid_channel'},
|
||||
desc: 'The verification method to use'
|
||||
end
|
||||
# TODO you can delete this api and use above
|
||||
post '/send_code' do
|
||||
error!({ errors: ['resource.phone.code_doesnt_expired'] }, 422) if current_user.read_cache('register-phone')
|
||||
declared_params = declared(params)
|
||||
validate_phone!(declared_params[:phone_number], true)
|
||||
|
||||
phone_number = Phone.international(declared_params[:phone_number])
|
||||
phone = current_user.phones.find_by_number(phone_number)
|
||||
error!({ errors: ['resource.phone.doesnt_exist'] }, 404) unless phone
|
||||
|
||||
KaveNegarSmsService.send_call_confirmation(current_user)
|
||||
end
|
||||
|
||||
|
||||
desc 'Verify a phone (enter code and verify number)',
|
||||
failure: [
|
||||
{ code: 400, message: 'Required params are empty' },
|
||||
{ code: 401, message: 'Invalid bearer token' },
|
||||
{ code: 404, message: 'Record is not found' }
|
||||
],
|
||||
success: API::V2::Entities::UserWithFullInfo
|
||||
params do
|
||||
requires :phone_number,
|
||||
type: String,
|
||||
allow_blank: false,
|
||||
desc: 'Phone number with country code(in iran with +98)'
|
||||
requires :verification_code,
|
||||
type: String,
|
||||
allow_blank: false,
|
||||
desc: 'Verification code from call'
|
||||
end
|
||||
post '/verify' do
|
||||
declared_params = declared(params)
|
||||
validate_phone!(declared_params[:phone_number], true)
|
||||
|
||||
# phone_number = Phone.international(declared_params[:phone_number])
|
||||
phone = current_user.phones.find_by(step: 'telephone', category: 'landline')
|
||||
error!({ errors: ['resource.phone.doesnt_exist'] }, 404) unless phone
|
||||
|
||||
error!({ errors: ['resource.phone.verification_invalid'] }, 404) unless TOTPServiceAction.new('register-phone').validate?(current_user.uid, declared(params)[:verification_code])
|
||||
current_user.delete_cache('register-phone')
|
||||
phone.update(validated_at: Time.current, state: 'verified')
|
||||
present current_user, with: API::V2::Entities::UserWithFullInfo
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
Reference in New Issue
Block a user