Files
Dalan/app/api/v2/identity/sessions.rb
2026-08-13 19:56:46 +03:30

177 lines
6.9 KiB
Ruby

# frozen_string_literal: true
require_dependency 'barong/jwt'
module API::V2
module Identity
class Sessions < Grape::API
helpers do
def get_user(email)
user = User.find_by(email: email)
error!({ errors: ['identity.session.invalid_params'] }, 401) unless user
if user.state == 'banned'
login_error!(reason: 'Your account is banned', error_code: 401,
user: user.id, action: 'login', result: 'failed', error_text: 'banned')
end
if user.state == 'deleted'
login_error!(reason: 'Your account is deleted', error_code: 401,
user: user.id, action: 'login', result: 'failed', error_text: 'deleted')
end
# if user is not active or pending, then return 401
unless user.state.in?(%w[active pending])
login_error!(reason: 'Your account is not active', error_code: 401,
user: user.id, action: 'login', result: 'failed', error_text: 'not_active')
end
user
end
end
desc 'Session related routes'
resource :sessions do
desc 'Start a new session for every LogIn',
failure: [
{ code: 400, message: 'Required params are empty' },
{ code: 404, message: 'Record is not found' }
]
params do
requires :email
requires :password
optional :captcha_response,
types: { value: [String, Hash], message: 'identity.session.invalid_captcha_format' },
desc: 'Response from captcha widget'
optional :otp_code,
type: String,
desc: 'Code from Google Authenticator'
end
post do
verify_captcha!(response: params['captcha_response'], endpoint: 'session_create')
declared_params = declared(params, include_missing: false)
user = get_user(declared_params[:email])
error!({ errors: ['identity.session.not_active'] }, 401) unless user.state == 'active'
unless user.authenticate(declared_params[:password])
publish_session_failed(user)
login_error!(reason: 'Invalid Email or Password', error_code: 401, user: user.id,
action: 'login', result: 'failed', error_text: 'invalid_params')
end
unless user.otp
activity_record(user: user.id, action: 'login', result: 'succeed', topic: 'session')
csrf_token = open_session(user)
publish_session_create(user)
present user, with: API::V2::Entities::UserWithFullInfo, csrf_token: csrf_token
return status 200
end
error!({ errors: ['identity.session.missing_otp'] }, 401) if declared_params[:otp_code].blank?
unless TOTPService.validate?(user.uid, declared_params[:otp_code])
login_error!(reason: 'OTP code is invalid', error_code: 403,
user: user.id, action: 'login::2fa', result: 'failed', error_text: 'invalid_otp')
end
activity_record(user: user.id, action: 'login::2fa', result: 'succeed', topic: 'session')
csrf_token = open_session(user)
publish_session_create(user)
present user, with: API::V2::Entities::UserWithFullInfo, csrf_token: csrf_token
status(200)
end
desc 'Destroy current session for LogOut',
failure: [
{ code: 400, message: 'Required params are empty' },
{ code: 404, message: 'Record is not found' }
],
success: { code: 200, message: 'Session was destroyed' }
delete do
user = User.find_by(uid: session[:uid])
error!({ errors: ['identity.session.not_found'] }, 404) unless user
activity_record(user: user.id, action: 'logout', result: 'succeed', topic: 'session')
session.destroy
status(200)
end
desc 'Auth0 authentication by id_token',
success: { code: 200, message: 'User authenticated' },
failure: [
{ code: 400, message: 'Required params are empty' },
{ code: 404, message: 'Record is not found' }
]
params do
requires :id_token,
type: String,
allow_blank: false,
desc: 'ID Token'
end
post '/auth0' do
begin
# Decode ID token to get user info
claims = Barong::Auth0::JWT.verify(params[:id_token]).first
error!({ errors: ['identity.session.auth0.invalid_params'] }, 401) unless claims.key?('email')
user = User.find_by(email: claims['email'])
# If there is no user in platform and user email verified from id_token
# system will create user
if user.blank? && claims['email_verified']
user = User.create!(email: claims['email'], state: 'active')
user.labels.create!(scope: 'private', key: 'email', value: 'verified')
elsif claims['email_verified'] == false
error!({ errors: ['identity.session.auth0.invalid_params'] }, 401) unless user
end
activity_record(user: user.id, action: 'login', result: 'succeed', topic: 'session')
csrf_token = open_session(user)
publish_session_create(user)
present user, with: API::V2::Entities::UserWithFullInfo, csrf_token: csrf_token
rescue StandardError => e
report_exception(e)
error!({ errors: ['identity.session.auth0.invalid_params'] }, 422)
end
end
desc 'Resend confirmations code(authorization code)',
success: { code: 201, message: 'Generated verification code' },
failure: [
{ code: 400, message: 'Required params are missing' },
{ code: 422, message: 'Validation errors' }
]
params do
requires :data,
type: String,
allow_blank: false,
desc: 'Account email or Telephone number'
requires :action,
type: String,
allow_blank: false,
desc: 'for what need auth code'
optional :channel,
type: String,
allow_blank: true,
default: 'email',
desc: 'channel that send in'
optional :captcha_response,
types: [String, Hash],
desc: 'Response from captcha widget'
end
post '/resend' do
current_user = User.find_by_email(params[:data])
return status 201 if current_user.nil?
publish_confirmation_code(current_user, Barong::App.config.domain, params[:action])
status 201
end
end
end
end
end