hackatime/app/controllers/users_controller.rb
Mahad Kalam ef3f36c829
Inertia migration/UI3 (#911)
* Inertia p1?

* Inertia'fied signed out homepage?

* Split up signed in page

* WIP signed in v2?

* Better signed in?

* Clean up extensions page!

* Fix currently hacking

* Better docs page?

* Docs update 2

* Clean up "What is Hackatime?" + get rid of that godawful green dev mode

* Better nav?

* Cleaner settings?

* Fix commit times

* Fix flashes + OS improv

* Setup v2

* Readd some of the syncers?

* Remove stray emdash

* Clean up Step 3

* Oops, remove .vite

* bye bye, /inertia-example

* bin/rubocop -A

* Fix docs vuln
2026-02-09 11:26:30 +00:00

190 lines
5.5 KiB
Ruby

class UsersController < InertiaController
layout "inertia"
include ActionView::Helpers::NumberHelper
before_action :set_user
before_action :require_current_user, except: [ :update_trust_level ]
before_action :require_admin, only: [ :update_trust_level ]
def edit
prepare_settings_page
end
def update
# Handle regular user settings updates
if params[:user].present?
if @user.update(user_params)
if @user.uses_slack_status?
@user.update_slack_status
end
redirect_to is_own_settings? ? my_settings_path : settings_user_path(@user),
notice: "Settings updated successfully"
else
flash.now[:error] = @user.errors.full_messages.to_sentence.presence || "Failed to update settings"
prepare_settings_page
render :edit, status: :unprocessable_entity
end
else
redirect_to is_own_settings? ? my_settings_path : settings_user_path(@user),
notice: "Settings updated successfully!"
end
end
def migrate_heartbeats
MigrateUserFromHackatimeJob.perform_later(@user.id)
redirect_to is_own_settings? ? my_settings_path : settings_user_path(@user),
notice: "Heartbeats & api keys migration started"
end
def rotate_api_key
@user.api_keys.transaction do
@user.api_keys.destroy_all
new_api_key = @user.api_keys.create!(name: "Hackatime key")
render json: { token: new_api_key.token }, status: :ok
end
rescue => e
Rails.logger.error("error rotate #{e.class.name} #{e.message}")
render json: { error: "cant rotate" }, status: :unprocessable_entity
end
def wakatime_setup
api_key = current_user&.api_keys&.last
api_key ||= current_user.api_keys.create!(name: "Wakatime API Key")
setup_os = detect_setup_os(request.user_agent)
render inertia: "WakatimeSetup/Index", props: {
current_user_api_key: api_key&.token,
setup_os: setup_os.to_s,
api_url: api_hackatime_v1_url,
heartbeat_check_url: api_v1_my_heartbeats_most_recent_path(source_type: "test_entry")
}
end
def wakatime_setup_step_2
render inertia: "WakatimeSetup/Step2", props: {}
end
def wakatime_setup_step_3
api_key = current_user&.api_keys&.last
api_key ||= current_user.api_keys.create!(name: "Wakatime API Key")
editor = params[:editor]
render inertia: "WakatimeSetup/Step3", props: {
current_user_api_key: api_key&.token,
editor: editor,
heartbeat_check_url: api_v1_my_heartbeats_most_recent_path
}
end
def wakatime_setup_step_4
render inertia: "WakatimeSetup/Step4", props: {
dino_video_url: FlavorText.dino_meme_videos.sample,
return_url: session.dig(:return_data, "url"),
return_button_text: session.dig(:return_data, "button_text") || "Done"
}
end
def update_trust_level
@user = User.find(params[:id])
require_admin
trust_level = params[:trust_level]
reason = params[:reason]
notes = params[:notes]
if @user && (current_user.admin_level == "admin" || current_user.admin_level == "superadmin") && trust_level.present?
unless User.trust_levels.key?(trust_level)
return render json: { error: "you fucked it up lmaooo" }, status: :unprocessable_entity
end
if trust_level == "red" && current_user.admin_level != "superadmin"
return render json: { error: "no perms lmaooo" }, status: :forbidden
end
success = @user.set_trust(
trust_level,
changed_by_user: current_user,
reason: reason,
notes: notes
)
if success
render json: {
success: true,
message: "updated",
trust_level: @user.trust_level
}
else
render json: { error: "402 invalid" }, status: :unprocessable_entity
end
else
render json: { error: "lmao no perms" }, status: :unprocessable_entity
end
end
private
def require_admin
unless current_user && (current_user.admin_level == "admin" || current_user.admin_level == "superadmin")
redirect_to root_path, alert: "You are not authorized to access this page"
end
end
def require_current_user
unless @user == current_user
redirect_to root_path, alert: "You are not authorized to access this page"
end
end
def detect_setup_os(user_agent)
ua = user_agent.to_s
return :windows if ua.match?(/windows/i)
:mac_linux
end
def prepare_settings_page
@is_own_settings = is_own_settings?
@can_enable_slack_status = @user.slack_access_token.present? && @user.slack_scopes.include?("users.profile:write")
@enabled_sailors_logs = SailorsLogNotificationPreference.where(
slack_uid: @user.slack_uid,
enabled: true,
).where.not(slack_channel_id: SailorsLog::DEFAULT_CHANNELS)
@heartbeats_migration_jobs = @user.data_migration_jobs
@projects = @user.project_repo_mappings.distinct.pluck(:project_name)
@work_time_stats_url = "https://hackatime-badge.hackclub.com/#{@user.slack_uid}/#{@projects.first || 'example'}"
end
def set_user
@user = if params["id"].present?
User.find(params["id"])
else
current_user
end
redirect_to root_path, alert: "You need to log in!" if @user.nil?
end
def is_own_settings?
@is_own_settings ||= params["id"] == "my" || params["id"]&.blank?
end
def user_params
params.require(:user).permit(
:uses_slack_status,
:hackatime_extension_text_type,
:timezone,
:country_code,
:allow_public_stats_lookup,
:username,
)
end
end