mirror of
https://github.com/System-End/hackatime.git
synced 2026-04-19 21:05:15 +00:00
311 lines
12 KiB
Ruby
311 lines
12 KiB
Ruby
class AdminLevelConstraint
|
||
def initialize(*require)
|
||
@require = require.map(&:to_s)
|
||
end
|
||
|
||
def matches?(request)
|
||
return false unless request.session[:user_id]
|
||
user = User.find_by(id: request.session[:user_id])
|
||
user && @require.include?(user.admin_level)
|
||
end
|
||
end
|
||
|
||
Rails.application.routes.draw do
|
||
# Redirect to localhost from 127.0.0.1 to use same IP address with Vite server
|
||
constraints(host: "127.0.0.1") do
|
||
get "(*path)", to: redirect { |params, req| "#{req.protocol}localhost:#{req.port}/#{params[:path]}" }
|
||
end
|
||
|
||
mount Rswag::Api::Engine => "/api-docs"
|
||
mount Rswag::Ui::Engine => "/api-docs"
|
||
use_doorkeeper
|
||
|
||
post "/oauth/applications/:id/rotate_secret", to: "doorkeeper/applications#rotate_secret", as: :rotate_secret_oauth_application
|
||
root "static_pages#index"
|
||
|
||
resources :extensions, only: [ :index ]
|
||
|
||
constraints AdminLevelConstraint.new(:superadmin) do
|
||
mount GoodJob::Engine => "good_job"
|
||
mount Flipper::UI.app(Flipper) => "flipper", as: :flipper
|
||
|
||
namespace :admin do
|
||
resources :admin_users, only: [ :index, :update ] do
|
||
collection do
|
||
get :search
|
||
end
|
||
end
|
||
resources :oauth_applications, only: [ :index, :show, :edit, :update ] do
|
||
member do
|
||
post :toggle_verified
|
||
post :rotate_secret
|
||
end
|
||
end
|
||
end
|
||
end
|
||
|
||
constraints AdminLevelConstraint.new(:superadmin, :admin, :viewer) do
|
||
namespace :admin do
|
||
get "timeline", to: "timeline#show", as: :timeline
|
||
get "timeline/search_users", to: "timeline#search_users"
|
||
get "timeline/leaderboard_users", to: "timeline#leaderboard_users"
|
||
|
||
resources :trust_level_audit_logs, only: [ :index, :show ]
|
||
resources :admin_api_keys, except: [ :edit, :update ]
|
||
resources :deletion_requests, only: [ :index, :show ] do
|
||
member do
|
||
post :approve
|
||
post :reject
|
||
end
|
||
end
|
||
end
|
||
get "/impersonate/:id", to: "sessions#impersonate", as: :impersonate_user
|
||
end
|
||
|
||
constraints AdminLevelConstraint.new(:superadmin) do
|
||
namespace :admin do
|
||
resources :permissions, only: [ :index, :update ]
|
||
end
|
||
end
|
||
get "/stop_impersonating", to: "sessions#stop_impersonating", as: :stop_impersonating
|
||
|
||
if Rails.env.development?
|
||
mount LetterOpenerWeb::Engine, at: "/letter_opener"
|
||
end
|
||
|
||
# Reveal health status on /up that returns 200 if the app boots with no exceptions, otherwise 500.
|
||
# Can be used by load balancers and uptime monitors to verify that the app is live.
|
||
get "up" => "rails/health#show", as: :rails_health_check
|
||
|
||
# Render dynamic PWA files from app/views/pwa/* (remember to link manifest in application.html.erb)
|
||
# get "manifest" => "rails/pwa#manifest", as: :pwa_manifest
|
||
# get "service-worker" => "rails/pwa#service_worker", as: :pwa_service_worker
|
||
|
||
resources :static_pages, only: [ :index ] do
|
||
collection do
|
||
get :project_durations
|
||
get :currently_hacking
|
||
get :currently_hacking_count
|
||
get :filterable_dashboard_content
|
||
get :filterable_dashboard
|
||
get :streak
|
||
# get :timeline # Removed: Old route for timeline
|
||
end
|
||
end
|
||
|
||
get "/minimal_login", to: "static_pages#minimal_login", as: :minimal_login
|
||
|
||
# Auth routes
|
||
get "/auth/hca", to: "sessions#hca_new", as: :hca_auth
|
||
get "/auth/hca/callback", to: "sessions#hca_create"
|
||
get "/auth/slack", to: "sessions#slack_new", as: :slack_auth
|
||
get "/auth/slack/callback", to: "sessions#slack_create"
|
||
get "/auth/github", to: "sessions#github_new", as: :github_auth
|
||
get "/auth/github/callback", to: "sessions#github_create"
|
||
delete "/auth/github/unlink", to: "sessions#github_unlink", as: :github_unlink
|
||
post "/auth/email", to: "sessions#email", as: :email_auth
|
||
post "/auth/email/add", to: "sessions#add_email", as: :add_email_auth
|
||
delete "/auth/email/unlink", to: "sessions#unlink_email", as: :unlink_email_auth
|
||
get "/auth/token/:token", to: "sessions#token", as: :auth_token
|
||
get "/auth/close_window", to: "sessions#close_window", as: :close_window
|
||
delete "signout", to: "sessions#destroy", as: "signout"
|
||
|
||
resources :leaderboards, only: [ :index ] do
|
||
get :entries, on: :collection
|
||
end
|
||
|
||
# Docs routes
|
||
get "docs", to: "docs#index", as: :docs
|
||
get "docs/*path", to: "docs#show", as: :doc
|
||
|
||
# Nested under users for admin access
|
||
resources :users, only: [] do
|
||
get "settings", on: :member, to: "settings/profile#show"
|
||
patch "settings", on: :member, to: "settings/profile#update"
|
||
member do
|
||
patch :update_trust_level
|
||
end
|
||
resource :wakatime_mirrors, only: [ :create ]
|
||
resources :wakatime_mirrors, only: [ :destroy ]
|
||
end
|
||
|
||
get "my/projects", to: "my/project_repo_mappings#index", as: :my_projects
|
||
|
||
# Namespace for current user actions
|
||
get "my/settings", to: "settings/profile#show", as: :my_settings
|
||
patch "my/settings", to: "settings/profile#update"
|
||
get "my/settings/profile", to: "settings/profile#show", as: :my_settings_profile
|
||
patch "my/settings/profile", to: "settings/profile#update"
|
||
get "my/settings/integrations", to: "settings/integrations#show", as: :my_settings_integrations
|
||
patch "my/settings/integrations", to: "settings/integrations#update"
|
||
get "my/settings/access", to: "settings/access#show", as: :my_settings_access
|
||
patch "my/settings/access", to: "settings/access#update"
|
||
get "my/settings/badges", to: "settings/badges#show", as: :my_settings_badges
|
||
get "my/settings/data", to: "settings/data#show", as: :my_settings_data
|
||
get "my/settings/admin", to: "settings/admin#show", as: :my_settings_admin
|
||
post "my/settings/migrate_heartbeats", to: "settings/data#migrate_heartbeats", as: :my_settings_migrate_heartbeats
|
||
post "my/settings/rotate_api_key", to: "settings/access#rotate_api_key", as: :my_settings_rotate_api_key
|
||
|
||
namespace :my do
|
||
resources :project_repo_mappings, param: :project_name, only: [ :edit, :update ], constraints: { project_name: /.+/ } do
|
||
member do
|
||
patch :archive
|
||
patch :unarchive
|
||
end
|
||
end
|
||
# resource :mailing_address, only: [ :show, :edit ]
|
||
# get "mailroom", to: "mailroom#index"
|
||
resources :heartbeats, only: [] do
|
||
collection do
|
||
get :export
|
||
post :import
|
||
end
|
||
end
|
||
end
|
||
|
||
get "deletion", to: "deletion_requests#show", as: :deletion
|
||
post "deletion", to: "deletion_requests#create", as: :create_deletion
|
||
delete "deletion", to: "deletion_requests#cancel", as: :cancel_deletion
|
||
|
||
get "my/wakatime_setup", to: "users#wakatime_setup"
|
||
get "my/wakatime_setup/step-2", to: "users#wakatime_setup_step_2"
|
||
get "my/wakatime_setup/step-3", to: "users#wakatime_setup_step_3"
|
||
get "my/wakatime_setup/step-4", to: "users#wakatime_setup_step_4"
|
||
|
||
post "/sailors_log/slack/commands", to: "slack#create"
|
||
post "/timedump/slack/commands", to: "slack#create"
|
||
|
||
get "/hackatime/v1", to: redirect("/", status: 302) # some clients seem to link this as the user's dashboard instead of /api/v1/hackatime
|
||
# API routes
|
||
namespace :api do
|
||
# This is our own API– don't worry about compatibility.
|
||
namespace :v1 do
|
||
get "leaderboard", to: "leaderboard#daily"
|
||
get "leaderboard/daily", to: "leaderboard#daily"
|
||
get "leaderboard/weekly", to: "leaderboard#weekly"
|
||
|
||
get "stats", to: "stats#show"
|
||
get "users/:username/stats", to: "stats#user_stats"
|
||
get "users/:username/heartbeats/spans", to: "stats#user_spans"
|
||
get "users/:username/trust_factor", to: "stats#trust_factor"
|
||
get "users/:username/projects", to: "stats#user_projects"
|
||
get "users/:username/project/:project_name", to: "stats#user_project"
|
||
get "users/:username/projects/details", to: "stats#user_projects_details"
|
||
|
||
get "users/lookup_email/:email", to: "users#lookup_email", constraints: { email: /[^\/]+/ }
|
||
get "users/lookup_slack_uid/:slack_uid", to: "users#lookup_slack_uid"
|
||
|
||
get "banned_users/counts", to: "stats#banned_users_counts"
|
||
|
||
# External service Slack OAuth integration
|
||
post "external/slack/oauth", to: "external_slack#create_user"
|
||
|
||
resources :ysws_programs, only: [ :index ] do
|
||
post :claim, on: :collection
|
||
end
|
||
|
||
get "dashboard_stats", to: "dashboard_stats#show"
|
||
|
||
namespace :my do
|
||
get "heartbeats/most_recent", to: "heartbeats#most_recent"
|
||
get "heartbeats", to: "heartbeats#index"
|
||
end
|
||
|
||
# oauth authenticated namespace
|
||
namespace :authenticated do
|
||
resources :me, only: [ :index ]
|
||
get "hours", to: "hours#index"
|
||
get "streak", to: "streak#show"
|
||
get "projects", to: "projects#index"
|
||
# get "projects/:name", to: "projects#show", constraints: { name: /.+/ }
|
||
get "heartbeats/latest", to: "heartbeats#latest"
|
||
get "api_keys", to: "api_keys#index"
|
||
end
|
||
end
|
||
|
||
# Admin-only API namespace
|
||
namespace :admin do
|
||
namespace :v1 do
|
||
get "check", to: "admin#check"
|
||
get "user/info", to: "admin#user_info"
|
||
get "user/info_batch", to: "admin#user_info_batch"
|
||
get "user/heartbeats", to: "admin#user_heartbeats"
|
||
get "user/heartbeat_values", to: "admin#user_heartbeat_values"
|
||
get "user/get_users_by_ip", to: "admin#get_users_by_ip"
|
||
get "user/get_users_by_machine", to: "admin#get_users_by_machine"
|
||
get "user/stats", to: "admin#user_stats"
|
||
get "user/projects", to: "admin#user_projects"
|
||
get "user/trust_logs", to: "admin#trust_logs"
|
||
get "banned_users", to: "admin#banned_users"
|
||
post "user/get_user_by_email", to: "admin#get_user_by_email"
|
||
post "user/search_fuzzy", to: "admin#search_users_fuzzy"
|
||
post "user/convict", to: "admin#user_convict"
|
||
|
||
# Admin API Keys management
|
||
resources :admin_api_keys, only: [ :index, :show, :create, :destroy ]
|
||
|
||
# Trust level audit logs
|
||
resources :trust_level_audit_logs, only: [ :index, :show ]
|
||
|
||
# Deletion requests
|
||
resources :deletion_requests, only: [ :index, :show ] do
|
||
member do
|
||
post :approve
|
||
post :reject
|
||
end
|
||
end
|
||
|
||
# Permissions management
|
||
resources :permissions, only: [ :index ] do
|
||
collection do
|
||
patch ":id", to: "permissions#update", as: :update
|
||
end
|
||
end
|
||
|
||
# Timeline
|
||
get "timeline", to: "timeline#show"
|
||
get "timeline/search_users", to: "timeline#search_users"
|
||
get "timeline/leaderboard_users", to: "timeline#leaderboard_users"
|
||
get "users/:id/visualization/quantized", to: "admin#visualization_quantized"
|
||
get "alts/candidates", to: "admin#alt_candidates"
|
||
get "alts/shared_machines", to: "admin#shared_machines"
|
||
get "users/active", to: "admin#active_users"
|
||
post "audit_logs/counts", to: "admin#audit_logs_counts"
|
||
end
|
||
end
|
||
|
||
# wakatime compatible summary
|
||
get "summary", to: "summary#index"
|
||
|
||
# Everything in this namespace conforms to wakatime.com's API.
|
||
namespace :hackatime do
|
||
namespace :v1 do
|
||
get "/", to: redirect("/", status: 302) # some clients seem to link this as the user's dashboard instead of /api/v1/hackatime
|
||
get "/users/:id/statusbar/today", to: "hackatime#status_bar_today"
|
||
post "/users/:id/heartbeats", to: "hackatime#push_heartbeats"
|
||
get "/users/current/stats/last_7_days", to: "hackatime#stats_last_7_days"
|
||
end
|
||
end
|
||
|
||
namespace :internal do
|
||
post "revoke", to: "revocations#create"
|
||
post "/can_i_have_a_magic_link_for/:id", to: "magic_links#create"
|
||
end
|
||
end
|
||
|
||
get "/@:username", to: "profiles#show", as: :profile, constraints: { username: /[A-Za-z0-9_-]+/ }
|
||
get "/@:username/time_stats", to: "profiles#time_stats", as: :profile_time_stats, constraints: { username: /[A-Za-z0-9_-]+/ }
|
||
get "/@:username/projects", to: "profiles#projects", as: :profile_projects, constraints: { username: /[A-Za-z0-9_-]+/ }
|
||
get "/@:username/languages", to: "profiles#languages", as: :profile_languages, constraints: { username: /[A-Za-z0-9_-]+/ }
|
||
get "/@:username/editors", to: "profiles#editors", as: :profile_editors, constraints: { username: /[A-Za-z0-9_-]+/ }
|
||
get "/@:username/activity", to: "profiles#activity", as: :profile_activity, constraints: { username: /[A-Za-z0-9_-]+/ }
|
||
|
||
# SEO routes
|
||
get "/sitemap.xml", to: "sitemap#sitemap", defaults: { format: "xml" }
|
||
|
||
# fuck ups
|
||
match "/400", to: "errors#bad_request", via: :all
|
||
match "/404", to: "errors#not_found", via: :all
|
||
match "/422", to: "errors#unprocessable_entity", via: :all
|
||
match "/500", to: "errors#internal_server_error", via: :all
|
||
end
|