UNPKG

anticlone-sdk

Version:

SDK for generating app fingerprints and protecting against clone/fake apps

251 lines (199 loc) • 8.56 kB
#!/usr/bin/env node const AntiCloneSDK = require('../index.js'); const fs = require('fs').promises; const path = require('path'); class AntiCloneCLI { constructor() { this.sdk = new AntiCloneSDK(); this.configPath = path.join(process.cwd(), '.anticlone.json'); } async run() { const args = process.argv.slice(2); const command = args[0]; try { await this.loadConfig(); switch (command) { case 'register': await this.register(); break; case 'config': await this.configure(); break; case 'fingerprint': await this.generateFingerprint(args); break; case 'upload': await this.uploadFingerprint(args); break; case 'profile': await this.showProfile(); break; case 'help': default: this.showHelp(); break; } } catch (error) { console.error('āŒ Error:', error.message); process.exit(1); } } async loadConfig() { try { const config = await fs.readFile(this.configPath, 'utf8'); const { developerId, apiKey } = JSON.parse(config); this.sdk.setCredentials(developerId, apiKey); } catch (error) { console.error('āŒ "Config file does not exist or is invalid":', error.message); } } async saveConfig(developerId, apiKey) { const config = { developerId, apiKey }; await fs.writeFile(this.configPath, JSON.stringify(config, null, 2)); console.log(`āœ… Configuration saved to ${this.configPath}`); } async register() { const readline = require('readline').createInterface({ input: process.stdin, output: process.stdout }); const question = (prompt) => new Promise(resolve => readline.question(prompt, resolve)); try { console.log('šŸ” Developer Registration\n'); const developerName = await question('Developer Name: '); const companyName = await question('Company Name (optional): '); const email = await question('Email: '); const phone = await question('Phone (optional): '); const website = await question('Website (optional): '); const developerInfo = { developerName, companyName: companyName || null, email, contactInfo: { phone: phone || null, website: website || null } }; const response = await this.sdk.registerDeveloper(developerInfo); // Save credentials await this.saveConfig(response.credentials.developerId, response.credentials.apiKey); console.log('\nšŸ“„ Please save your passkey separately:'); console.log(`Passkey: ${response.credentials.passkey}\n`); console.log('āš ļø Your account needs verification before you can upload fingerprints.'); } finally { readline.close(); } } async configure() { const readline = require('readline').createInterface({ input: process.stdin, output: process.stdout }); const question = (prompt) => new Promise(resolve => readline.question(prompt, resolve)); try { console.log('āš™ļø SDK Configuration\n'); const developerId = await question('Developer ID: '); const apiKey = await question('API Key: '); this.sdk.setCredentials(developerId, apiKey); // Test credentials await this.sdk.getDeveloperProfile(); await this.saveConfig(developerId, apiKey); } finally { readline.close(); } } async generateFingerprint(args) { const inputPath = args[1]; const outputPath = args[2] || 'fingerprint.json'; if (!inputPath) { throw new Error('Input path is required. Usage: anticlone fingerprint <path> [output]'); } const readline = require('readline').createInterface({ input: process.stdin, output: process.stdout }); const question = (prompt) => new Promise(resolve => readline.question(prompt, resolve)); try { console.log('šŸ“± App Information\n'); const appId = await question('App ID/Package Name: '); const appName = await question('App Name: '); const version = await question('Version: '); const packageName = await question('Package Name (optional): '); const appInfo = { appId, appName, version, packageName: packageName || appId }; console.log('\nšŸ” Generating fingerprint...'); let fingerprint; const stats = await fs.stat(inputPath); if (stats.isDirectory()) { fingerprint = await this.sdk.generateFingerprintFromProject(inputPath, appInfo); } else { fingerprint = await this.sdk.generateFingerprintFromFile(inputPath, appInfo); } await fs.writeFile(outputPath, JSON.stringify(fingerprint, null, 2)); console.log(`āœ… Fingerprint generated and saved to ${outputPath}`); console.log(`Overall Hash: ${fingerprint.overallHash}`); console.log(`Files Analyzed: ${fingerprint.metadata.totalFiles || 'N/A'}`); } finally { readline.close(); } } async uploadFingerprint(args) { const fingerprintPath = args[1] || 'fingerprint.json'; try { const fingerprintData = await fs.readFile(fingerprintPath, 'utf8'); const fingerprint = JSON.parse(fingerprintData); console.log('šŸ“¤ Uploading fingerprint...'); const response = await this.sdk.uploadFingerprint(fingerprint); console.log(`āœ… Upload successful! ID: ${response.id}`); } catch (error) { if (error.code === 'ENOENT') { throw new Error(`Fingerprint file not found: ${fingerprintPath}`); } throw error; } } async showProfile() { const profile = await this.sdk.getDeveloperProfile(); if (profile.success) { console.log('šŸ‘¤ Developer Profile\n'); console.log(`Name: ${profile.profile.developer_name}`); console.log(`Company: ${profile.profile.company_name || 'N/A'}`); console.log(`Email: ${profile.profile.email}`); console.log(`Status: ${profile.profile.verification_status}`); console.log(`Registered: ${new Date(profile.profile.registration_date).toLocaleDateString()}`); console.log(`Apps: ${profile.profile.app_count}`); } } showHelp() { console.log(` šŸ›”ļø AntiClone SDK - App Fingerprinting Tool USAGE: anticlone <command> [options] COMMANDS: register Register as a new developer config Configure SDK with your credentials fingerprint <path> Generate fingerprint from project/APK/IPA upload [file] Upload fingerprint to database profile Show your developer profile help Show this help message EXAMPLES: anticlone register anticlone config anticlone fingerprint ./my-app-project anticlone fingerprint ./myapp.apk output.json anticlone upload fingerprint.json anticlone profile For detailed documentation, visit: https://www.npmjs.com/package/anticlone-sdk?activeTab=readme `); } } // Run CLI if (require.main === module) { const cli = new AntiCloneCLI(); cli.run().catch(console.error); } module.exports = AntiCloneCLI;