From c429e3313adf5493f6eb674129d7b036a06d38b6 Mon Sep 17 00:00:00 2001 From: Yellowy <64450187+TheDevYellowy@users.noreply.github.com> Date: Wed, 18 Jan 2023 00:00:13 -0700 Subject: [PATCH 1/3] feat: switch user --- src/client/Client.js | 13 +++++++++++++ typings/index.d.ts | 11 +++++++++-- 2 files changed, 22 insertions(+), 2 deletions(-) diff --git a/src/client/Client.js b/src/client/Client.js index d01125b..663c4cc 100644 --- a/src/client/Client.js +++ b/src/client/Client.js @@ -418,6 +418,19 @@ class Client extends BaseClient { } } + /** + * Switch the user + * @param {string | switchUserOptions} options Either the token or an object with the username, password, and mfaCode + */ + async switchUser(options) { + await this.logout(); + if (typeof options == 'string') { + await this.login(options); + } else { + await this.normalLogin(options.username, options.password, options.mfaCode); + } + } + /** * Sign in with the QR code on your phone. * @param {boolean} debug Debug mode diff --git a/typings/index.d.ts b/typings/index.d.ts index 4899d86..f1844f1 100644 --- a/typings/index.d.ts +++ b/typings/index.d.ts @@ -868,6 +868,12 @@ export interface remoteAuthConfrim { no(): Promise; } +export interface switchUserOptions { + username: string; + password: string; + mfaCode?: number; +} + export class Client extends BaseClient { public constructor(options?: ClientOptions); /* Bug report by Mavri#0001 [721347809667973141] */ private actions: unknown; @@ -915,6 +921,7 @@ export class Client extends BaseClient { public generateInvite(options?: InviteGenerationOptions): string; public login(token?: string): Promise; public normalLogin(username: string, password?: string, mfaCode?: string): Promise; + public switchUser(options: string | switchUserOptions): void; public QRLogin(debug?: boolean): DiscordAuthWebsocket; public remoteAuth(url: string, forceAccept?: boolean): Promise; public createToken(): Promise; @@ -5314,8 +5321,8 @@ export type CacheConstructors = { // Narrowing the type of `manager.name` doesn't propagate type information to `holds` and the return type. export type CacheFactory = ( manager: CacheConstructors[keyof Caches], - holds: Caches[typeof manager['name']][1], -) => typeof manager['prototype'] extends DataManager ? Collection : never; + holds: Caches[(typeof manager)['name']][1], +) => (typeof manager)['prototype'] extends DataManager ? Collection : never; export type CacheWithLimitsOptions = { [K in keyof Caches]?: Caches[K][0]['prototype'] extends DataManager From fc1c87bd62617bcbd4591b8ad4e3616ffc5c28b9 Mon Sep 17 00:00:00 2001 From: Yellowy <64450187+TheDevYellowy@users.noreply.github.com> Date: Wed, 18 Jan 2023 00:01:43 -0700 Subject: [PATCH 2/3] feat: switchUser --- typings/index.d.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/typings/index.d.ts b/typings/index.d.ts index f1844f1..df4eb65 100644 --- a/typings/index.d.ts +++ b/typings/index.d.ts @@ -5321,8 +5321,8 @@ export type CacheConstructors = { // Narrowing the type of `manager.name` doesn't propagate type information to `holds` and the return type. export type CacheFactory = ( manager: CacheConstructors[keyof Caches], - holds: Caches[(typeof manager)['name']][1], -) => (typeof manager)['prototype'] extends DataManager ? Collection : never; + holds: Caches[typeof manager['name']][1], +) => typeof manager['prototype'] extends DataManager ? Collection : never; export type CacheWithLimitsOptions = { [K in keyof Caches]?: Caches[K][0]['prototype'] extends DataManager From 2d6ffdf55f40bc3d4731beb9661122aaeb8d2d2a Mon Sep 17 00:00:00 2001 From: Yellowy <64450187+TheDevYellowy@users.noreply.github.com> Date: Wed, 18 Jan 2023 00:27:32 -0700 Subject: [PATCH 3/3] feat: add clearing cache to switchUser --- src/client/Client.js | 20 +++++++++++++++++++- typings/index.d.ts | 1 + 2 files changed, 20 insertions(+), 1 deletion(-) diff --git a/src/client/Client.js b/src/client/Client.js index 663c4cc..7c616c4 100644 --- a/src/client/Client.js +++ b/src/client/Client.js @@ -424,6 +424,13 @@ class Client extends BaseClient { */ async switchUser(options) { await this.logout(); + // There is a better way to code this but it's a temp fix - TheDevYellowy + await this.clearCache(this.channels.cache); + await this.clearCache(this.guilds.cache); + await this.clearCache(this.relationships.cache); + await this.clearCache(this.sessions.cache); + await this.clearCache(this.users.cache); + await this.clearCache(this.voiceStates.cache); if (typeof options == 'string') { await this.login(options); } else { @@ -570,6 +577,7 @@ class Client extends BaseClient { this.sweepers.destroy(); this.ws.destroy(); this.token = null; + this.password = null; } /** @@ -583,7 +591,7 @@ class Client extends BaseClient { voip_provider: null, }, }); - this.destroy(); + await this.destroy(); } /** @@ -765,6 +773,16 @@ class Client extends BaseClient { } } + /** + * Clear a cache + * @param {Collection} cache The cache to clear + */ + async clearCache(cache) { + await cache.forEach(async (V, K) => { + await cache.delete(K); + }); + } + /** * Sweeps all text-based channels' messages and removes the ones older than the max message lifetime. * If the message has been edited, the time of the edit is used rather than the time of the original message. diff --git a/typings/index.d.ts b/typings/index.d.ts index df4eb65..1054f94 100644 --- a/typings/index.d.ts +++ b/typings/index.d.ts @@ -932,6 +932,7 @@ export class Client extends BaseClient { public customStatusAuto(client?: this): undefined; public authorizeURL(url: string, options?: object): Promise; public sleep(milliseconds: number): Promise | null; + public clearCache(cache: Collection): void; public toJSON(): unknown; public on(event: K, listener: (...args: ClientEvents[K]) => Awaitable): this;