nolimit-x 1.0.0

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.
@@ -0,0 +1,125 @@
1
+ const crypto = require('crypto');
2
+
3
+ class MessageEncryption {
4
+ constructor() {
5
+ this.algorithm = 'aes-256-cbc';
6
+ this.keyLength = 32;
7
+ this.ivLength = 16;
8
+ }
9
+
10
+ // Generate a random encryption key
11
+ generateKey() {
12
+ return crypto.randomBytes(this.keyLength);
13
+ }
14
+
15
+ // Generate a random IV
16
+ generateIV() {
17
+ return crypto.randomBytes(this.ivLength);
18
+ }
19
+
20
+ // Encrypt message content
21
+ encryptMessage(message, key = null) {
22
+ try {
23
+ const encryptionKey = key || this.generateKey();
24
+ const iv = this.generateIV();
25
+
26
+ const cipher = crypto.createCipheriv(this.algorithm, encryptionKey, iv);
27
+ let encrypted = cipher.update(message, 'utf8', 'hex');
28
+ encrypted += cipher.final('hex');
29
+
30
+ return {
31
+ encrypted: encrypted,
32
+ key: encryptionKey.toString('hex'),
33
+ iv: iv.toString('hex'),
34
+ algorithm: this.algorithm
35
+ };
36
+ } catch (error) {
37
+ console.error('Encryption failed:', error.message);
38
+ return null;
39
+ }
40
+ }
41
+
42
+ // Decrypt message content
43
+ decryptMessage(encryptedData) {
44
+ try {
45
+ const { encrypted, key, iv, algorithm } = encryptedData;
46
+
47
+ const decipher = crypto.createDecipheriv(algorithm, Buffer.from(key, 'hex'), Buffer.from(iv, 'hex'));
48
+ let decrypted = decipher.update(encrypted, 'hex', 'utf8');
49
+ decrypted += decipher.final('utf8');
50
+
51
+ return decrypted;
52
+ } catch (error) {
53
+ console.error('Decryption failed:', error.message);
54
+ return null;
55
+ }
56
+ }
57
+
58
+ // Encrypt file content
59
+ encryptFile(fileContent, key = null) {
60
+ return this.encryptMessage(fileContent, key);
61
+ }
62
+
63
+ // Generate encrypted attachment wrapper
64
+ createEncryptedAttachment(originalContent, filename) {
65
+ const encrypted = this.encryptMessage(originalContent);
66
+ if (!encrypted) return null;
67
+
68
+ return {
69
+ filename: `${filename}.encrypted`,
70
+ content: encrypted.encrypted,
71
+ metadata: {
72
+ originalName: filename,
73
+ key: encrypted.key,
74
+ iv: encrypted.iv,
75
+ algorithm: encrypted.algorithm
76
+ }
77
+ };
78
+ }
79
+
80
+ // Create self-decrypting HTML wrapper
81
+ createSelfDecryptingWrapper(encryptedData, originalFilename) {
82
+ const { encrypted, key, iv, algorithm } = encryptedData;
83
+
84
+ return `
85
+ <!DOCTYPE html>
86
+ <html>
87
+ <head>
88
+ <meta charset="UTF-8">
89
+ <title>Encrypted Message - ${originalFilename}</title>
90
+ <script src="https://cdnjs.cloudflare.com/ajax/libs/crypto-js/4.1.1/crypto-js.min.js"></script>
91
+ </head>
92
+ <body>
93
+ <div id="encrypted-content" style="display:none;">${encrypted}</div>
94
+ <div id="decrypted-content"></div>
95
+
96
+ <script>
97
+ function decryptContent() {
98
+ try {
99
+ const encrypted = document.getElementById('encrypted-content').textContent;
100
+ const key = '${key}';
101
+ const iv = '${iv}';
102
+
103
+ const decrypted = CryptoJS.AES.decrypt(encrypted, key, {
104
+ iv: CryptoJS.enc.Hex.parse(iv),
105
+ mode: CryptoJS.mode.CBC,
106
+ padding: CryptoJS.pad.Pkcs7
107
+ });
108
+
109
+ const decryptedText = decrypted.toString(CryptoJS.enc.Utf8);
110
+ document.getElementById('decrypted-content').innerHTML = decryptedText;
111
+ } catch (error) {
112
+ document.getElementById('decrypted-content').innerHTML =
113
+ '<p style="color: red;">Decryption failed. Please contact the sender.</p>';
114
+ }
115
+ }
116
+
117
+ // Auto-decrypt on page load
118
+ window.onload = decryptContent;
119
+ </script>
120
+ </body>
121
+ </html>`;
122
+ }
123
+ }
124
+
125
+ module.exports = MessageEncryption;
package/src/init.js ADDED
@@ -0,0 +1,79 @@
1
+ const fs = require("fs");
2
+ const path = require("path");
3
+
4
+ function printBanner() {
5
+ console.log(`\n\x1b[36m` +
6
+ ` _ _ _ _ _ _ _ \n| \ | | ___ | | | __| (_)___| |_ \n| \| |/ _ \| | |/ _ | / __| __|\n| |\ | (_) | | | (_| | \__ \ |_ \n|_| \_|\___/|_|_|\__,_|_|___/\__|\n` + '\x1b[0m');
7
+ }
8
+
9
+ function copyTemplate(src, dest) {
10
+ try {
11
+ const srcPath = path.join(__dirname, "../templates", src);
12
+ const destPath = path.join(dest, src);
13
+ console.log(`Copying from ${srcPath} to ${destPath}`);
14
+ fs.copyFileSync(srcPath, destPath);
15
+ } catch (err) {
16
+ console.error(`Failed to copy template ${src}:`, err);
17
+ throw err;
18
+ }
19
+ }
20
+
21
+ function fixConfigPaths(configPath, workspace) {
22
+ // Read config, update all file paths to be relative to workspace
23
+ const config = JSON.parse(fs.readFileSync(configPath, 'utf8'));
24
+ if (config.emails_list) config.emails_list.path = "emails.txt";
25
+ if (config.senders_list) config.senders_list.path = "senders.txt";
26
+ if (config.messages_body) config.messages_body.path = "messages.html";
27
+ if (Array.isArray(config.attachments)) {
28
+ config.attachments.forEach(att => {
29
+ if (att.path) att.path = path.join("attachments", path.basename(att.path));
30
+ });
31
+ }
32
+ fs.writeFileSync(configPath, JSON.stringify(config, null, 2));
33
+ }
34
+
35
+ async function init(projectName) {
36
+ printBanner();
37
+ process.stdout.write('Setting up workspace...');
38
+ const projectPath = path.resolve(process.cwd(), projectName);
39
+ console.log("Project path:", projectPath);
40
+
41
+ if (fs.existsSync(projectPath)) {
42
+ console.error(`\nDirectory ${projectName} already exists.`);
43
+ process.exit(1);
44
+ }
45
+
46
+ try {
47
+ fs.mkdirSync(projectPath);
48
+ console.log("Created directory:", projectPath);
49
+
50
+ // Create attachments dir if needed
51
+ const attachmentsDir = path.join(projectPath, "attachments");
52
+ if (!fs.existsSync(attachmentsDir)) fs.mkdirSync(attachmentsDir);
53
+
54
+ ["config.json", "emails.txt", "senders.txt", "messages.html"].forEach(file => {
55
+ copyTemplate(file, projectPath);
56
+ console.log("Copied template:", file);
57
+ });
58
+
59
+ // Fix config paths
60
+ fixConfigPaths(path.join(projectPath, "config.json"), projectPath);
61
+
62
+ // Simulate progress
63
+ await new Promise(res => setTimeout(res, 800));
64
+ process.stdout.clearLine();
65
+ process.stdout.cursorTo(0);
66
+ console.log("\x1b[32mWorkspace ready!\x1b[0m\n");
67
+ console.log("Template files created:");
68
+ ["config.json", "emails.txt", "senders.txt", "messages.html"].forEach(file => {
69
+ console.log(` - ${file}`);
70
+ });
71
+ console.log(" - attachments/ (directory)");
72
+ console.log(`\nInitialized new campaign in ${projectPath}`);
73
+ } catch (error) {
74
+ console.error("Error during initialization:", error);
75
+ process.exit(1);
76
+ }
77
+ }
78
+
79
+ module.exports = init;
@@ -0,0 +1,184 @@
1
+ const fs = require('fs');
2
+ const utils = require('./utils');
3
+
4
+ class MultiHandler {
5
+ constructor() {
6
+ this.senders = [];
7
+ this.subjects = [];
8
+ this.fromNames = [];
9
+ this.links = [];
10
+ this.currentIndexes = {
11
+ sender: 0,
12
+ subject: 0,
13
+ fromName: 0,
14
+ link: 0
15
+ };
16
+ }
17
+
18
+ // Load multiple senders from file
19
+ loadSenders(filePath) {
20
+ try {
21
+ if (!fs.existsSync(filePath)) {
22
+ console.warn(`Senders file not found: ${filePath}`);
23
+ return false;
24
+ }
25
+
26
+ const content = fs.readFileSync(filePath, 'utf8');
27
+ this.senders = content.split('\n')
28
+ .map(line => line.trim())
29
+ .filter(line => line && !line.startsWith('#') && utils.isValidEmail(line));
30
+
31
+ console.log(`Loaded ${this.senders.length} senders from ${filePath}`);
32
+ return true;
33
+ } catch (error) {
34
+ console.error(`Failed to load senders: ${error.message}`);
35
+ return false;
36
+ }
37
+ }
38
+
39
+ // Load multiple subjects from file
40
+ loadSubjects(filePath) {
41
+ try {
42
+ if (!fs.existsSync(filePath)) {
43
+ console.warn(`Subjects file not found: ${filePath}`);
44
+ return false;
45
+ }
46
+
47
+ const content = fs.readFileSync(filePath, 'utf8');
48
+ this.subjects = content.split('\n')
49
+ .map(line => line.trim())
50
+ .filter(line => line && !line.startsWith('#'));
51
+
52
+ console.log(`Loaded ${this.subjects.length} subjects from ${filePath}`);
53
+ return true;
54
+ } catch (error) {
55
+ console.error(`Failed to load subjects: ${error.message}`);
56
+ return false;
57
+ }
58
+ }
59
+
60
+ // Load multiple from names from file
61
+ loadFromNames(filePath) {
62
+ try {
63
+ if (!fs.existsSync(filePath)) {
64
+ console.warn(`From names file not found: ${filePath}`);
65
+ return false;
66
+ }
67
+
68
+ const content = fs.readFileSync(filePath, 'utf8');
69
+ this.fromNames = content.split('\n')
70
+ .map(line => line.trim())
71
+ .filter(line => line && !line.startsWith('#'));
72
+
73
+ console.log(`Loaded ${this.fromNames.length} from names from ${filePath}`);
74
+ return true;
75
+ } catch (error) {
76
+ console.error(`Failed to load from names: ${error.message}`);
77
+ return false;
78
+ }
79
+ }
80
+
81
+ // Load multiple links from file
82
+ loadLinks(filePath) {
83
+ try {
84
+ if (!fs.existsSync(filePath)) {
85
+ console.warn(`Links file not found: ${filePath}`);
86
+ return false;
87
+ }
88
+
89
+ const content = fs.readFileSync(filePath, 'utf8');
90
+ this.links = content.split('\n')
91
+ .map(line => line.trim())
92
+ .filter(line => line && !line.startsWith('#'));
93
+
94
+ console.log(`Loaded ${this.links.length} links from ${filePath}`);
95
+ return true;
96
+ } catch (error) {
97
+ console.error(`Failed to load links: ${error.message}`);
98
+ return false;
99
+ }
100
+ }
101
+
102
+ // Get next sender (round-robin)
103
+ getNextSender() {
104
+ if (this.senders.length === 0) return null;
105
+
106
+ const sender = this.senders[this.currentIndexes.sender];
107
+ this.currentIndexes.sender = (this.currentIndexes.sender + 1) % this.senders.length;
108
+ return sender;
109
+ }
110
+
111
+ // Get next subject (round-robin)
112
+ getNextSubject() {
113
+ if (this.subjects.length === 0) return null;
114
+
115
+ const subject = this.subjects[this.currentIndexes.subject];
116
+ this.currentIndexes.subject = (this.currentIndexes.subject + 1) % this.subjects.length;
117
+ return subject;
118
+ }
119
+
120
+ // Get next from name (round-robin)
121
+ getNextFromName() {
122
+ if (this.fromNames.length === 0) return null;
123
+
124
+ const fromName = this.fromNames[this.currentIndexes.fromName];
125
+ this.currentIndexes.fromName = (this.currentIndexes.fromName + 1) % this.fromNames.length;
126
+ return fromName;
127
+ }
128
+
129
+ // Get next link (round-robin)
130
+ getNextLink() {
131
+ if (this.links.length === 0) return null;
132
+
133
+ const link = this.links[this.currentIndexes.link];
134
+ this.currentIndexes.link = (this.currentIndexes.link + 1) % this.links.length;
135
+ return link;
136
+ }
137
+
138
+ // Get random sender
139
+ getRandomSender() {
140
+ if (this.senders.length === 0) return null;
141
+ return this.senders[Math.floor(Math.random() * this.senders.length)];
142
+ }
143
+
144
+ // Get random subject
145
+ getRandomSubject() {
146
+ if (this.subjects.length === 0) return null;
147
+ return this.subjects[Math.floor(Math.random() * this.subjects.length)];
148
+ }
149
+
150
+ // Get random from name
151
+ getRandomFromName() {
152
+ if (this.fromNames.length === 0) return null;
153
+ return this.fromNames[Math.floor(Math.random() * this.fromNames.length)];
154
+ }
155
+
156
+ // Get random link
157
+ getRandomLink() {
158
+ if (this.links.length === 0) return null;
159
+ return this.links[Math.floor(Math.random() * this.links.length)];
160
+ }
161
+
162
+ // Reset all indexes
163
+ resetIndexes() {
164
+ this.currentIndexes = {
165
+ sender: 0,
166
+ subject: 0,
167
+ fromName: 0,
168
+ link: 0
169
+ };
170
+ }
171
+
172
+ // Get statistics
173
+ getStats() {
174
+ return {
175
+ senders: this.senders.length,
176
+ subjects: this.subjects.length,
177
+ fromNames: this.fromNames.length,
178
+ links: this.links.length,
179
+ currentIndexes: { ...this.currentIndexes }
180
+ };
181
+ }
182
+ }
183
+
184
+ module.exports = MultiHandler;