first commit

This commit is contained in:
adrapier03
2026-07-07 23:19:04 +07:00
commit aac4a943bd
4 changed files with 918 additions and 0 deletions
+204
View File
@@ -0,0 +1,204 @@
const fs = require('fs');
const path = require('path');
// Read accounts from akun.txt
const akunPath = path.join(__dirname, 'akun.txt');
if (!fs.existsSync(akunPath)) {
console.error('Error: akun.txt not found! Please create it first.');
process.exit(1);
}
const content = fs.readFileSync(akunPath, 'utf-8');
const accounts = content.split('\n')
.map(line => line.trim())
.filter(line => line && !line.startsWith('#') && line.includes('|'))
.map(line => {
const parts = line.split('|');
return {
email: parts[0].trim(),
password: parts[1].trim(),
profileName: parts[2] ? parts[2].trim() : null // Optional profile name
};
});
if (accounts.length === 0) {
console.log('No active accounts found in akun.txt.');
process.exit(0);
}
console.log(`Found ${accounts.length} account(s) to process.`);
// Parse --headless argument from CLI (e.g. node automation.js --headless true)
const headlessIndex = process.argv.indexOf('--headless');
const isHeadless = headlessIndex !== -1 ? (process.argv[headlessIndex + 1] !== 'false') : false;
async function run() {
const { launch } = await import('cloakbrowser');
console.log(`Launching CloakBrowser (headless: ${isHeadless})...`);
const browser = await launch({
headless: isHeadless,
// Add other fingerprint options here if needed
});
for (let i = 0; i < accounts.length; i++) {
const account = accounts[i];
console.log(`\n==================================================`);
console.log(`[Account ${i + 1}/${accounts.length}] Processing: ${account.email}`);
console.log(`==================================================`);
// Create a clean isolated context for each account to prevent session leaks
const context = await browser.newContext({
permissions: ['clipboard-read', 'clipboard-write'],
viewport: null
});
try {
// Primary page initialization
const page1 = await context.newPage();
await page1.goto('https://evolink.ai/');
// Click on a "Sign Up"
await page1.getByRole('link', { name: 'Sign Up' }).click();
await page1.waitForTimeout(1000);
// Start waiting for Google Login window/tab to open before clicking
const page2Promise = context.waitForEvent('page');
// Click on button "Sign up with Google"
await page1.getByRole('button', { name: 'Sign up with Google' }).click();
// Wait for the new tab to open
const page2 = await page2Promise;
console.log('Google login tab opened. Logging in...');
// Fill email
await page2.locator('#identifierId').waitFor({ state: 'visible', timeout: 5000 });
await page2.locator('#identifierId').click();
await page2.locator('#identifierId').fill(account.email);
// Click on button "Next"
await page2.getByRole('button', { name: 'Next' }).click();
await page2.waitForTimeout(2000); // Wait for password input to load
// Fill password
await page2.locator('div#password > div > div > div > input').waitFor({ state: 'visible', timeout: 5000 });
await page2.locator('div#password > div > div > div > input').fill(account.password);
// Click on button "Next"
await page2.getByRole('button', { name: 'Next' }).click();
await page2.waitForTimeout(2000);
// Click on button "I understand" (if Terms speedbump shows up)
try {
await page2.getByRole('button', { name: 'I understand' }).waitFor({ state: 'visible', timeout: 3000 });
await page2.getByRole('button', { name: 'I understand' }).click();
await page2.waitForTimeout(1000);
console.log('Clicked "I understand" button.');
} catch (e) {
console.log('Speedbump "I understand" not present, skipping...');
}
// Click on button "Continue" (OAuth consent page)
try {
const continueBtn = page2.getByRole('button', { name: /^(Sign in|Continue|Allow|Login|Masuk|Lanjutkan|Izinkan)$/i });
await continueBtn.waitFor({ state: 'visible', timeout: 5000 });
await continueBtn.click();
await page2.waitForTimeout(2000);
console.log('Clicked login/continue button.');
} catch (e) {
console.log('Login/continue button not found or already bypassed.');
}
// Back on page1, wait for login state to reflect
await page1.waitForTimeout(3000);
// Click on profile dropdown button (using the name-independent chevron selector)
const profileBtn = page1.locator(".w-4.h-4.text-gray-400.transition-transform.duration-200").first();
await profileBtn.waitFor({ state: 'visible', timeout: 7000 });
await profileBtn.click();
await page1.waitForTimeout(1000);
// Click on a "Dashboard"
await page1.getByRole('link', { name: 'Dashboard' }).click();
await page1.waitForTimeout(1000);
// Click on a "API Keys"
await page1.getByRole('link', { name: 'API Keys' }).click();
await page1.waitForTimeout(1000);
// Click on button "Create New Key"
await page1.getByRole('button', { name: 'Create New Key' }).click();
await page1.waitForTimeout(1000);
// Click on input
await page1.getByRole('textbox', { name: 'e.g.: Production Key' }).click();
await page1.waitForTimeout(500);
// Fill value in input
await page1.getByRole('textbox', { name: 'e.g.: Production Key' }).fill('my api key');
// Click on button "Create Key"
await page1.getByRole('button', { name: 'Create Key' }).click();
await page1.waitForTimeout(2000);
// Click copy/close button on modal
console.log('Clicking copy button...');
await page1.locator('html > body > div:nth-of-type(6) > div > div > div:nth-of-type(2) > div > button').click();
await page1.waitForTimeout(1000); // Wait for clipboard writing to complete
// Extract API key from clipboard and fallback to DOM
let apiKey = await page1.evaluate(async () => {
try {
return await navigator.clipboard.readText();
} catch (e) {
return null;
}
}).catch(() => null);
if (!apiKey || apiKey.trim().length === 0) {
// Fallback: search DOM inside the modal container
apiKey = await page1.evaluate(() => {
const modal = document.querySelector('body > div:nth-of-type(6)');
if (!modal) return null;
const input = modal.querySelector('input, textarea');
if (input && input.value) return input.value.trim();
const elements = Array.from(modal.querySelectorAll('span, div, code, p'));
for (const el of elements) {
const txt = el.innerText ? el.innerText.trim() : '';
// API Keys are usually longer alphanumeric strings with no spaces
if (txt.length > 20 && !txt.includes(' ') && /^[a-zA-Z0-9_\-\.]+$/.test(txt)) {
return txt;
}
}
return null;
}).catch(() => null);
}
if (apiKey) {
console.log(`[Success] Extracted API Key: ${apiKey}`);
fs.appendFileSync(path.join(__dirname, 'api_keys.txt'), `${account.email}|${apiKey}\n`);
} else {
console.log('[Warning] Could not extract API Key from clipboard or modal DOM.');
}
// Click on button "Complete"
await page1.getByRole('button', { name: 'Complete' }).click();
await page1.waitForTimeout(1000);
console.log(`[Account ${i + 1}/${accounts.length}] Successfully completed API Key creation.`);
} catch (err) {
console.error(`[Account ${i + 1}/${accounts.length}] Failed with error:`, err.message || err);
} finally {
// Close context to clear session cookies for the next account
await context.close();
}
}
console.log('\nAll accounts processed.');
await browser.close();
}
run().catch(console.error);