-
Notifications
You must be signed in to change notification settings - Fork 653
Expand file tree
/
Copy pathindex.ts
More file actions
181 lines (157 loc) · 6.27 KB
/
index.ts
File metadata and controls
181 lines (157 loc) · 6.27 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
/**
* Device Activity Tracker - CLI Interface
*
* This is a proof-of-concept tool demonstrating privacy vulnerabilities
* in messaging apps (in this case WhatsApp) through RTT-based activity analysis.
*
* For educational and research purposes only.
*/
const debugMode = process.argv.includes('--debug') || process.argv.includes('-d');
const originalConsoleLog = console.log;
const originalStdoutWrite = process.stdout.write.bind(process.stdout);
// prevents Baileys from spamming the console
const shouldSuppressOutput = (message: string): boolean => {
return message.includes('Closing session:') ||
message.includes('SessionEntry') ||
message.includes('_chains') ||
message.includes('registrationId') ||
message.includes('currentRatchet') ||
message.includes('ephemeralKeyPair') ||
message.includes('pendingPreKey') ||
message.includes('indexInfo') ||
message.includes('baseKey') ||
message.includes('remoteIdentityKey') ||
message.includes('lastRemoteEphemeralKey') ||
message.includes('previousCounter') ||
message.includes('rootKey') ||
message.includes('signedKeyId') ||
message.includes('preKeyId') ||
message.includes('<Buffer');
};
if (!debugMode) {
// Override console.log
console.log = (...args: any[]) => {
const message = String(args[0] || '');
if (!shouldSuppressOutput(message)) {
originalConsoleLog(...args);
}
};
// Override process.stdout.write to catch low-level output
process.stdout.write = ((chunk: any, encoding?: any, callback?: any): boolean => {
const message = String(chunk);
if (shouldSuppressOutput(message)) {
// Suppress - but still call callback if provided
if (typeof encoding === 'function') {
encoding();
} else if (typeof callback === 'function') {
callback();
}
return true;
}
return originalStdoutWrite(chunk, encoding, callback);
}) as typeof process.stdout.write;
}
// Now safe to import modules
import '@whiskeysockets/baileys';
import makeWASocket, { DisconnectReason, useMultiFileAuthState } from '@whiskeysockets/baileys';
import { pino } from 'pino';
import { Boom } from '@hapi/boom';
import qrcode from 'qrcode-terminal';
import { WhatsAppTracker } from './tracker.js';
import * as readline from 'readline';
if (debugMode) {
originalConsoleLog('🔍 Debug mode enabled\n');
} else {
originalConsoleLog('📊 Normal mode (important outputs only)\n');
originalConsoleLog('💡 Tip: Use --debug or -d for detailed debug output\n');
}
let currentTargetJid: string | null = null;
let currentTracker: WhatsAppTracker | null = null;
async function connectToWhatsApp() {
const { state, saveCreds } = await useMultiFileAuthState('auth_info_baileys');
const sock = makeWASocket({
auth: state,
logger: pino({ level: 'silent' }),
markOnlineOnConnect: true,
});
originalConsoleLog('🔌 Connecting to WhatsApp... (use the --debug flag for more details)');
let isConnected = false;
sock.ev.on('connection.update', async (update) => {
const { connection, lastDisconnect, qr } = update;
if (qr) {
qrcode.generate(qr, { small: true });
}
if (connection === 'close') {
isConnected = false;
// Stop the tracker if it's running, as the socket is dead
if (currentTracker) {
currentTracker.stopTracking();
currentTracker = null;
}
const shouldReconnect = (lastDisconnect?.error as Boom)?.output?.statusCode !== DisconnectReason.loggedOut;
if (debugMode) {
originalConsoleLog('connection closed due to ', lastDisconnect?.error, ', reconnecting ', shouldReconnect);
}
if (shouldReconnect) {
connectToWhatsApp();
}
} else if (connection === 'open') {
originalConsoleLog('✅ Connected to WhatsApp');
isConnected = true;
if (currentTargetJid) {
if (debugMode) {
originalConsoleLog(`Resuming tracking for ${currentTargetJid}...`);
}
currentTracker = new WhatsAppTracker(sock, currentTargetJid, debugMode);
currentTracker.startTracking();
} else {
askForTarget();
}
} else {
if (debugMode) {
originalConsoleLog('connection update', update);
}
}
});
sock.ev.on('creds.update', saveCreds);
const askForTarget = () => {
const rl = readline.createInterface({
input: process.stdin,
output: process.stdout
});
rl.question('Enter target phone number (with country code, e.g., 491701234567): ', async (number) => {
// Basic cleanup
const cleanNumber = number.replace(/\D/g, '');
if (cleanNumber.length < 10) {
originalConsoleLog('Invalid number format. Please try again.');
rl.close();
askForTarget();
return;
}
const targetJid = cleanNumber + '@s.whatsapp.net';
if (debugMode) {
originalConsoleLog(`Verifying ${targetJid}...`);
}
try {
const results = await sock.onWhatsApp(targetJid);
const result = results?.[0];
if (result?.exists) {
currentTargetJid = result.jid;
currentTracker = new WhatsAppTracker(sock, result.jid, debugMode);
currentTracker.startTracking();
originalConsoleLog(`✅ Tracking started for ${result.jid}`);
rl.close();
} else {
originalConsoleLog('❌ Number not registered on WhatsApp.');
rl.close();
askForTarget();
}
} catch (err) {
console.error('Error verifying number:', err);
rl.close();
askForTarget();
}
});
};
}
connectToWhatsApp();