1- import { MTProto } from '@mtproto/core' ;
2- import dotenv from 'dotenv' ;
3- dotenv . config ( ) ;
1+ import * as MTProto from '@mtproto/core' ;
2+ import * as fs from 'fs' ;
3+ import { stdin as input , stdout as output } from 'process' ;
4+ import * as readline from 'readline' ;
45
5- const PHONE = '' ;
6- const CODE = '' ;
6+ const rl = readline . createInterface ( { input, output } ) ;
7+ const API_ID = '' ;
8+ const API_HASH = '' ;
79
810const store : Record < string , string > = { } ;
911const api = new MTProto ( {
10- api_id : Number ( process . env . TELEGRAM_API_ID ! ) ,
11- api_hash : process . env . TELEGRAM_API_HASH ! ,
12+ api_id : Number ( API_ID ) ,
13+ api_hash : API_HASH ,
1214 storageOptions : {
1315 instance : {
1416 get : async ( key : string ) => store [ key ] ,
@@ -19,44 +21,76 @@ const api = new MTProto({
1921 } ,
2022} ) ;
2123
24+ api . updateInitConnectionParams ( {
25+ platform : 'Web' ,
26+ system_version : '1.1.1' ,
27+ device_model : 'tgbucket' ,
28+ app_name : 'TGBucket' ,
29+ app_version : '1.1.1' ,
30+ } ) ;
31+
2232( async ( ) => {
23- const user = await getUser ( ) ;
24- console . log ( 'currentUser' , user ) ;
33+ try {
34+ await createSession ( ) ;
35+ process . exit ( 0 ) ;
36+ } catch ( e ) {
37+ console . error ( 'Failed to create session' , e ) ;
38+ process . exit ( 1 ) ;
39+ }
40+ } ) ( ) ;
2541
26- if ( ! user ) {
27- try {
28- const { phone_code_hash } = await sendCode ( PHONE ) ;
42+ /* Core */
43+ async function createSession ( ) : Promise < void > {
44+ try {
45+ await logIn ( ) ;
46+ } catch ( e : any ) {
47+ if ( e . error_message === 'SESSION_PASSWORD_NEEDED' ) {
48+ console . log ( 'Account have enabled 2FA' ) ;
49+ await logIn2FA ( ) ;
50+ return ;
51+ }
2952
30- const signInResult = await signIn ( CODE , PHONE , phone_code_hash ) ;
53+ throw e ;
54+ }
55+ }
3156
32- console . log ( 'result' , signInResult ) ;
33- console . log ( 'session' , JSON . stringify ( store ) ) ;
34- } catch ( err : any ) {
35- if ( err . error_message !== 'SESSION_PASSWORD_NEEDED' ) {
36- console . log ( `error:` , err ) ;
57+ async function logIn ( ) : Promise < void > {
58+ const phone = await prompt ( 'Phone (without +):' ) ;
59+ console . log ( 'phone' , phone , phone . length ) ;
60+ const { phone_code_hash } = await sendCode ( phone ) ;
3761
38- return ;
39- }
62+ const code = await prompt ( 'Code:' ) ;
63+ const signInResult = await signIn ( code , phone , phone_code_hash ) ;
4064
41- console . error ( '2FA is set' ) ;
42- }
43- }
44- } ) ( ) ;
65+ console . debug ( 'signInResult' , signInResult ) ;
66+ saveSessions ( ) ;
67+ }
4568
46- async function getUser ( ) {
47- try {
48- const user = await api . call ( 'users.getFullUser' , {
49- id : {
50- _ : 'inputUserSelf' ,
51- } ,
52- } ) ;
69+ async function logIn2FA ( ) : Promise < void > {
70+ const password = await prompt ( 'Password:' ) ;
71+ const { srp_id, current_algo, srp_B } = await getPassword ( ) ;
72+ const { g, p, salt1, salt2 } = current_algo ;
73+ const { A, M1 } = await ( api as any ) . crypto . getSRPParams ( {
74+ g,
75+ p,
76+ salt1,
77+ salt2,
78+ gB : srp_B ,
79+ password,
80+ } ) ;
5381
54- return user ;
55- } catch ( error ) {
56- return null ;
57- }
82+ const checkPasswordResult = await checkPassword ( srp_id , A , M1 ) ;
83+ console . debug ( 'checkPasswordResult' , checkPasswordResult ) ;
84+ saveSessions ( ) ;
5885}
5986
87+ function saveSessions ( ) : void {
88+ const session = JSON . stringify ( store ) ;
89+ console . log ( 'Session created:' , session ) ;
90+ fs . writeFileSync ( './session.json' , session ) ;
91+ }
92+
93+ /* MTProto */
6094function sendCode ( phone : string ) {
6195 return api . call ( 'auth.sendCode' , {
6296 phone_number : phone ,
@@ -73,3 +107,25 @@ function signIn(code: string, phone: string, phoneCodeHash: string) {
73107 phone_code_hash : phoneCodeHash ,
74108 } ) ;
75109}
110+
111+ function getPassword ( ) {
112+ return api . call ( 'account.getPassword' ) ;
113+ }
114+
115+ function checkPassword ( srpId : string , A : string , M1 : string ) {
116+ return api . call ( 'auth.checkPassword' , {
117+ password : {
118+ _ : 'inputCheckPasswordSRP' ,
119+ srp_id : srpId ,
120+ A,
121+ M1 ,
122+ } ,
123+ } ) ;
124+ }
125+
126+ /* Utils */
127+ function prompt ( text : string ) : Promise < string > {
128+ return new Promise < string > ( ( resolve ) => {
129+ rl . question ( text + ' ' , ( input ) => resolve ( input ) ) ;
130+ } ) ;
131+ }
0 commit comments