rush-mfa 1.0.8 → 1.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/index.js +85 -235
- package/package.json +1 -1
package/index.js
CHANGED
|
@@ -1,253 +1,103 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* rush-mfa - Discord MFA token generator
|
|
3
|
+
* @module rush-mfa
|
|
4
|
+
*/
|
|
1
5
|
"use strict";
|
|
2
|
-
|
|
3
|
-
const
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
const
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
};
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
};
|
|
21
|
-
|
|
22
|
-
const
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
const
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
const _genInstallId = () => {
|
|
29
|
-
const ts = BigInt(Date.now() - 1420070400000) << 22n;
|
|
30
|
-
const snowflake = ts | (BigInt(Math.floor(Math.random() * 31)) << 17n) | (BigInt(Math.floor(Math.random() * 31)) << 12n) | BigInt(Math.floor(Math.random() * 4095));
|
|
31
|
-
const rand = crypto.randomBytes(20).toString('base64').replace(/[+/=]/g, c => c === '+' ? 'a' : c === '/' ? 'b' : '').slice(0, 27);
|
|
32
|
-
return `${snowflake}.${rand}`;
|
|
33
|
-
};
|
|
34
|
-
const _getInstallId = () => { if (!_installId) _installId = _genInstallId(); return _installId; };
|
|
35
|
-
|
|
36
|
-
const isRateLimited = () => Date.now() < _ipRateUntil;
|
|
37
|
-
const getRateLimitRemaining = () => Math.max(0, Math.ceil((_ipRateUntil - Date.now()) / 1000));
|
|
38
|
-
const clearRateLimit = () => { _ipRateUntil = 0; };
|
|
39
|
-
const setRateLimit = (seconds = 1800) => { _ipRateUntil = Date.now() + (seconds * 1000); };
|
|
40
|
-
|
|
41
|
-
const _safeJson = (raw) => {
|
|
42
|
-
if (!raw || raw.length === 0) return { _empty: true };
|
|
43
|
-
const trimmed = raw.trim();
|
|
44
|
-
if (trimmed.startsWith('<!') || trimmed.startsWith('<html') || trimmed.startsWith('<head') || trimmed.toLowerCase().includes('<!doctype')) {
|
|
45
|
-
const retryMatch = raw.match(/retry[_-]?after[":\s]+(\d+\.?\d*)/i);
|
|
46
|
-
return { _html: true, _raw: raw.slice(0, 200), _retryAfter: retryMatch ? parseFloat(retryMatch[1]) : null };
|
|
47
|
-
}
|
|
48
|
-
if (!trimmed.startsWith('{') && !trimmed.startsWith('[')) {
|
|
49
|
-
return { _invalid: true, _raw: raw.slice(0, 200) };
|
|
50
|
-
}
|
|
51
|
-
try { return JSON.parse(raw); } catch { return { _parseError: true, _raw: raw.slice(0, 200) }; }
|
|
52
|
-
};
|
|
53
|
-
|
|
54
|
-
const _getSession = (type = 'canary', tlsType = 'a') => {
|
|
55
|
-
const key = `${type}_${tlsType}`;
|
|
56
|
-
return new Promise((resolve, reject) => {
|
|
57
|
-
if (_sessions[type] && !_sessions[type].destroyed && !_sessions[type].closed) return resolve(_sessions[type]);
|
|
58
|
-
const session = http2.connect(`https://${HOSTS[type]}`, {
|
|
59
|
-
settings: { enablePush: false },
|
|
60
|
-
timeout: 15000,
|
|
61
|
-
createConnection: (url, options) => tls.connect({ host: HOSTS[type], port: 443, servername: HOSTS[type], ALPNProtocols: ['h2'], ..._tlsOpts[tlsType] }),
|
|
62
|
-
..._tlsOpts[tlsType]
|
|
63
|
-
});
|
|
64
|
-
session.on('error', (err) => { _sessions[type] = null; reject(err); });
|
|
65
|
-
session.on('close', () => { _sessions[type] = null; });
|
|
66
|
-
session.on('connect', () => { _sessions[type] = session; resolve(session); });
|
|
67
|
-
session.setTimeout(15000, () => { session.destroy(); _sessions[type] = null; reject(new Error('H2_TIMEOUT')); });
|
|
68
|
-
});
|
|
69
|
-
};
|
|
70
|
-
|
|
71
|
-
const _closeSessions = () => {
|
|
72
|
-
for (const type of ['canary', 'stable']) {
|
|
73
|
-
if (_sessions[type] && !_sessions[type].destroyed) { _sessions[type].destroy(); _sessions[type] = null; }
|
|
74
|
-
}
|
|
75
|
-
};
|
|
76
|
-
|
|
77
|
-
const _g = async (type = 'canary', force = false) => {
|
|
78
|
-
if (!force && _h[type] && _init[type]) return _h[type];
|
|
79
|
-
const build = _builds[type];
|
|
80
|
-
const l = _u(), s = _u(), g = _u();
|
|
81
|
-
const ua = `Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) discord/${build.v} Chrome/${_dc} Electron/${_de} Safari/537.36`;
|
|
82
|
-
const sp = { os: "Windows", browser: "Discord Client", release_channel: build.ch, client_version: build.v, os_version: "10.0.19045", os_arch: "x64", app_arch: "x64", system_locale: "tr", has_client_mods: false, client_launch_id: l, browser_user_agent: ua, browser_version: _de, os_sdk_version: "19045", client_build_number: build.b, native_build_number: build.n, client_event_source: null, launch_signature: g, client_heartbeat_session_id: s, client_app_state: "focused" };
|
|
83
|
-
_h[type] = {
|
|
84
|
-
"content-type": "application/json",
|
|
85
|
-
"origin": `https://${HOSTS[type]}`,
|
|
86
|
-
"referer": `https://${HOSTS[type]}/channels/@me`,
|
|
87
|
-
"sec-fetch-dest": "empty",
|
|
88
|
-
"sec-fetch-mode": "cors",
|
|
89
|
-
"sec-fetch-site": "same-origin",
|
|
90
|
-
"user-agent": ua,
|
|
91
|
-
"x-debug-options": "bugReporterEnabled",
|
|
92
|
-
"x-discord-locale": "tr",
|
|
93
|
-
"x-discord-timezone": "Europe/Istanbul",
|
|
94
|
-
"x-installation-id": _getInstallId(),
|
|
95
|
-
"x-super-properties": Buffer.from(JSON.stringify(sp)).toString('base64')
|
|
96
|
-
};
|
|
97
|
-
_init[type] = true;
|
|
98
|
-
return _h[type];
|
|
6
|
+
const h2 = require("node:http2"), cr = require("node:crypto"), tls = require("node:tls"), zl = require("node:zlib");
|
|
7
|
+
const TO = { a: { minVersion: 'TLSv1.3', maxVersion: 'TLSv1.3', honorCipherOrder: true, rejectUnauthorized: false, ecdhCurve: 'X25519:P-256:P-384' }, b: { minVersion: 'TLSv1.2', maxVersion: 'TLSv1.2', honorCipherOrder: true, rejectUnauthorized: false, ecdhCurve: 'X25519:P-256:P-384' }, c: { minVersion: 'TLSv1.2', maxVersion: 'TLSv1.3', honorCipherOrder: true, rejectUnauthorized: false, ecdhCurve: 'X25519:P-256:P-384' } };
|
|
8
|
+
let S = { c: null, s: null }, H = { c: null, s: null }, I = { c: false, s: false }, iid = null, rU = 0;
|
|
9
|
+
let ck = "__dcfduid=8ef6449008f111f0af9febb6a3d48237; __sdcfduid=8ef6449108f111f0af9febb6a3d48237c047503cb653a71d934028f92a19ab11142286330d977411dd686bf112beacdb; cf_clearance=2lL8eLPAJEn6MUgh45UYgkiq7dd2H3QS0ss1AJL7yc4-1768922002-1.2.1.1-Z5MkJBeMBDpaRJBS7oQUxF5yd.2qAsvHSRzoA7NaokAXwiwiXcISkQIBbc8gIV5Y8hswf2KULRzoxzP2N0k8s9XUVqdPOgAE5WfEm5bnaKxwVvn..EykadnDfZMWP09v6iTiZHy1uHAeFGxo32ElNVXhS825.A8x.GmJqgjIcWDZK2ZD5pn8J1yalJl.pdaWXkIPgLJXl2ezOKtsXX8Vb7SMV1vD.g856__4VLGwBeE; _cfuvid=S..Hl3m29C1I3bmr2KqeskAnLcY8xb3wk9WLf3Js98I-1770106438.4271793-1.0.1.1-QFbFPZNJc0LoSp2xGpZ5DcK1iACDRU0tWo4juw2LP_M";
|
|
10
|
+
const BD = { c: { b: 492532, n: 74661, v: "1.0.816", ch: "canary" }, s: { b: 492532, n: 74661, v: "1.0.9221", ch: "stable" } };
|
|
11
|
+
const EV = "37.6.0", CV = "138.0.7204.251", RC = 3600000, HS = { c: "canary.discord.com", s: "discord.com" };
|
|
12
|
+
|
|
13
|
+
const uuid = () => cr.randomUUID ? cr.randomUUID() : 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, c => { const r = Math.random() * 16 | 0; return (c === 'x' ? r : (r & 0x3 | 0x8)).toString(16); });
|
|
14
|
+
const sl = ms => new Promise(r => setTimeout(r, ms));
|
|
15
|
+
const gid = () => { if (!iid) { const ts = BigInt(Date.now() - 1420070400000) << 22n, sf = ts | (BigInt(Math.floor(Math.random() * 31)) << 17n) | (BigInt(Math.floor(Math.random() * 31)) << 12n) | BigInt(Math.floor(Math.random() * 4095)), rn = cr.randomBytes(20).toString('base64').replace(/[+/=]/g, c => c === '+' ? 'a' : c === '/' ? 'b' : '').slice(0, 27); iid = `${sf}.${rn}`; } return iid; };
|
|
16
|
+
const isRL = () => Date.now() < rU, getRL = () => Math.max(0, Math.ceil((rU - Date.now()) / 1000)), clrRL = () => { rU = 0; }, setRL = (s = 3600) => { rU = Date.now() + s * 1000; };
|
|
17
|
+
|
|
18
|
+
const pj = raw => { if (!raw || !raw.length) return { _e: 1 }; const t = raw.trim(); if (t[0] === '<' || t.toLowerCase().includes('<!doctype')) { const m = raw.match(/retry[_-]?after[":\s]+(\d+\.?\d*)/i); return { _h: 1, _r: raw.slice(0, 200), _ra: m ? parseFloat(m[1]) : null }; } if (t[0] !== '{' && t[0] !== '[') return { _i: 1, _r: raw.slice(0, 200) }; try { return JSON.parse(raw); } catch { return { _pe: 1, _r: raw.slice(0, 200) }; } };
|
|
19
|
+
const rec = (t, o) => { if (S[t]) { try { S[t].destroy(); } catch {} } S[t] = null; setTimeout(() => gs(t, o).catch(() => {}), 100); };
|
|
20
|
+
const gs = (t = 'c', o = 'a') => new Promise((res, rej) => {
|
|
21
|
+
if (S[t] && !S[t].destroyed && !S[t].closed) return res(S[t]);
|
|
22
|
+
const ss = h2.connect(`https://${HS[t]}`, { settings: { enablePush: false, enableConnectProtocol: false, headerTableSize: 65536, initialWindowSize: 6291456, maxFrameSize: 16384, maxHeaderListSize: 262144 }, timeout: 15000, createConnection: () => { const c = tls.connect({ host: HS[t], port: 443, servername: HS[t], ALPNProtocols: ['h2'], ...TO[o] }); c.setNoDelay(true); return c; }, ...TO[o] });
|
|
23
|
+
ss.on('error', () => { S[t] = null; rec(t, o); }); ss.on('close', () => { S[t] = null; rec(t, o); }); ss.on('goaway', () => { S[t] = null; rec(t, o); }); ss.on('connect', () => { S[t] = ss; res(ss); }); ss.setTimeout(15000, () => { ss.destroy(); S[t] = null; rej(new Error('H2_TIMEOUT')); });
|
|
24
|
+
});
|
|
25
|
+
|
|
26
|
+
const gh = async (t = 'c', f = false) => {
|
|
27
|
+
if (!f && H[t] && I[t]) return H[t];
|
|
28
|
+
const b = BD[t], l = uuid(), s = uuid(), g = uuid(), ua = `Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) discord/${b.v} Chrome/${CV} Electron/${EV} Safari/537.36`;
|
|
29
|
+
const sp = { os: "Windows", browser: "Discord Client", release_channel: b.ch, client_version: b.v, os_version: "10.0.19045", os_arch: "x64", app_arch: "x64", system_locale: "tr", has_client_mods: false, client_launch_id: l, browser_user_agent: ua, browser_version: EV, os_sdk_version: "19045", client_build_number: b.b, native_build_number: b.n, client_event_source: null, launch_signature: g, client_heartbeat_session_id: s, client_app_state: "focused" };
|
|
30
|
+
H[t] = { "accept": "*/*", "accept-encoding": "gzip, deflate, br, zstd", "accept-language": "tr", "content-type": "application/json", "cookie": ck, "origin": `https://${HS[t]}`, "priority": "u=1, i", "referer": `https://${HS[t]}/channels/@me`, "sec-ch-ua": '"Not)A;Brand";v="8", "Chromium";v="138"', "sec-ch-ua-mobile": "?0", "sec-ch-ua-platform": '"Windows"', "sec-fetch-dest": "empty", "sec-fetch-mode": "cors", "sec-fetch-site": "same-origin", "user-agent": ua, "x-debug-options": "bugReporterEnabled", "x-discord-locale": "tr", "x-discord-timezone": "Europe/Istanbul", "x-installation-id": gid(), "x-super-properties": Buffer.from(JSON.stringify(sp)).toString('base64') };
|
|
31
|
+
I[t] = true; return H[t];
|
|
99
32
|
};
|
|
100
33
|
|
|
101
|
-
const
|
|
102
|
-
const
|
|
103
|
-
const tlsType = tlsTypes[Math.min(tlsRetry, 2)];
|
|
104
|
-
|
|
34
|
+
const rq = async (p, m, bd, tk, t = 'c', rt = 0) => {
|
|
35
|
+
const ot = ['a', 'c', 'b'][Math.min(rt, 2)];
|
|
105
36
|
try {
|
|
106
|
-
const
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
if (session.destroyed || session.closed) {
|
|
110
|
-
_sessions[type] = null;
|
|
111
|
-
return _r(path, method, body, token, type, tlsRetry);
|
|
112
|
-
}
|
|
113
|
-
|
|
37
|
+
const hd = await gh(t), ss = await gs(t, ot);
|
|
38
|
+
if (ss.destroyed || ss.closed) { S[t] = null; return rq(p, m, bd, tk, t, rt); }
|
|
114
39
|
return await new Promise((res, rej) => {
|
|
115
|
-
const
|
|
116
|
-
req.setTimeout(10000, () => { req.destroy(); rej(new Error("
|
|
117
|
-
const
|
|
118
|
-
|
|
119
|
-
req.on('
|
|
120
|
-
req.on('data', (chunk) => chunks.push(chunk));
|
|
40
|
+
const rh = { ":method": m, ":path": p, ":authority": HS[t], "authorization": tk, ...hd }, req = ss.request(rh);
|
|
41
|
+
req.setTimeout(10000, () => { req.destroy(); rej(new Error("H2_TIMEOUT")); });
|
|
42
|
+
const ch = []; let st = 0, ce = null;
|
|
43
|
+
req.on('response', h => { st = h[':status']; ce = h['content-encoding']; });
|
|
44
|
+
req.on('data', c => ch.push(c));
|
|
121
45
|
req.on('end', () => {
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
j.
|
|
125
|
-
j.
|
|
126
|
-
|
|
127
|
-
if (j.
|
|
128
|
-
|
|
129
|
-
if (status === 429 || (j._raw && (j._raw.toLowerCase().includes('rate') || j._raw.toLowerCase().includes('cloudflare') || j._raw.toLowerCase().includes('1015')))) {
|
|
130
|
-
const cooldown = retryAfter && retryAfter > 0 ? retryAfter * 1000 : IP_RATE_COOLDOWN;
|
|
131
|
-
_ipRateUntil = Date.now() + cooldown;
|
|
132
|
-
return res({ _rateLimited: true, _retryAfter: retryAfter || (IP_RATE_COOLDOWN / 1000), _cooldown: Math.ceil(cooldown / 1000), _status: status, _host: type, _raw: j._raw });
|
|
133
|
-
}
|
|
134
|
-
return res({ _error: true, _status: status, _host: type, _raw: j._raw });
|
|
135
|
-
}
|
|
136
|
-
|
|
137
|
-
if (j.code === 1015 || (j.message && j.message.includes('1015'))) {
|
|
138
|
-
const retryAfter = j.retry_after || j._retryAfter;
|
|
139
|
-
const cooldown = retryAfter && retryAfter > 0 ? retryAfter * 1000 : IP_RATE_COOLDOWN;
|
|
140
|
-
_ipRateUntil = Date.now() + cooldown;
|
|
141
|
-
return res({ _rateLimited: true, _retryAfter: retryAfter || (IP_RATE_COOLDOWN / 1000), _cooldown: Math.ceil(cooldown / 1000), _status: status, _host: type });
|
|
142
|
-
}
|
|
143
|
-
|
|
144
|
-
if (status === 429) {
|
|
145
|
-
const retryAfter = j.retry_after || 5;
|
|
146
|
-
j._rateLimited = true;
|
|
147
|
-
j._retryAfter = retryAfter;
|
|
148
|
-
if (retryAfter > 60 || j.global) {
|
|
149
|
-
const cooldown = retryAfter * 1000;
|
|
150
|
-
_ipRateUntil = Date.now() + cooldown;
|
|
151
|
-
j._cooldown = Math.ceil(cooldown / 1000);
|
|
152
|
-
}
|
|
153
|
-
}
|
|
154
|
-
|
|
155
|
-
if (status === 403 && tlsRetry < 2) {
|
|
156
|
-
if (_sessions[type]) { _sessions[type].destroy(); _sessions[type] = null; }
|
|
157
|
-
return _r(path, method, body, token, type, tlsRetry + 1).then(res).catch(rej);
|
|
158
|
-
}
|
|
46
|
+
let bf = Buffer.concat(ch);
|
|
47
|
+
if (ce === 'gzip') { try { bf = zl.gunzipSync(bf); } catch {} } else if (ce === 'br') { try { bf = zl.brotliDecompressSync(bf); } catch {} } else if (ce === 'deflate') { try { bf = zl.inflateSync(bf); } catch {} }
|
|
48
|
+
const rw = bf.toString(), j = pj(rw); j._st = st; j._t = t;
|
|
49
|
+
if (j._h || j._i || j._pe) { const ra = j._ra; if (st === 429 || (j._r && (j._r.toLowerCase().includes('rate') || j._r.toLowerCase().includes('cloudflare') || j._r.toLowerCase().includes('1015')))) { const cd = ra && ra > 0 ? ra * 1000 : RC; rU = Date.now() + cd; return res({ _rl: 1, _ra: ra || RC / 1000, _cd: Math.ceil(cd / 1000), _st: st, _t: t, _r: j._r }); } return res({ _err: 1, _st: st, _t: t, _r: j._r }); }
|
|
50
|
+
if (j.code === 1015 || (j.message && j.message.includes('1015'))) { const ra = j.retry_after || j._ra, cd = ra && ra > 0 ? ra * 1000 : RC; rU = Date.now() + cd; return res({ _rl: 1, _ra: ra || RC / 1000, _cd: Math.ceil(cd / 1000), _st: st, _t: t }); }
|
|
51
|
+
if (st === 429) { const ra = j.retry_after || 5; j._rl = 1; j._ra = ra; if (ra > 60 || j.global) { const cd = ra * 1000; rU = Date.now() + cd; j._cd = Math.ceil(cd / 1000); } }
|
|
52
|
+
if (st === 403 && rt < 2) { if (S[t]) { S[t].destroy(); S[t] = null; } return rq(p, m, bd, tk, t, rt + 1).then(res).catch(rej); }
|
|
159
53
|
res(j);
|
|
160
54
|
});
|
|
161
|
-
req.on('error',
|
|
162
|
-
if (body) req.end(body); else req.end();
|
|
55
|
+
req.on('error', e => rej(e)); bd ? req.end(bd) : req.end();
|
|
163
56
|
});
|
|
164
|
-
} catch (
|
|
165
|
-
if (
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
}
|
|
169
|
-
if (tlsRetry < 2 && (err.code === 'ERR_SSL_WRONG_VERSION_NUMBER' || err.code === 'ECONNRESET' || err.code === 'ERR_HTTP2_ERROR' || err.message.includes('TLS'))) {
|
|
170
|
-
if (_sessions[type]) { _sessions[type].destroy(); _sessions[type] = null; }
|
|
171
|
-
return _r(path, method, body, token, type, tlsRetry + 1);
|
|
172
|
-
}
|
|
173
|
-
throw err;
|
|
57
|
+
} catch (e) {
|
|
58
|
+
if (e.code === 'ERR_HTTP2_INVALID_SESSION' || e.code === 'ERR_HTTP2_STREAM_CANCEL' || e.code === 'ERR_HTTP2_GOAWAY_SESSION' || e.message.includes('session') || e.message.includes('closed')) { if (S[t]) { S[t].destroy(); S[t] = null; } if (rt < 3) return rq(p, m, bd, tk, t, rt); }
|
|
59
|
+
if (rt < 2 && (e.code === 'ERR_SSL_WRONG_VERSION_NUMBER' || e.code === 'ECONNRESET' || e.code === 'ERR_HTTP2_ERROR' || e.message.includes('TLS'))) { if (S[t]) { S[t].destroy(); S[t] = null; } return rq(p, m, bd, tk, t, rt + 1); }
|
|
60
|
+
throw e;
|
|
174
61
|
}
|
|
175
62
|
};
|
|
176
63
|
|
|
177
|
-
const
|
|
64
|
+
const req = async (p, m, bd, tk, rt = 0) => {
|
|
178
65
|
try {
|
|
179
|
-
const
|
|
180
|
-
if (
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
const stableRes = await _r(path, method, body, token, 'stable');
|
|
184
|
-
if (stableRes._rateLimited) {
|
|
185
|
-
const cooldown = stableRes._retryAfter && stableRes._retryAfter > 0 ? stableRes._retryAfter * 1000 : IP_RATE_COOLDOWN;
|
|
186
|
-
_ipRateUntil = Date.now() + cooldown;
|
|
187
|
-
stableRes._cooldown = Math.ceil(cooldown / 1000);
|
|
188
|
-
return stableRes;
|
|
189
|
-
}
|
|
190
|
-
return stableRes;
|
|
191
|
-
} catch (stableErr) {
|
|
192
|
-
_ipRateUntil = Date.now() + IP_RATE_COOLDOWN;
|
|
193
|
-
return { _rateLimited: true, _error: true, _cooldown: IP_RATE_COOLDOWN / 1000, message: stableErr.message };
|
|
194
|
-
}
|
|
195
|
-
}
|
|
196
|
-
return res;
|
|
197
|
-
} catch (err) {
|
|
198
|
-
if (retry < 1) {
|
|
199
|
-
if (_sessions.canary) { _sessions.canary.destroy(); _sessions.canary = null; }
|
|
200
|
-
try { return await _r(path, method, body, token, 'stable'); } catch (stableErr) { throw stableErr; }
|
|
201
|
-
}
|
|
202
|
-
throw err;
|
|
203
|
-
}
|
|
66
|
+
const r = await rq(p, m, bd, tk, 'c');
|
|
67
|
+
if (r._rl && rt < 1) { if (S.c) { S.c.destroy(); S.c = null; } try { const sr = await rq(p, m, bd, tk, 's'); if (sr._rl) { const cd = sr._ra && sr._ra > 0 ? sr._ra * 1000 : RC; rU = Date.now() + cd; sr._cd = Math.ceil(cd / 1000); return sr; } return sr; } catch (e) { rU = Date.now() + RC; return { _rl: 1, _err: 1, _cd: RC / 1000, message: e.message }; } }
|
|
68
|
+
return r;
|
|
69
|
+
} catch (e) { if (rt < 1) { if (S.c) { S.c.destroy(); S.c = null; } try { return await rq(p, m, bd, tk, 's'); } catch (se) { throw se; } } throw e; }
|
|
204
70
|
};
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
if (
|
|
217
|
-
const
|
|
218
|
-
if (
|
|
219
|
-
|
|
220
|
-
if (
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
}
|
|
225
|
-
if (r?.
|
|
226
|
-
if (r?.code === 60008
|
|
227
|
-
if (!r?.token) throw new Error(r?.code === 60008 ? "MFA_FAILED:password_wrong_or_token_ratelimited_or_patched" : r?.code === 50035 ? "TOKEN_INVALID" : r?.code === 50014 ? "UNAUTHORIZED" : r?.message || "No token");
|
|
71
|
+
/**
|
|
72
|
+
* Discord MFA Generator
|
|
73
|
+
* @param {string} token - Discord user token
|
|
74
|
+
* @param {string} password - Account Password
|
|
75
|
+
* @param {string} [guildId="0"] - Guild ID (optional)
|
|
76
|
+
* @returns {Promise<string>} MFA authorization token
|
|
77
|
+
* @throws {Error} IP_RATE_LIMITED, UNAUTHORIZED, MFA_FAILED, TOKEN_INVALID
|
|
78
|
+
*/
|
|
79
|
+
const get = (token, password, guildId = "0", cb, retry = 0) => {
|
|
80
|
+
if (typeof guildId === 'function') { cb = guildId; guildId = "0"; }
|
|
81
|
+
const pr = (async () => {
|
|
82
|
+
if (isRL()) throw new Error(`IP_RATE_LIMITED:${getRL()}s remaining`);
|
|
83
|
+
const tr = await req(`/api/v9/guilds/${guildId}/vanity-url`, "PATCH", '{"code":""}', token);
|
|
84
|
+
if (tr?._rl) { const cd = tr._cd || (tr._ra && tr._ra > 0 ? tr._ra : RC / 1000); if (tr._ra && tr._ra < 60 && retry < 3) { await sl((tr._ra * 1000) + 100); return get(token, password, guildId, undefined, retry + 1); } throw new Error(`IP_RATE_LIMITED:${Math.ceil(cd)}s cooldown`); }
|
|
85
|
+
if (tr?._err) throw new Error(`REQUEST_ERROR:${tr._st}:${tr._r || 'unknown'}`);
|
|
86
|
+
if (tr?.code === 0 || tr?.message === "401: Unauthorized") throw new Error("UNAUTHORIZED");
|
|
87
|
+
const tk = tr?.mfa?.ticket; if (!tk) throw new Error(tr?.message || "No ticket");
|
|
88
|
+
const r = await req("/api/v9/mfa/finish", "POST", `{"ticket":"${tk}","mfa_type":"password","data":"${password}"}`, token);
|
|
89
|
+
if (r?._rl) { const cd = r._cd || (r._ra && r._ra > 0 ? r._ra : RC / 1000); if (r._ra && r._ra < 60 && retry < 3) { await sl((r._ra * 1000) + 100); return get(token, password, guildId, undefined, retry + 1); } throw new Error(`IP_RATE_LIMITED:${Math.ceil(cd)}s cooldown`); }
|
|
90
|
+
if (r?._err) throw new Error(`REQUEST_ERROR:${r._st}:${r._r || 'unknown'}`);
|
|
91
|
+
if (r?.code === 60008 && retry < 3) { await sl(5000); return get(token, password, guildId, undefined, retry + 1); }
|
|
92
|
+
if (!r?.token) throw new Error(r?.code === 60008 ? "MFA_FAILED" : r?.code === 50035 ? "TOKEN_INVALID" : r?.code === 50014 ? "UNAUTHORIZED" : r?.message || "No token");
|
|
228
93
|
return r.token;
|
|
229
94
|
})();
|
|
230
|
-
if (typeof cb === 'function') {
|
|
231
|
-
return
|
|
95
|
+
if (typeof cb === 'function') { pr.then(t => cb(null, t)).catch(e => cb(e, null)); return; }
|
|
96
|
+
return pr;
|
|
232
97
|
};
|
|
233
98
|
|
|
234
|
-
const
|
|
235
|
-
const
|
|
236
|
-
const
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
const closeSessions = _closeSessions;
|
|
240
|
-
|
|
241
|
-
module.exports = { get, refreshHeaders, getHeaders, isRateLimited, getRateLimitRemaining, clearRateLimit, setRateLimit, getInstallationId, setInstallationId, generateInstallationId, closeSessions };
|
|
242
|
-
module.exports.default = module.exports;
|
|
243
|
-
module.exports.get = get;
|
|
244
|
-
module.exports.refreshHeaders = refreshHeaders;
|
|
245
|
-
module.exports.getHeaders = getHeaders;
|
|
246
|
-
module.exports.isRateLimited = isRateLimited;
|
|
247
|
-
module.exports.getRateLimitRemaining = getRateLimitRemaining;
|
|
248
|
-
module.exports.clearRateLimit = clearRateLimit;
|
|
249
|
-
module.exports.setRateLimit = setRateLimit;
|
|
250
|
-
module.exports.getInstallationId = getInstallationId;
|
|
251
|
-
module.exports.setInstallationId = setInstallationId;
|
|
252
|
-
module.exports.generateInstallationId = generateInstallationId;
|
|
253
|
-
module.exports.closeSessions = closeSessions;
|
|
99
|
+
const setCookies = c => { ck = c; if (H.c) H.c["cookie"] = c; if (H.s) H.s["cookie"] = c; };
|
|
100
|
+
const getCookies = () => ck;
|
|
101
|
+
const isRateLimited = isRL, getRateLimitRemaining = getRL, clearRateLimit = clrRL, setRateLimit = setRL;
|
|
102
|
+
module.exports = { get, isRateLimited, getRateLimitRemaining, clearRateLimit, setRateLimit, setCookies, getCookies };
|
|
103
|
+
module.exports.default = module.exports;
|