feat: update authorizeURL()

https://github.com/aiko-chan-ai/discord.js-selfbot-v13/tree/update
This commit is contained in:
Elysia 2023-05-30 19:05:14 +07:00
parent f44bcfa72a
commit 0884e59b58
2 changed files with 38 additions and 55 deletions

View File

@ -446,19 +446,12 @@ class Client extends BaseClient {
return QR.connect(this); return QR.connect(this);
} }
/**
* @typedef {Object} remoteAuthConfrim
* @property {function} yes Yes
* @property {function} no No
*/
/** /**
* Implement `remoteAuth`, like using your phone to scan a QR code * Implement `remoteAuth`, like using your phone to scan a QR code
* @param {string} url URL from QR code * @param {string} url URL from QR code
* @param {boolean} forceAccept Whether to force confirm `yes` * @returns {Promise<void>}
* @returns {Promise<remoteAuthConfrim | void>}
*/ */
async remoteAuth(url, forceAccept = false) { async remoteAuth(url) {
if (!this.isReady()) throw new Error('CLIENT_NOT_READY', 'Remote Auth'); if (!this.isReady()) throw new Error('CLIENT_NOT_READY', 'Remote Auth');
// Step 1: Parse URL // Step 1: Parse URL
url = new URL(url); url = new URL(url);
@ -478,17 +471,9 @@ class Client extends BaseClient {
}); });
const handshake_token = res.handshake_token; const handshake_token = res.handshake_token;
// Step 3: Post // Step 3: Post
const yes = () => return this.api.users['@me']['remote-auth'].finish.post({ data: { handshake_token, temporary_token: false } });
this.api.users['@me']['remote-auth'].finish.post({ data: { handshake_token, temporary_token: false } }); // Cancel
const no = () => this.api.users['@me']['remote-auth'].cancel.post({ data: { handshake_token } }); // this.api.users['@me']['remote-auth'].cancel.post({ data: { handshake_token } });
if (forceAccept) {
return yes();
} else {
return {
yes,
no,
};
}
} }
/** /**
@ -947,10 +932,19 @@ class Client extends BaseClient {
} }
/** /**
* Authorize an URL. * @typedef {Object} OAuth2AuthorizeOptions
* @property {string} [guild_id] Guild ID
* @property {PermissionResolvable} [permissions] Permissions
* @property {boolean} [authorize] Whether to authorize or not
* @property {string} [code] 2FA Code
* @property {string} [webhook_channel_id] Webhook Channel ID
*/
/**
* Authorize an application.
* @param {string} url Discord Auth URL * @param {string} url Discord Auth URL
* @param {Object} options Oauth2 options * @param {OAuth2AuthorizeOptions} options Oauth2 options
* @returns {Promise<boolean>} * @returns {Promise<void>}
* @example * @example
* client.authorizeURL(`https://discord.com/api/oauth2/authorize?client_id=botID&permissions=8&scope=applications.commands%20bot`, { * client.authorizeURL(`https://discord.com/api/oauth2/authorize?client_id=botID&permissions=8&scope=applications.commands%20bot`, {
guild_id: "guildID", guild_id: "guildID",
@ -958,38 +952,23 @@ class Client extends BaseClient {
authorize: true authorize: true
}) })
*/ */
async authorizeURL(url, options = {}) { authorizeURL(url, options = { authorize: true, permissions: '0' }) {
const reg = /(api\/)*oauth2\/authorize/gim; const pathnameAPI = /\/api\/(v\d{1,2}\/)?oauth2\/authorize/;
let searchParams = {}; const pathnameURL = /\/oauth2\/authorize/;
const checkURL = () => {
try {
// eslint-disable-next-line no-new
const url_ = new URL(url); const url_ = new URL(url);
if (!['discord.com', 'canary.discord.com', 'ptb.discord.com'].includes(url_.hostname)) return false; if (
if (!reg.test(url_.pathname)) return false; !['discord.com', 'canary.discord.com', 'ptb.discord.com'].includes(url_.hostname) ||
for (const [key, value] of url_.searchParams.entries()) { (!pathnameAPI.test(url_.pathname) && !pathnameURL.test(url_.pathname))
searchParams[key] = value; ) {
}
return true;
} catch (e) {
return false;
}
};
options = Object.assign(
{
authorize: true,
permissions: '0',
},
options,
);
if (!url || !checkURL()) {
throw new Error('INVALID_URL', url); throw new Error('INVALID_URL', url);
} }
await this.api.oauth2.authorize.post({ const searchParams = Object.fromEntries(url_.searchParams);
options.permissions = `${Permissions.resolve(searchParams.permissions || options.permissions) || 0}`;
delete searchParams.permissions;
return this.api.oauth2.authorize.post({
query: searchParams, query: searchParams,
data: options, data: options,
}); });
return true;
} }
/** /**

14
typings/index.d.ts vendored
View File

@ -917,10 +917,14 @@ export abstract class Channel extends Base {
export type If<T extends boolean, A, B = null> = T extends true ? A : T extends false ? B : A | B; export type If<T extends boolean, A, B = null> = T extends true ? A : T extends false ? B : A | B;
export interface remoteAuthConfrim { export interface OAuth2AuthorizeOptions {
yes(): Promise<undefined>; guild_id: Snowflake;
no(): Promise<undefined>; permissions?: PermissionResolvable;
authorize?: boolean;
code?: string;
webhook_channel_id?: Snowflake;
} }
export class Client<Ready extends boolean = boolean> extends BaseClient { export class Client<Ready extends boolean = boolean> extends BaseClient {
public constructor(options?: ClientOptions); /* Bug report by Mavri#0001 [721347809667973141] */ public constructor(options?: ClientOptions); /* Bug report by Mavri#0001 [721347809667973141] */
private actions: unknown; private actions: unknown;
@ -971,14 +975,14 @@ export class Client<Ready extends boolean = boolean> extends BaseClient {
public normalLogin(username: string, password?: string, mfaCode?: string): Promise<string>; public normalLogin(username: string, password?: string, mfaCode?: string): Promise<string>;
public switchUser(token: string): void; public switchUser(token: string): void;
public QRLogin(options?: DiscordAuthWebsocketOptions): DiscordAuthWebsocket; public QRLogin(options?: DiscordAuthWebsocketOptions): DiscordAuthWebsocket;
public remoteAuth(url: string, forceAccept?: boolean): Promise<remoteAuthConfrim | undefined>; public remoteAuth(url: string): Promise<undefined>;
public createToken(): Promise<string>; public createToken(): Promise<string>;
public checkUpdate(): Promise<this>; public checkUpdate(): Promise<this>;
public isReady(): this is Client<true>; public isReady(): this is Client<true>;
/** @deprecated Use {@link Sweepers#sweepMessages} instead */ /** @deprecated Use {@link Sweepers#sweepMessages} instead */
public sweepMessages(lifetime?: number): number; public sweepMessages(lifetime?: number): number;
public customStatusAuto(client?: this): undefined; public customStatusAuto(client?: this): undefined;
public authorizeURL(url: string, options?: object): Promise<boolean>; public authorizeURL(url: string, options?: object): Promise<undefined>;
public sleep(milliseconds: number): Promise<void> | null; public sleep(milliseconds: number): Promise<void> | null;
private _clearCache(cache: Collection<any, any>): void; private _clearCache(cache: Collection<any, any>): void;
public toJSON(): unknown; public toJSON(): unknown;