@@ -5,11 +5,10 @@ import { Prisma } from '@prisma/client';
55import { customAlphabet } from 'nanoid' ;
66import dayjs from 'dayjs' ;
77
8- import { CommandBus , EventBus , QueryBus } from '@nestjs/cqrs' ;
98import { Inject , Injectable , Logger } from '@nestjs/common' ;
10- import { Transactional } from '@nestjs-cls/transactional' ;
119import { EventEmitter2 } from '@nestjs/event-emitter' ;
1210import { CACHE_MANAGER } from '@nestjs/cache-manager' ;
11+ import { EventBus , QueryBus } from '@nestjs/cqrs' ;
1312import { ConfigService } from '@nestjs/config' ;
1413
1514import { wrapBigInt , wrapBigIntNullable } from '@common/utils' ;
@@ -54,7 +53,6 @@ export class UsersService {
5453
5554 constructor (
5655 private readonly userRepository : UsersRepository ,
57- private readonly commandBus : CommandBus ,
5856 private readonly eventBus : EventBus ,
5957 private readonly eventEmitter : EventEmitter2 ,
6058 private readonly queryBus : QueryBus ,
@@ -72,9 +70,9 @@ export class UsersService {
7270 const userEntity = new BaseUserEntity ( {
7371 username : dto . username ,
7472 shortUuid : dto . shortUuid || this . createNanoId ( ) ,
75- trojanPassword : dto . trojanPassword || this . createTrojanPassword ( ) ,
73+ trojanPassword : dto . trojanPassword || this . createPassword ( ) ,
7674 vlessUuid : dto . vlessUuid || this . createUuid ( ) ,
77- ssPassword : dto . ssPassword || this . createSSPassword ( ) ,
75+ ssPassword : dto . ssPassword || this . createPassword ( ) ,
7876 status : dto . status ,
7977 trafficLimitBytes : wrapBigInt ( dto . trafficLimitBytes ) ,
8078 trafficLimitStrategy : dto . trafficLimitStrategy ,
@@ -138,72 +136,13 @@ export class UsersService {
138136 }
139137
140138 public async updateUser ( dto : UpdateUserRequestDto ) : Promise < TResult < UserEntity > > {
141- try {
142- const user = await this . updateUserTransactional ( dto ) ;
143-
144- if ( ! user . isOk ) return fail ( ERRORS . UPDATE_USER_ERROR ) ;
145-
146- if (
147- user . response . user . status === USERS_STATUS . ACTIVE &&
148- user . response . isNeedToBeAddedToNode &&
149- ! user . response . isNeedToBeRemovedFromNode
150- ) {
151- this . eventBus . publish ( new AddUserToNodeEvent ( user . response . user . uuid ) ) ;
152- }
153-
154- if ( user . response . isNeedToBeRemovedFromNode ) {
155- this . eventBus . publish (
156- new RemoveUserFromNodeEvent (
157- user . response . user . tId ,
158- user . response . user . vlessUuid ,
159- ) ,
160- ) ;
161- }
162-
163- this . eventEmitter . emit (
164- EVENTS . USER . MODIFIED ,
165- new UserEvent ( {
166- user : user . response . user ,
167- event : EVENTS . USER . MODIFIED ,
168- } ) ,
169- ) ;
170-
171- await this . invalidateShortUuidRangeCache ( user . response . user . shortUuid ) ;
172-
173- return ok ( user . response . user ) ;
174- } catch ( error ) {
175- if ( error instanceof Error && error . message === ERRORS . USER_NOT_FOUND . code ) {
176- return fail ( ERRORS . USER_NOT_FOUND ) ;
177- }
178-
179- if (
180- error instanceof Error &&
181- error . message === ERRORS . CANT_GET_CREATED_USER_WITH_INBOUNDS . code
182- ) {
183- return fail ( ERRORS . CANT_GET_CREATED_USER_WITH_INBOUNDS ) ;
184- }
185-
186- this . logger . error ( error ) ;
187-
188- return fail ( ERRORS . UPDATE_USER_ERROR ) ;
189- }
190- }
191-
192- @Transactional ( )
193- public async updateUserTransactional ( dto : UpdateUserRequestDto ) : Promise <
194- TResult < {
195- isNeedToBeAddedToNode : boolean ;
196- isNeedToBeRemovedFromNode : boolean ;
197- user : UserEntity ;
198- } >
199- > {
200139 try {
201140 const {
202141 username,
203142 uuid,
204143 trafficLimitBytes,
205144 telegramId,
206- activeInternalSquads,
145+ activeInternalSquads : newActiveInternalSquadsUuids ,
207146 status,
208147 ...rest
209148 } = dto ;
@@ -214,28 +153,27 @@ export class UsersService {
214153 activeInternalSquads : true ,
215154 } ) ;
216155
217- if ( ! user ) {
218- throw new Error ( ERRORS . USER_NOT_FOUND . code ) ;
219- }
156+ if ( ! user ) return fail ( ERRORS . USER_NOT_FOUND ) ;
220157
221158 const newUserEntity = new BaseUserEntity ( {
222159 ...rest ,
223- uuid : user . uuid ,
160+ tId : user . tId ,
224161 trafficLimitBytes : wrapBigInt ( trafficLimitBytes ) ,
225162 telegramId : wrapBigIntNullable ( telegramId ) ,
226163 lastTriggeredThreshold : trafficLimitBytes !== undefined ? 0 : undefined ,
227164 } ) ;
228165
229- let isNeedToBeAddedToNode = false ;
230- let isNeedToBeRemovedFromNode = false ;
166+ let addToNode = false ;
167+ let removeFromNode = false ;
168+ let updateInternalSquads = false ;
231169
232170 if ( user . status !== 'ACTIVE' && status === 'ACTIVE' ) {
233- isNeedToBeAddedToNode = true ;
171+ addToNode = true ;
234172 newUserEntity . status = 'ACTIVE' ;
235173 }
236174
237175 if ( user . status === 'ACTIVE' && status === 'DISABLED' ) {
238- isNeedToBeRemovedFromNode = true ;
176+ removeFromNode = true ;
239177 newUserEntity . status = 'DISABLED' ;
240178 }
241179
@@ -246,7 +184,7 @@ export class UsersService {
246184 trafficLimitBytes === 0
247185 ) {
248186 newUserEntity . status = 'ACTIVE' ;
249- isNeedToBeAddedToNode = true ;
187+ addToNode = true ;
250188 }
251189 }
252190 }
@@ -259,18 +197,15 @@ export class UsersService {
259197 if ( ! currentExpireDate . isSame ( newExpireDate ) ) {
260198 if ( newExpireDate . isAfter ( now ) ) {
261199 newUserEntity . status = 'ACTIVE' ;
262- isNeedToBeAddedToNode = true ;
200+ addToNode = true ;
263201 }
264202 }
265203 }
266204
267- const result = await this . userRepository . update ( newUserEntity ) ;
268-
269- if ( activeInternalSquads ) {
270- const newActiveInternalSquadsUuids = activeInternalSquads ;
271-
272- const currentInternalSquadsUuids =
273- user . activeInternalSquads . map ( ( squad ) => squad . uuid ) || [ ] ;
205+ if ( newActiveInternalSquadsUuids ) {
206+ const currentInternalSquadsUuids = user . activeInternalSquads . map (
207+ ( squad ) => squad . uuid ,
208+ ) ;
274209
275210 const hasChanges =
276211 newActiveInternalSquadsUuids . length !== currentInternalSquadsUuids . length ||
@@ -279,41 +214,47 @@ export class UsersService {
279214 ) ;
280215
281216 if ( hasChanges ) {
282- await this . userRepository . removeUserFromInternalSquads ( result . tId ) ;
217+ updateInternalSquads = true ;
218+ removeFromNode = newActiveInternalSquadsUuids . length === 0 ;
219+ addToNode = newActiveInternalSquadsUuids . length > 0 ;
220+ }
221+ }
283222
284- if ( newActiveInternalSquadsUuids . length === 0 ) {
285- isNeedToBeRemovedFromNode = true ;
286- }
223+ const updatedUser = await this . userRepository . update ( {
224+ ...newUserEntity ,
225+ activeInternalSquads : newActiveInternalSquadsUuids || [ ] ,
226+ updateInternalSquads,
227+ } ) ;
228+
229+ if ( ! updatedUser ) {
230+ return fail ( ERRORS . UPDATE_USER_ERROR ) ;
231+ }
287232
288- if ( newActiveInternalSquadsUuids . length > 0 ) {
289- await this . userRepository . addUserToInternalSquads (
290- result . tId ,
291- newActiveInternalSquadsUuids ,
292- ) ;
233+ if ( updatedUser . status === USERS_STATUS . ACTIVE && addToNode && ! removeFromNode ) {
234+ this . eventBus . publish ( new AddUserToNodeEvent ( updatedUser . uuid ) ) ;
235+ }
293236
294- isNeedToBeAddedToNode = true ;
295- }
296- }
237+ if ( removeFromNode ) {
238+ this . eventBus . publish (
239+ new RemoveUserFromNodeEvent ( updatedUser . tId , updatedUser . vlessUuid ) ,
240+ ) ;
297241 }
298242
299- const userWithInbounds = await this . userRepository . findUniqueByCriteria (
300- { tId : result . tId } ,
301- {
302- activeInternalSquads : true ,
303- } ,
243+ this . eventEmitter . emit (
244+ EVENTS . USER . MODIFIED ,
245+ new UserEvent ( {
246+ user : updatedUser ,
247+ event : EVENTS . USER . MODIFIED ,
248+ } ) ,
304249 ) ;
305250
306- if ( ! userWithInbounds ) {
307- throw new Error ( ERRORS . CANT_GET_CREATED_USER_WITH_INBOUNDS . code ) ;
308- }
251+ await this . invalidateShortUuidRangeCache ( updatedUser . shortUuid ) ;
309252
310- return ok ( {
311- user : userWithInbounds ,
312- isNeedToBeAddedToNode,
313- isNeedToBeRemovedFromNode,
314- } ) ;
253+ return ok ( updatedUser ) ;
315254 } catch ( error ) {
316- throw error ;
255+ this . logger . error ( error ) ;
256+
257+ return fail ( ERRORS . UPDATE_USER_ERROR ) ;
317258 }
318259 }
319260
@@ -383,10 +324,12 @@ export class UsersService {
383324 const updateResult = await this . userRepository . revokeUserSubscription ( {
384325 uuid : user . uuid ,
385326 shortUuid : shortUuid ?? this . createNanoId ( ) ,
386- trojanPassword : this . createTrojanPassword ( ) ,
327+ trojanPassword : this . createPassword ( ) ,
387328 vlessUuid : this . createUuid ( ) ,
388- ssPassword : this . createTrojanPassword ( ) ,
329+ ssPassword : this . createPassword ( ) ,
389330 subRevokedAt : new Date ( ) ,
331+ subLastOpenedAt : null ,
332+ subLastUserAgent : null ,
390333 } ) ;
391334
392335 if ( ! updateResult ) return fail ( ERRORS . REVOKE_USER_SUBSCRIPTION_ERROR ) ;
@@ -867,16 +810,9 @@ export class UsersService {
867810 return nanoid ( ) ;
868811 }
869812
870- private createTrojanPassword ( ) : string {
871- const alphabet = '0123456789ABCDEFGHJKLMNPQRSTUVWXYZ_abcdefghjkmnopqrstuvwxyz-' ;
872- const nanoid = customAlphabet ( alphabet , 30 ) ;
873-
874- return nanoid ( ) ;
875- }
876-
877- private createSSPassword ( ) : string {
813+ private createPassword ( length : number = 32 ) : string {
878814 const alphabet = '0123456789ABCDEFGHJKLMNPQRSTUVWXYZ_abcdefghjkmnopqrstuvwxyz-' ;
879- const nanoid = customAlphabet ( alphabet , 32 ) ;
815+ const nanoid = customAlphabet ( alphabet , length ) ;
880816
881817 return nanoid ( ) ;
882818 }
0 commit comments