@@ -321,25 +321,13 @@ def forgot_password
321321 )
322322 end
323323
324- user = User . find_by ( email : email )
324+ user = User . unscoped . find_by ( email : email )
325+ player = Player . find_by ( player_email : email ) unless user
325326
326327 if user
327- reset_token = user . password_reset_tokens . create! (
328- ip_address : request . remote_ip ,
329- user_agent : request . user_agent
330- )
331-
332- deliver_email ( UserMailer . password_reset ( user , reset_token ) )
333-
334- AuditLog . create! (
335- organization : user . organization ,
336- user : user ,
337- action : 'password_reset_requested' ,
338- entity_type : 'User' ,
339- entity_id : user . id ,
340- ip_address : request . remote_ip ,
341- user_agent : request . user_agent
342- )
328+ handle_user_password_reset ( user )
329+ elsif player
330+ handle_player_password_reset ( player )
343331 end
344332
345333 render_success (
@@ -382,24 +370,11 @@ def reset_password
382370
383371 reset_token = PasswordResetToken . valid . find_by ( token : token )
384372
385- if reset_token
386- user = reset_token . user
387- user . update! ( password : new_password )
388-
389- reset_token . mark_as_used!
390-
391- deliver_email ( UserMailer . password_reset_confirmation ( user ) )
392-
393- AuditLog . create! (
394- organization : user . organization ,
395- user : user ,
396- action : 'password_reset_completed' ,
397- entity_type : 'User' ,
398- entity_id : user . id ,
399- ip_address : request . remote_ip ,
400- user_agent : request . user_agent
401- )
402-
373+ if reset_token &.user
374+ complete_user_password_reset ( reset_token , new_password )
375+ render_success ( { } , message : 'Password reset successful' )
376+ elsif reset_token &.player
377+ complete_player_password_reset ( reset_token , new_password )
403378 render_success ( { } , message : 'Password reset successful' )
404379 else
405380 render_error (
@@ -442,7 +417,8 @@ def create_organization!
442417 def create_user! ( organization )
443418 User . create! ( user_params . merge (
444419 organization : organization ,
445- role : 'owner' # First user is always the owner
420+ role : 'owner' ,
421+ source_app : source_app_from_origin
446422 ) )
447423 end
448424
@@ -534,7 +510,8 @@ def build_free_agent_player(player_email, summoner_name, password, discord)
534510 discord_user_id : discord . presence ,
535511 player_access_enabled : true ,
536512 status : 'active' ,
537- role : 'top'
513+ role : 'top' ,
514+ source_app : 'arena_br'
538515 # organization_id intentionally omitted (nil) — free agent
539516 )
540517 end
@@ -557,6 +534,75 @@ def serialize_new_free_agent(player)
557534 }
558535 end
559536
537+ def handle_user_password_reset ( user )
538+ reset_token = user . password_reset_tokens . create! (
539+ ip_address : request . remote_ip ,
540+ user_agent : request . user_agent
541+ )
542+ frontend_url = frontend_url_from_origin || frontend_base_for ( user )
543+ deliver_email ( UserMailer . password_reset ( user , reset_token , frontend_url ) )
544+ AuditLog . create! (
545+ organization : user . organization ,
546+ user : user ,
547+ action : 'password_reset_requested' ,
548+ entity_type : 'User' ,
549+ entity_id : user . id ,
550+ ip_address : request . remote_ip ,
551+ user_agent : request . user_agent
552+ )
553+ end
554+
555+ def handle_player_password_reset ( player )
556+ reset_token = player . password_reset_tokens . create! (
557+ ip_address : request . remote_ip ,
558+ user_agent : request . user_agent
559+ )
560+ frontend_url = frontend_url_from_origin || frontend_base_for ( player )
561+ deliver_email ( PlayerMailer . password_reset ( player , reset_token , frontend_url ) )
562+ end
563+
564+ def complete_user_password_reset ( reset_token , new_password )
565+ user = reset_token . user
566+ user . update! ( password : new_password )
567+ reset_token . mark_as_used!
568+ deliver_email ( UserMailer . password_reset_confirmation ( user ) )
569+ AuditLog . create! (
570+ organization : user . organization ,
571+ user : user ,
572+ action : 'password_reset_completed' ,
573+ entity_type : 'User' ,
574+ entity_id : user . id ,
575+ ip_address : request . remote_ip ,
576+ user_agent : request . user_agent
577+ )
578+ end
579+
580+ def complete_player_password_reset ( reset_token , new_password )
581+ player = reset_token . player
582+ player . update! ( player_password : new_password )
583+ reset_token . mark_as_used!
584+ deliver_email ( PlayerMailer . password_reset_confirmation ( player ) )
585+ end
586+
587+ def source_app_from_origin
588+ origin = request . headers [ 'Origin' ] &.strip &.chomp ( '/' )
589+ return 'prostaff' unless origin . present?
590+
591+ Constants ::SOURCE_APP_URLS . find { |_src , url | url . chomp ( '/' ) == origin } &.first || 'prostaff'
592+ end
593+
594+ def frontend_url_from_origin
595+ origin = request . headers [ 'Origin' ] &.strip &.chomp ( '/' )
596+ return nil unless origin . present?
597+
598+ Constants ::SOURCE_APP_URLS . values . find { |url | url . chomp ( '/' ) == origin }
599+ end
600+
601+ def frontend_base_for ( record )
602+ source = record . source_app . presence || 'prostaff'
603+ Constants ::SOURCE_APP_URLS . fetch ( source , ENV . fetch ( 'PROSTAFF_URL' , 'https://prostaff.gg' ) )
604+ end
605+
560606 def authenticate_user!
561607 email = params [ :email ] &.downcase &.strip
562608 password = params [ :password ]
0 commit comments