@@ -7,15 +7,24 @@ import { Request, Response } from 'express';
77import { Op } from 'sequelize' ;
88
99import { getSystemConfig } from '../config/getSystemConfig' ;
10+ import { setAuthCookies } from '../lib/cookie' ;
11+ import { generateRefreshToken , hashRefreshToken , signAccessToken } from '../lib/token' ;
12+ import { AuthEvent } from '../models/authEvents' ;
1013import { MagicLinkToken } from '../models/magicLinks' ;
14+ import { Session } from '../models/sessions' ;
1115import { User } from '../models/users' ;
12- import { MagicLinkVerifyQuerySchema } from '../schemas/magicLink.schema' ;
1316import { AuthEventService } from '../services/authEventService' ;
1417import { sendMagicLinkEmail } from '../services/messagingService' ;
1518import { AuthenticatedRequest } from '../types/types' ;
16- import { hashDeviceFingerprint , hashSha256 } from '../utils/utils' ;
19+ import {
20+ computeSessionTimes ,
21+ hashDeviceFingerprint ,
22+ hashSha256 ,
23+ parseDurationToSeconds ,
24+ } from '../utils/utils' ;
1725
1826const TTL_MINUTES = 15 ;
27+ const AUTH_MODE : 'web' | 'server' = process . env . AUTH_MODE ! as 'web' | 'server' ;
1928
2029export async function requestMagicLink ( req : Request , res : Response ) {
2130 const authReq = req as AuthenticatedRequest ;
@@ -166,7 +175,59 @@ export async function pollMagicLinkConfirmation(req: Request, res: Response) {
166175 type : 'magic_link_poll_completed_successfully' ,
167176 req,
168177 } ) ;
169- return res . status ( 200 ) . json ( { message : 'Success' } ) ;
178+
179+ const refreshToken = generateRefreshToken ( ) ;
180+ const refreshTokenHash = await hashRefreshToken ( refreshToken ) ;
181+ const { expiresAt, idleExpiresAt } = computeSessionTimes ( ) ;
182+
183+ const session = await Session . create ( {
184+ userId : user . id ,
185+ infraId : process . env . APP_ID ! ,
186+ mode : AUTH_MODE ,
187+ refreshTokenHash,
188+ userAgent : req . get ( 'user-agent' ) ,
189+ ipAddress : req . ip ,
190+ expiresAt,
191+ idleExpiresAt,
192+ lastUsedAt : undefined ,
193+ } ) ;
194+
195+ const token = await signAccessToken ( session . id , user . id , user . roles ) ;
196+
197+ user . challenge = '' ;
198+ user . verified = true ;
199+
200+ await user . save ( ) ;
201+
202+ if ( token && refreshToken ) {
203+ await AuthEvent . create ( {
204+ user_id : user . id ,
205+ type : 'registration_success' ,
206+ ip_address : req . ip ,
207+ user_agent : req . headers [ 'user-agent' ] ,
208+ metadata : { } ,
209+ } ) ;
210+
211+ if ( AUTH_MODE === 'web' ) {
212+ await setAuthCookies ( res , { accessToken : token , refreshToken } ) ;
213+ res . status ( 200 ) . json ( { message : 'Success' } ) ;
214+ return ;
215+ }
216+
217+ const { access_token_ttl, refresh_token_ttl } = await getSystemConfig ( ) ;
218+
219+ return res . status ( 200 ) . json ( {
220+ message : 'Success' ,
221+ token,
222+ refreshToken,
223+ sub : user . id ,
224+ roles : user . roles ,
225+ email : user . email ,
226+ phone : user . phone ,
227+ ttl : parseDurationToSeconds ( access_token_ttl || '15m' ) ,
228+ refreshTtl : parseDurationToSeconds ( refresh_token_ttl || '1h' ) ,
229+ } ) ;
230+ }
170231 }
171232
172233 return res . status ( 204 ) . json ( { error : 'Not verified.' } ) ;
0 commit comments