@mtkruto/node 0.0.821 → 0.0.823

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.
@@ -4,16 +4,43 @@ import * as functions from "../tl/3_functions.js";
4
4
  import { ClientAbstract } from "./client_abstract.js";
5
5
  import { Session } from "../session/session.js";
6
6
  import { DC, TransportProvider } from "../transport/transport_provider.js";
7
- export interface AuthorizeUserParams<S = string, N = {
8
- first: S;
9
- last: S;
10
- }> {
7
+ export declare const restartAuth: unique symbol;
8
+ export interface AuthorizeUserParams<S = string> {
11
9
  phone: S | (() => MaybePromise<S>);
12
10
  code: S | (() => MaybePromise<S>);
13
11
  password: S | (() => MaybePromise<S>);
14
- names: N | (() => MaybePromise<N>);
15
12
  }
16
13
  export type UpdatesHandler = null | ((client: Client, update: types.Updates) => MaybePromise<void>);
14
+ export interface ClientParams {
15
+ /**
16
+ * The transport provider to use. Defaults to `defaultTransportProvider`.
17
+ */
18
+ transportProvider?: TransportProvider;
19
+ /**
20
+ * The app_version parameter to be passed to initConnection when calling `authorize`.
21
+ */
22
+ appVersion?: string;
23
+ /**
24
+ * The device_version parameter to be passed to initConnection when calling `authorize`.
25
+ */
26
+ deviceModel?: string;
27
+ /**
28
+ * The lang_code parameter to be passed to initConnection when calling `authorize`.
29
+ */
30
+ langCode?: string;
31
+ /**
32
+ * The lang_pack parameter to be passed to initConnection when calling `authorize`.
33
+ */
34
+ langPack?: string;
35
+ /**
36
+ * The system_lang_cde parameter to be passed to initConnection when calling `authorize`.
37
+ */
38
+ systemLangCode?: string;
39
+ /**
40
+ * The system_version parameter to be passed to initConnection when calling `authorize`.
41
+ */
42
+ systemVersion?: string;
43
+ }
17
44
  export declare class Client extends ClientAbstract {
18
45
  readonly session: Session;
19
46
  readonly apiId: number;
@@ -29,22 +56,59 @@ export declare class Client extends ClientAbstract {
29
56
  readonly langPack: string;
30
57
  readonly systemLangCode: string;
31
58
  readonly systemVersion: string;
32
- constructor(session?: Session, apiId?: number, apiHash?: string, params?: {
33
- transportProvider?: TransportProvider;
34
- appVersion?: string;
35
- deviceModel?: string;
36
- langCode?: string;
37
- langPack?: string;
38
- systemLangCode?: string;
39
- systemVersion?: string;
40
- });
59
+ /**
60
+ * Constructs the client.
61
+ *
62
+ * @param session The session provider to use. Defaults to in-memory session.
63
+ * @param apiId App's API ID from [my.telegram.org](https://my.telegram.org/apps). Defaults to 0 (unset).
64
+ * @param apiHash App's API hash from [my.telegram.org/apps](https://my.telegram.org/apps). Default to empty string (unset).
65
+ * @param params Other parameters.
66
+ */
67
+ constructor(session?: Session, apiId?: number, apiHash?: string, params?: ClientParams);
41
68
  private shouldLoadSession;
69
+ /**
70
+ * Sets the DC and resets the auth key stored in the session provider
71
+ * if the stored DC was not the same as the `dc` parameter.
72
+ *
73
+ * @param dc The DC to change to.
74
+ */
42
75
  setDc(dc: DC): void;
76
+ /**
77
+ * Loads the session if `setDc` was not called, initializes and connnects
78
+ * a `ClientPlain` to generate auth key if there was none, and connects the client.
79
+ * Before establishing the connection, the session is saved.
80
+ */
43
81
  connect(): Promise<void>;
82
+ /**
83
+ * Calls [initConnection](1) and authorizes the client with one of the following:
84
+ *
85
+ * - Bot token (`string`)
86
+ * - Exported authorization (`types.AuthExportedAuthorization`)
87
+ * - User authorization handlers (`AuthorizeUserParams`)
88
+ *
89
+ * if the current auth key doesn't throw AUTH_KEY_UNREGISTERED when calling [updates.getState](2).
90
+ *
91
+ * Notes:
92
+ * 1. Requires the `apiId` and `apiHash` paramters to be passed when constructing the client.
93
+ * 2. Reconnects the client to the appropriate DC in case of MIGRATE_X errors.
94
+ * 3. The parameters passed to the [initConnection][1] call can be configured with the last parameter of the constructor.
95
+ *
96
+ * [1]: https://core.telegram.org/method/initConnection
97
+ * [2]: https://core.telegram.org/method/updates.getState
98
+ */
44
99
  authorize(params: string | types.AuthExportedAuthorization | AuthorizeUserParams): Promise<void>;
45
100
  private receiveLoop;
46
101
  private pingLoop;
102
+ /**
103
+ * Invokes a function waiting and returning its reply if the second parameter is not `true`. Requires the client
104
+ * to be connected.
105
+ *
106
+ * @param function_ The function to invoke.
107
+ */
47
108
  invoke<T extends (functions.Function<unknown> | types.Type) = functions.Function<unknown>>(function_: T): Promise<T extends functions.Function<unknown> ? T["__R"] : void>;
48
109
  invoke<T extends (functions.Function<unknown> | types.Type) = functions.Function<unknown>>(function_: T, noWait: true): Promise<void>;
110
+ /**
111
+ * Alias for `invoke` with its second parameter being `true`.
112
+ */
49
113
  send<T extends (functions.Function<unknown> | types.Type) = functions.Function<unknown>>(function_: T): Promise<void>;
50
114
  }
@@ -2,6 +2,7 @@ import { gunzip } from "../deps.js";
2
2
  import { ackThreshold, DEFAULT_APP_VERSION, DEFAULT_DEVICE_MODEL, DEFAULT_LANG_CODE, DEFAULT_LANG_PACK, DEFAULT_SYSTEM_LANG_CODE, DEFAULT_SYSTEM_VERSION, LAYER } from "../constants.js";
3
3
  import { getRandomBigInt } from "../utilities/0_bigint.js";
4
4
  import { decryptMessage, encryptMessage, getMessageId } from "../utilities/1_message.js";
5
+ import { checkPassword } from "../utilities/1_password.js";
5
6
  import * as types from "../tl/2_types.js";
6
7
  import * as functions from "../tl/3_functions.js";
7
8
  import { TLReader } from "../tl/3_tl_reader.js";
@@ -11,7 +12,16 @@ import { MessageContainer } from "../tl/6_message_container.js";
11
12
  import { ClientAbstract } from "./client_abstract.js";
12
13
  import { ClientPlain } from "./client_plain.js";
13
14
  import { SessionMemory } from "../session/session_memory.js";
15
+ export const restartAuth = Symbol();
14
16
  export class Client extends ClientAbstract {
17
+ /**
18
+ * Constructs the client.
19
+ *
20
+ * @param session The session provider to use. Defaults to in-memory session.
21
+ * @param apiId App's API ID from [my.telegram.org](https://my.telegram.org/apps). Defaults to 0 (unset).
22
+ * @param apiHash App's API hash from [my.telegram.org/apps](https://my.telegram.org/apps). Default to empty string (unset).
23
+ * @param params Other parameters.
24
+ */
15
25
  constructor(session = new SessionMemory(), apiId = 0, apiHash = "", params) {
16
26
  super(params?.transportProvider);
17
27
  Object.defineProperty(this, "session", {
@@ -111,6 +121,12 @@ export class Client extends ClientAbstract {
111
121
  this.systemLangCode = params?.systemLangCode ?? DEFAULT_SYSTEM_LANG_CODE;
112
122
  this.systemVersion = params?.systemVersion ?? DEFAULT_SYSTEM_VERSION;
113
123
  }
124
+ /**
125
+ * Sets the DC and resets the auth key stored in the session provider
126
+ * if the stored DC was not the same as the `dc` parameter.
127
+ *
128
+ * @param dc The DC to change to.
129
+ */
114
130
  setDc(dc) {
115
131
  if (this.session.dc != dc) {
116
132
  this.session.dc = dc;
@@ -121,6 +137,11 @@ export class Client extends ClientAbstract {
121
137
  }
122
138
  super.setDc(dc);
123
139
  }
140
+ /**
141
+ * Loads the session if `setDc` was not called, initializes and connnects
142
+ * a `ClientPlain` to generate auth key if there was none, and connects the client.
143
+ * Before establishing the connection, the session is saved.
144
+ */
124
145
  async connect() {
125
146
  if (this.shouldLoadSession) {
126
147
  await this.session.load();
@@ -146,6 +167,23 @@ export class Client extends ClientAbstract {
146
167
  this.receiveLoop();
147
168
  this.pingLoop();
148
169
  }
170
+ /**
171
+ * Calls [initConnection](1) and authorizes the client with one of the following:
172
+ *
173
+ * - Bot token (`string`)
174
+ * - Exported authorization (`types.AuthExportedAuthorization`)
175
+ * - User authorization handlers (`AuthorizeUserParams`)
176
+ *
177
+ * if the current auth key doesn't throw AUTH_KEY_UNREGISTERED when calling [updates.getState](2).
178
+ *
179
+ * Notes:
180
+ * 1. Requires the `apiId` and `apiHash` paramters to be passed when constructing the client.
181
+ * 2. Reconnects the client to the appropriate DC in case of MIGRATE_X errors.
182
+ * 3. The parameters passed to the [initConnection][1] call can be configured with the last parameter of the constructor.
183
+ *
184
+ * [1]: https://core.telegram.org/method/initConnection
185
+ * [2]: https://core.telegram.org/method/updates.getState
186
+ */
149
187
  async authorize(params) {
150
188
  if (!this.apiId) {
151
189
  throw new Error("apiId not set");
@@ -166,6 +204,36 @@ export class Client extends ClientAbstract {
166
204
  systemLangCode: this.systemLangCode,
167
205
  systemVersion: this.systemVersion,
168
206
  }));
207
+ const handlePassword = async (err) => {
208
+ params = params;
209
+ if (err instanceof types.RPCError && err.errorMessage == "SESSION_PASSWORD_NEEDED") {
210
+ while (true) {
211
+ const ap = await this.invoke(new functions.AccountGetPassword());
212
+ if (ap.currentAlgo instanceof types.PasswordKdfAlgoSHA256SHA256PBKDF2HMACSHA512iter100000SHA256ModPow) {
213
+ try {
214
+ const password = typeof params.password === "string" ? params.password : await params.password();
215
+ const input = await checkPassword(password, ap);
216
+ await this.invoke(new functions.AuthCheckPassword({ password: input }));
217
+ break;
218
+ }
219
+ catch (err) {
220
+ if (err instanceof types.RPCError && err.errorMessage == "PASSWORD_HASH_INVALID") {
221
+ continue;
222
+ }
223
+ else {
224
+ throw err;
225
+ }
226
+ }
227
+ }
228
+ else {
229
+ throw new Error(`Handling ${ap.currentAlgo?.constructor.name} not implemented`);
230
+ }
231
+ }
232
+ }
233
+ else {
234
+ throw err;
235
+ }
236
+ };
169
237
  try {
170
238
  await this.invoke(new functions.UpdatesGetState());
171
239
  return;
@@ -175,12 +243,66 @@ export class Client extends ClientAbstract {
175
243
  throw err;
176
244
  }
177
245
  }
246
+ let signedIn = false;
247
+ let phoneNumber = null;
178
248
  try {
179
249
  if (params instanceof types.AuthExportedAuthorization) {
180
250
  await this.invoke(new functions.AuthImportAuthorization({ id: params.id, bytes: params.bytes }));
181
251
  }
182
252
  else if (typeof params == "object") {
183
- throw new Error("Not implemented");
253
+ while (true) {
254
+ if (signedIn) {
255
+ break;
256
+ }
257
+ try {
258
+ try {
259
+ phoneNumber = typeof params.phone === "string" ? params.phone : await params.phone();
260
+ const sentCode = await this.invoke(new functions.AuthSendCode({
261
+ apiId: this.apiId,
262
+ apiHash: this.apiHash,
263
+ phoneNumber,
264
+ settings: new types.CodeSettings(),
265
+ }));
266
+ if (sentCode instanceof types.AuthSentCode) {
267
+ while (true) {
268
+ const phoneCode = typeof params.code === "string" ? params.code : await params.code();
269
+ try {
270
+ const auth = await this.invoke(new functions.AuthSignIn({ phoneNumber, phoneCode, phoneCodeHash: sentCode.phoneCodeHash }));
271
+ if (auth instanceof types.AuthAuthorizationSignUpRequired) {
272
+ throw new Error("Sign up not supported");
273
+ }
274
+ else {
275
+ signedIn = true;
276
+ break;
277
+ }
278
+ }
279
+ catch (err) {
280
+ if (err instanceof types.RPCError && err.errorMessage == "PHONE_CODE_INVALID") {
281
+ continue;
282
+ }
283
+ else {
284
+ throw err;
285
+ }
286
+ }
287
+ }
288
+ }
289
+ else {
290
+ throw new Error(`Handling ${sentCode.constructor.name} not implemented`);
291
+ }
292
+ }
293
+ catch (err) {
294
+ await handlePassword(err);
295
+ }
296
+ }
297
+ catch (err) {
298
+ if (err == restartAuth) {
299
+ continue;
300
+ }
301
+ else {
302
+ throw err;
303
+ }
304
+ }
305
+ }
184
306
  }
185
307
  else {
186
308
  await this.invoke(new functions.AuthImportBotAuthorization({ apiId: this.apiId, apiHash: this.apiHash, botAuthToken: params, flags: 0 }));
@@ -195,10 +317,14 @@ export class Client extends ClientAbstract {
195
317
  newDc += "-test";
196
318
  }
197
319
  await this.reconnect(newDc);
320
+ if (typeof params === "object" && phoneNumber != null) {
321
+ params = Object.assign({}, params);
322
+ params.phone = phoneNumber;
323
+ }
198
324
  await this.authorize(params);
199
325
  }
200
326
  else {
201
- throw err;
327
+ await handlePassword(err);
202
328
  }
203
329
  }
204
330
  else {
@@ -318,6 +444,9 @@ export class Client extends ClientAbstract {
318
444
  return result;
319
445
  }
320
446
  }
447
+ /**
448
+ * Alias for `invoke` with its second parameter being `true`.
449
+ */
321
450
  send(function_) {
322
451
  return this.invoke(function_, true);
323
452
  }