fix: enhance TOTP handling and improve documentation for TOTPKey

This commit is contained in:
Elysia
2025-07-10 20:31:29 +07:00
parent a82ba7aad1
commit 780dfe8078
2 changed files with 42 additions and 27 deletions

View File

@@ -386,36 +386,48 @@ class RequestHandler {
return this.execute(request, captcha, data.captcha_rqtoken); return this.execute(request, captcha, data.captcha_rqtoken);
} }
// Two factor handling // Two factor handling
if ( if (data?.code && data.code == 60003 && request.options.auth !== false && request.retries < 1) {
data?.code && // https://gist.github.com/Dziurwa14/de2498e5ee28d2089f095aa037957cbb
data.code == 60003 && // Two factor is required for this operation // 60003: Two factor is required for this operation
data.mfa.methods.find(o => o.type === 'totp') && // TOTP is available /**
typeof this.manager.client.options.TOTPKey === 'string' && * {
request.options.auth !== false && * message: "Two factor is required for this operation";
request.retries < 1 * code: 60003;
) { * mfa: {
// Get mfa code * ticket: string;
const otp = this.manager.client.authenticator.generate(this.manager.client.options.TOTPKey); * methods: {
this.manager.client.emit( * type: "password" | "totp" | "sms" | "backup" | "webauthn";
DEBUG, * }[];
`${data.message} * };
* };
*/
if (
data.mfa.methods.find(o => o.type === 'totp') &&
typeof this.manager.client.options.TOTPKey === 'string'
) {
// Get mfa code
const otp = this.manager.client.authenticator.generate(this.manager.client.options.TOTPKey);
this.manager.client.emit(
DEBUG,
`${data.message}
Method : ${request.method} Method : ${request.method}
Path : ${request.path} Path : ${request.path}
Route : ${request.route} Route : ${request.route}
mfaCode : ${otp}`, mfaCode : ${otp}`,
); );
// Get ticket // Get ticket
const mfaData = data.mfa; const mfaData = data.mfa;
const mfaPost = await this.manager.client.api.mfa.finish.post({ const mfaPost = await this.manager.client.api.mfa.finish.post({
data: { data: {
ticket: mfaData.ticket, ticket: mfaData.ticket,
data: otp, data: otp,
mfa_type: 'totp', mfa_type: 'totp',
}, },
}); });
request.options.mfaToken = mfaPost.token; request.options.mfaToken = mfaPost.token;
request.retries++; request.retries++;
return this.execute(request); return this.execute(request);
}
} }
} catch (err) { } catch (err) {
throw new HTTPError(err.message, err.constructor.name, err.status, request); throw new HTTPError(err.message, err.constructor.name, err.status, request);

View File

@@ -53,7 +53,10 @@ const Intents = require('./Intents');
* @property {number} [DMChannelVoiceStatusSync=0] The amount of time in milliseconds that the Client to register the event with each DM channel (0=Disable) * @property {number} [DMChannelVoiceStatusSync=0] The amount of time in milliseconds that the Client to register the event with each DM channel (0=Disable)
* @property {number} [captchaRetryLimit=3] Captcha retry limit * @property {number} [captchaRetryLimit=3] Captcha retry limit
* @property {CaptchaSolver} [captchaSolver] Captcha Solver * @property {CaptchaSolver} [captchaSolver] Captcha Solver
* @property {string} [TOTPKey] TOTP key for two-factor authentication * @property {string} [TOTPKey] TOTP key / 2FA Key for two-factor authentication
* This is a 32-character Base32 string (excluding spaces), typically shown only once during your 2FA setup (QR code), or in the "Manual Entry" section.
* The library automatically removes spaces and converts the secret to uppercase.
* Example value: 'ftc3 uz6q 5lpw 2kew 4thr vtyp n2cu topn' or 'WSLIVE6EKYSRMVRBZLFGG2KVIVJMMQY5'
* @property {number} [closeTimeout=5000] The amount of time in milliseconds to wait for the close frame to be received * @property {number} [closeTimeout=5000] The amount of time in milliseconds to wait for the close frame to be received
* from the WebSocket. * from the WebSocket.
* <info>Don't have this too high/low. It's best to have it between 2000-6000 ms.</info> * <info>Don't have this too high/low. It's best to have it between 2000-6000 ms.</info>