File size: 3,506 Bytes
874ae95
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
class UsersController < ApplicationController
  before_action :authenticate_user!, except: :delete_account
  layout "student"

  # GET /dashboard/
  def dashboard
    @user = authorize(current_user)
  end

  # GET /user/edit
  def edit
    @user = authorize(current_user)

    if session.key?(:course_requiring_discord)
      redirect_to discord_account_required_user_path
    end
  end

  # GET /users/delete_account
  def delete_account
    user =
      Users::ValidateDeletionTokenService.new(
        params[:token],
        current_school
      ).authenticate
    if user.present?
      sign_in user
      @token = params[:token]
    else
      flash[:error] = t(".link_expired")
      redirect_to root_path
    end
  end

  # POST /user/upload_avatar
  def upload_avatar
    @form = Users::UploadAvatarForm.new(current_user)
    if @form.validate(params[:user])
      avatar_url = @form.save
      render json: { avatarUrl: avatar_url }
    else
      render "edit"
    end
  end

  # POST /user/clear_discord_id
  def clear_discord_id
    if current_user.discord_user_id.present?
      Discord::ClearRolesJob.perform_later(
        current_user.discord_user_id,
        current_school
      )
      current_user.update!(discord_user_id: nil)
    end

    flash[:success] = t(".success")
    redirect_to edit_user_path
  end

  # GET /user/update_email
  def update_email
    user =
      Users::ValidateUpdateEmailTokenService.new(
        params[:token],
        current_school
      ).authenticate

    if user.present? && user.new_email.present?
      old_email = user.email
      new_email = user.new_email

      # Update user email
      user.update!(email: new_email, update_email_token: nil, new_email: nil)

      # Create audit record
      AuditRecord.create!(
        audit_type: AuditRecord.audit_types[:update_email],
        school_id: current_school.id,
        metadata: {
          user_id: current_user.id,
          email: new_email,
          old_email: old_email
        }
      )

      # Send success email to user - both old and new email for security
      UserMailer.confirm_email_update(user, user.email, old_email).deliver_later

      UserMailer.confirm_email_update(user, old_email, old_email).deliver_later

      # Send notification email to admins
      current_school
        .school_admins
        .where.not(user_id: user.id)
        .each do |admin|
          SchoolAdminMailer.email_updated_notification(
            admin,
            user,
            old_email
          ).deliver_later
        end

      redirect_to edit_user_path
    else
      flash[:error] = t(".link_expired")
      redirect_to edit_user_path
    end
  end

  # GET /user/discord_account_required?course_requiring_discord
  def discord_account_required
    authorize(current_user)

    @course_requiring_discord_account =
      if params[:course_requiring_discord].present? &&
           !current_user.discord_account_connected?
        course =
          current_user.courses.find_by(id: params[:course_requiring_discord])

        session[:course_requiring_discord] = course.id if course.present?
        course
      elsif session.key?(:course_requiring_discord)
        course =
          current_user.courses.find_by(id: session[:course_requiring_discord])

        session.delete(:course_requiring_discord)
        course
      end
  end

  # GET /user/standing
  def standing
    @presenter =
      Users::StandingPresenter.new(view_context, authorize(current_user))
  end
end