Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
MR414N-ID
GitHub Repository: MR414N-ID/botku2
Path: blob/master/node_modules/@adiwajshing/baileys/lib/LegacySocket/auth.js
1129 views
1
"use strict";
2
var __importDefault = (this && this.__importDefault) || function (mod) {
3
return (mod && mod.__esModule) ? mod : { "default": mod };
4
};
5
Object.defineProperty(exports, "__esModule", { value: true });
6
const boom_1 = require("@hapi/boom");
7
const events_1 = __importDefault(require("events"));
8
const Types_1 = require("../Types");
9
const Utils_1 = require("../Utils");
10
const socket_1 = require("./socket");
11
const makeAuthSocket = (config) => {
12
const { logger, version, browser, connectTimeoutMs, printQRInTerminal, auth: initialAuthInfo } = config;
13
const ev = new events_1.default();
14
const authInfo = initialAuthInfo || (0, Utils_1.newLegacyAuthCreds)();
15
const state = {
16
legacy: {
17
phoneConnected: false,
18
},
19
connection: 'connecting',
20
};
21
const socket = (0, socket_1.makeSocket)(config);
22
const { ws } = socket;
23
let curveKeys;
24
let initTimeout;
25
ws.on('phone-connection', ({ value: phoneConnected }) => {
26
updateState({ legacy: { ...state.legacy, phoneConnected } });
27
});
28
// add close listener
29
ws.on('ws-close', (error) => {
30
logger.info({ error }, 'closed connection to WhatsApp');
31
initTimeout && clearTimeout(initTimeout);
32
// if no reconnects occur
33
// send close event
34
updateState({
35
connection: 'close',
36
qr: undefined,
37
lastDisconnect: {
38
error,
39
date: new Date()
40
}
41
});
42
});
43
/** Can you login to WA without scanning the QR */
44
const canLogin = () => !!(authInfo === null || authInfo === void 0 ? void 0 : authInfo.encKey) && !!(authInfo === null || authInfo === void 0 ? void 0 : authInfo.macKey);
45
const updateState = (update) => {
46
Object.assign(state, update);
47
ev.emit('connection.update', update);
48
};
49
/**
50
* Logs you out from WA
51
* If connected, invalidates the credentials with the server
52
*/
53
const logout = async () => {
54
if (state.connection === 'open') {
55
await socket.sendNode({
56
json: ['admin', 'Conn', 'disconnect'],
57
tag: 'goodbye'
58
});
59
}
60
// will call state update to close connection
61
socket === null || socket === void 0 ? void 0 : socket.end(new boom_1.Boom('Logged Out', { statusCode: Types_1.DisconnectReason.loggedOut }));
62
};
63
const updateEncKeys = () => {
64
// update the keys so we can decrypt traffic
65
socket.updateKeys({ encKey: authInfo.encKey, macKey: authInfo.macKey });
66
};
67
const generateKeysForAuth = async (ref, ttl) => {
68
curveKeys = Utils_1.Curve.generateKeyPair();
69
const publicKey = Buffer.from(curveKeys.public).toString('base64');
70
const qrLoop = ttl => {
71
const qr = [ref, publicKey, authInfo.clientID].join(',');
72
updateState({ qr });
73
initTimeout = setTimeout(async () => {
74
var _a;
75
if (state.connection !== 'connecting') {
76
return;
77
}
78
logger.debug('regenerating QR');
79
try {
80
// request new QR
81
const { ref: newRef, ttl: newTTL } = await socket.query({
82
json: ['admin', 'Conn', 'reref'],
83
expect200: true,
84
longTag: true,
85
requiresPhoneConnection: false
86
});
87
ttl = newTTL;
88
ref = newRef;
89
}
90
catch (error) {
91
logger.error({ error }, 'error in QR gen');
92
if (((_a = error.output) === null || _a === void 0 ? void 0 : _a.statusCode) === 429) { // too many QR requests
93
socket.end(error);
94
return;
95
}
96
}
97
qrLoop(ttl);
98
}, ttl || 20000); // default is 20s, on the off-chance ttl is not present
99
};
100
qrLoop(ttl);
101
};
102
const onOpen = async () => {
103
var _a, _b;
104
const canDoLogin = canLogin();
105
const initQuery = (async () => {
106
const { ref, ttl } = await socket.query({
107
json: ['admin', 'init', version, browser, authInfo.clientID, true],
108
expect200: true,
109
longTag: true,
110
requiresPhoneConnection: false
111
});
112
if (!canDoLogin) {
113
generateKeysForAuth(ref, ttl);
114
}
115
})();
116
let loginTag;
117
if (canDoLogin) {
118
updateEncKeys();
119
// if we have the info to restore a closed session
120
const json = [
121
'admin',
122
'login',
123
authInfo.clientToken,
124
authInfo.serverToken,
125
authInfo.clientID,
126
'takeover'
127
];
128
loginTag = socket.generateMessageTag(true);
129
// send login every 10s
130
const sendLoginReq = () => {
131
if (state.connection === 'open') {
132
logger.warn('Received login timeout req when state=open, ignoring...');
133
return;
134
}
135
logger.info('sending login request');
136
socket.sendNode({
137
json,
138
tag: loginTag
139
});
140
initTimeout = setTimeout(sendLoginReq, 10000);
141
};
142
sendLoginReq();
143
}
144
await initQuery;
145
// wait for response with tag "s1"
146
let response = await Promise.race([
147
socket.waitForMessage('s1', false, undefined).promise,
148
...(loginTag ? [socket.waitForMessage(loginTag, false, connectTimeoutMs).promise] : [])
149
]);
150
initTimeout && clearTimeout(initTimeout);
151
initTimeout = undefined;
152
if (response.status && response.status !== 200) {
153
throw new boom_1.Boom('Unexpected error in login', { data: response, statusCode: response.status });
154
}
155
// if its a challenge request (we get it when logging in)
156
if ((_a = response[1]) === null || _a === void 0 ? void 0 : _a.challenge) {
157
const json = (0, Utils_1.computeChallengeResponse)(response[1].challenge, authInfo);
158
logger.info('resolving login challenge');
159
await socket.query({ json, expect200: true, timeoutMs: connectTimeoutMs });
160
response = await socket.waitForMessage('s2', true).promise;
161
}
162
if (!response || !response[1]) {
163
throw new boom_1.Boom('Received unexpected login response', { data: response });
164
}
165
if (response[1].type === 'upgrade_md_prod') {
166
throw new boom_1.Boom('Require multi-device edition', { statusCode: Types_1.DisconnectReason.multideviceMismatch });
167
}
168
// validate the new connection
169
const { user, auth } = (0, Utils_1.validateNewConnection)(response[1], authInfo, curveKeys); // validate the connection
170
const isNewLogin = user.id !== ((_b = state.legacy.user) === null || _b === void 0 ? void 0 : _b.id);
171
Object.assign(authInfo, auth);
172
updateEncKeys();
173
logger.info({ user }, 'logged in');
174
ev.emit('creds.update', auth);
175
updateState({
176
connection: 'open',
177
legacy: {
178
phoneConnected: true,
179
user,
180
},
181
isNewLogin,
182
qr: undefined
183
});
184
};
185
ws.once('open', async () => {
186
try {
187
await onOpen();
188
}
189
catch (error) {
190
socket.end(error);
191
}
192
});
193
if (printQRInTerminal) {
194
(0, Utils_1.printQRIfNecessaryListener)(ev, logger);
195
}
196
process.nextTick(() => {
197
ev.emit('connection.update', {
198
...state
199
});
200
});
201
return {
202
...socket,
203
state,
204
authInfo,
205
ev,
206
canLogin,
207
logout,
208
/** Waits for the connection to WA to reach a state */
209
waitForConnectionUpdate: (0, Utils_1.bindWaitForConnectionUpdate)(ev)
210
};
211
};
212
exports.default = makeAuthSocket;
213
214