|
| 1 | +module V1 |
| 2 | + class EmailVerificationsController < ApiController |
| 3 | + skip_before_action :reject_without_user!, only: [:verification] |
| 4 | + |
| 5 | + def create |
| 6 | + user = User.find_by(auth_id: current_auth_id) |
| 7 | + new_email = params.dig('_jsonapi', 'new_email') |
| 8 | + |
| 9 | + verification_request = verification_request(user, new_email) |
| 10 | + |
| 11 | + if verification_request.save |
| 12 | + |
| 13 | + SendEmailVerificationJob.perform_later( |
| 14 | + new_email: new_email, |
| 15 | + verification_url: verification_request.verification_url, |
| 16 | + person_name: user.name |
| 17 | + ) |
| 18 | + |
| 19 | + render jsonapi: verification_request, status: :ok, context: { request: request } |
| 20 | + else |
| 21 | + render jsonapi_errors: verification_request.errors, status: :unprocessable_entity |
| 22 | + end |
| 23 | + end |
| 24 | + |
| 25 | + def verification |
| 26 | + token = find_token_params || (return render_invalid_token_error) |
| 27 | + email_change_request = EmailChangeRequest.find_by(token: token) || (return render_invalid_token_error) |
| 28 | + update_user_email = update_email(email_change_request) |
| 29 | + email_change_request.update(used_at: Time.current, active: false) |
| 30 | + |
| 31 | + return render jsonapi: email_change_request.user, status: :ok if update_user_email&.call |
| 32 | + |
| 33 | + error_body = verification_request&.errors || |
| 34 | + { error: I18n.t('email_verifications.invalid_or_expired_token') } |
| 35 | + render jsonapi_errors: error_body, status: :unprocessable_entity |
| 36 | + end |
| 37 | + |
| 38 | + def active |
| 39 | + user = User.find_by(auth_id: current_auth_id) |
| 40 | + unless user |
| 41 | + render jsonapi_errors: { error: 'User not found' }, status: :not_found |
| 42 | + return |
| 43 | + end |
| 44 | + |
| 45 | + verification = EmailChangeRequest.where(user: user, active: true).order(created_at: :desc).first |
| 46 | + |
| 47 | + if verification |
| 48 | + render jsonapi: verification, status: :ok, context: { request: request } |
| 49 | + else |
| 50 | + render jsonapi_errors: { error: 'No active email verification found' }, status: :not_found |
| 51 | + end |
| 52 | + end |
| 53 | + |
| 54 | + def cancel_pending_email_change |
| 55 | + user = User.find_by(auth_id: current_auth_id) |
| 56 | + unless user |
| 57 | + render jsonapi_errors: { error: 'User not found' }, status: :not_found |
| 58 | + return |
| 59 | + end |
| 60 | + |
| 61 | + EmailChangeRequest.where(user: user, active: true).find_each do |record| |
| 62 | + record.update(active: false) |
| 63 | + end |
| 64 | + |
| 65 | + head :no_content |
| 66 | + end |
| 67 | + |
| 68 | + private |
| 69 | + |
| 70 | + def verification_request(user, new_email) |
| 71 | + expires_at = 2.days.from_now |
| 72 | + |
| 73 | + EmailChangeRequest.where(user: user, active: true).find_each do |record| |
| 74 | + record.update(active: false) |
| 75 | + end |
| 76 | + |
| 77 | + EmailChangeRequest.new( |
| 78 | + user: user, |
| 79 | + new_email: new_email, |
| 80 | + expires_at: expires_at |
| 81 | + ) |
| 82 | + end |
| 83 | + |
| 84 | + def update_email(email_change_request) |
| 85 | + UpdateUserEmail.new(email_change_request.user, email_change_request.new_email) |
| 86 | + end |
| 87 | + |
| 88 | + def render_invalid_token_error |
| 89 | + render jsonapi_errors: ApiMessage.new({ message: I18n.t('email_verifications.invalid_or_expired_token') }), |
| 90 | + status: :unprocessable_entity |
| 91 | + end |
| 92 | + |
| 93 | + def find_token_params |
| 94 | + params.dig('_jsonapi', 'token') |
| 95 | + end |
| 96 | + end |
| 97 | +end |
0 commit comments