rettiwt-api 5.1.0-alpha.0 → 6.0.1
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/.eslintrc.js +13 -8
- package/README.md +8 -1
- package/dist/cli.js +17 -14
- package/dist/cli.js.map +1 -1
- package/dist/collections/Extractors.d.ts +1 -1
- package/dist/collections/Extractors.js +21 -21
- package/dist/collections/Extractors.js.map +1 -1
- package/dist/collections/Groups.d.ts +4 -4
- package/dist/collections/Groups.js +45 -45
- package/dist/collections/Groups.js.map +1 -1
- package/dist/collections/Requests.d.ts +3 -3
- package/dist/collections/Requests.js +3 -3
- package/dist/collections/Requests.js.map +1 -1
- package/dist/collections/Tweet.d.ts +4 -4
- package/dist/collections/Tweet.js +5 -5
- package/dist/collections/Tweet.js.map +1 -1
- package/dist/commands/Tweet.js +32 -4
- package/dist/commands/Tweet.js.map +1 -1
- package/dist/enums/Api.d.ts +1 -1
- package/dist/enums/Api.js +7 -7
- package/dist/enums/Api.js.map +1 -1
- package/dist/enums/Authentication.d.ts +1 -1
- package/dist/enums/Authentication.js +7 -7
- package/dist/enums/Authentication.js.map +1 -1
- package/dist/enums/Data.d.ts +1 -1
- package/dist/enums/Data.js +7 -7
- package/dist/enums/Data.js.map +1 -1
- package/dist/enums/Logging.d.ts +1 -1
- package/dist/enums/Logging.js +11 -11
- package/dist/enums/Logging.js.map +1 -1
- package/dist/enums/Media.d.ts +1 -1
- package/dist/enums/Media.js +7 -7
- package/dist/enums/Media.js.map +1 -1
- package/dist/enums/Notification.d.ts +1 -1
- package/dist/enums/Notification.js +9 -9
- package/dist/enums/Notification.js.map +1 -1
- package/dist/enums/Resource.d.ts +1 -1
- package/dist/enums/Resource.js +42 -42
- package/dist/enums/Resource.js.map +1 -1
- package/dist/enums/Tweet.d.ts +1 -1
- package/dist/enums/Tweet.js +7 -7
- package/dist/enums/Tweet.js.map +1 -1
- package/dist/enums/raw/Analytics.d.ts +2 -2
- package/dist/enums/raw/Analytics.js +21 -21
- package/dist/enums/raw/Analytics.js.map +1 -1
- package/dist/enums/raw/Media.d.ts +1 -1
- package/dist/enums/raw/Media.js +7 -7
- package/dist/enums/raw/Media.js.map +1 -1
- package/dist/enums/raw/Notification.d.ts +1 -1
- package/dist/enums/raw/Notification.js +8 -8
- package/dist/enums/raw/Notification.js.map +1 -1
- package/dist/enums/raw/Tweet.d.ts +2 -2
- package/dist/enums/raw/Tweet.js +12 -12
- package/dist/enums/raw/Tweet.js.map +1 -1
- package/dist/index.d.ts +0 -1
- package/dist/index.js +0 -1
- package/dist/index.js.map +1 -1
- package/dist/models/RettiwtConfig.d.ts +3 -4
- package/dist/models/RettiwtConfig.js +7 -7
- package/dist/models/RettiwtConfig.js.map +1 -1
- package/dist/models/args/FetchArgs.d.ts +3 -3
- package/dist/models/args/FetchArgs.js +3 -3
- package/dist/models/args/FetchArgs.js.map +1 -1
- package/dist/models/auth/AuthCredential.d.ts +2 -2
- package/dist/models/auth/AuthCredential.js +3 -3
- package/dist/models/auth/AuthCredential.js.map +1 -1
- package/dist/models/data/CursoredData.d.ts +2 -2
- package/dist/models/data/CursoredData.js +3 -3
- package/dist/models/data/CursoredData.js.map +1 -1
- package/dist/models/data/Notification.d.ts +2 -2
- package/dist/models/data/Notification.js +3 -3
- package/dist/models/data/Notification.js.map +1 -1
- package/dist/models/data/Tweet.d.ts +4 -4
- package/dist/models/data/Tweet.js +18 -18
- package/dist/models/data/Tweet.js.map +1 -1
- package/dist/models/data/User.js +9 -9
- package/dist/models/data/User.js.map +1 -1
- package/dist/requests/Tweet.d.ts +2 -2
- package/dist/requests/Tweet.js +2 -2
- package/dist/requests/Tweet.js.map +1 -1
- package/dist/requests/User.d.ts +2 -2
- package/dist/requests/User.js.map +1 -1
- package/dist/services/internal/AuthService.js +1 -1
- package/dist/services/internal/AuthService.js.map +1 -1
- package/dist/services/internal/ErrorService.d.ts +2 -2
- package/dist/services/internal/ErrorService.js +4 -4
- package/dist/services/internal/ErrorService.js.map +1 -1
- package/dist/services/internal/LogService.d.ts +2 -2
- package/dist/services/internal/LogService.js.map +1 -1
- package/dist/services/public/FetcherService.d.ts +7 -9
- package/dist/services/public/FetcherService.js +102 -51
- package/dist/services/public/FetcherService.js.map +1 -1
- package/dist/services/public/ListService.js +4 -4
- package/dist/services/public/ListService.js.map +1 -1
- package/dist/services/public/TweetService.d.ts +3 -3
- package/dist/services/public/TweetService.js +35 -35
- package/dist/services/public/TweetService.js.map +1 -1
- package/dist/services/public/UserService.js +37 -37
- package/dist/services/public/UserService.js.map +1 -1
- package/dist/types/RettiwtConfig.d.ts +6 -3
- package/dist/types/args/FetchArgs.d.ts +2 -2
- package/dist/types/auth/AuthCredential.d.ts +2 -2
- package/dist/types/auth/TransactionHeader.d.ts +6 -0
- package/dist/types/auth/TransactionHeader.js +4 -0
- package/dist/types/auth/TransactionHeader.js.map +1 -0
- package/dist/types/data/Notification.d.ts +2 -2
- package/dist/types/data/Tweet.d.ts +2 -2
- package/dist/types/raw/base/Media.d.ts +2 -2
- package/dist/types/raw/base/Notification.d.ts +2 -2
- package/package.json +19 -18
- package/src/cli.ts +20 -14
- package/src/collections/Extractors.ts +21 -21
- package/src/collections/Groups.ts +45 -45
- package/src/collections/Requests.ts +4 -4
- package/src/collections/Tweet.ts +6 -6
- package/src/commands/Tweet.ts +33 -4
- package/src/enums/Api.ts +1 -1
- package/src/enums/Authentication.ts +1 -1
- package/src/enums/Data.ts +1 -1
- package/src/enums/Logging.ts +1 -1
- package/src/enums/Media.ts +1 -1
- package/src/enums/Notification.ts +1 -1
- package/src/enums/Resource.ts +1 -1
- package/src/enums/Tweet.ts +1 -1
- package/src/enums/raw/Analytics.ts +2 -2
- package/src/enums/raw/Media.ts +1 -1
- package/src/enums/raw/Notification.ts +1 -1
- package/src/enums/raw/Tweet.ts +2 -2
- package/src/index.ts +0 -1
- package/src/models/RettiwtConfig.ts +7 -8
- package/src/models/args/FetchArgs.ts +5 -5
- package/src/models/auth/AuthCredential.ts +5 -5
- package/src/models/data/CursoredData.ts +5 -5
- package/src/models/data/Notification.ts +6 -6
- package/src/models/data/Tweet.ts +22 -22
- package/src/models/data/User.ts +10 -10
- package/src/requests/Tweet.ts +4 -4
- package/src/requests/User.ts +3 -3
- package/src/services/internal/AuthService.ts +2 -2
- package/src/services/internal/ErrorService.ts +4 -4
- package/src/services/internal/LogService.ts +2 -2
- package/src/services/public/FetcherService.ts +82 -57
- package/src/services/public/ListService.ts +6 -6
- package/src/services/public/TweetService.ts +39 -39
- package/src/services/public/UserService.ts +40 -40
- package/src/types/RettiwtConfig.ts +7 -4
- package/src/types/args/FetchArgs.ts +2 -2
- package/src/types/auth/AuthCredential.ts +2 -2
- package/src/types/auth/TransactionHeader.ts +8 -0
- package/src/types/data/Notification.ts +2 -2
- package/src/types/data/Tweet.ts +2 -2
- package/src/types/raw/base/Media.ts +2 -2
- package/src/types/raw/base/Notification.ts +2 -2
- package/.tool-versions +0 -1
- package/dist/helper/TidUtils.d.ts +0 -4
- package/dist/helper/TidUtils.js +0 -171
- package/dist/helper/TidUtils.js.map +0 -1
- package/dist/services/internal/TidService.d.ts +0 -43
- package/dist/services/internal/TidService.js +0 -156
- package/dist/services/internal/TidService.js.map +0 -1
- package/dist/types/auth/TidDynamicArgs.d.ts +0 -10
- package/dist/types/auth/TidDynamicArgs.js +0 -3
- package/dist/types/auth/TidDynamicArgs.js.map +0 -1
- package/dist/types/auth/TidHeader.d.ts +0 -8
- package/dist/types/auth/TidHeader.js +0 -3
- package/dist/types/auth/TidHeader.js.map +0 -1
- package/dist/types/auth/TidParams.d.ts +0 -27
- package/dist/types/auth/TidParams.js +0 -3
- package/dist/types/auth/TidParams.js.map +0 -1
- package/dist/types/auth/TidProvider.d.ts +0 -18
- package/dist/types/auth/TidProvider.js +0 -3
- package/dist/types/auth/TidProvider.js.map +0 -1
- package/src/helper/TidUtils.ts +0 -198
- package/src/services/internal/TidService.ts +0 -140
- package/src/types/auth/TidDynamicArgs.ts +0 -10
- package/src/types/auth/TidHeader.ts +0 -12
- package/src/types/auth/TidParams.ts +0 -36
- package/src/types/auth/TidProvider.ts +0 -19
package/src/helper/TidUtils.ts
DELETED
|
@@ -1,198 +0,0 @@
|
|
|
1
|
-
import { createHash } from 'node:crypto';
|
|
2
|
-
|
|
3
|
-
import { ITidParams } from '../types/auth/TidParams';
|
|
4
|
-
|
|
5
|
-
export function getUnixTime(): number {
|
|
6
|
-
const [seconds, nanoseconds] = process.hrtime();
|
|
7
|
-
return Date.now() / 1000 + seconds + nanoseconds / 1e9;
|
|
8
|
-
}
|
|
9
|
-
|
|
10
|
-
export function getNanosecondPrecisionTime(): number {
|
|
11
|
-
return Number(((BigInt(Date.now()) * 1000000n + process.hrtime.bigint()) * 1000n) / BigInt(1000000)) / 1000000;
|
|
12
|
-
}
|
|
13
|
-
|
|
14
|
-
export function calculateClientTransactionIdHeader(args: ITidParams): string {
|
|
15
|
-
const time = Math.floor(((args.time || getUnixTime()) * 1000 - 1682924400 * 1000) / 1000);
|
|
16
|
-
const timeBuffer = new Uint8Array(new Uint32Array([time]).buffer);
|
|
17
|
-
|
|
18
|
-
const keyBytes = Array.from(Buffer.from(args.verificationKey, 'base64'));
|
|
19
|
-
const animationKey = args.animationKey || getAnimationKey(keyBytes, args.frames, args.indices);
|
|
20
|
-
|
|
21
|
-
const value = [args.method, args.path, time].join('!') + args.keyword + animationKey;
|
|
22
|
-
const valueEncoded = new TextEncoder().encode(value);
|
|
23
|
-
|
|
24
|
-
const hash = createHash('sha-256').update(valueEncoded).digest();
|
|
25
|
-
const hashBytes = Array.from(new Uint8Array(hash));
|
|
26
|
-
|
|
27
|
-
const xorByte = args.xorByte || Math.floor(Math.random() * 256);
|
|
28
|
-
|
|
29
|
-
const bytes = new Uint8Array(keyBytes.concat(Array.from(timeBuffer), hashBytes.slice(0, 16), [args.extraByte]));
|
|
30
|
-
return encode(xor(xorByte, bytes));
|
|
31
|
-
}
|
|
32
|
-
|
|
33
|
-
function getAnimationKey(keyBytes: number[], frames: number[][][], indices: number[]): string {
|
|
34
|
-
const totalTime = 4096;
|
|
35
|
-
const rowIndex = keyBytes[indices[0]] % 16;
|
|
36
|
-
const frameTime = indices
|
|
37
|
-
.slice(1)
|
|
38
|
-
.map((idx) => keyBytes[idx] % 16)
|
|
39
|
-
.reduce((a, b) => a * b, 1);
|
|
40
|
-
const targetTime = frameTime / totalTime;
|
|
41
|
-
const frameRow = frames[keyBytes[5] % 4][rowIndex];
|
|
42
|
-
return animate(frameRow, targetTime);
|
|
43
|
-
}
|
|
44
|
-
|
|
45
|
-
function animate(frameRow: number[], targetTime: number): string {
|
|
46
|
-
const curves = frameRow.slice(7).map((v, i) => Number(a(v, b(i), 1).toFixed(2)));
|
|
47
|
-
const cubicValue = getCubicCurveValue(curves, targetTime);
|
|
48
|
-
|
|
49
|
-
const fromColor = [...frameRow.slice(0, 3), 1];
|
|
50
|
-
const toColor = [...frameRow.slice(3, 6), 1];
|
|
51
|
-
const color = interpolate(fromColor, toColor, cubicValue);
|
|
52
|
-
|
|
53
|
-
const fromRotation = [0];
|
|
54
|
-
const toRotation = [Math.floor(a(frameRow[6], 60, 360))];
|
|
55
|
-
const rotation = interpolate(fromRotation, toRotation, cubicValue);
|
|
56
|
-
const matrix = convertRotationToMatrix(rotation[0]);
|
|
57
|
-
|
|
58
|
-
const strArray: string[] = [];
|
|
59
|
-
for (let i = 0; i < color.length - 1; i++) {
|
|
60
|
-
strArray.push(Math.round(color[i]).toString(16));
|
|
61
|
-
}
|
|
62
|
-
|
|
63
|
-
for (let i = 0; i < matrix.length; i++) {
|
|
64
|
-
let rounded = Number(matrix[i].toFixed(2));
|
|
65
|
-
if (rounded < 0) {
|
|
66
|
-
rounded = -rounded;
|
|
67
|
-
}
|
|
68
|
-
const hexValue = floatToHex(rounded);
|
|
69
|
-
if (hexValue.startsWith('.')) {
|
|
70
|
-
strArray.push('0' + hexValue);
|
|
71
|
-
} else if (hexValue) {
|
|
72
|
-
strArray.push(hexValue);
|
|
73
|
-
} else {
|
|
74
|
-
strArray.push('0');
|
|
75
|
-
}
|
|
76
|
-
}
|
|
77
|
-
|
|
78
|
-
strArray.push('0', '0');
|
|
79
|
-
return strArray.join('').replace(/[.-]/g, '').toLowerCase();
|
|
80
|
-
}
|
|
81
|
-
|
|
82
|
-
function a(b: number, c: number, d: number): number {
|
|
83
|
-
return (b * (d - c)) / 255 + c;
|
|
84
|
-
}
|
|
85
|
-
|
|
86
|
-
function b(a: number): number {
|
|
87
|
-
return a % 2 === 1 ? -1 : 0;
|
|
88
|
-
}
|
|
89
|
-
|
|
90
|
-
function getCubicCurveValue(curves: number[], time: number): number {
|
|
91
|
-
let startGradient = 0;
|
|
92
|
-
let endGradient = 0;
|
|
93
|
-
|
|
94
|
-
if (time <= 0) {
|
|
95
|
-
if (curves[0] > 0) {
|
|
96
|
-
startGradient = curves[1] / curves[0];
|
|
97
|
-
} else if (curves[1] === 0 && curves[2] > 0) {
|
|
98
|
-
startGradient = curves[3] / curves[2];
|
|
99
|
-
}
|
|
100
|
-
return startGradient * time;
|
|
101
|
-
}
|
|
102
|
-
|
|
103
|
-
if (time >= 1) {
|
|
104
|
-
if (curves[2] < 1) {
|
|
105
|
-
endGradient = (curves[3] - 1) / (curves[2] - 1);
|
|
106
|
-
} else if (curves[2] === 1 && curves[0] < 1) {
|
|
107
|
-
endGradient = (curves[1] - 1) / (curves[0] - 1);
|
|
108
|
-
}
|
|
109
|
-
return 1 + endGradient * (time - 1);
|
|
110
|
-
}
|
|
111
|
-
|
|
112
|
-
let start = 0;
|
|
113
|
-
let end = 1;
|
|
114
|
-
let mid = 0;
|
|
115
|
-
|
|
116
|
-
while (start < end) {
|
|
117
|
-
mid = (start + end) / 2;
|
|
118
|
-
const xEst = calculateBezier(curves[0], curves[2], mid);
|
|
119
|
-
if (Math.abs(time - xEst) < 0.00001) {
|
|
120
|
-
return calculateBezier(curves[1], curves[3], mid);
|
|
121
|
-
}
|
|
122
|
-
if (xEst < time) {
|
|
123
|
-
start = mid;
|
|
124
|
-
} else {
|
|
125
|
-
end = mid;
|
|
126
|
-
}
|
|
127
|
-
}
|
|
128
|
-
|
|
129
|
-
return calculateBezier(curves[1], curves[3], mid);
|
|
130
|
-
}
|
|
131
|
-
|
|
132
|
-
function calculateBezier(a: number, b: number, m: number): number {
|
|
133
|
-
return 3 * a * (1 - m) * (1 - m) * m + 3 * b * (1 - m) * m * m + m * m * m;
|
|
134
|
-
}
|
|
135
|
-
|
|
136
|
-
function interpolate(from: number[], to: number[], f: number): number[] {
|
|
137
|
-
const out: number[] = [];
|
|
138
|
-
for (let i = 0; i < from.length; i++) {
|
|
139
|
-
out.push(from[i] * (1 - f) + to[i] * f);
|
|
140
|
-
}
|
|
141
|
-
return out;
|
|
142
|
-
}
|
|
143
|
-
|
|
144
|
-
function convertRotationToMatrix(degrees: number): number[] {
|
|
145
|
-
const radians = (degrees * Math.PI) / 180;
|
|
146
|
-
const c = Math.cos(radians);
|
|
147
|
-
const s = Math.sin(radians);
|
|
148
|
-
return [c, -s, s, c];
|
|
149
|
-
}
|
|
150
|
-
|
|
151
|
-
function floatToHex(x: number): string {
|
|
152
|
-
const result: string[] = [];
|
|
153
|
-
let quotient = Math.floor(x);
|
|
154
|
-
let fraction = x - quotient;
|
|
155
|
-
|
|
156
|
-
while (quotient > 0) {
|
|
157
|
-
const remainder = quotient % 16;
|
|
158
|
-
quotient = Math.floor(quotient / 16);
|
|
159
|
-
|
|
160
|
-
if (remainder > 9) {
|
|
161
|
-
result.unshift(String.fromCharCode(remainder + 55));
|
|
162
|
-
} else {
|
|
163
|
-
result.unshift(remainder.toString());
|
|
164
|
-
}
|
|
165
|
-
}
|
|
166
|
-
|
|
167
|
-
if (fraction === 0) {
|
|
168
|
-
return result.join('');
|
|
169
|
-
}
|
|
170
|
-
|
|
171
|
-
result.push('.');
|
|
172
|
-
|
|
173
|
-
while (fraction > 0) {
|
|
174
|
-
fraction *= 16;
|
|
175
|
-
const integer = Math.floor(fraction);
|
|
176
|
-
fraction -= integer;
|
|
177
|
-
|
|
178
|
-
if (integer > 9) {
|
|
179
|
-
result.push(String.fromCharCode(integer + 55));
|
|
180
|
-
} else {
|
|
181
|
-
result.push(integer.toString());
|
|
182
|
-
}
|
|
183
|
-
}
|
|
184
|
-
|
|
185
|
-
return result.join('');
|
|
186
|
-
}
|
|
187
|
-
|
|
188
|
-
function xor(xorByte: number, data: Uint8Array): Uint8Array {
|
|
189
|
-
return new Uint8Array([xorByte, ...data.map((v) => v ^ xorByte)]);
|
|
190
|
-
}
|
|
191
|
-
|
|
192
|
-
function encode(data: Uint8Array): string {
|
|
193
|
-
return btoa(
|
|
194
|
-
Array.from(data)
|
|
195
|
-
.map((v) => String.fromCharCode(v))
|
|
196
|
-
.join(''),
|
|
197
|
-
).replaceAll('=', '');
|
|
198
|
-
}
|
|
@@ -1,140 +0,0 @@
|
|
|
1
|
-
import axios from 'axios';
|
|
2
|
-
import * as htmlParser from 'node-html-parser';
|
|
3
|
-
|
|
4
|
-
import { ELogActions } from '../../enums/Logging';
|
|
5
|
-
|
|
6
|
-
import { calculateClientTransactionIdHeader } from '../../helper/TidUtils';
|
|
7
|
-
|
|
8
|
-
import { RettiwtConfig } from '../../models/RettiwtConfig';
|
|
9
|
-
import { ITidDynamicArgs } from '../../types/auth/TidDynamicArgs';
|
|
10
|
-
import { ITidProvider } from '../../types/auth/TidProvider';
|
|
11
|
-
|
|
12
|
-
import { LogService } from './LogService';
|
|
13
|
-
|
|
14
|
-
/**
|
|
15
|
-
* Handles transaction ID generation for requests to Twitter.
|
|
16
|
-
*
|
|
17
|
-
* @internal
|
|
18
|
-
*/
|
|
19
|
-
export class TidService implements ITidProvider {
|
|
20
|
-
private readonly _cdnUrl: string;
|
|
21
|
-
private readonly _config: RettiwtConfig;
|
|
22
|
-
private _dynamicArgs?: ITidDynamicArgs;
|
|
23
|
-
|
|
24
|
-
/**
|
|
25
|
-
* @param config - The config for Rettiwt.
|
|
26
|
-
*/
|
|
27
|
-
public constructor(config: RettiwtConfig) {
|
|
28
|
-
this._cdnUrl = 'https://abs.twimg.com/responsive-web/client-web';
|
|
29
|
-
this._config = config;
|
|
30
|
-
}
|
|
31
|
-
|
|
32
|
-
/**
|
|
33
|
-
* Fetches the dynamic args embedded in the homepage.
|
|
34
|
-
*
|
|
35
|
-
* @returns The new dynamic args.
|
|
36
|
-
*/
|
|
37
|
-
private async getDynamicArgs(): Promise<ITidDynamicArgs> {
|
|
38
|
-
const html = await this.getHomepageHtml();
|
|
39
|
-
const root = htmlParser.parse(html);
|
|
40
|
-
const keyElement = root.querySelector("[name='twitter-site-verification']");
|
|
41
|
-
const frameElements = root.querySelectorAll("[id^='loading-x-anim']");
|
|
42
|
-
|
|
43
|
-
return {
|
|
44
|
-
verificationKey: keyElement?.getAttribute('content') ?? '',
|
|
45
|
-
frames: frameElements.map((el) => this.parseFrameElement(el)),
|
|
46
|
-
indices: await this.getKeyBytesIndices(html),
|
|
47
|
-
};
|
|
48
|
-
}
|
|
49
|
-
|
|
50
|
-
/**
|
|
51
|
-
* Fetches the HTML content of Twitter's homepage.
|
|
52
|
-
*
|
|
53
|
-
* @returns The stringified HTML content of the homepage.
|
|
54
|
-
*/
|
|
55
|
-
private async getHomepageHtml(): Promise<string> {
|
|
56
|
-
const response = await axios.get<string>('https://x.com', {
|
|
57
|
-
headers: this._config.headers,
|
|
58
|
-
httpAgent: this._config.httpsAgent,
|
|
59
|
-
httpsAgent: this._config.httpsAgent,
|
|
60
|
-
});
|
|
61
|
-
|
|
62
|
-
return response.data;
|
|
63
|
-
}
|
|
64
|
-
|
|
65
|
-
private async getKeyBytesIndices(html: string): Promise<number[]> {
|
|
66
|
-
const ondemandFileMatch = html.match(/ondemand\.s":"([^"]+)"/);
|
|
67
|
-
if (!ondemandFileMatch || !ondemandFileMatch[1]) {
|
|
68
|
-
LogService.log(ELogActions.WARNING, { message: 'ondemand.s file not found' });
|
|
69
|
-
|
|
70
|
-
return [0, 0, 0, 0];
|
|
71
|
-
}
|
|
72
|
-
|
|
73
|
-
const onDemandFileHash = ondemandFileMatch ? ondemandFileMatch[1] : '';
|
|
74
|
-
const response = await axios.get<string>(`${this._cdnUrl}/ondemand.s.${onDemandFileHash}a.js`, {
|
|
75
|
-
httpAgent: this._config.httpsAgent,
|
|
76
|
-
httpsAgent: this._config.httpsAgent,
|
|
77
|
-
});
|
|
78
|
-
const match = response.data.matchAll(/(\(\w\[(\d{1,2})],\s*16\))+?/gm);
|
|
79
|
-
|
|
80
|
-
return Array.from(match).map((m) => Number(m[2]));
|
|
81
|
-
}
|
|
82
|
-
|
|
83
|
-
private parseFrameElement(element: htmlParser.HTMLElement): number[][] {
|
|
84
|
-
const pathElement = element.children[0].children[1];
|
|
85
|
-
const value = pathElement.getAttribute('d');
|
|
86
|
-
if (!value) {
|
|
87
|
-
return [[]];
|
|
88
|
-
}
|
|
89
|
-
|
|
90
|
-
const rawFrames = value.substring(9).split('C');
|
|
91
|
-
|
|
92
|
-
return rawFrames.map((str) => str.replaceAll(/\D+/g, ' ').trim().split(' ')).map((arr) => arr.map(Number));
|
|
93
|
-
}
|
|
94
|
-
|
|
95
|
-
/**
|
|
96
|
-
* Generate an `x-client-transaction-id` for the specific URL method and path.
|
|
97
|
-
*
|
|
98
|
-
* @param method - The target method.
|
|
99
|
-
* @param path - The target path.
|
|
100
|
-
*
|
|
101
|
-
* @returns The specific `x-client-transaction-id` token.
|
|
102
|
-
*/
|
|
103
|
-
public async generate(method: string, path: string): Promise<string | undefined> {
|
|
104
|
-
try {
|
|
105
|
-
// Refreshing dynamic args
|
|
106
|
-
await this.refreshDynamicArgs();
|
|
107
|
-
|
|
108
|
-
// If dynamic args weren't obtained, skip with error
|
|
109
|
-
if (!this._dynamicArgs) {
|
|
110
|
-
throw new Error('Dynamic args failed to generate');
|
|
111
|
-
}
|
|
112
|
-
|
|
113
|
-
const { verificationKey, frames, indices } = this._dynamicArgs;
|
|
114
|
-
|
|
115
|
-
return calculateClientTransactionIdHeader({
|
|
116
|
-
keyword: 'obfiowerehiring',
|
|
117
|
-
method: method,
|
|
118
|
-
path: path,
|
|
119
|
-
verificationKey: verificationKey,
|
|
120
|
-
frames: frames,
|
|
121
|
-
indices: indices,
|
|
122
|
-
extraByte: 3,
|
|
123
|
-
});
|
|
124
|
-
} catch (err) {
|
|
125
|
-
LogService.log(ELogActions.WARNING, {
|
|
126
|
-
message: 'Failed to generated transaction token. Request may or may not work',
|
|
127
|
-
error: err,
|
|
128
|
-
});
|
|
129
|
-
|
|
130
|
-
return;
|
|
131
|
-
}
|
|
132
|
-
}
|
|
133
|
-
|
|
134
|
-
/**
|
|
135
|
-
* Refreshes the dynamic args from the homepage.
|
|
136
|
-
*/
|
|
137
|
-
public async refreshDynamicArgs(): Promise<void> {
|
|
138
|
-
this._dynamicArgs = await this.getDynamicArgs();
|
|
139
|
-
}
|
|
140
|
-
}
|
|
@@ -1,12 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* The header for the transaction ID.
|
|
3
|
-
*
|
|
4
|
-
* @public
|
|
5
|
-
*/
|
|
6
|
-
export interface ITidHeader {
|
|
7
|
-
/* eslint-disable @typescript-eslint/naming-convention */
|
|
8
|
-
|
|
9
|
-
'x-client-transaction-id': string;
|
|
10
|
-
|
|
11
|
-
/* eslint-enable @typescript-eslint/naming-convention */
|
|
12
|
-
}
|
|
@@ -1,36 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* The parameters for generating the transaction ID.
|
|
3
|
-
*
|
|
4
|
-
* @internal
|
|
5
|
-
*/
|
|
6
|
-
export interface ITidParams {
|
|
7
|
-
/** Secret used for transaction ID calculation. */
|
|
8
|
-
keyword: string;
|
|
9
|
-
|
|
10
|
-
/** Request method. */
|
|
11
|
-
method: string;
|
|
12
|
-
|
|
13
|
-
/** Endpoint path without query parameters. */
|
|
14
|
-
path: string;
|
|
15
|
-
|
|
16
|
-
/** Twitter verification key received from HTML. */
|
|
17
|
-
verificationKey: string;
|
|
18
|
-
|
|
19
|
-
/** Animation frames extracted from HTML. */
|
|
20
|
-
frames: number[][][];
|
|
21
|
-
|
|
22
|
-
/** Indices used for getting the correct verification key bytes during animation key calculation. */
|
|
23
|
-
indices: number[];
|
|
24
|
-
|
|
25
|
-
/** Final byte of the transaction ID. */
|
|
26
|
-
extraByte: number;
|
|
27
|
-
|
|
28
|
-
/** Current time */
|
|
29
|
-
time?: number;
|
|
30
|
-
|
|
31
|
-
/** XOR byte used for final hash calculation, must be in 0-255 range. */
|
|
32
|
-
xorByte?: number;
|
|
33
|
-
|
|
34
|
-
/** Precomputed animation key. */
|
|
35
|
-
animationKey?: string;
|
|
36
|
-
}
|
|
@@ -1,19 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Service responsible for generating the `x-client-transaction-id` header.
|
|
3
|
-
*
|
|
4
|
-
* @public
|
|
5
|
-
*/
|
|
6
|
-
export interface ITidProvider {
|
|
7
|
-
/**
|
|
8
|
-
* Generates new `x-client-transaction-id` header.
|
|
9
|
-
*
|
|
10
|
-
* @param method - Request method.
|
|
11
|
-
* @param path - Endpoint path without query parameters.
|
|
12
|
-
*/
|
|
13
|
-
generate(method: string, path: string): Promise<string | undefined>;
|
|
14
|
-
|
|
15
|
-
/**
|
|
16
|
-
* Refresh arguments obtained from parsing the HTML page, if any.
|
|
17
|
-
*/
|
|
18
|
-
refreshDynamicArgs(): Promise<void>;
|
|
19
|
-
}
|