@@ -7,6 +7,7 @@ import { generateSteamCode } from '../services/steamService';
77import { guardWriteByIp } from '../middleware/rateLimiters' ;
88import {
99 finishSteamEnrollment ,
10+ refreshSteamLoginSession ,
1011 startSteamEnrollment ,
1112 SteamEnrollmentError
1213} from '../services/steamEnrollmentService' ;
@@ -474,7 +475,7 @@ const accountRoutes: FastifyPluginAsync = async (app) => {
474475
475476 app . post < {
476477 Params : { accountId : string } ;
477- Body : { steamLoginSecure ?: string ; sessionid ?: string ; oauthToken ?: string ; steamid ?: string } ;
478+ Body : { steamLoginSecure ?: string ; sessionid ?: string ; oauthToken ?: string ; refreshToken ?: string ; steamid ?: string } ;
478479 } > ( '/api/accounts/:accountId/session' , { preHandler : app . authenticate } , async ( request , reply ) => {
479480 const accountId = Number ( request . params . accountId ) ;
480481 const user = await getUserSecret ( request . user . id ) ;
@@ -485,11 +486,17 @@ const accountRoutes: FastifyPluginAsync = async (app) => {
485486 return reply . code ( 404 ) . send ( { message : error . message } ) ;
486487 }
487488
489+ const cookieTokenPart =
490+ request . body . steamLoginSecure && request . body . steamLoginSecure . includes ( '||' )
491+ ? request . body . steamLoginSecure . split ( '||' ) [ 1 ]
492+ : undefined ;
493+
488494 const session = {
489495 steamid : request . body . steamid ,
490496 steamLoginSecure : request . body . steamLoginSecure ,
491497 sessionid : request . body . sessionid ,
492- oauthToken : request . body . oauthToken
498+ oauthToken : request . body . oauthToken ?? cookieTokenPart ,
499+ refreshToken : request . body . refreshToken
493500 } ;
494501
495502 await execute (
@@ -507,6 +514,101 @@ const accountRoutes: FastifyPluginAsync = async (app) => {
507514 return { success : true } ;
508515 } ) ;
509516
517+ app . post < {
518+ Params : { accountId : string } ;
519+ Body : { password ?: string ; guardCode ?: string } ;
520+ } > ( '/api/accounts/:accountId/reconnect' , { preHandler : app . authenticate } , async ( request , reply ) => {
521+ try {
522+ await guardWriteByIp ( request . ip ) ;
523+ } catch ( error : any ) {
524+ return reply . code ( 429 ) . send ( { message : error . message } ) ;
525+ }
526+
527+ const accountId = Number ( request . params . accountId ) ;
528+ const password = request . body . password ;
529+ const guardCode = request . body . guardCode ?. trim ( ) ;
530+ const user = await getUserSecret ( request . user . id ) ;
531+
532+ if ( ! password ) {
533+ return reply . code ( 400 ) . send ( { message : 'Steam password is required' } ) ;
534+ }
535+
536+ let account : AccountRow ;
537+ try {
538+ account = await getAccountByOwner ( request . user . id , accountId ) ;
539+ } catch ( error : any ) {
540+ return reply . code ( 404 ) . send ( { message : error . message } ) ;
541+ }
542+
543+ try {
544+ const ma = parseMaFile ( decryptForUser ( account . encrypted_ma , user . password_hash , user . id ) ) ;
545+ const { steamid, session } = await refreshSteamLoginSession ( {
546+ accountName : account . account_name ,
547+ password,
548+ guardCode,
549+ totpCodeProvider : ( ) => generateSteamCode ( ma . shared_secret )
550+ } ) ;
551+
552+ ma . Session = {
553+ ...( ma . Session ?? { } ) ,
554+ SteamID : session . steamid ?? steamid ,
555+ SteamLoginSecure : session . steamLoginSecure ,
556+ SessionID : session . sessionid ,
557+ OAuthToken : session . oauthToken ,
558+ RefreshToken : session . refreshToken
559+ } ;
560+
561+ await execute (
562+ `UPDATE user_accounts
563+ SET steamid = ?, encrypted_ma = ?
564+ WHERE id = ? AND user_id = ?` ,
565+ [
566+ steamid ,
567+ encryptForUser ( JSON . stringify ( ma ) , user . password_hash , user . id ) ,
568+ accountId ,
569+ request . user . id
570+ ]
571+ ) ;
572+
573+ await execute (
574+ `INSERT INTO account_sessions (account_id, session_json)
575+ VALUES (?, ?)
576+ ON DUPLICATE KEY UPDATE session_json = VALUES(session_json)` ,
577+ [ accountId , encodeAccountSession ( session , user . password_hash , user . id ) ]
578+ ) ;
579+
580+ await execute (
581+ "INSERT INTO logs (user_id, account_id, type, details) VALUES (?, ?, 'system', JSON_OBJECT('event', 'session_updated'))" ,
582+ [ request . user . id , accountId ]
583+ ) ;
584+
585+ return {
586+ success : true ,
587+ steamid
588+ } ;
589+ } catch ( error : any ) {
590+ if ( error instanceof SteamEnrollmentError ) {
591+ if ( error . code === 'STEAM_GUARD_REQUIRED' ) {
592+ return reply . code ( 428 ) . send ( {
593+ code : error . code ,
594+ guardType : error . guardType ,
595+ guardDomain : error . guardDomain ?? null ,
596+ message : error . message
597+ } ) ;
598+ }
599+
600+ if ( error . code === 'STEAM_GUARD_INVALID' ) {
601+ return reply . code ( 400 ) . send ( {
602+ code : error . code ,
603+ message : error . message
604+ } ) ;
605+ }
606+ }
607+
608+ return reply . code ( 400 ) . send ( { message : error . message || 'Failed to refresh Steam session' } ) ;
609+ }
610+ } ) ;
611+
510612 app . get < { Params : { accountId : string } } > (
511613 '/api/accounts/:accountId/code' ,
512614 { preHandler : app . authenticate } ,
0 commit comments