rubjs 2.8.6 → 2.8.7

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "rubjs",
3
- "version": "2.8.6",
3
+ "version": "2.8.7",
4
4
  "main": "rubjs/index.js",
5
5
  "types": "rubjs/index.d.ts",
6
6
  "keywords": [
package/rubjs/index.d.ts CHANGED
@@ -1,6 +1,6 @@
1
1
  import Client from "./client";
2
2
  import Crypto from "./crypto";
3
3
  import * as Types from "./types";
4
- import { Filters, Utils, VoiceChatClient, SendLiveClient } from "./utils";
4
+ import { Filters, Utils, VoiceChatClient, SendLiveClient, LoginClient } from "./utils";
5
5
  export default Client;
6
- export { Client, Crypto, Utils, VoiceChatClient, Filters, Types, SendLiveClient, };
6
+ export { Client, Crypto, Utils, VoiceChatClient, Filters, Types, SendLiveClient, LoginClient, };
package/rubjs/index.js CHANGED
@@ -36,7 +36,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
36
36
  return (mod && mod.__esModule) ? mod : { "default": mod };
37
37
  };
38
38
  Object.defineProperty(exports, "__esModule", { value: true });
39
- exports.SendLiveClient = exports.Types = exports.Filters = exports.VoiceChatClient = exports.Utils = exports.Crypto = exports.Client = void 0;
39
+ exports.LoginClient = exports.SendLiveClient = exports.Types = exports.Filters = exports.VoiceChatClient = exports.Utils = exports.Crypto = exports.Client = void 0;
40
40
  const client_1 = __importDefault(require("./client"));
41
41
  exports.Client = client_1.default;
42
42
  const crypto_1 = __importDefault(require("./crypto"));
@@ -48,4 +48,5 @@ Object.defineProperty(exports, "Filters", { enumerable: true, get: function () {
48
48
  Object.defineProperty(exports, "Utils", { enumerable: true, get: function () { return utils_1.Utils; } });
49
49
  Object.defineProperty(exports, "VoiceChatClient", { enumerable: true, get: function () { return utils_1.VoiceChatClient; } });
50
50
  Object.defineProperty(exports, "SendLiveClient", { enumerable: true, get: function () { return utils_1.SendLiveClient; } });
51
+ Object.defineProperty(exports, "LoginClient", { enumerable: true, get: function () { return utils_1.LoginClient; } });
51
52
  exports.default = client_1.default;
@@ -9,6 +9,7 @@ declare class Network {
9
9
  private wssUrl;
10
10
  private ws;
11
11
  private agent;
12
+ private reconnecting;
12
13
  session: Axios;
13
14
  constructor(client: Client);
14
15
  getDcs(): Promise<boolean>;
@@ -67,6 +67,7 @@ class Network {
67
67
  connection: "keep-alive",
68
68
  "user-agent": client.userAgent,
69
69
  };
70
+ this.reconnecting = false;
70
71
  if (client.defaultPlatform.platform === "Android") {
71
72
  delete this.Headers.origin;
72
73
  delete this.Headers.referer;
@@ -146,6 +147,7 @@ class Network {
146
147
  this.ws = new ws_1.default(this.wssUrl);
147
148
  this.ws.on("open", () => __awaiter(this, void 0, void 0, function* () {
148
149
  console.log("WebSocket connected.");
150
+ this.reconnecting = false;
149
151
  yield this.handleConnect();
150
152
  this.resetInactivityTimer();
151
153
  }));
@@ -154,12 +156,18 @@ class Network {
154
156
  this.resetInactivityTimer();
155
157
  }));
156
158
  this.ws.on("error", () => __awaiter(this, void 0, void 0, function* () {
157
- console.error("WebSocket error, reconnecting...");
158
- yield this.resetConnection();
159
+ if (!this.reconnecting) {
160
+ console.error("WebSocket error, reconnecting...");
161
+ this.reconnecting = true;
162
+ yield this.resetConnection();
163
+ }
159
164
  }));
160
165
  this.ws.on("close", () => __awaiter(this, void 0, void 0, function* () {
161
- console.warn("WebSocket closed, reconnecting...");
162
- yield this.resetConnection();
166
+ if (!this.reconnecting) {
167
+ console.warn("WebSocket closed, reconnecting...");
168
+ this.reconnecting = true;
169
+ yield this.resetConnection();
170
+ }
163
171
  }));
164
172
  });
165
173
  }
@@ -189,7 +197,10 @@ class Network {
189
197
  var _a;
190
198
  (_a = this.ws) === null || _a === void 0 ? void 0 : _a.close();
191
199
  this.ws = null;
192
- setTimeout(() => this.getUpdates(), 5000);
200
+ setTimeout(() => __awaiter(this, void 0, void 0, function* () {
201
+ yield this.getUpdates();
202
+ this.reconnecting = false;
203
+ }), 5000);
193
204
  });
194
205
  }
195
206
  handleMessage(message) {
@@ -0,0 +1,39 @@
1
+ import { AxiosInstance } from "axios";
2
+ interface PlatformInfo {
3
+ app_name: string;
4
+ app_version: string;
5
+ platform: string;
6
+ package: string;
7
+ lang_code: string;
8
+ }
9
+ interface AuthInfo {
10
+ auth?: string;
11
+ decode_auth?: string;
12
+ key?: Buffer;
13
+ privateKey?: string;
14
+ }
15
+ interface SendOptions {
16
+ input?: Record<string, any>;
17
+ method?: string;
18
+ tmp_session?: boolean;
19
+ }
20
+ interface ServerResponse {
21
+ data_enc?: string;
22
+ status?: string;
23
+ status_det?: string;
24
+ data?: Record<string, any>;
25
+ }
26
+ declare class Network {
27
+ private Headers;
28
+ private agent;
29
+ private apiUrl;
30
+ session: AxiosInstance;
31
+ defaultPlatform: PlatformInfo;
32
+ userAgent: string;
33
+ constructor();
34
+ getDcs(): Promise<boolean>;
35
+ request(url: string, data: Record<string, any>): Promise<any>;
36
+ send({ input, method, tmp_session }: SendOptions, { auth, decode_auth, key, privateKey }: AuthInfo): Promise<ServerResponse | undefined>;
37
+ bulder(name: string, input: Record<string, any>, { auth, key, decode_auth, privateKey }: AuthInfo, tmp_session?: boolean): Promise<Record<string, any> | undefined>;
38
+ }
39
+ export default Network;
@@ -0,0 +1,122 @@
1
+ "use strict";
2
+ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
3
+ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
4
+ return new (P || (P = Promise))(function (resolve, reject) {
5
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
6
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
7
+ function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
8
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
9
+ });
10
+ };
11
+ var __importDefault = (this && this.__importDefault) || function (mod) {
12
+ return (mod && mod.__esModule) ? mod : { "default": mod };
13
+ };
14
+ Object.defineProperty(exports, "__esModule", { value: true });
15
+ const https_1 = __importDefault(require("https"));
16
+ const axios_1 = __importDefault(require("axios"));
17
+ const __1 = require("..");
18
+ class Network {
19
+ constructor() {
20
+ this.apiUrl = null;
21
+ this.defaultPlatform = {
22
+ app_name: "Main",
23
+ app_version: "4.4.9",
24
+ platform: "Web",
25
+ package: "web.rubika.ir",
26
+ lang_code: "fa",
27
+ };
28
+ this.userAgent = `Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/102.0.0.0 Safari/537.36`;
29
+ this.Headers = {
30
+ origin: "https://web.rubika.ir",
31
+ referer: "https://web.rubika.ir/",
32
+ "content-type": "application/json",
33
+ connection: "keep-alive",
34
+ "user-agent": this.userAgent,
35
+ };
36
+ this.agent = new https_1.default.Agent({ rejectUnauthorized: false });
37
+ this.session = axios_1.default.create({
38
+ headers: this.Headers,
39
+ timeout: 10000,
40
+ httpsAgent: this.agent,
41
+ });
42
+ }
43
+ getDcs() {
44
+ return __awaiter(this, void 0, void 0, function* () {
45
+ while (true) {
46
+ try {
47
+ const response = yield axios_1.default.get("https://getdcmess.iranlms.ir/", {
48
+ httpsAgent: this.agent,
49
+ });
50
+ if (response.status === 200) {
51
+ const data = response.data.data;
52
+ this.apiUrl = data.API[data.default_api] + "/";
53
+ return true;
54
+ }
55
+ }
56
+ catch (_a) {
57
+ console.error("Error while fetching dcs");
58
+ }
59
+ yield new Promise((resolve) => setTimeout(resolve, 3000));
60
+ }
61
+ });
62
+ }
63
+ request(url, data) {
64
+ return __awaiter(this, void 0, void 0, function* () {
65
+ for (let i = 0; i < 3; i++) {
66
+ try {
67
+ const response = yield this.session.post(url, data);
68
+ if (response.status === 200)
69
+ return response.data;
70
+ }
71
+ catch (_a) {
72
+ console.error("Error in request");
73
+ }
74
+ }
75
+ throw new Error("Failed to get response after 3 attempts");
76
+ });
77
+ }
78
+ send(_a, _b) {
79
+ return __awaiter(this, arguments, void 0, function* ({ input = {}, method = "getUserInfo", tmp_session }, { auth, decode_auth, key, privateKey }) {
80
+ if (!this.apiUrl)
81
+ yield this.getDcs();
82
+ const payload = {
83
+ api_version: "6",
84
+ [tmp_session ? "tmp_session" : "auth"]: tmp_session ? auth : decode_auth,
85
+ };
86
+ const data_enc = JSON.stringify({
87
+ client: this.defaultPlatform,
88
+ method,
89
+ input,
90
+ });
91
+ payload["data_enc"] = __1.Crypto.encrypt(data_enc, key);
92
+ if (!tmp_session && privateKey) {
93
+ payload["sign"] = __1.Crypto.sign(payload["data_enc"], privateKey);
94
+ }
95
+ return yield this.request(this.apiUrl, payload);
96
+ });
97
+ }
98
+ bulder(name_1, input_1, _a) {
99
+ return __awaiter(this, arguments, void 0, function* (name, input, { auth, key, decode_auth, privateKey }, tmp_session = false) {
100
+ if (!auth)
101
+ auth = __1.Crypto.secret(32);
102
+ if (!key)
103
+ key = Buffer.from(__1.Crypto.passphrase(auth), "utf8");
104
+ const result = yield this.send({
105
+ input,
106
+ tmp_session,
107
+ method: name,
108
+ }, { auth, key, decode_auth, privateKey });
109
+ if (result) {
110
+ const { data_enc } = result;
111
+ if (data_enc) {
112
+ const decrypted = __1.Crypto.decrypt(data_enc, key);
113
+ const parsed = JSON.parse(decrypted);
114
+ if (parsed.status === "OK" && parsed.status_det === "OK") {
115
+ return Object.assign(Object.assign({}, parsed.data), { auth_data: auth, key_data: key });
116
+ }
117
+ }
118
+ }
119
+ });
120
+ }
121
+ }
122
+ exports.default = Network;
@@ -26,7 +26,8 @@ declare class Filters {
26
26
  static isPoll(message: MessageUpdate): boolean;
27
27
  static isLive(message: MessageUpdate): boolean;
28
28
  static isEvent(message: MessageUpdate): boolean;
29
- static startsWithCommand(text: string, object_guid?: string): (message: MessageUpdate) => boolean;
29
+ static isLength(length: number, object_guid?: string): (message: MessageUpdate) => boolean;
30
+ static startsWithCommand(text: string, object_guid?: string, length?: number): (message: MessageUpdate) => boolean;
30
31
  static equalCommand(text: string, object_guid?: string): (message: MessageUpdate) => boolean;
31
32
  }
32
33
  export default Filters;
@@ -122,14 +122,31 @@ class Filters {
122
122
  static isEvent(message) {
123
123
  return !!Filters.findKey(message, "event_data");
124
124
  }
125
- static startsWithCommand(text, object_guid) {
125
+ static isLength(length, object_guid) {
126
126
  return (message) => {
127
- var _a;
127
+ var _a, _b;
128
+ if (object_guid) {
129
+ if (object_guid !== message.object_guid)
130
+ return false;
131
+ }
132
+ if ((_a = message === null || message === void 0 ? void 0 : message.message) === null || _a === void 0 ? void 0 : _a.text) {
133
+ return ((_b = message === null || message === void 0 ? void 0 : message.message) === null || _b === void 0 ? void 0 : _b.text.length) === length;
134
+ }
135
+ return false;
136
+ };
137
+ }
138
+ static startsWithCommand(text, object_guid, length) {
139
+ return (message) => {
140
+ var _a, _b;
128
141
  if (object_guid) {
129
142
  if (object_guid !== message.object_guid)
130
143
  return false;
131
144
  }
132
145
  if ((_a = message === null || message === void 0 ? void 0 : message.message) === null || _a === void 0 ? void 0 : _a.text) {
146
+ if (length) {
147
+ if (((_b = message === null || message === void 0 ? void 0 : message.message) === null || _b === void 0 ? void 0 : _b.text.length) !== length)
148
+ return false;
149
+ }
133
150
  return message.message.text.startsWith(text);
134
151
  }
135
152
  };
@@ -2,4 +2,5 @@ import Filters from "./filters";
2
2
  import Utils from "./utils";
3
3
  import VoiceChatClient from "./VoiceChatClient";
4
4
  import SendLiveClient from "./sendLiveClient";
5
- export { Filters, Utils, VoiceChatClient, SendLiveClient };
5
+ import LoginClient from "./loginClient";
6
+ export { Filters, Utils, VoiceChatClient, SendLiveClient, LoginClient };
@@ -3,7 +3,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
3
3
  return (mod && mod.__esModule) ? mod : { "default": mod };
4
4
  };
5
5
  Object.defineProperty(exports, "__esModule", { value: true });
6
- exports.SendLiveClient = exports.VoiceChatClient = exports.Utils = exports.Filters = void 0;
6
+ exports.LoginClient = exports.SendLiveClient = exports.VoiceChatClient = exports.Utils = exports.Filters = void 0;
7
7
  const filters_1 = __importDefault(require("./filters"));
8
8
  exports.Filters = filters_1.default;
9
9
  const utils_1 = __importDefault(require("./utils"));
@@ -12,3 +12,5 @@ const VoiceChatClient_1 = __importDefault(require("./VoiceChatClient"));
12
12
  exports.VoiceChatClient = VoiceChatClient_1.default;
13
13
  const sendLiveClient_1 = __importDefault(require("./sendLiveClient"));
14
14
  exports.SendLiveClient = sendLiveClient_1.default;
15
+ const loginClient_1 = __importDefault(require("./loginClient"));
16
+ exports.LoginClient = loginClient_1.default;
@@ -0,0 +1,36 @@
1
+ import Network from "../network/loginNetwork";
2
+ interface AuthResult {
3
+ isOk: boolean;
4
+ status?: string;
5
+ phone_code_hash?: string;
6
+ code_digits_count?: number;
7
+ auth?: string;
8
+ key?: Buffer;
9
+ decode_auth?: string;
10
+ phone_number?: string;
11
+ }
12
+ interface AuthFace {
13
+ auth: string;
14
+ key: Buffer;
15
+ privateKey: any;
16
+ decode_auth?: string;
17
+ }
18
+ declare class LoginClient {
19
+ static systemVersions: Record<string, string>;
20
+ static sendCode(phone_number: string, pass_key?: string): Promise<AuthResult>;
21
+ static signIn(phone_code: string, sessionPath: string, datas: AuthResult): Promise<{
22
+ isOk: boolean;
23
+ status: string;
24
+ }>;
25
+ static registerDevice(network: Network, datas: AuthFace): Promise<void>;
26
+ static getBrowser(userAgent: string, langCode: string, appVersion: string): Promise<{
27
+ token: string;
28
+ lang_code: string;
29
+ token_type: string;
30
+ app_version: string;
31
+ system_version: string;
32
+ device_model: string;
33
+ device_hash: string;
34
+ }>;
35
+ }
36
+ export default LoginClient;
@@ -0,0 +1,120 @@
1
+ "use strict";
2
+ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
3
+ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
4
+ return new (P || (P = Promise))(function (resolve, reject) {
5
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
6
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
7
+ function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
8
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
9
+ });
10
+ };
11
+ var __importDefault = (this && this.__importDefault) || function (mod) {
12
+ return (mod && mod.__esModule) ? mod : { "default": mod };
13
+ };
14
+ Object.defineProperty(exports, "__esModule", { value: true });
15
+ const crypto_1 = __importDefault(require("../crypto"));
16
+ const loginNetwork_1 = __importDefault(require("../network/loginNetwork"));
17
+ const session_1 = __importDefault(require("../session"));
18
+ class LoginClient {
19
+ static sendCode(phone_number, pass_key) {
20
+ return __awaiter(this, void 0, void 0, function* () {
21
+ const network = new loginNetwork_1.default();
22
+ const data = {
23
+ phone_number,
24
+ pass_key: pass_key || null,
25
+ send_type: "SMS",
26
+ };
27
+ const result = yield network.bulder("sendCode", data, {}, true);
28
+ if (result)
29
+ return {
30
+ isOk: true,
31
+ status: result.status,
32
+ phone_code_hash: result.phone_code_hash,
33
+ code_digits_count: result.code_digits_count,
34
+ auth: result.auth_data,
35
+ key: result.key_data,
36
+ phone_number,
37
+ };
38
+ return {
39
+ isOk: false,
40
+ };
41
+ });
42
+ }
43
+ static signIn(phone_code, sessionPath, datas) {
44
+ return __awaiter(this, void 0, void 0, function* () {
45
+ const network = new loginNetwork_1.default();
46
+ const [publicKey, privateKey] = crypto_1.default.createKeys();
47
+ const data = {
48
+ phone_code,
49
+ phone_number: datas.phone_number,
50
+ phone_code_hash: datas.phone_code_hash,
51
+ public_key: publicKey,
52
+ };
53
+ const auth = {
54
+ auth: datas.auth,
55
+ key: datas.key,
56
+ privateKey,
57
+ };
58
+ const response = yield network.bulder("signIn", data, auth, true);
59
+ if ((response === null || response === void 0 ? void 0 : response.status) === "CodeIsInvalid") {
60
+ return { isOk: false, status: "CodeIsInvalid" };
61
+ }
62
+ const sampleAuth = crypto_1.default.decrypt_RSA_OAEP(privateKey, response.auth);
63
+ auth.key = Buffer.from(crypto_1.default.passphrase(sampleAuth), "utf8");
64
+ auth.auth = sampleAuth;
65
+ auth.decode_auth = crypto_1.default.decode_auth(sampleAuth);
66
+ const session = new session_1.default(sessionPath);
67
+ session.saveSession({
68
+ phone: response.user.phone,
69
+ auth: auth.auth,
70
+ guid: response.user.user_guid,
71
+ agent: network.userAgent,
72
+ private_key: privateKey,
73
+ });
74
+ yield this.registerDevice(network, auth);
75
+ return { isOk: true, status: "Sucessfull" };
76
+ });
77
+ }
78
+ static registerDevice(network, datas) {
79
+ return __awaiter(this, void 0, void 0, function* () {
80
+ const browserData = yield this.getBrowser(network.userAgent, network.defaultPlatform.lang_code, network.defaultPlatform.app_version);
81
+ const sendData = {};
82
+ yield network.bulder("registerDevice", browserData, datas);
83
+ });
84
+ }
85
+ static getBrowser(userAgent, langCode, appVersion) {
86
+ return __awaiter(this, void 0, void 0, function* () {
87
+ var _a, _b;
88
+ const match = userAgent
89
+ .toLowerCase()
90
+ .match(/(opera|chrome|safari|firefox|msie|trident)\/(\d+)/);
91
+ if (!match) {
92
+ throw new Error(`Cannot parse user-agent: ${userAgent}`);
93
+ }
94
+ const deviceModel = `${match[1]} ${match[2]}`;
95
+ const systemVersion = ((_a = Object.entries(this.systemVersions).find(([key]) => userAgent.includes(key))) === null || _a === void 0 ? void 0 : _a[1]) || "Unknown";
96
+ const deviceHash = "2" + (((_b = userAgent.match(/\d+/g)) === null || _b === void 0 ? void 0 : _b.join("")) || "");
97
+ return {
98
+ token: "",
99
+ lang_code: langCode,
100
+ token_type: "Web",
101
+ app_version: `WB_${appVersion}`,
102
+ system_version: systemVersion,
103
+ device_model: deviceModel.charAt(0).toUpperCase() + deviceModel.slice(1),
104
+ device_hash: deviceHash,
105
+ };
106
+ });
107
+ }
108
+ }
109
+ LoginClient.systemVersions = {
110
+ "Windows NT 10.0": "Windows 10",
111
+ "Windows NT 6.2": "Windows 8",
112
+ "Windows NT 6.1": "Windows 7",
113
+ "Windows NT 6.0": "Windows Vista",
114
+ "Windows NT 5.1": "Windows XP",
115
+ "Windows NT 5.0": "Windows 2000",
116
+ Mac: "Mac/iOS",
117
+ X11: "UNIX",
118
+ Linux: "Linux",
119
+ };
120
+ exports.default = LoginClient;