rettiwt-api 1.0.5 → 1.0.6
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/README.md +2 -2
- package/dist/index.d.ts +2 -0
- package/dist/index.js +3 -1
- package/dist/index.js.map +1 -1
- package/dist/queries/RootQuery.js +11 -0
- package/dist/queries/RootQuery.js.map +1 -1
- package/dist/resolvers/AccountResolver.d.ts +12 -0
- package/dist/resolvers/AccountResolver.js +84 -0
- package/dist/resolvers/AccountResolver.js.map +1 -0
- package/dist/server.js +3 -1
- package/dist/server.js.map +1 -1
- package/dist/services/AccountsService.d.ts +17 -0
- package/dist/services/AccountsService.js +171 -0
- package/dist/services/AccountsService.js.map +1 -0
- package/dist/services/FetcherService.d.ts +11 -2
- package/dist/services/FetcherService.js +47 -23
- package/dist/services/FetcherService.js.map +1 -1
- package/dist/services/accounting/AccountsService.d.ts +20 -0
- package/dist/services/accounting/AccountsService.js +147 -0
- package/dist/services/accounting/AccountsService.js.map +1 -0
- package/dist/services/accounting/Flows.d.ts +0 -0
- package/dist/services/accounting/Flows.js +2 -0
- package/dist/services/accounting/Flows.js.map +1 -0
- package/dist/services/accounting/LoginFlows.d.ts +20 -0
- package/dist/services/accounting/LoginFlows.js +70 -0
- package/dist/services/accounting/LoginFlows.js.map +1 -0
- package/dist/services/accounts/AccountService.d.ts +42 -0
- package/dist/services/accounts/AccountService.js +291 -0
- package/dist/services/accounts/AccountService.js.map +1 -0
- package/dist/services/accounts/LoginFlows.d.ts +77 -0
- package/dist/services/accounts/LoginFlows.js +92 -0
- package/dist/services/accounts/LoginFlows.js.map +1 -0
- package/dist/services/helper/Headers.d.ts +11 -1
- package/dist/services/helper/Headers.js +28 -2
- package/dist/services/helper/Headers.js.map +1 -1
- package/dist/types/HTTP.d.ts +0 -7
- package/dist/types/HTTP.js +1 -10
- package/dist/types/HTTP.js.map +1 -1
- package/dist/types/Service.d.ts +2 -0
- package/dist/types/Service.js.map +1 -1
- package/package.json +4 -2
- package/src/index.ts +3 -1
- package/src/queries/RootQuery.ts +11 -0
- package/src/resolvers/AccountResolver.ts +22 -0
- package/src/server.ts +3 -1
- package/src/services/FetcherService.ts +26 -8
- package/src/services/accounts/AccountService.ts +156 -0
- package/src/services/accounts/LoginFlows.ts +90 -0
- package/src/services/helper/Headers.ts +27 -1
- package/src/types/HTTP.ts +0 -8
- package/src/types/Service.ts +3 -1
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
declare const LoginFlows: {
|
|
2
|
+
InitiateLogin: {
|
|
3
|
+
url: string;
|
|
4
|
+
};
|
|
5
|
+
JsInstrumentationSubtask: {
|
|
6
|
+
url: string;
|
|
7
|
+
body: (flowToken: string) => {
|
|
8
|
+
flow_token: string;
|
|
9
|
+
subtask_inputs: {
|
|
10
|
+
subtask_id: string;
|
|
11
|
+
js_instrumentation: {
|
|
12
|
+
response: string;
|
|
13
|
+
link: string;
|
|
14
|
+
};
|
|
15
|
+
}[];
|
|
16
|
+
};
|
|
17
|
+
};
|
|
18
|
+
EnterUserIdentifier: {
|
|
19
|
+
url: string;
|
|
20
|
+
body: (flowToken: string, email: string) => {
|
|
21
|
+
flow_token: string;
|
|
22
|
+
subtask_inputs: {
|
|
23
|
+
subtask_id: string;
|
|
24
|
+
settings_list: {
|
|
25
|
+
setting_responses: {
|
|
26
|
+
key: string;
|
|
27
|
+
response_data: {
|
|
28
|
+
text_data: {
|
|
29
|
+
result: string;
|
|
30
|
+
};
|
|
31
|
+
};
|
|
32
|
+
}[];
|
|
33
|
+
link: string;
|
|
34
|
+
};
|
|
35
|
+
}[];
|
|
36
|
+
};
|
|
37
|
+
};
|
|
38
|
+
EnterAlternateUserIdentifier: {
|
|
39
|
+
url: string;
|
|
40
|
+
body: (flowToken: string, userName: string) => {
|
|
41
|
+
flow_token: string;
|
|
42
|
+
subtask_inputs: {
|
|
43
|
+
subtask_id: string;
|
|
44
|
+
enter_text: {
|
|
45
|
+
text: string;
|
|
46
|
+
link: string;
|
|
47
|
+
};
|
|
48
|
+
}[];
|
|
49
|
+
};
|
|
50
|
+
};
|
|
51
|
+
EnterPassword: {
|
|
52
|
+
url: string;
|
|
53
|
+
body: (flowToken: string, password: string) => {
|
|
54
|
+
flow_token: string;
|
|
55
|
+
subtask_inputs: {
|
|
56
|
+
subtask_id: string;
|
|
57
|
+
enter_password: {
|
|
58
|
+
password: string;
|
|
59
|
+
link: string;
|
|
60
|
+
};
|
|
61
|
+
}[];
|
|
62
|
+
};
|
|
63
|
+
};
|
|
64
|
+
AccountDuplicationCheck: {
|
|
65
|
+
url: string;
|
|
66
|
+
body: (flowToken: string) => {
|
|
67
|
+
flow_token: string;
|
|
68
|
+
subtask_inputs: {
|
|
69
|
+
subtask_id: string;
|
|
70
|
+
check_logged_in_account: {
|
|
71
|
+
link: string;
|
|
72
|
+
};
|
|
73
|
+
}[];
|
|
74
|
+
};
|
|
75
|
+
};
|
|
76
|
+
};
|
|
77
|
+
export default LoginFlows;
|
|
@@ -0,0 +1,92 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
exports.__esModule = true;
|
|
3
|
+
var LoginFlows = {
|
|
4
|
+
"InitiateLogin": {
|
|
5
|
+
url: 'https://api.twitter.com/1.1/onboarding/task.json?flow_name=login'
|
|
6
|
+
},
|
|
7
|
+
"JsInstrumentationSubtask": {
|
|
8
|
+
url: 'https://api.twitter.com/1.1/onboarding/task.json',
|
|
9
|
+
body: function (flowToken) { return ({
|
|
10
|
+
"flow_token": flowToken,
|
|
11
|
+
"subtask_inputs": [
|
|
12
|
+
{
|
|
13
|
+
"subtask_id": "LoginJsInstrumentationSubtask",
|
|
14
|
+
"js_instrumentation": {
|
|
15
|
+
"response": "{\"rf\":{\"a09453c7341fb1cbb7d51561f92d478fa0752bc77e7ca6b5703258680b2c51d7\":-4,\"bd26c6694e256b10766447d992deaf92bb220bc05e3b8205ba5c9a4f83302230\":0,\"abfa440376b8dc33ca518e1e2a998b3ac4200a8122ef09781eea2c1408717111\":-1,\"a4e87b66027f638a4634561275fab00f9f7446b81a180b5f03eda69fa32eb8f4\":-224},\"s\":\"yET9nlXrlGRAylCyyBKEsxOpUweMpjRz5RfKzTzQyVADnKE64gmpyILfKBK0-HIHWY8FbJPHGWr6QrCb5A-Z3q2SLRm4DReprZGXykJ111_ynet8kSjFkRjODKKDN2FzT1V6rx9FILnUuRCaMu9ewfPgPBi4wO1g7EUeEsSSHIiCwNc9URJr4c2xVTA3ibIfTbu8p2WhX7RZAk8LWRPpPPB21st8Z1j0LcLlR0bkZoF6LsN-7w75lGB0s4z1JKqus2MVuRcPMay0wWZbn8Qx9In_-tSTvEBLcxjUpDgwu29G0g0iCWoISFzLY4-LLvV7UBGklkByIcPtwYbDbREqRQAAAYYmXAsG\"}",
|
|
16
|
+
"link": "next_link"
|
|
17
|
+
}
|
|
18
|
+
}
|
|
19
|
+
]
|
|
20
|
+
}); }
|
|
21
|
+
},
|
|
22
|
+
"EnterUserIdentifier": {
|
|
23
|
+
url: 'https://api.twitter.com/1.1/onboarding/task.json',
|
|
24
|
+
body: function (flowToken, email) { return ({
|
|
25
|
+
"flow_token": flowToken,
|
|
26
|
+
"subtask_inputs": [
|
|
27
|
+
{
|
|
28
|
+
"subtask_id": "LoginEnterUserIdentifierSSO",
|
|
29
|
+
"settings_list": {
|
|
30
|
+
"setting_responses": [
|
|
31
|
+
{
|
|
32
|
+
"key": "user_identifier",
|
|
33
|
+
"response_data": {
|
|
34
|
+
"text_data": {
|
|
35
|
+
"result": email
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
],
|
|
40
|
+
"link": "next_link"
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
]
|
|
44
|
+
}); }
|
|
45
|
+
},
|
|
46
|
+
"EnterAlternateUserIdentifier": {
|
|
47
|
+
url: 'https://api.twitter.com/1.1/onboarding/task.json',
|
|
48
|
+
body: function (flowToken, userName) { return ({
|
|
49
|
+
"flow_token": flowToken,
|
|
50
|
+
"subtask_inputs": [
|
|
51
|
+
{
|
|
52
|
+
"subtask_id": "LoginEnterAlternateIdentifierSubtask",
|
|
53
|
+
"enter_text": {
|
|
54
|
+
"text": userName,
|
|
55
|
+
"link": "next_link"
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
]
|
|
59
|
+
}); }
|
|
60
|
+
},
|
|
61
|
+
"EnterPassword": {
|
|
62
|
+
url: 'https://api.twitter.com/1.1/onboarding/task.json',
|
|
63
|
+
body: function (flowToken, password) { return ({
|
|
64
|
+
"flow_token": flowToken,
|
|
65
|
+
"subtask_inputs": [
|
|
66
|
+
{
|
|
67
|
+
"subtask_id": "LoginEnterPassword",
|
|
68
|
+
"enter_password": {
|
|
69
|
+
"password": password,
|
|
70
|
+
"link": "next_link"
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
]
|
|
74
|
+
}); }
|
|
75
|
+
},
|
|
76
|
+
"AccountDuplicationCheck": {
|
|
77
|
+
url: 'https://api.twitter.com/1.1/onboarding/task.json',
|
|
78
|
+
body: function (flowToken) { return ({
|
|
79
|
+
"flow_token": flowToken,
|
|
80
|
+
"subtask_inputs": [
|
|
81
|
+
{
|
|
82
|
+
"subtask_id": "AccountDuplicationCheck",
|
|
83
|
+
"check_logged_in_account": {
|
|
84
|
+
"link": "AccountDuplicationCheck_false"
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
]
|
|
88
|
+
}); }
|
|
89
|
+
}
|
|
90
|
+
};
|
|
91
|
+
exports["default"] = LoginFlows;
|
|
92
|
+
//# sourceMappingURL=LoginFlows.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"LoginFlows.js","sourceRoot":"","sources":["../../../src/services/accounts/LoginFlows.ts"],"names":[],"mappings":";;AAAA,IAAM,UAAU,GAAG;IACf,eAAe,EAAE;QACb,GAAG,EAAE,kEAAkE;KAC1E;IACD,0BAA0B,EAAE;QACxB,GAAG,EAAE,kDAAkD;QACvD,IAAI,EAAE,UAAC,SAAiB,IAAK,OAAA,CAAC;YAC1B,YAAY,EAAE,SAAS;YACvB,gBAAgB,EAAE;gBACd;oBACI,YAAY,EAAE,+BAA+B;oBAC7C,oBAAoB,EAAE;wBAClB,UAAU,EAAE,wpBAAwpB;wBACpqB,MAAM,EAAE,WAAW;qBACtB;iBACJ;aACJ;SACJ,CAAC,EAX2B,CAW3B;KACL;IACD,qBAAqB,EAAE;QACnB,GAAG,EAAE,kDAAkD;QACvD,IAAI,EAAE,UAAC,SAAiB,EAAE,KAAa,IAAK,OAAA,CAAC;YACzC,YAAY,EAAE,SAAS;YACvB,gBAAgB,EAAE;gBACd;oBACI,YAAY,EAAE,6BAA6B;oBAC3C,eAAe,EAAE;wBACb,mBAAmB,EAAE;4BACjB;gCACI,KAAK,EAAE,iBAAiB;gCACxB,eAAe,EAAE;oCACb,WAAW,EAAE;wCACT,QAAQ,EAAE,KAAK;qCAClB;iCACJ;6BACJ;yBACJ;wBACD,MAAM,EAAE,WAAW;qBACtB;iBACJ;aACJ;SACJ,CAAC,EApB0C,CAoB1C;KACL;IACD,8BAA8B,EAAE;QAC5B,GAAG,EAAE,kDAAkD;QACvD,IAAI,EAAE,UAAC,SAAiB,EAAE,QAAgB,IAAK,OAAA,CAAC;YAC5C,YAAY,EAAE,SAAS;YACvB,gBAAgB,EAAE;gBACd;oBACI,YAAY,EAAE,sCAAsC;oBACpD,YAAY,EAAE;wBACV,MAAM,EAAE,QAAQ;wBAChB,MAAM,EAAE,WAAW;qBACtB;iBACJ;aACJ;SACJ,CAAC,EAX6C,CAW7C;KACL;IACD,eAAe,EAAE;QACb,GAAG,EAAE,kDAAkD;QACvD,IAAI,EAAE,UAAC,SAAiB,EAAE,QAAgB,IAAK,OAAA,CAAC;YAC5C,YAAY,EAAE,SAAS;YACvB,gBAAgB,EAAE;gBACd;oBACI,YAAY,EAAE,oBAAoB;oBAClC,gBAAgB,EAAE;wBACd,UAAU,EAAE,QAAQ;wBACpB,MAAM,EAAE,WAAW;qBACtB;iBACJ;aACJ;SACJ,CAAC,EAX6C,CAW7C;KACL;IACD,yBAAyB,EAAE;QACvB,GAAG,EAAE,kDAAkD;QACvD,IAAI,EAAE,UAAC,SAAiB,IAAK,OAAA,CAAC;YAC1B,YAAY,EAAE,SAAS;YACvB,gBAAgB,EAAE;gBACd;oBACI,YAAY,EAAE,yBAAyB;oBACvC,yBAAyB,EAAE;wBACvB,MAAM,EAAE,+BAA+B;qBAC1C;iBACJ;aACJ;SACJ,CAAC,EAV2B,CAU3B;KACL;CACJ,CAAA;AAED,qBAAe,UAAU,CAAC"}
|
|
@@ -1,9 +1,19 @@
|
|
|
1
1
|
import { GuestCredentials, AuthCredentials } from '../../types/Authentication';
|
|
2
2
|
/**
|
|
3
|
-
* @returns The header required for making authorized HTTP requests
|
|
4
3
|
* @param authToken The authentication token received from Twitter
|
|
5
4
|
* @param csrfToken The csrf token received from Twitter
|
|
6
5
|
* @param cookie The cookie associated with the logged in account
|
|
6
|
+
* @returns The header required for making authorized HTTP requests
|
|
7
7
|
*/
|
|
8
8
|
export declare function authorizedHeader(authCred: AuthCredentials): any;
|
|
9
|
+
/**
|
|
10
|
+
* @param guestCred The guest credentials to use
|
|
11
|
+
* @returns The header requred for making guest HTTP requests
|
|
12
|
+
*/
|
|
9
13
|
export declare function guestHeader(guestCred: GuestCredentials): any;
|
|
14
|
+
/**
|
|
15
|
+
* @param guestCred The guest credentials to use for making the login requests
|
|
16
|
+
* @param cookie The cookie to be used
|
|
17
|
+
* @returns The header for making HTTP request for logging in
|
|
18
|
+
*/
|
|
19
|
+
export declare function loginHeader(guestCred: GuestCredentials, cookie: string): any;
|
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
exports.__esModule = true;
|
|
3
|
-
exports.guestHeader = exports.authorizedHeader = void 0;
|
|
3
|
+
exports.loginHeader = exports.guestHeader = exports.authorizedHeader = void 0;
|
|
4
4
|
/**
|
|
5
|
-
* @returns The header required for making authorized HTTP requests
|
|
6
5
|
* @param authToken The authentication token received from Twitter
|
|
7
6
|
* @param csrfToken The csrf token received from Twitter
|
|
8
7
|
* @param cookie The cookie associated with the logged in account
|
|
8
|
+
* @returns The header required for making authorized HTTP requests
|
|
9
9
|
*/
|
|
10
10
|
function authorizedHeader(authCred) {
|
|
11
11
|
return [
|
|
@@ -24,6 +24,10 @@ function authorizedHeader(authCred) {
|
|
|
24
24
|
];
|
|
25
25
|
}
|
|
26
26
|
exports.authorizedHeader = authorizedHeader;
|
|
27
|
+
/**
|
|
28
|
+
* @param guestCred The guest credentials to use
|
|
29
|
+
* @returns The header requred for making guest HTTP requests
|
|
30
|
+
*/
|
|
27
31
|
function guestHeader(guestCred) {
|
|
28
32
|
return [
|
|
29
33
|
'Accept: */*',
|
|
@@ -33,4 +37,26 @@ function guestHeader(guestCred) {
|
|
|
33
37
|
];
|
|
34
38
|
}
|
|
35
39
|
exports.guestHeader = guestHeader;
|
|
40
|
+
/**
|
|
41
|
+
* @param guestCred The guest credentials to use for making the login requests
|
|
42
|
+
* @param cookie The cookie to be used
|
|
43
|
+
* @returns The header for making HTTP request for logging in
|
|
44
|
+
*/
|
|
45
|
+
function loginHeader(guestCred, cookie) {
|
|
46
|
+
return [
|
|
47
|
+
"sec-ch-ua: \"Not_A Brand\";v=\"99\", \"Microsoft Edge\";v=\"109\", \"Chromium\";v=\"109\"",
|
|
48
|
+
"x-twitter-client-language: en",
|
|
49
|
+
"sec-ch-ua-mobile: ?0",
|
|
50
|
+
"authorization: ".concat(guestCred.authToken),
|
|
51
|
+
"User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/109.0.0.0 Safari/537.36 Edg/109.0.1518.78",
|
|
52
|
+
"content-type: application/json",
|
|
53
|
+
"x-guest-token: ".concat(guestCred.guestToken),
|
|
54
|
+
"x-twitter-active-user: yes",
|
|
55
|
+
"sec-ch-ua-platform: \"Windows\"",
|
|
56
|
+
"Accept: */*",
|
|
57
|
+
"host: api.twitter.com",
|
|
58
|
+
"Cookie: ".concat(cookie)
|
|
59
|
+
];
|
|
60
|
+
}
|
|
61
|
+
exports.loginHeader = loginHeader;
|
|
36
62
|
//# sourceMappingURL=Headers.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Headers.js","sourceRoot":"","sources":["../../../src/services/helper/Headers.ts"],"names":[],"mappings":";;;AAGA;;;;;GAKG;AACH,SAAgB,gBAAgB,CAAC,QAAyB;IACtD,OAAO;QACH,2FAA+E;QAC/E,+BAA+B;QAC/B,wBAAiB,QAAQ,CAAC,SAAS,CAAE;QACrC,sBAAsB;QACtB,yBAAkB,QAAQ,CAAC,SAAS,CAAE;QACtC,+IAA+I;QAC/I,oCAAoC;QACpC,4BAA4B;QAC5B,iCAA+B;QAC/B,aAAa;QACb,uBAAuB;QACvB,kBAAW,QAAQ,CAAC,MAAM,CAAE;KAC/B,CAAC;AACN,CAAC;AAfD,4CAeC;AAED,SAAgB,WAAW,CAAC,SAA2B;IACnD,OAAO;QACH,aAAa;QACb,yBAAkB,SAAS,CAAC,SAAS,CAAE;QACvC,+IAA+I;QAC/I,yBAAkB,SAAS,CAAC,UAAU,CAAE;KAC3C,CAAC;AACN,CAAC;AAPD,kCAOC"}
|
|
1
|
+
{"version":3,"file":"Headers.js","sourceRoot":"","sources":["../../../src/services/helper/Headers.ts"],"names":[],"mappings":";;;AAGA;;;;;GAKG;AACH,SAAgB,gBAAgB,CAAC,QAAyB;IACtD,OAAO;QACH,2FAA+E;QAC/E,+BAA+B;QAC/B,wBAAiB,QAAQ,CAAC,SAAS,CAAE;QACrC,sBAAsB;QACtB,yBAAkB,QAAQ,CAAC,SAAS,CAAE;QACtC,+IAA+I;QAC/I,oCAAoC;QACpC,4BAA4B;QAC5B,iCAA+B;QAC/B,aAAa;QACb,uBAAuB;QACvB,kBAAW,QAAQ,CAAC,MAAM,CAAE;KAC/B,CAAC;AACN,CAAC;AAfD,4CAeC;AAED;;;GAGG;AACH,SAAgB,WAAW,CAAC,SAA2B;IACnD,OAAO;QACH,aAAa;QACb,yBAAkB,SAAS,CAAC,SAAS,CAAE;QACvC,+IAA+I;QAC/I,yBAAkB,SAAS,CAAC,UAAU,CAAE;KAC3C,CAAC;AACN,CAAC;AAPD,kCAOC;AAED;;;;GAIG;AACH,SAAgB,WAAW,CAAC,SAA2B,EAAE,MAAc;IACnE,OAAO;QACH,2FAA+E;QAC/E,+BAA+B;QAC/B,sBAAsB;QACtB,yBAAkB,SAAS,CAAC,SAAS,CAAE;QACvC,+IAA+I;QAC/I,gCAAgC;QAChC,yBAAkB,SAAS,CAAC,UAAU,CAAE;QACxC,4BAA4B;QAC5B,iCAA+B;QAC/B,aAAa;QACb,uBAAuB;QACvB,kBAAW,MAAM,CAAE;KACtB,CAAC;AACN,CAAC;AAfD,kCAeC"}
|
package/dist/types/HTTP.d.ts
CHANGED
package/dist/types/HTTP.js
CHANGED
|
@@ -1,15 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
exports.__esModule = true;
|
|
3
|
-
exports.HttpStatus =
|
|
4
|
-
/**
|
|
5
|
-
* @summary Stores all the different type of http requests
|
|
6
|
-
*/
|
|
7
|
-
var HttpMethods;
|
|
8
|
-
(function (HttpMethods) {
|
|
9
|
-
HttpMethods["POST"] = "POST";
|
|
10
|
-
HttpMethods["GET"] = "GET";
|
|
11
|
-
})(HttpMethods = exports.HttpMethods || (exports.HttpMethods = {}));
|
|
12
|
-
;
|
|
3
|
+
exports.HttpStatus = void 0;
|
|
13
4
|
/**
|
|
14
5
|
* @summary Stores the different types of http status codes
|
|
15
6
|
*/
|
package/dist/types/HTTP.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"HTTP.js","sourceRoot":"","sources":["../../src/types/HTTP.ts"],"names":[],"mappings":";;;AAAA;;GAEG;AACH,IAAY,
|
|
1
|
+
{"version":3,"file":"HTTP.js","sourceRoot":"","sources":["../../src/types/HTTP.ts"],"names":[],"mappings":";;;AAAA;;GAEG;AACH,IAAY,UAWX;AAXD,WAAY,UAAU;IAClB,yDAAgB,CAAA;IAChB,6DAAkB,CAAA;IAClB,uDAAe,CAAA;IACf,qDAAc,CAAA;IACd,qEAAsB,CAAA;IACtB,iEAAoB,CAAA;IACpB,mEAAqB,CAAA;IACrB,2EAAyB,CAAA;IACzB,yDAAgB,CAAA;IAChB,yEAAwB,CAAA;AAC5B,CAAC,EAXW,UAAU,GAAV,kBAAU,KAAV,kBAAU,QAWrB;AAAA,CAAC"}
|
package/dist/types/Service.d.ts
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { AccountService } from "../services/accounts/AccountService";
|
|
1
2
|
import { TweetService } from "../services/data/TweetService";
|
|
2
3
|
import { UserAccountService } from "../services/data/UserAccountService";
|
|
3
4
|
/**
|
|
@@ -25,4 +26,5 @@ export interface CursoredData<Type> {
|
|
|
25
26
|
export interface DataContext {
|
|
26
27
|
users: UserAccountService;
|
|
27
28
|
tweets: TweetService;
|
|
29
|
+
account: AccountService;
|
|
28
30
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Service.js","sourceRoot":"","sources":["../../src/types/Service.ts"],"names":[],"mappings":";;;
|
|
1
|
+
{"version":3,"file":"Service.js","sourceRoot":"","sources":["../../src/types/Service.ts"],"names":[],"mappings":";;;AAKA;;GAEG;AACH;IAII,cAAc;IACd;;;OAGG;IACH,gBAAY,SAAiB;QACzB,IAAI,CAAC,KAAK,GAAG,SAAS,CAAC;IAC3B,CAAC;IACL,aAAC;AAAD,CAAC,AAZD,IAYC;AAZY,wBAAM"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "rettiwt-api",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.6",
|
|
4
4
|
"main": "dist/index.js",
|
|
5
5
|
"types": "dist/index.d.ts",
|
|
6
6
|
"description": "An API for fetching data from TwitterAPI, without any rate limits!",
|
|
@@ -24,13 +24,15 @@
|
|
|
24
24
|
"homepage": "https://github.com/Rishikant181/Rettiwt-API#readme",
|
|
25
25
|
"dependencies": {
|
|
26
26
|
"axios": "^1.3.2",
|
|
27
|
-
"
|
|
27
|
+
"cookiejar": "2.1.4",
|
|
28
|
+
"express": "4.18.2",
|
|
28
29
|
"express-graphql": "0.12.0",
|
|
29
30
|
"graphql": "14.7.0",
|
|
30
31
|
"node-cache": "5.1.2",
|
|
31
32
|
"node-libcurl": "3.0.0"
|
|
32
33
|
},
|
|
33
34
|
"devDependencies": {
|
|
35
|
+
"@types/cookiejar": "^2.1.2",
|
|
34
36
|
"@types/express": "4.17.13",
|
|
35
37
|
"@types/graphql": "14.5.0",
|
|
36
38
|
"@types/node": "17.0.24",
|
package/src/index.ts
CHANGED
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
import { AuthService } from "./services/AuthService";
|
|
3
3
|
import { UserAccountService } from "./services/data/UserAccountService";
|
|
4
4
|
import { TweetService } from "./services/data/TweetService";
|
|
5
|
+
import { AccountService } from "./services/accounts/AccountService";
|
|
5
6
|
|
|
6
7
|
/**
|
|
7
8
|
* @param cookie The cookies string to use to fetch data
|
|
@@ -14,6 +15,7 @@ export const Rettiwt = (cookie: string = '') => {
|
|
|
14
15
|
// Using the auth service instance to create data services instances
|
|
15
16
|
return {
|
|
16
17
|
users: new UserAccountService(auth),
|
|
17
|
-
tweets: new TweetService(auth)
|
|
18
|
+
tweets: new TweetService(auth),
|
|
19
|
+
account: new AccountService()
|
|
18
20
|
};
|
|
19
21
|
}
|
package/src/queries/RootQuery.ts
CHANGED
|
@@ -9,6 +9,7 @@ import { TweetFilter } from '../types/Tweet';
|
|
|
9
9
|
// RESOLVERS
|
|
10
10
|
import UserResolver from '../resolvers/UserResolver';
|
|
11
11
|
import TweetResolver from '../resolvers/TweetResolver';
|
|
12
|
+
import AccountResolver from '../resolvers/AccountResolver';
|
|
12
13
|
|
|
13
14
|
export const rootQuery = new GraphQLObjectType({
|
|
14
15
|
name: 'Root',
|
|
@@ -51,6 +52,16 @@ export const rootQuery = new GraphQLObjectType({
|
|
|
51
52
|
cursor: { type: GraphQLString, defaultValue: '' }
|
|
52
53
|
},
|
|
53
54
|
resolve: (parent, args, context) => new TweetResolver(context).resolveTweets(args as TweetFilter, args.count, args.cursor)
|
|
55
|
+
},
|
|
56
|
+
Login: {
|
|
57
|
+
type: GraphQLString,
|
|
58
|
+
description: "Returns the cookies that can be used to fetch data from twitter",
|
|
59
|
+
args: {
|
|
60
|
+
email: { type: GraphQLString },
|
|
61
|
+
userName: { type: GraphQLString },
|
|
62
|
+
password: { type: GraphQLString }
|
|
63
|
+
},
|
|
64
|
+
resolve: (parent, args, context) => new AccountResolver(context).resolveLogin(args.email, args.userName, args.password)
|
|
54
65
|
}
|
|
55
66
|
}
|
|
56
67
|
})
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
// RESOLVERS
|
|
2
|
+
import ResolverBase from './ResolverBase';
|
|
3
|
+
|
|
4
|
+
// TYPES
|
|
5
|
+
import { DataContext } from '../types/Service';
|
|
6
|
+
|
|
7
|
+
export default class AccountResolver extends ResolverBase {
|
|
8
|
+
// MEMBER METHODS
|
|
9
|
+
constructor(context: DataContext) {
|
|
10
|
+
super(context);
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
/**
|
|
14
|
+
* @param email The email of the account to be logged into
|
|
15
|
+
* @param userName The username associated with the account
|
|
16
|
+
* @param password The password to the account
|
|
17
|
+
* @returns The cookie string that can be used to authenticate against twitter
|
|
18
|
+
*/
|
|
19
|
+
async resolveLogin(email: string, userName: string, password: string): Promise<string> {
|
|
20
|
+
return await this.context.account.login(email, userName, password);
|
|
21
|
+
}
|
|
22
|
+
}
|
package/src/server.ts
CHANGED
|
@@ -6,6 +6,7 @@ import { GraphQLSchema } from 'graphql';
|
|
|
6
6
|
// Services
|
|
7
7
|
import { UserAccountService } from './services/data/UserAccountService';
|
|
8
8
|
import { TweetService } from './services/data/TweetService';
|
|
9
|
+
import { AccountService } from './services/accounts/AccountService';
|
|
9
10
|
import { AuthService } from './services/AuthService';
|
|
10
11
|
|
|
11
12
|
// SCHEMA
|
|
@@ -24,7 +25,8 @@ app.use('/graphql', graphqlHTTP(req => ({
|
|
|
24
25
|
}),
|
|
25
26
|
context: {
|
|
26
27
|
users: new UserAccountService(new AuthService(req.headers.cookie as string)),
|
|
27
|
-
tweets: new TweetService(new AuthService(req.headers.cookie as string))
|
|
28
|
+
tweets: new TweetService(new AuthService(req.headers.cookie as string)),
|
|
29
|
+
account: new AccountService()
|
|
28
30
|
},
|
|
29
31
|
// If app is running in development environment, enable graphiql
|
|
30
32
|
graphiql: config.is_development
|
|
@@ -13,6 +13,15 @@ import { Result as RawTweet } from '../types/raw/tweet/Tweet';
|
|
|
13
13
|
// HELPERS
|
|
14
14
|
import * as Headers from './helper/Headers'
|
|
15
15
|
import * as Deserializers from './helper/Deserializers';
|
|
16
|
+
import { CurlyOptions } from 'node-libcurl/dist/curly';
|
|
17
|
+
|
|
18
|
+
/**
|
|
19
|
+
* @summary Stores all the different type of http requests
|
|
20
|
+
*/
|
|
21
|
+
export enum HttpMethods {
|
|
22
|
+
POST = "POST",
|
|
23
|
+
GET = "GET"
|
|
24
|
+
};
|
|
16
25
|
|
|
17
26
|
/**
|
|
18
27
|
* @service The base serivice from which all other data services derive their behaviour
|
|
@@ -43,16 +52,25 @@ export class FetcherService {
|
|
|
43
52
|
/**
|
|
44
53
|
* @returns The absolute raw json data from give url
|
|
45
54
|
* @param url The url to fetch data from
|
|
46
|
-
* @param
|
|
55
|
+
* @param authenticate Whether to authenticate requests or not
|
|
56
|
+
* @param method The HTTP method to use
|
|
57
|
+
* @param data The data to be sent along with the request (works with only POST method)
|
|
47
58
|
*/
|
|
48
|
-
protected async request<DataType>(url: string,
|
|
49
|
-
//
|
|
50
|
-
let
|
|
51
|
-
httpHeader:
|
|
52
|
-
sslVerifyPeer: false
|
|
53
|
-
}
|
|
59
|
+
protected async request<DataType>(url: string, authenticate: boolean = true, method: HttpMethods = HttpMethods.GET, data?: any): Promise<CurlyResult<DataType>> {
|
|
60
|
+
// Creating the configuration for the http request
|
|
61
|
+
let config: CurlyOptions = {
|
|
62
|
+
httpHeader: authenticate ? Headers.authorizedHeader(await this.auth.getAuthCredentials()) : Headers.guestHeader(await this.auth.getGuestCredentials()),
|
|
63
|
+
sslVerifyPeer: false,
|
|
64
|
+
};
|
|
54
65
|
|
|
55
|
-
|
|
66
|
+
// If post request is to be made
|
|
67
|
+
if (method == HttpMethods.POST) {
|
|
68
|
+
return await curly.post(url, { ...config, postFields: JSON.stringify(data) }).then(res => this.handleHTTPError(res));
|
|
69
|
+
}
|
|
70
|
+
// If get request is to be made
|
|
71
|
+
else {
|
|
72
|
+
return await curly.get(url, config).then(res => this.handleHTTPError(res));
|
|
73
|
+
}
|
|
56
74
|
}
|
|
57
75
|
|
|
58
76
|
/**
|
|
@@ -0,0 +1,156 @@
|
|
|
1
|
+
// PACKAGES
|
|
2
|
+
import { curly, CurlyResult } from 'node-libcurl';
|
|
3
|
+
|
|
4
|
+
// SERVICES
|
|
5
|
+
import { AuthService } from '../AuthService';
|
|
6
|
+
|
|
7
|
+
// TYPES
|
|
8
|
+
import { GuestCredentials } from '../../types/Authentication';
|
|
9
|
+
|
|
10
|
+
// HELPERS
|
|
11
|
+
import LoginFlows from './LoginFlows';
|
|
12
|
+
import { loginHeader } from '../helper/Headers';
|
|
13
|
+
import { Cookie, CookieJar } from 'cookiejar';
|
|
14
|
+
|
|
15
|
+
export class AccountService {
|
|
16
|
+
// MEMBER DATA
|
|
17
|
+
private auth: AuthService; // To store the auth service instance to use
|
|
18
|
+
private guestCreds: GuestCredentials; // To store the guest credentials to use
|
|
19
|
+
private cookies: Cookie[]; // To store the cookies received from twitter
|
|
20
|
+
private flowToken: string; // To store the flow token received from current flow
|
|
21
|
+
|
|
22
|
+
// MEMBER METHODS
|
|
23
|
+
constructor() {
|
|
24
|
+
this.auth = new AuthService();
|
|
25
|
+
this.guestCreds = { authToken: '', guestToken: '' };
|
|
26
|
+
this.cookies = [];
|
|
27
|
+
this.flowToken = '';
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
/**
|
|
31
|
+
* @returns The current guest credentials to use. If if does not exists, then a new one is created
|
|
32
|
+
*/
|
|
33
|
+
private async getGuestCredentials(): Promise<GuestCredentials> {
|
|
34
|
+
// If a guest credential has not been already set, get a new one
|
|
35
|
+
if (!this.guestCreds.guestToken) {
|
|
36
|
+
this.guestCreds = await this.auth.getGuestCredentials();
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
return this.guestCreds;
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
/**
|
|
43
|
+
* @summary Step 1: Initiates login
|
|
44
|
+
*/
|
|
45
|
+
private async initiateLogin(): Promise<void> {
|
|
46
|
+
// Initiating the login process
|
|
47
|
+
const res: CurlyResult = await curly.post(LoginFlows.InitiateLogin.url, {
|
|
48
|
+
httpHeader: loginHeader(await this.getGuestCredentials(), this.cookies.toString()),
|
|
49
|
+
sslVerifyPeer: false,
|
|
50
|
+
postFields: ''
|
|
51
|
+
});
|
|
52
|
+
|
|
53
|
+
// Storing cookies received
|
|
54
|
+
this.cookies = new CookieJar().setCookies(res.headers[0]['Set-Cookie'] as string[]);
|
|
55
|
+
|
|
56
|
+
// Getting the flow token
|
|
57
|
+
this.flowToken = res.data['flow_token'];
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
/**
|
|
61
|
+
* @summary Step 2: Does something
|
|
62
|
+
*/
|
|
63
|
+
private async jsInstrumentationSubtask(): Promise<void> {
|
|
64
|
+
// Executing the flow
|
|
65
|
+
const res: CurlyResult = await curly.post(LoginFlows.JsInstrumentationSubtask.url, {
|
|
66
|
+
httpHeader: loginHeader(await this.getGuestCredentials(), this.cookies.join(';').toString()),
|
|
67
|
+
sslVerifyPeer: false,
|
|
68
|
+
postFields: JSON.stringify(LoginFlows.JsInstrumentationSubtask.body(this.flowToken))
|
|
69
|
+
});
|
|
70
|
+
|
|
71
|
+
// Getting the flow token
|
|
72
|
+
this.flowToken = res.data['flow_token'];
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
/**
|
|
76
|
+
* @summary Step 3: Takes the email for login
|
|
77
|
+
*/
|
|
78
|
+
private async enterUserIdentifier(email: string): Promise<void> {
|
|
79
|
+
// Executing the flow
|
|
80
|
+
const res: CurlyResult = await curly.post(LoginFlows.EnterUserIdentifier.url, {
|
|
81
|
+
httpHeader: loginHeader(await this.getGuestCredentials(), this.cookies.join(';').toString()),
|
|
82
|
+
sslVerifyPeer: false,
|
|
83
|
+
postFields: JSON.stringify(LoginFlows.EnterUserIdentifier.body(this.flowToken, email))
|
|
84
|
+
});
|
|
85
|
+
|
|
86
|
+
// Getting the flow token
|
|
87
|
+
this.flowToken = res.data['flow_token'];
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
/**
|
|
91
|
+
* @summary Step 4: Takes the username for login
|
|
92
|
+
*/
|
|
93
|
+
private async enterAlternateUserIdentifier(userName: string): Promise<void> {
|
|
94
|
+
// Executing the flow
|
|
95
|
+
const res: CurlyResult = await curly.post(LoginFlows.EnterAlternateUserIdentifier.url, {
|
|
96
|
+
httpHeader: loginHeader(await this.getGuestCredentials(), this.cookies.join(';').toString()),
|
|
97
|
+
sslVerifyPeer: false,
|
|
98
|
+
postFields: JSON.stringify(LoginFlows.EnterAlternateUserIdentifier.body(this.flowToken, userName))
|
|
99
|
+
});
|
|
100
|
+
|
|
101
|
+
// Getting the flow token
|
|
102
|
+
this.flowToken = res.data['flow_token'];
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
/**
|
|
106
|
+
* @summary Step 5: Takes the password for login
|
|
107
|
+
*/
|
|
108
|
+
private async enterPassword(password: string): Promise<void> {
|
|
109
|
+
// Executing the flow
|
|
110
|
+
const res: CurlyResult = await curly.post(LoginFlows.EnterPassword.url, {
|
|
111
|
+
httpHeader: loginHeader(await this.getGuestCredentials(), this.cookies.join(';').toString()),
|
|
112
|
+
sslVerifyPeer: false,
|
|
113
|
+
postFields: JSON.stringify(LoginFlows.EnterPassword.body(this.flowToken, password))
|
|
114
|
+
});
|
|
115
|
+
|
|
116
|
+
// Getting the flow token
|
|
117
|
+
this.flowToken = res.data['flow_token'];
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
/**
|
|
121
|
+
* @summary Step 6: Gets the actual cookies
|
|
122
|
+
*/
|
|
123
|
+
private async accountDuplicationCheck(): Promise<void> {
|
|
124
|
+
// Executing the flow
|
|
125
|
+
const res: CurlyResult = await curly.post(LoginFlows.AccountDuplicationCheck.url, {
|
|
126
|
+
httpHeader: loginHeader(await this.getGuestCredentials(), this.cookies.join(';').toString()),
|
|
127
|
+
sslVerifyPeer: false,
|
|
128
|
+
postFields: JSON.stringify(LoginFlows.AccountDuplicationCheck.body(this.flowToken))
|
|
129
|
+
});
|
|
130
|
+
|
|
131
|
+
// Storing cookies received
|
|
132
|
+
this.cookies = new CookieJar().setCookies(res.headers[0]['Set-Cookie'] as string[]);
|
|
133
|
+
|
|
134
|
+
// Getting the flow token
|
|
135
|
+
this.flowToken = res.data['flow_token'];
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
/**
|
|
139
|
+
* @param email The email of the account to be logged into
|
|
140
|
+
* @param userName The username associated with the given account
|
|
141
|
+
* @param password The password to the account
|
|
142
|
+
* @returns The cookies for authenticating with the given account
|
|
143
|
+
*/
|
|
144
|
+
public async login(email: string, userName: string, password: string): Promise<string> {
|
|
145
|
+
// Executing each step of login flow
|
|
146
|
+
await this.initiateLogin();
|
|
147
|
+
await this.jsInstrumentationSubtask();
|
|
148
|
+
await this.enterUserIdentifier(email);
|
|
149
|
+
await this.enterAlternateUserIdentifier(userName);
|
|
150
|
+
await this.enterPassword(password);
|
|
151
|
+
await this.accountDuplicationCheck();
|
|
152
|
+
|
|
153
|
+
// Returning the final cookies
|
|
154
|
+
return this.cookies.join(';');
|
|
155
|
+
}
|
|
156
|
+
}
|