@mtkruto/node 0.0.823 → 0.0.825
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/esm/client/client.d.ts +12 -6
- package/esm/client/client.js +165 -31
- package/esm/client/client_abstract.d.ts +2 -1
- package/esm/client/client_abstract.js +1 -0
- package/esm/constants.d.ts +4 -0
- package/esm/constants.js +4 -0
- package/esm/mod.d.ts +4 -3
- package/esm/mod.js +4 -3
- package/esm/storage/storage.d.ts +23 -0
- package/esm/storage/storage.js +98 -0
- package/esm/storage/storage_local_storage.d.ts +9 -0
- package/esm/storage/storage_local_storage.js +36 -0
- package/esm/storage/storage_memory.d.ts +8 -0
- package/esm/storage/storage_memory.js +25 -0
- package/esm/storage/storage_session_storage.d.ts +9 -0
- package/esm/storage/storage_session_storage.js +36 -0
- package/package.json +1 -1
- package/script/client/client.d.ts +12 -6
- package/script/client/client.js +163 -29
- package/script/client/client_abstract.d.ts +2 -1
- package/script/client/client_abstract.js +1 -0
- package/script/constants.d.ts +4 -0
- package/script/constants.js +5 -1
- package/script/mod.d.ts +4 -3
- package/script/mod.js +4 -3
- package/script/storage/storage.d.ts +23 -0
- package/script/storage/storage.js +102 -0
- package/script/storage/storage_local_storage.d.ts +9 -0
- package/script/storage/storage_local_storage.js +40 -0
- package/script/storage/storage_memory.d.ts +8 -0
- package/script/storage/storage_memory.js +29 -0
- package/script/storage/storage_session_storage.d.ts +9 -0
- package/script/storage/storage_session_storage.js +40 -0
- package/esm/session/session.d.ts +0 -12
- package/esm/session/session.js +0 -36
- package/esm/session/session_local_storage.d.ts +0 -7
- package/esm/session/session_local_storage.js +0 -26
- package/esm/session/session_memory.d.ts +0 -5
- package/esm/session/session_memory.js +0 -5
- package/script/session/session.d.ts +0 -12
- package/script/session/session.js +0 -40
- package/script/session/session_local_storage.d.ts +0 -7
- package/script/session/session_local_storage.js +0 -30
- package/script/session/session_memory.d.ts +0 -5
- package/script/session/session_memory.js +0 -9
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
import { Storage } from "./storage.js";
|
|
2
|
+
export class StorageSessionStorage extends Storage {
|
|
3
|
+
constructor(prefix) {
|
|
4
|
+
if (typeof sessionStorage === "undefined") {
|
|
5
|
+
throw new Error("Unavailable in current environment");
|
|
6
|
+
}
|
|
7
|
+
if (prefix.length <= 0) {
|
|
8
|
+
throw new Error("Empty prefix");
|
|
9
|
+
}
|
|
10
|
+
else if (!/^[0-9a-zA-Z]+$/.test(prefix)) {
|
|
11
|
+
throw new Error("Unallowed prefix");
|
|
12
|
+
}
|
|
13
|
+
super();
|
|
14
|
+
Object.defineProperty(this, "prefix", {
|
|
15
|
+
enumerable: true,
|
|
16
|
+
configurable: true,
|
|
17
|
+
writable: true,
|
|
18
|
+
value: prefix
|
|
19
|
+
});
|
|
20
|
+
}
|
|
21
|
+
init() {
|
|
22
|
+
}
|
|
23
|
+
get(key) {
|
|
24
|
+
key = this.prefix + key;
|
|
25
|
+
return sessionStorage.getItem(key);
|
|
26
|
+
}
|
|
27
|
+
set(key, value) {
|
|
28
|
+
key = this.prefix + key;
|
|
29
|
+
if (value != null) {
|
|
30
|
+
sessionStorage.setItem(key, value);
|
|
31
|
+
}
|
|
32
|
+
else {
|
|
33
|
+
sessionStorage.removeItem(key);
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
}
|
package/package.json
CHANGED
|
@@ -2,7 +2,7 @@ import { MaybePromise } from "../types.js";
|
|
|
2
2
|
import * as types from "../tl/2_types.js";
|
|
3
3
|
import * as functions from "../tl/3_functions.js";
|
|
4
4
|
import { ClientAbstract } from "./client_abstract.js";
|
|
5
|
-
import {
|
|
5
|
+
import { Storage } from "../storage/storage.js";
|
|
6
6
|
import { DC, TransportProvider } from "../transport/transport_provider.js";
|
|
7
7
|
export declare const restartAuth: unique symbol;
|
|
8
8
|
export interface AuthorizeUserParams<S = string> {
|
|
@@ -42,9 +42,10 @@ export interface ClientParams {
|
|
|
42
42
|
systemVersion?: string;
|
|
43
43
|
}
|
|
44
44
|
export declare class Client extends ClientAbstract {
|
|
45
|
-
readonly
|
|
45
|
+
readonly storage: Storage;
|
|
46
46
|
readonly apiId: number;
|
|
47
47
|
readonly apiHash: string;
|
|
48
|
+
private auth;
|
|
48
49
|
private sessionId;
|
|
49
50
|
private state;
|
|
50
51
|
private promises;
|
|
@@ -59,20 +60,21 @@ export declare class Client extends ClientAbstract {
|
|
|
59
60
|
/**
|
|
60
61
|
* Constructs the client.
|
|
61
62
|
*
|
|
62
|
-
* @param
|
|
63
|
+
* @param storage The storage provider to use. Defaults to memory storage.
|
|
63
64
|
* @param apiId App's API ID from [my.telegram.org](https://my.telegram.org/apps). Defaults to 0 (unset).
|
|
64
65
|
* @param apiHash App's API hash from [my.telegram.org/apps](https://my.telegram.org/apps). Default to empty string (unset).
|
|
65
66
|
* @param params Other parameters.
|
|
66
67
|
*/
|
|
67
|
-
constructor(
|
|
68
|
-
private
|
|
68
|
+
constructor(storage?: Storage, apiId?: number, apiHash?: string, params?: ClientParams);
|
|
69
|
+
private storageInited;
|
|
69
70
|
/**
|
|
70
71
|
* Sets the DC and resets the auth key stored in the session provider
|
|
71
72
|
* if the stored DC was not the same as the `dc` parameter.
|
|
72
73
|
*
|
|
73
74
|
* @param dc The DC to change to.
|
|
74
75
|
*/
|
|
75
|
-
setDc(dc: DC): void
|
|
76
|
+
setDc(dc: DC): Promise<void>;
|
|
77
|
+
private setAuth;
|
|
76
78
|
/**
|
|
77
79
|
* Loads the session if `setDc` was not called, initializes and connnects
|
|
78
80
|
* a `ClientPlain` to generate auth key if there was none, and connects the client.
|
|
@@ -111,4 +113,8 @@ export declare class Client extends ClientAbstract {
|
|
|
111
113
|
* Alias for `invoke` with its second parameter being `true`.
|
|
112
114
|
*/
|
|
113
115
|
send<T extends (functions.Function<unknown> | types.Type) = functions.Function<unknown>>(function_: T): Promise<void>;
|
|
116
|
+
private processChats;
|
|
117
|
+
private processUsers;
|
|
118
|
+
private processUpdates;
|
|
119
|
+
getInputPeer(id: string | number): Promise<types.InputPeerChat | types.InputPeerUser | types.InputPeerChannel>;
|
|
114
120
|
}
|
package/script/client/client.js
CHANGED
|
@@ -29,6 +29,7 @@ const constants_js_1 = require("../constants.js");
|
|
|
29
29
|
const _0_bigint_js_1 = require("../utilities/0_bigint.js");
|
|
30
30
|
const _1_message_js_1 = require("../utilities/1_message.js");
|
|
31
31
|
const _1_password_js_1 = require("../utilities/1_password.js");
|
|
32
|
+
const _1_tl_object_js_1 = require("../tl/1_tl_object.js");
|
|
32
33
|
const types = __importStar(require("../tl/2_types.js"));
|
|
33
34
|
const functions = __importStar(require("../tl/3_functions.js"));
|
|
34
35
|
const _3_tl_reader_js_1 = require("../tl/3_tl_reader.js");
|
|
@@ -37,24 +38,25 @@ const _5_message_js_1 = require("../tl/5_message.js");
|
|
|
37
38
|
const _6_message_container_js_1 = require("../tl/6_message_container.js");
|
|
38
39
|
const client_abstract_js_1 = require("./client_abstract.js");
|
|
39
40
|
const client_plain_js_1 = require("./client_plain.js");
|
|
40
|
-
const
|
|
41
|
+
const storage_memory_js_1 = require("../storage/storage_memory.js");
|
|
42
|
+
const _0_hash_js_1 = require("../utilities/0_hash.js");
|
|
41
43
|
exports.restartAuth = Symbol();
|
|
42
44
|
class Client extends client_abstract_js_1.ClientAbstract {
|
|
43
45
|
/**
|
|
44
46
|
* Constructs the client.
|
|
45
47
|
*
|
|
46
|
-
* @param
|
|
48
|
+
* @param storage The storage provider to use. Defaults to memory storage.
|
|
47
49
|
* @param apiId App's API ID from [my.telegram.org](https://my.telegram.org/apps). Defaults to 0 (unset).
|
|
48
50
|
* @param apiHash App's API hash from [my.telegram.org/apps](https://my.telegram.org/apps). Default to empty string (unset).
|
|
49
51
|
* @param params Other parameters.
|
|
50
52
|
*/
|
|
51
|
-
constructor(
|
|
53
|
+
constructor(storage = new storage_memory_js_1.StorageMemory(), apiId = 0, apiHash = "", params) {
|
|
52
54
|
super(params?.transportProvider);
|
|
53
|
-
Object.defineProperty(this, "
|
|
55
|
+
Object.defineProperty(this, "storage", {
|
|
54
56
|
enumerable: true,
|
|
55
57
|
configurable: true,
|
|
56
58
|
writable: true,
|
|
57
|
-
value:
|
|
59
|
+
value: storage
|
|
58
60
|
});
|
|
59
61
|
Object.defineProperty(this, "apiId", {
|
|
60
62
|
enumerable: true,
|
|
@@ -68,6 +70,12 @@ class Client extends client_abstract_js_1.ClientAbstract {
|
|
|
68
70
|
writable: true,
|
|
69
71
|
value: apiHash
|
|
70
72
|
});
|
|
73
|
+
Object.defineProperty(this, "auth", {
|
|
74
|
+
enumerable: true,
|
|
75
|
+
configurable: true,
|
|
76
|
+
writable: true,
|
|
77
|
+
value: null
|
|
78
|
+
});
|
|
71
79
|
Object.defineProperty(this, "sessionId", {
|
|
72
80
|
enumerable: true,
|
|
73
81
|
configurable: true,
|
|
@@ -134,11 +142,11 @@ class Client extends client_abstract_js_1.ClientAbstract {
|
|
|
134
142
|
writable: true,
|
|
135
143
|
value: void 0
|
|
136
144
|
});
|
|
137
|
-
Object.defineProperty(this, "
|
|
145
|
+
Object.defineProperty(this, "storageInited", {
|
|
138
146
|
enumerable: true,
|
|
139
147
|
configurable: true,
|
|
140
148
|
writable: true,
|
|
141
|
-
value:
|
|
149
|
+
value: false
|
|
142
150
|
});
|
|
143
151
|
this.appVersion = params?.appVersion ?? constants_js_1.DEFAULT_APP_VERSION;
|
|
144
152
|
this.deviceModel = params?.deviceModel ?? constants_js_1.DEFAULT_DEVICE_MODEL;
|
|
@@ -153,42 +161,57 @@ class Client extends client_abstract_js_1.ClientAbstract {
|
|
|
153
161
|
*
|
|
154
162
|
* @param dc The DC to change to.
|
|
155
163
|
*/
|
|
156
|
-
setDc(dc) {
|
|
157
|
-
if (this.
|
|
158
|
-
this.
|
|
159
|
-
this.
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
164
|
+
async setDc(dc) {
|
|
165
|
+
if (!this.storageInited) {
|
|
166
|
+
await this.storage.init();
|
|
167
|
+
this.storageInited = true;
|
|
168
|
+
}
|
|
169
|
+
if (await this.storage.getDc() != dc) {
|
|
170
|
+
await this.storage.setDc(dc);
|
|
171
|
+
await this.storage.setAuthKey(null);
|
|
163
172
|
}
|
|
164
173
|
super.setDc(dc);
|
|
165
174
|
}
|
|
175
|
+
async setAuth(key) {
|
|
176
|
+
const hash = await (0, _0_hash_js_1.sha1)(key);
|
|
177
|
+
const id = (0, _0_bigint_js_1.bigIntFromBuffer)(hash.slice(-8), true, false);
|
|
178
|
+
this.auth = { key, id };
|
|
179
|
+
}
|
|
166
180
|
/**
|
|
167
181
|
* Loads the session if `setDc` was not called, initializes and connnects
|
|
168
182
|
* a `ClientPlain` to generate auth key if there was none, and connects the client.
|
|
169
183
|
* Before establishing the connection, the session is saved.
|
|
170
184
|
*/
|
|
171
185
|
async connect() {
|
|
172
|
-
if (this.
|
|
173
|
-
await this.
|
|
174
|
-
this.
|
|
186
|
+
if (!this.storageInited) {
|
|
187
|
+
await this.storage.init();
|
|
188
|
+
this.storageInited = true;
|
|
175
189
|
}
|
|
176
|
-
|
|
190
|
+
const authKey = await this.storage.getAuthKey();
|
|
191
|
+
if (authKey == null) {
|
|
177
192
|
const plain = new client_plain_js_1.ClientPlain(this.transportProvider);
|
|
178
|
-
|
|
179
|
-
|
|
193
|
+
const dc = await this.storage.getDc();
|
|
194
|
+
if (dc != null) {
|
|
195
|
+
plain.setDc(dc);
|
|
180
196
|
}
|
|
181
197
|
await plain.connect();
|
|
182
198
|
const { authKey, salt } = await plain.createAuthKey();
|
|
183
199
|
await plain.disconnect();
|
|
200
|
+
await this.storage.setAuthKey(authKey);
|
|
201
|
+
await this.setAuth(authKey);
|
|
184
202
|
this.state.salt = salt;
|
|
185
|
-
this.session.authKey = authKey;
|
|
186
203
|
}
|
|
187
|
-
|
|
188
|
-
this.
|
|
204
|
+
else {
|
|
205
|
+
await this.setAuth(authKey);
|
|
206
|
+
}
|
|
207
|
+
const dc = await this.storage.getDc();
|
|
208
|
+
if (dc != null) {
|
|
209
|
+
await this.setDc(dc);
|
|
189
210
|
}
|
|
190
|
-
await this.session.save();
|
|
191
211
|
await super.connect();
|
|
212
|
+
if (dc == null) {
|
|
213
|
+
await this.storage.setDc(constants_js_1.DEFAULT_INITIAL_DC);
|
|
214
|
+
}
|
|
192
215
|
// logger().debug("Client connected");
|
|
193
216
|
this.receiveLoop();
|
|
194
217
|
this.pingLoop();
|
|
@@ -359,7 +382,7 @@ class Client extends client_abstract_js_1.ClientAbstract {
|
|
|
359
382
|
}
|
|
360
383
|
}
|
|
361
384
|
async receiveLoop() {
|
|
362
|
-
if (!this.
|
|
385
|
+
if (!this.auth) {
|
|
363
386
|
throw new Error("Not connected");
|
|
364
387
|
}
|
|
365
388
|
while (this.connected) {
|
|
@@ -381,7 +404,7 @@ class Client extends client_abstract_js_1.ClientAbstract {
|
|
|
381
404
|
}
|
|
382
405
|
let decrypted;
|
|
383
406
|
try {
|
|
384
|
-
decrypted = await (0, _1_message_js_1.decryptMessage)(buffer, this.
|
|
407
|
+
decrypted = await (0, _1_message_js_1.decryptMessage)(buffer, this.auth.key, this.auth.id, this.sessionId);
|
|
385
408
|
}
|
|
386
409
|
catch (_err) {
|
|
387
410
|
// logger().error(`Failed to decrypt message: ${err}`);
|
|
@@ -395,7 +418,7 @@ class Client extends client_abstract_js_1.ClientAbstract {
|
|
|
395
418
|
}
|
|
396
419
|
// logger().debug(`Received ${body.constructor.name}`);
|
|
397
420
|
if (body instanceof types.Updates) {
|
|
398
|
-
this.
|
|
421
|
+
this.processUpdates(body);
|
|
399
422
|
}
|
|
400
423
|
else if (message.body instanceof _4_rpc_result_js_1.RPCResult) {
|
|
401
424
|
let result = message.body.result;
|
|
@@ -408,6 +431,10 @@ class Client extends client_abstract_js_1.ClientAbstract {
|
|
|
408
431
|
promise.reject(result);
|
|
409
432
|
}
|
|
410
433
|
else {
|
|
434
|
+
if (result instanceof types.Updates) {
|
|
435
|
+
await this.processChats(result.chats);
|
|
436
|
+
await this.processUsers(result.users);
|
|
437
|
+
}
|
|
411
438
|
promise.resolve(result);
|
|
412
439
|
}
|
|
413
440
|
this.promises.delete(message.body.messageId);
|
|
@@ -446,7 +473,7 @@ class Client extends client_abstract_js_1.ClientAbstract {
|
|
|
446
473
|
}
|
|
447
474
|
}
|
|
448
475
|
async invoke(function_, noWait) {
|
|
449
|
-
if (!this.
|
|
476
|
+
if (!this.auth) {
|
|
450
477
|
throw new Error("Not connected");
|
|
451
478
|
}
|
|
452
479
|
let seqNo = this.state.seqNo * 2;
|
|
@@ -455,7 +482,7 @@ class Client extends client_abstract_js_1.ClientAbstract {
|
|
|
455
482
|
this.state.seqNo++;
|
|
456
483
|
}
|
|
457
484
|
const message = new _5_message_js_1.Message((0, _1_message_js_1.getMessageId)(), seqNo, function_);
|
|
458
|
-
await this.transport.send(await (0, _1_message_js_1.encryptMessage)(message, this.
|
|
485
|
+
await this.transport.send(await (0, _1_message_js_1.encryptMessage)(message, this.auth.key, this.auth.id, this.state.salt, this.sessionId));
|
|
459
486
|
// logger().debug(`Invoked ${function_.constructor.name}`);
|
|
460
487
|
if (noWait) {
|
|
461
488
|
return;
|
|
@@ -476,5 +503,112 @@ class Client extends client_abstract_js_1.ClientAbstract {
|
|
|
476
503
|
send(function_) {
|
|
477
504
|
return this.invoke(function_, true);
|
|
478
505
|
}
|
|
506
|
+
async processChats(chats) {
|
|
507
|
+
for (const chat of chats) {
|
|
508
|
+
if (chat instanceof types.Channel && chat.accessHash) {
|
|
509
|
+
await this.storage.setChannelAccessHash(chat.id, chat.accessHash);
|
|
510
|
+
if (chat.username) {
|
|
511
|
+
await this.storage.updateUsernames("channel", chat.id, [chat.username]);
|
|
512
|
+
}
|
|
513
|
+
if (chat.usernames) {
|
|
514
|
+
await this.storage.updateUsernames("channel", chat.id, chat.usernames.map((v) => v[_1_tl_object_js_1.as](types.Username)).map((v) => v.username));
|
|
515
|
+
}
|
|
516
|
+
}
|
|
517
|
+
}
|
|
518
|
+
}
|
|
519
|
+
async processUsers(users) {
|
|
520
|
+
for (const user of users) {
|
|
521
|
+
if (user instanceof types.User && user.accessHash) {
|
|
522
|
+
await this.storage.setUserAccessHash(user.id, user.accessHash);
|
|
523
|
+
if (user.username) {
|
|
524
|
+
await this.storage.updateUsernames("user", user.id, [user.username]);
|
|
525
|
+
}
|
|
526
|
+
if (user.usernames) {
|
|
527
|
+
await this.storage.updateUsernames("user", user.id, user.usernames.map((v) => v[_1_tl_object_js_1.as](types.Username)).map((v) => v.username));
|
|
528
|
+
}
|
|
529
|
+
}
|
|
530
|
+
}
|
|
531
|
+
}
|
|
532
|
+
async processUpdates(updates) {
|
|
533
|
+
try {
|
|
534
|
+
await this.processChats(updates.chats);
|
|
535
|
+
await this.processUsers(updates.users);
|
|
536
|
+
for (const update of updates.updates) {
|
|
537
|
+
if (update instanceof types.UpdateUserName) {
|
|
538
|
+
await this.storage.updateUsernames("user", update.userId, update.usernames.map((v) => v[_1_tl_object_js_1.as](types.Username)).map((v) => v.username));
|
|
539
|
+
}
|
|
540
|
+
}
|
|
541
|
+
await this.updatesHandler?.(this, updates);
|
|
542
|
+
}
|
|
543
|
+
catch (err) {
|
|
544
|
+
console.error("Error processing updates:", err);
|
|
545
|
+
}
|
|
546
|
+
}
|
|
547
|
+
async getInputPeer(id) {
|
|
548
|
+
if (typeof id === "string") {
|
|
549
|
+
if (!id.startsWith("@")) {
|
|
550
|
+
throw new Error("Expected username to start with @");
|
|
551
|
+
}
|
|
552
|
+
else {
|
|
553
|
+
id = id.slice(1);
|
|
554
|
+
if (!id) {
|
|
555
|
+
throw new Error("Empty username");
|
|
556
|
+
}
|
|
557
|
+
let userId = 0n;
|
|
558
|
+
let channelId = 0n;
|
|
559
|
+
const maybeUsername = await this.storage.getUsername(id);
|
|
560
|
+
if (maybeUsername != null && Date.now() - maybeUsername[2].getTime() < constants_js_1.USERNAME_TTL) {
|
|
561
|
+
const [type, id] = maybeUsername;
|
|
562
|
+
if (type == "user") {
|
|
563
|
+
userId = id;
|
|
564
|
+
}
|
|
565
|
+
else {
|
|
566
|
+
channelId = id;
|
|
567
|
+
}
|
|
568
|
+
}
|
|
569
|
+
else {
|
|
570
|
+
const resolved = await this.invoke(new functions.ContactsResolveUsername({ username: id }));
|
|
571
|
+
await this.processChats(resolved.chats);
|
|
572
|
+
await this.processUsers(resolved.users);
|
|
573
|
+
if (resolved.peer instanceof types.PeerUser) {
|
|
574
|
+
userId = resolved.peer.userId;
|
|
575
|
+
}
|
|
576
|
+
else if (resolved.peer instanceof types.PeerChannel) {
|
|
577
|
+
channelId = resolved.peer.channelId;
|
|
578
|
+
}
|
|
579
|
+
else {
|
|
580
|
+
throw new Error("Unreachable");
|
|
581
|
+
}
|
|
582
|
+
}
|
|
583
|
+
if (userId) {
|
|
584
|
+
const accessHash = await this.storage.getUserAccessHash(userId);
|
|
585
|
+
return new types.InputPeerUser({ userId, accessHash: accessHash ?? 0n });
|
|
586
|
+
}
|
|
587
|
+
else if (channelId) {
|
|
588
|
+
const accessHash = await this.storage.getChannelAccessHash(channelId);
|
|
589
|
+
return new types.InputPeerChannel({ channelId, accessHash: accessHash ?? 0n });
|
|
590
|
+
}
|
|
591
|
+
else {
|
|
592
|
+
throw new Error("Unreachable");
|
|
593
|
+
}
|
|
594
|
+
}
|
|
595
|
+
}
|
|
596
|
+
else if (id > 0) {
|
|
597
|
+
const id_ = BigInt(id);
|
|
598
|
+
const accessHash = await this.storage.getUserAccessHash(id_);
|
|
599
|
+
return new types.InputPeerUser({ userId: id_, accessHash: accessHash ?? 0n });
|
|
600
|
+
}
|
|
601
|
+
else if (-constants_js_1.MAX_CHAT_ID <= id) {
|
|
602
|
+
return new types.InputPeerChat({ chatId: BigInt(Math.abs(id)) });
|
|
603
|
+
}
|
|
604
|
+
else if (constants_js_1.ZERO_CHANNEL_ID - constants_js_1.MAX_CHANNEL_ID <= id && id != constants_js_1.ZERO_CHANNEL_ID) {
|
|
605
|
+
const id_ = BigInt(Math.abs(id - constants_js_1.ZERO_CHANNEL_ID));
|
|
606
|
+
const accessHash = await this.storage.getChannelAccessHash(id_);
|
|
607
|
+
return new types.InputPeerChannel({ channelId: id_, accessHash: accessHash ?? 0n });
|
|
608
|
+
}
|
|
609
|
+
else {
|
|
610
|
+
throw new Error("ID format unknown or not implemented");
|
|
611
|
+
}
|
|
612
|
+
}
|
|
479
613
|
}
|
|
480
614
|
exports.Client = Client;
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { Connection } from "../connection/connection.js";
|
|
2
2
|
import { Transport } from "../transport/transport.js";
|
|
3
3
|
import { DC } from "../transport/transport_provider.js";
|
|
4
|
+
import { MaybePromise } from "../types.js";
|
|
4
5
|
export declare abstract class ClientAbstract {
|
|
5
6
|
protected transportProvider: import("../transport/transport_provider.js").TransportProvider;
|
|
6
7
|
protected connection: Connection;
|
|
@@ -9,7 +10,7 @@ export declare abstract class ClientAbstract {
|
|
|
9
10
|
protected connected: boolean;
|
|
10
11
|
constructor(transportProvider?: import("../transport/transport_provider.js").TransportProvider);
|
|
11
12
|
get dcId(): number;
|
|
12
|
-
setDc(dc: DC): void
|
|
13
|
+
setDc(dc: DC): MaybePromise<void>;
|
|
13
14
|
connect(): Promise<void>;
|
|
14
15
|
reconnect(dc?: DC): Promise<void>;
|
|
15
16
|
disconnect(): Promise<void>;
|
|
@@ -44,6 +44,7 @@ class ClientAbstract {
|
|
|
44
44
|
get dcId() {
|
|
45
45
|
return this._dcId;
|
|
46
46
|
}
|
|
47
|
+
// MaybePromise since `Client` has to deal with `Storage.set()`
|
|
47
48
|
setDc(dc) {
|
|
48
49
|
const { connection, transport, dcId } = this.transportProvider({ dc, cdn: false });
|
|
49
50
|
this.connection = connection;
|
package/script/constants.d.ts
CHANGED
|
@@ -10,3 +10,7 @@ export declare const DEFAULT_LANG_CODE = "en";
|
|
|
10
10
|
export declare const DEFAULT_LANG_PACK = "";
|
|
11
11
|
export declare const DEFAULT_SYSTEM_LANG_CODE = "en";
|
|
12
12
|
export declare const DEFAULT_SYSTEM_VERSION = "1.0";
|
|
13
|
+
export declare const USERNAME_TTL = 86400;
|
|
14
|
+
export declare const MAX_CHAT_ID = 999999999999;
|
|
15
|
+
export declare const MAX_CHANNEL_ID = 997852516352;
|
|
16
|
+
export declare const ZERO_CHANNEL_ID = -1000000000000;
|
package/script/constants.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.DEFAULT_SYSTEM_VERSION = exports.DEFAULT_SYSTEM_LANG_CODE = exports.DEFAULT_LANG_PACK = exports.DEFAULT_LANG_CODE = exports.DEFAULT_DEVICE_MODEL = exports.DEFAULT_APP_VERSION = exports.LAYER = exports.DEFAULT_INITIAL_DC = exports.VECTOR_CONSTRUCTOR = exports.publicKeys = exports.ackThreshold = void 0;
|
|
3
|
+
exports.ZERO_CHANNEL_ID = exports.MAX_CHANNEL_ID = exports.MAX_CHAT_ID = exports.USERNAME_TTL = exports.DEFAULT_SYSTEM_VERSION = exports.DEFAULT_SYSTEM_LANG_CODE = exports.DEFAULT_LANG_PACK = exports.DEFAULT_LANG_CODE = exports.DEFAULT_DEVICE_MODEL = exports.DEFAULT_APP_VERSION = exports.LAYER = exports.DEFAULT_INITIAL_DC = exports.VECTOR_CONSTRUCTOR = exports.publicKeys = exports.ackThreshold = void 0;
|
|
4
4
|
exports.ackThreshold = 10;
|
|
5
5
|
exports.publicKeys = new Map([
|
|
6
6
|
[
|
|
@@ -71,3 +71,7 @@ exports.DEFAULT_LANG_CODE = "en";
|
|
|
71
71
|
exports.DEFAULT_LANG_PACK = "";
|
|
72
72
|
exports.DEFAULT_SYSTEM_LANG_CODE = "en";
|
|
73
73
|
exports.DEFAULT_SYSTEM_VERSION = "1.0";
|
|
74
|
+
exports.USERNAME_TTL = 86400;
|
|
75
|
+
exports.MAX_CHAT_ID = 999999999999;
|
|
76
|
+
exports.MAX_CHANNEL_ID = 997852516352;
|
|
77
|
+
exports.ZERO_CHANNEL_ID = -1000000000000;
|
package/script/mod.d.ts
CHANGED
|
@@ -12,9 +12,10 @@ export * from "./tl/5_message.js";
|
|
|
12
12
|
export * from "./tl/6_message_container.js";
|
|
13
13
|
export * from "./client/client_plain.js";
|
|
14
14
|
export * from "./client/client.js";
|
|
15
|
-
export * from "./
|
|
16
|
-
export * from "./
|
|
17
|
-
export * from "./
|
|
15
|
+
export * from "./storage/storage.js";
|
|
16
|
+
export * from "./storage/storage_memory.js";
|
|
17
|
+
export * from "./storage/storage_local_storage.js";
|
|
18
|
+
export * from "./storage/storage_session_storage.js";
|
|
18
19
|
export * from "./transport/transport_abridged.js";
|
|
19
20
|
export * from "./transport/transport_intermediate.js";
|
|
20
21
|
export * from "./transport/transport.js";
|
package/script/mod.js
CHANGED
|
@@ -39,9 +39,10 @@ __exportStar(require("./tl/5_message.js"), exports);
|
|
|
39
39
|
__exportStar(require("./tl/6_message_container.js"), exports);
|
|
40
40
|
__exportStar(require("./client/client_plain.js"), exports);
|
|
41
41
|
__exportStar(require("./client/client.js"), exports);
|
|
42
|
-
__exportStar(require("./
|
|
43
|
-
__exportStar(require("./
|
|
44
|
-
__exportStar(require("./
|
|
42
|
+
__exportStar(require("./storage/storage.js"), exports);
|
|
43
|
+
__exportStar(require("./storage/storage_memory.js"), exports);
|
|
44
|
+
__exportStar(require("./storage/storage_local_storage.js"), exports);
|
|
45
|
+
__exportStar(require("./storage/storage_session_storage.js"), exports);
|
|
45
46
|
__exportStar(require("./transport/transport_abridged.js"), exports);
|
|
46
47
|
__exportStar(require("./transport/transport_intermediate.js"), exports);
|
|
47
48
|
__exportStar(require("./transport/transport.js"), exports);
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import { MaybePromise } from "../types.js";
|
|
2
|
+
import { DC } from "../transport/transport_provider.js";
|
|
3
|
+
export declare abstract class Storage {
|
|
4
|
+
private _authKeyId;
|
|
5
|
+
abstract init(): MaybePromise<void>;
|
|
6
|
+
abstract set(key: string, value: string | null): MaybePromise<void>;
|
|
7
|
+
abstract get(key: string): MaybePromise<string | null>;
|
|
8
|
+
setDc(dc: DC | null): MaybePromise<void>;
|
|
9
|
+
getDc(): Promise<DC | null>;
|
|
10
|
+
private resetAuthKeyId;
|
|
11
|
+
getAuthKey(): Promise<Uint8Array | null>;
|
|
12
|
+
setAuthKey(authKey: Uint8Array | null): Promise<void>;
|
|
13
|
+
get authKeyId(): bigint | null;
|
|
14
|
+
private readonly channelAccessHash__;
|
|
15
|
+
setChannelAccessHash(id: bigint, accessHash: bigint): MaybePromise<void>;
|
|
16
|
+
getChannelAccessHash(id: bigint): Promise<bigint | null>;
|
|
17
|
+
private readonly userAccessHash__;
|
|
18
|
+
setUserAccessHash(id: bigint, accessHash: bigint): MaybePromise<void>;
|
|
19
|
+
getUserAccessHash(id: bigint): Promise<bigint | null>;
|
|
20
|
+
private readonly username__;
|
|
21
|
+
updateUsernames(type: "user" | "channel", id: bigint, usernames: string[]): Promise<void>;
|
|
22
|
+
getUsername(username: string): Promise<readonly ["user" | "channel", bigint, Date] | null>;
|
|
23
|
+
}
|
|
@@ -0,0 +1,102 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.Storage = void 0;
|
|
4
|
+
const _0_hash_js_1 = require("../utilities/0_hash.js");
|
|
5
|
+
const _0_bigint_js_1 = require("../utilities/0_bigint.js");
|
|
6
|
+
class Storage {
|
|
7
|
+
constructor() {
|
|
8
|
+
Object.defineProperty(this, "_authKeyId", {
|
|
9
|
+
enumerable: true,
|
|
10
|
+
configurable: true,
|
|
11
|
+
writable: true,
|
|
12
|
+
value: null
|
|
13
|
+
});
|
|
14
|
+
Object.defineProperty(this, "channelAccessHash__", {
|
|
15
|
+
enumerable: true,
|
|
16
|
+
configurable: true,
|
|
17
|
+
writable: true,
|
|
18
|
+
value: "channelAccessHash__"
|
|
19
|
+
});
|
|
20
|
+
Object.defineProperty(this, "userAccessHash__", {
|
|
21
|
+
enumerable: true,
|
|
22
|
+
configurable: true,
|
|
23
|
+
writable: true,
|
|
24
|
+
value: "userAccessHash__"
|
|
25
|
+
});
|
|
26
|
+
Object.defineProperty(this, "username__", {
|
|
27
|
+
enumerable: true,
|
|
28
|
+
configurable: true,
|
|
29
|
+
writable: true,
|
|
30
|
+
value: "username__"
|
|
31
|
+
});
|
|
32
|
+
}
|
|
33
|
+
setDc(dc) {
|
|
34
|
+
return this.set("dc", dc);
|
|
35
|
+
}
|
|
36
|
+
async getDc() {
|
|
37
|
+
return await this.get("dc");
|
|
38
|
+
}
|
|
39
|
+
async resetAuthKeyId(authKey) {
|
|
40
|
+
if (authKey != null) {
|
|
41
|
+
this._authKeyId = await (0, _0_hash_js_1.sha1)(authKey).then((hash) => (0, _0_bigint_js_1.bigIntFromBuffer)(hash.slice(-8), true, false));
|
|
42
|
+
}
|
|
43
|
+
else {
|
|
44
|
+
this._authKeyId = null;
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
async getAuthKey() {
|
|
48
|
+
const authKey_ = await this.get("authKey");
|
|
49
|
+
const authKey = authKey_ == null ? null : new Uint8Array(authKey_.split(/([0-9a-f]{2})/).filter((v) => v).map((v) => parseInt(v, 16)));
|
|
50
|
+
await this.resetAuthKeyId(authKey);
|
|
51
|
+
return authKey;
|
|
52
|
+
}
|
|
53
|
+
async setAuthKey(authKey) {
|
|
54
|
+
await this.set("authKey", authKey == null ? null : Array.from(authKey).map((v) => v.toString(16)).map((v) => v.padStart(2, "0")).join(""));
|
|
55
|
+
await this.resetAuthKeyId(authKey);
|
|
56
|
+
}
|
|
57
|
+
get authKeyId() {
|
|
58
|
+
return this._authKeyId;
|
|
59
|
+
}
|
|
60
|
+
setChannelAccessHash(id, accessHash) {
|
|
61
|
+
return this.set(`${this.channelAccessHash__}${id}`, String(accessHash));
|
|
62
|
+
}
|
|
63
|
+
async getChannelAccessHash(id) {
|
|
64
|
+
const accessHash = await this.get(`${this.channelAccessHash__}${id}`);
|
|
65
|
+
if (accessHash != null) {
|
|
66
|
+
return BigInt(accessHash);
|
|
67
|
+
}
|
|
68
|
+
else {
|
|
69
|
+
return null;
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
setUserAccessHash(id, accessHash) {
|
|
73
|
+
return this.set(`${this.userAccessHash__}${id}`, String(accessHash));
|
|
74
|
+
}
|
|
75
|
+
async getUserAccessHash(id) {
|
|
76
|
+
const accessHash = await this.get(`${this.userAccessHash__}${id}`);
|
|
77
|
+
if (accessHash != null) {
|
|
78
|
+
return BigInt(accessHash);
|
|
79
|
+
}
|
|
80
|
+
else {
|
|
81
|
+
return null;
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
async updateUsernames(type, id, usernames) {
|
|
85
|
+
for (let username of usernames) {
|
|
86
|
+
username = username.toLowerCase();
|
|
87
|
+
await this.set(`${this.username__}${username}`, JSON.stringify([type, String(id), new Date()]));
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
async getUsername(username) {
|
|
91
|
+
username = username.toLowerCase();
|
|
92
|
+
const username_ = await this.get(`${this.username__}${username}`);
|
|
93
|
+
if (username_ != null) {
|
|
94
|
+
const [type, id, updatedAt] = JSON.parse(username_);
|
|
95
|
+
return [type, BigInt(id), new Date(updatedAt)];
|
|
96
|
+
}
|
|
97
|
+
else {
|
|
98
|
+
return null;
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
exports.Storage = Storage;
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import { MaybePromise } from "../types.js";
|
|
2
|
+
import { Storage } from "./storage.js";
|
|
3
|
+
export declare class StorageLocalStorage extends Storage implements Storage {
|
|
4
|
+
private readonly prefix;
|
|
5
|
+
constructor(prefix: string);
|
|
6
|
+
init(): void;
|
|
7
|
+
get(key: string): string | null;
|
|
8
|
+
set(key: string, value: string | null): MaybePromise<void>;
|
|
9
|
+
}
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.StorageLocalStorage = void 0;
|
|
4
|
+
const storage_js_1 = require("./storage.js");
|
|
5
|
+
class StorageLocalStorage extends storage_js_1.Storage {
|
|
6
|
+
constructor(prefix) {
|
|
7
|
+
if (typeof localStorage === "undefined") {
|
|
8
|
+
throw new Error("Unavailable in current environment");
|
|
9
|
+
}
|
|
10
|
+
if (prefix.length <= 0) {
|
|
11
|
+
throw new Error("Empty prefix");
|
|
12
|
+
}
|
|
13
|
+
else if (!/^[0-9a-zA-Z]+$/.test(prefix)) {
|
|
14
|
+
throw new Error("Unallowed prefix");
|
|
15
|
+
}
|
|
16
|
+
super();
|
|
17
|
+
Object.defineProperty(this, "prefix", {
|
|
18
|
+
enumerable: true,
|
|
19
|
+
configurable: true,
|
|
20
|
+
writable: true,
|
|
21
|
+
value: prefix
|
|
22
|
+
});
|
|
23
|
+
}
|
|
24
|
+
init() {
|
|
25
|
+
}
|
|
26
|
+
get(key) {
|
|
27
|
+
key = this.prefix + key;
|
|
28
|
+
return localStorage.getItem(key);
|
|
29
|
+
}
|
|
30
|
+
set(key, value) {
|
|
31
|
+
key = this.prefix + key;
|
|
32
|
+
if (value != null) {
|
|
33
|
+
localStorage.setItem(key, value);
|
|
34
|
+
}
|
|
35
|
+
else {
|
|
36
|
+
localStorage.removeItem(key);
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
exports.StorageLocalStorage = StorageLocalStorage;
|