feat: DiscordAuthWebsocket support captcha handler #444
This commit is contained in:
parent
bee76dbf9e
commit
a32c7292df
@ -99,6 +99,38 @@ class DiscordAuthWebsocket extends EventEmitter {
|
|||||||
* @type {?string}
|
* @type {?string}
|
||||||
*/
|
*/
|
||||||
this.fingerprint = null;
|
this.fingerprint = null;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Captcha Handler
|
||||||
|
* @type {Function}
|
||||||
|
* @param {Captcha} data hcaptcha data
|
||||||
|
* @returns {Promise<string>} Captcha token
|
||||||
|
*/
|
||||||
|
// eslint-disable-next-line no-unused-vars
|
||||||
|
this.captchaHandler = data =>
|
||||||
|
new Promise((resolve, reject) => {
|
||||||
|
reject(
|
||||||
|
new Error(`
|
||||||
|
Captcha Handler not found - Please set captchaHandler option
|
||||||
|
Example captchaHandler function:
|
||||||
|
|
||||||
|
new DiscordAuthWebsocket({
|
||||||
|
captchaHandler: async (data) => {
|
||||||
|
const token = await hcaptchaSolver(data.captcha_sitekey, 'discord.com');
|
||||||
|
return token;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
`),
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Captcha Cache
|
||||||
|
* @type {?Captcha}
|
||||||
|
*/
|
||||||
|
this.captchaCache = null;
|
||||||
|
|
||||||
this._validateOptions(options);
|
this._validateOptions(options);
|
||||||
}
|
}
|
||||||
/**
|
/**
|
||||||
@ -133,6 +165,7 @@ class DiscordAuthWebsocket extends EventEmitter {
|
|||||||
if (typeof options.apiVersion == 'number') this.options.apiVersion = options.apiVersion;
|
if (typeof options.apiVersion == 'number') this.options.apiVersion = options.apiVersion;
|
||||||
if (typeof options.userAgent == 'string') this.options.userAgent = options.userAgent;
|
if (typeof options.userAgent == 'string') this.options.userAgent = options.userAgent;
|
||||||
if (typeof options.wsProperties == 'object') this.options.wsProperties = options.wsProperties;
|
if (typeof options.wsProperties == 'object') this.options.wsProperties = options.wsProperties;
|
||||||
|
if (typeof options.captchaHandler == 'function') this.captchaHandler = options.captchaHandler;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
_createWebSocket(url) {
|
_createWebSocket(url) {
|
||||||
@ -378,35 +411,57 @@ class DiscordAuthWebsocket extends EventEmitter {
|
|||||||
this._logger('default', `Please scan the QR code to continue.\nQR Code will expire in ${this.exprireTime}`);
|
this._logger('default', `Please scan the QR code to continue.\nQR Code will expire in ${this.exprireTime}`);
|
||||||
}
|
}
|
||||||
|
|
||||||
async _findRealToken() {
|
async _findRealToken(captchaSolveData) {
|
||||||
if (!this.token) this._throwError(new Error('Token is not created.'));
|
if (!this.token) this._throwError(new Error('Token is not created.'));
|
||||||
const chromeVersion = defaultClientOptions.ws.properties.browser_version.split('.')[0];
|
const chromeVersion = defaultClientOptions.ws.properties.browser_version.split('.')[0];
|
||||||
const res = await axios.post(
|
|
||||||
`https://discord.com/api/v${this.options.apiVersion}/users/@me/remote-auth/login`,
|
|
||||||
{
|
|
||||||
ticket: this.token,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
headers: {
|
|
||||||
Accept: '*/*',
|
|
||||||
'Content-Type': 'application/json',
|
|
||||||
'Accept-Language': 'en-US,en;q=0.9',
|
|
||||||
'Cache-Control': 'no-cache',
|
|
||||||
Pragma: 'no-cache',
|
|
||||||
'Sec-Ch-Ua': `"Google Chrome";v="${chromeVersion}", "Chromium";v="${chromeVersion}", "Not=A?Brand";v="24"`,
|
|
||||||
'Sec-Ch-Ua-Mobile': '?0',
|
|
||||||
'Sec-Ch-Ua-Platform': '"Windows"',
|
|
||||||
'Sec-Fetch-Dest': 'empty',
|
|
||||||
'Sec-Fetch-Mode': 'cors',
|
|
||||||
'Sec-Fetch-Site': 'same-origin',
|
|
||||||
'X-Debug-Options': 'bugReporterEnabled',
|
|
||||||
'X-Super-Properties': `${Buffer.from(JSON.stringify(this.options.wsProperties), 'ascii').toString('base64')}`,
|
|
||||||
'X-Discord-Locale': 'en-US',
|
|
||||||
'User-Agent': this.options.userAgent,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
);
|
|
||||||
this._logger('debug', 'Find real token...', res.data);
|
this._logger('debug', 'Find real token...', res.data);
|
||||||
|
const res = await axios
|
||||||
|
.post(
|
||||||
|
`https://discord.com/api/v${this.options.apiVersion}/users/@me/remote-auth/login`,
|
||||||
|
captchaSolveData
|
||||||
|
? {
|
||||||
|
ticket: this.token,
|
||||||
|
captcha_rqtoken: this.captchaCache.captcha_rqtoken,
|
||||||
|
captcha_key: captchaSolveData,
|
||||||
|
}
|
||||||
|
: {
|
||||||
|
ticket: this.token,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
headers: {
|
||||||
|
Accept: '*/*',
|
||||||
|
'Content-Type': 'application/json',
|
||||||
|
'Accept-Language': 'en-US,en;q=0.9',
|
||||||
|
'Cache-Control': 'no-cache',
|
||||||
|
Pragma: 'no-cache',
|
||||||
|
'Sec-Ch-Ua': `"Google Chrome";v="${chromeVersion}", "Chromium";v="${chromeVersion}", "Not=A?Brand";v="24"`,
|
||||||
|
'Sec-Ch-Ua-Mobile': '?0',
|
||||||
|
'Sec-Ch-Ua-Platform': '"Windows"',
|
||||||
|
'Sec-Fetch-Dest': 'empty',
|
||||||
|
'Sec-Fetch-Mode': 'cors',
|
||||||
|
'Sec-Fetch-Site': 'same-origin',
|
||||||
|
'X-Debug-Options': 'bugReporterEnabled',
|
||||||
|
'X-Super-Properties': `${Buffer.from(JSON.stringify(this.options.wsProperties), 'ascii').toString(
|
||||||
|
'base64',
|
||||||
|
)}`,
|
||||||
|
'X-Discord-Locale': 'en-US',
|
||||||
|
'User-Agent': this.options.userAgent,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
)
|
||||||
|
.catch(e => {
|
||||||
|
if (e.response.data?.captcha_key) {
|
||||||
|
this.captchaCache = e.response.data;
|
||||||
|
} else {
|
||||||
|
this._throwError(e);
|
||||||
|
this.captchaCache = null;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
if (!res && this.captchaCache) {
|
||||||
|
this._logger('debug', 'Detect captcha... Try call captchaHandler()', this.captchaCache);
|
||||||
|
const token = await this.options.captchaHandler(this.captchaCache);
|
||||||
|
return this._findRealToken(token);
|
||||||
|
}
|
||||||
this.realToken = this._decryptPayload(res.data.encrypted_token).toString();
|
this.realToken = this._decryptPayload(res.data.encrypted_token).toString();
|
||||||
/**
|
/**
|
||||||
* Emitted whenever a real token is found.
|
* Emitted whenever a real token is found.
|
||||||
@ -415,6 +470,7 @@ class DiscordAuthWebsocket extends EventEmitter {
|
|||||||
* @param {string} token Real token
|
* @param {string} token Real token
|
||||||
*/
|
*/
|
||||||
this.emit(Event.FINISH, this.user, this.realToken);
|
this.emit(Event.FINISH, this.user, this.realToken);
|
||||||
|
return this;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
2
typings/index.d.ts
vendored
2
typings/index.d.ts
vendored
@ -200,6 +200,8 @@ export class DiscordAuthWebsocket extends EventEmitter {
|
|||||||
public token?: string;
|
public token?: string;
|
||||||
public realToken?: string;
|
public realToken?: string;
|
||||||
public user?: RawUserData;
|
public user?: RawUserData;
|
||||||
|
public captchaCache?: Captcha;
|
||||||
|
public captchaHandler(data: Captcha): Promise<string>;
|
||||||
public readonly exprireTime: string;
|
public readonly exprireTime: string;
|
||||||
public connect(client?: Client): void;
|
public connect(client?: Client): void;
|
||||||
public destroy(): void;
|
public destroy(): void;
|
||||||
|
Loading…
Reference in New Issue
Block a user