Last active
October 17, 2023 14:42
-
-
Save artyomlagun/b6940ab954588fcd35d750fcbc706931 to your computer and use it in GitHub Desktop.
Send OTP
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
class PasscodeService | |
# assume that phone can contain from 7 to 9 digits | |
PHONE_REGEXP = /^\d{7,9}$/ | |
def initialize | |
@response = { action: false, message: '' } | |
end | |
def send(phone) | |
# validate phone through regexp | |
unless PHONE_REGEXP.match?(phone.to_s) | |
@response[:message] = 'Phone is invalid' | |
return @response | |
end | |
if user.present? | |
SendPasscodeWorker.deliver(phone, user.generate_otp) | |
@response[:action] = true | |
else | |
@response[:message] = 'User not found' | |
end | |
@response | |
end | |
def verify(phone, otp) | |
if user.present? | |
@response[:action] = user.verify_otp(otp) | |
@response[:message] = 'Invalid OTP' unless user.verify_otp(otp) | |
else | |
@response[:messgae] = 'User not found' | |
end | |
@response | |
end | |
private | |
def user | |
User.find_by_phone(phone) | |
end | |
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# User: | |
# id | |
# phone | |
# otp_secret | |
# last_otp_at | |
# for OTP we can use this gem: https://github.com/gotoyuzo/otp | |
# it's old, but not sure if we would have any critical issues with it | |
require 'otp' | |
class User < ApplicationRecord | |
def generate_otp | |
# create TOTP instance and new_secret | |
totp = OTP::TOTP.new | |
totp.new_secret | |
# update otp_secret and last_otp_at fields for current user | |
update_otp_fields!(totp.secret) | |
# return OTP | |
totp.password | |
end | |
def verify_otp(otp) | |
totp = OTP::TOTP.new | |
totp.secret = otp_secret | |
totp.verify(otp) | |
end | |
def update_otp_fields!(secret) | |
update!(otp_secret: secret, last_otp_at: Time.now) | |
end | |
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# in routes.rb | |
# resources :users do | |
# member do | |
# post :send_otp | |
# post :verify_otp | |
# end | |
# end | |
class UsersController < ApplicationController | |
def send_otp | |
response = PasscodeService.new.send(params[:phone]) | |
if response[:action] | |
render json: { is_sent: true }, status: :ok | |
else | |
redner json: { is_sent: false, message: response[:message] }, status: :bad_request | |
end | |
end | |
def verify_otp | |
response = PasscodeService.new.verify(params[:phone], params[:otp]) | |
if response[:action] | |
render json: { is_valid: true }, status: :ok | |
else | |
render json: { is_valid: false, message: response[:message] }, status: :bad_request | |
end | |
end | |
end |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment