11import { Injectable , OnApplicationBootstrap } from '@nestjs/common' ;
2- import { Cron , CronExpression } from '@nestjs/schedule' ;
3- import type { User , UserSession } from '@prisma/client' ;
4- import { PrismaClient } from '@prisma/client' ;
52import type { CookieOptions , Request , Response } from 'express' ;
63import { assign , pick } from 'lodash-es' ;
74
85import { Config , MailService , SignUpForbidden } from '../../base' ;
9- import { Models } from '../../models' ;
6+ import { Models , type User , type UserSession } from '../../models' ;
107import { FeatureManagementService } from '../features/management' ;
118import { QuotaService } from '../quota/service' ;
129import { QuotaType } from '../quota/types' ;
@@ -47,7 +44,6 @@ export class AuthService implements OnApplicationBootstrap {
4744
4845 constructor (
4946 private readonly config : Config ,
50- private readonly db : PrismaClient ,
5147 private readonly models : Models ,
5248 private readonly mailer : MailService ,
5349 private readonly feature : FeatureManagementService ,
@@ -105,14 +101,9 @@ export class AuthService implements OnApplicationBootstrap {
105101 async signOut ( sessionId : string , userId ?: string ) {
106102 // sign out all users in the session
107103 if ( ! userId ) {
108- await this . models . session . delete ( sessionId ) ;
104+ await this . models . session . deleteSession ( sessionId ) ;
109105 } else {
110- await this . db . userSession . deleteMany ( {
111- where : {
112- sessionId,
113- userId,
114- } ,
115- } ) ;
106+ await this . models . session . deleteUserSession ( userId , sessionId ) ;
116107 }
117108 }
118109
@@ -136,7 +127,8 @@ export class AuthService implements OnApplicationBootstrap {
136127 // fallback to the first valid session if user provided userId is invalid
137128 if ( ! userSession ) {
138129 // checked
139- userSession = sessions . at ( - 1 ) as UserSession ;
130+ // oxlint-disable-next-line @typescript-eslint/no-non-null-assertion
131+ userSession = sessions . at ( - 1 ) ! ;
140132 }
141133
142134 const user = await this . user . findUserById ( userSession . userId ) ;
@@ -149,117 +141,50 @@ export class AuthService implements OnApplicationBootstrap {
149141 }
150142
151143 async getUserSessions ( sessionId : string ) {
152- return this . db . userSession . findMany ( {
153- where : {
154- sessionId,
155- OR : [ { expiresAt : { gt : new Date ( ) } } , { expiresAt : null } ] ,
156- } ,
157- orderBy : {
158- createdAt : 'asc' ,
159- } ,
160- } ) ;
144+ return await this . models . session . findUserSessionsBySessionId ( sessionId ) ;
161145 }
162146
163- async createUserSession (
164- userId : string ,
165- sessionId ?: string ,
166- ttl = this . config . auth . session . ttl
167- ) {
168- // check whether given session is valid
169- if ( sessionId ) {
170- const session = await this . getSession ( sessionId ) ;
171-
172- if ( ! session ) {
173- sessionId = undefined ;
174- }
175- }
176-
177- if ( ! sessionId ) {
178- const session = await this . createSession ( ) ;
179- sessionId = session . id ;
180- }
181-
182- const expiresAt = new Date ( Date . now ( ) + ttl * 1000 ) ;
183-
184- return this . db . userSession . upsert ( {
185- where : {
186- sessionId_userId : {
187- sessionId,
188- userId,
189- } ,
190- } ,
191- update : {
192- expiresAt,
193- } ,
194- create : {
195- sessionId,
196- userId,
197- expiresAt,
198- } ,
199- } ) ;
147+ async createUserSession ( userId : string , sessionId ?: string , ttl ?: number ) {
148+ return await this . models . session . createOrRefreshUserSession (
149+ userId ,
150+ sessionId ,
151+ ttl
152+ ) ;
200153 }
201154
202155 async getUserList ( sessionId : string ) {
203- const sessions = await this . db . userSession . findMany ( {
204- where : {
205- sessionId,
206- OR : [
207- {
208- expiresAt : null ,
209- } ,
210- {
211- expiresAt : {
212- gt : new Date ( ) ,
213- } ,
214- } ,
215- ] ,
216- } ,
217- include : {
156+ const sessions = await this . models . session . findUserSessionsBySessionId (
157+ sessionId ,
158+ {
218159 user : true ,
219- } ,
220- orderBy : {
221- createdAt : 'asc' ,
222- } ,
223- } ) ;
224-
160+ }
161+ ) ;
225162 return sessions . map ( ( { user } ) => sessionUser ( user ) ) ;
226163 }
227164
228165 async createSession ( ) {
229- return await this . models . session . create ( ) ;
166+ return await this . models . session . createSession ( ) ;
230167 }
231168
232169 async getSession ( sessionId : string ) {
233- return await this . models . session . get ( sessionId ) ;
170+ return await this . models . session . getSession ( sessionId ) ;
234171 }
235172
236173 async refreshUserSessionIfNeeded (
237174 res : Response ,
238- session : UserSession ,
239- ttr = this . config . auth . session . ttr
175+ userSession : UserSession ,
176+ ttr ?: number
240177 ) : Promise < boolean > {
241- if (
242- session . expiresAt &&
243- session . expiresAt . getTime ( ) - Date . now ( ) > ttr * 1000
244- ) {
178+ const newExpiresAt = await this . models . session . refreshUserSessionIfNeeded (
179+ userSession ,
180+ ttr
181+ ) ;
182+ if ( ! newExpiresAt ) {
245183 // no need to refresh
246184 return false ;
247185 }
248186
249- const newExpiresAt = new Date (
250- Date . now ( ) + this . config . auth . session . ttl * 1000
251- ) ;
252-
253- await this . db . userSession . update ( {
254- where : {
255- id : session . id ,
256- } ,
257- data : {
258- expiresAt : newExpiresAt ,
259- } ,
260- } ) ;
261-
262- res . cookie ( AuthService . sessionCookieName , session . sessionId , {
187+ res . cookie ( AuthService . sessionCookieName , userSession . sessionId , {
263188 expires : newExpiresAt ,
264189 ...this . cookieOptions ,
265190 } ) ;
@@ -268,11 +193,7 @@ export class AuthService implements OnApplicationBootstrap {
268193 }
269194
270195 async revokeUserSessions ( userId : string ) {
271- return this . db . userSession . deleteMany ( {
272- where : {
273- userId,
274- } ,
275- } ) ;
196+ return await this . models . session . deleteUserSession ( userId ) ;
276197 }
277198
278199 getSessionOptionsFromRequest ( req : Request ) {
@@ -412,15 +333,4 @@ export class AuthService implements OnApplicationBootstrap {
412333 to : email ,
413334 } ) ;
414335 }
415-
416- @Cron ( CronExpression . EVERY_DAY_AT_MIDNIGHT )
417- async cleanExpiredSessions ( ) {
418- await this . db . userSession . deleteMany ( {
419- where : {
420- expiresAt : {
421- lte : new Date ( ) ,
422- } ,
423- } ,
424- } ) ;
425- }
426336}
0 commit comments