From 70f3298f01cab767585649741a052dd9928a5b1f Mon Sep 17 00:00:00 2001 From: lethemanh Date: Thu, 15 May 2025 11:55:42 +0700 Subject: [PATCH] =?UTF-8?q?=F0=9F=90=9B=20Fix=20sessions=20could=20not=20r?= =?UTF-8?q?emove=20after=20delete=20account=20success?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../controller/delete-user-controller.ts | 2 +- .../src/services/console/client-interface.ts | 2 +- .../src/services/console/clients/internal.ts | 2 +- .../src/services/console/clients/remote.ts | 26 +++++++++++++++++-- .../services/user/services/users/service.ts | 15 ++++++++--- 5 files changed, 39 insertions(+), 8 deletions(-) diff --git a/tdrive/backend/node/src/core/platform/services/admin/controller/delete-user-controller.ts b/tdrive/backend/node/src/core/platform/services/admin/controller/delete-user-controller.ts index 5424ae72..3f87e2cc 100644 --- a/tdrive/backend/node/src/core/platform/services/admin/controller/delete-user-controller.ts +++ b/tdrive/backend/node/src/core/platform/services/admin/controller/delete-user-controller.ts @@ -16,7 +16,7 @@ export class AdminDeleteUserController { userId: string, ): Promise<{ status: "failed" | "deleting" | "done"; userId?: string }> { try { - await gr.services.console.getClient().userWasDeletedForceLogout(userId); + await gr.services.console.getClient().userWasDeletedForceLogout({ userId }); await gr.services.users.markToDeleted({ id: userId }); } catch (err) { adminLogger.error({ err, userId }, "[DELETE USER] Error dustin updating user "); diff --git a/tdrive/backend/node/src/services/console/client-interface.ts b/tdrive/backend/node/src/services/console/client-interface.ts index 01878cc5..0bb27167 100644 --- a/tdrive/backend/node/src/services/console/client-interface.ts +++ b/tdrive/backend/node/src/services/console/client-interface.ts @@ -72,7 +72,7 @@ export interface ConsoleServiceClient { * Similar to backChannelLogout, but must be called by administrative authorized * code in case of user immediate kick out */ - userWasDeletedForceLogout(userId: string): Promise; + userWasDeletedForceLogout(payload: { userId?: string; email?: string }): Promise; resendVerificationEmail(email: string): Promise; } diff --git a/tdrive/backend/node/src/services/console/clients/internal.ts b/tdrive/backend/node/src/services/console/clients/internal.ts index a113e5b1..e70c4ee8 100644 --- a/tdrive/backend/node/src/services/console/clients/internal.ts +++ b/tdrive/backend/node/src/services/console/clients/internal.ts @@ -115,7 +115,7 @@ export class ConsoleInternalClient implements ConsoleServiceClient { throw new Error("Method should not be implemented."); } - async userWasDeletedForceLogout(_userId: string) { + async userWasDeletedForceLogout(_payload: { userId?: string; email?: string }) { logger.info("Internal: userWasDeletedForceLogout"); throw new Error("Method should not be implemented."); } diff --git a/tdrive/backend/node/src/services/console/clients/remote.ts b/tdrive/backend/node/src/services/console/clients/remote.ts index 04b573fc..5014413d 100644 --- a/tdrive/backend/node/src/services/console/clients/remote.ts +++ b/tdrive/backend/node/src/services/console/clients/remote.ts @@ -328,10 +328,32 @@ export class ConsoleRemoteClient implements ConsoleServiceClient { } } - async userWasDeletedForceLogout(userId: string) { + async userWasDeletedForceLogout(payload: { userId?: string; email?: string }) { const sessionRepository = gr.services.console.getSessionRepo(); if (!sessionRepository) return; - const sessions = (await sessionRepository.find({ sub: userId })).getEntities(); + + const { userId, email } = payload; + if (!userId && !email) { + logger.info("Missing query condition for session"); + return; + } + + /* Get sessions by userId or email + * Use condition to query for each criterias + * In case DB type is postgres we could not query by using IN as mongodb + * due to the function validate query of postgres do not allow to use array for column type string + */ + let sessions: Session[] = []; + if (userId) { + const results = (await sessionRepository.find({ sub: userId })).getEntities(); + sessions = sessions.concat(results); + } + if (email) { + const results = (await sessionRepository.find({ sub: email })).getEntities(); + sessions = sessions.concat(results); + } + + logger.info({ sessions }, "Sessions to delete"); for (const session of sessions) if (!session.revoked_at) { session.revoked_at = new Date().getTime(); diff --git a/tdrive/backend/node/src/services/user/services/users/service.ts b/tdrive/backend/node/src/services/user/services/users/service.ts index 827a8cad..13ce5bdd 100644 --- a/tdrive/backend/node/src/services/user/services/users/service.ts +++ b/tdrive/backend/node/src/services/user/services/users/service.ts @@ -33,7 +33,7 @@ import gr from "../../../global-resolver"; import { TYPE as DriveFileType, DriveFile } from "../../../documents/entities/drive-file"; import { UpdateUser } from "./types"; import { formatUsername } from "../../../../utils/users"; -import { logger } from "../../../../core/platform/framework"; +import { Configuration, logger } from "../../../../core/platform/framework"; export class UserServiceImpl { version: "1"; @@ -44,6 +44,7 @@ export class UserServiceImpl { driveFileRepository: Repository; private deviceRepository: Repository; private cache: NodeCache; + private configuration: Configuration; async init(): Promise { this.searchRepository = gr.platformServices.search.getRepository("user", User); @@ -62,6 +63,8 @@ export class UserServiceImpl { this.cache = new NodeCache({ stdTTL: 0.2, checkperiod: 120 }); + this.configuration = new Configuration("general.accounts"); + //If user deleted from Tdrive, remove it from all companies localEventBus.subscribe("user:deleted", async data => { if (data?.user?.id) gr.services.companies.ensureDeletedUserNotInCompanies(data.user); @@ -124,7 +127,10 @@ export class UserServiceImpl { const isChangeEmail = currentEmail !== body.email; if (isChangeEmail) { - await gr.services.console.getClient().userWasDeletedForceLogout(currentEmail); + const accType = this.configuration.get("type"); + if (accType === "remote") { + await gr.services.console.getClient().userWasDeletedForceLogout({ email: currentEmail }); + } const userByEmail = await gr.services.users.getByEmail(body.email, context); if (userByEmail) { throw CrudException.badRequest(`Email ${body.email} is existed`); @@ -186,7 +192,10 @@ export class UserServiceImpl { user.deleted = true; user.delete_process_started_epoch = new Date().getTime(); - await gr.services.console.getClient().userWasDeletedForceLogout(user.id); + await gr.services.console.getClient().userWasDeletedForceLogout({ + userId: user.id, + email: userCopy.email_canonical, + }); await this.save(user);