Update AccountActions.js

This commit is contained in:
Win8.1VMUser 2025-08-19 08:22:10 +02:00 • committed by GitHub
parent af6f655108
commit 7f14aa768a
No known key found for this signature in database
GPG key ID: B5690EEEBB952194

View file

@ -441,374 +441,4 @@ export {
addAccountWithToken,
addAccountWithCredentials,
forceLogout
};showConfirmationAlert({
title: "⚠️ Import Accounts - Security Warning",
content: "Importing accounts is UNSAFE and may compromise your security if the data comes from untrusted sources. Only import data you exported yourself or from sources you completely trust. Malicious imports could lead to account takeover.",
confirmText: "I Understand - Import",
cancelText: "Cancel",
confirmColor: "brand",
onConfirm: async () => {
try {
addLog('info', 'Starting account import');
let dataToImport = importText.trim();
if (!dataToImport) {
try {
dataToImport = await clipboard.getString();
} catch (e) {
addLog('error', 'Failed to get clipboard data', { error: e.message });
showToast("No data in clipboard or input field", 1);
return;
}
}
if (!dataToImport) {
addLog('warn', 'No data to import');
showToast("No data to import", 1);
return;
}
const importData = JSON.parse(dataToImport);
let accountsArray;
if (importData.accounts && Array.isArray(importData.accounts)) {
if (importData.exportPasswordHash) {
if (!storage.settings?.exportPasswordHash || storage.settings.exportPasswordHash !== importData.exportPasswordHash) {
addLog('error', 'Import password mismatch');
showToast("Import password mismatch or not set locally", 1);
return;
}
}
accountsArray = importData.accounts;
if (importData.exportPasswordHash && !storage.settings?.exportPasswordHash) {
storage.settings.exportPasswordHash = importData.exportPasswordHash;
addLog('info', 'Import password hash set from import data');
}
} else if (Array.isArray(importData)) {
accountsArray = importData;
addLog('debug', 'Using legacy import format');
} else {
addLog('error', 'Invalid import format');
showToast("Invalid import format", 1);
return;
}
let importedCount = 0;
let skippedCount = 0;
accountsArray.forEach(accountData => {
if (accountData.id && accountData.token && accountData.username) {
if (!storage.accounts[accountData.id]) {
storage.accounts[accountData.id] = {
id: accountData.id,
username: accountData.username,
discriminator: accountData.discriminator || "0",
avatar: accountData.avatar || null,
displayName: accountData.displayName || accountData.username,
token: accountData.token,
addedAt: accountData.addedAt || Date.now()
};
if (!storage.accountOrder.includes(accountData.id)) {
storage.accountOrder.push(accountData.id);
}
importedCount++;
} else {
skippedCount++;
}
}
});
addLog('info', 'Import completed', { imported: importedCount, skipped: skippedCount });
showToast(`Imported ${importedCount} accounts, skipped ${skippedCount} duplicates`, 0);
} catch (e) {
addLog('error', 'Import failed', { error: e.message });
console.error("Import error:", e);
showToast("Failed to import - invalid format or password mismatch", 1);
}
}
});
});
};
// Password management functions
const setExportPassword = (storage, newPassword, confirmPassword, setNewPassword, setConfirmPassword) => {
if (!newPassword.trim()) {
showToast("Please enter a password", 1);
return;
}
if (newPassword !== confirmPassword) {
showToast("Passwords don't match", 1);
return;
}
const passwordHash = simpleHash(newPassword);
storage.settings.exportPasswordHash = passwordHash;
setNewPassword("");
setConfirmPassword("");
addLog('info', 'Export password set successfully');
showToast("Export password set successfully", 0);
};
const removeExportPassword = (storage, showPasswordDialog) => {
const checkPassword = (callback) => {
showPasswordDialog({
type: 'remove',
title: 'Enter Password to Remove',
message: 'Enter your current password to remove protection',
callback: callback
});
};
checkPassword(() => {
showConfirmationAlert({
title: "Remove Export Password",
content: "Are you sure you want to remove the export password? This will make exports/imports less secure.",
confirmText: "Remove Password",
cancelText: "Cancel",
confirmColor: "brand",
onConfirm: () => {
delete storage.settings.exportPasswordHash;
addLog('info', 'Export password removed');
showToast("Export password removed", 0);
}
});
});
};
// Account management functions
const addAccountWithToken = async (storage, newToken, setNewToken, setIsAdding) => {
if (!storage.settings.enableUnsafeFeatures) return;
setIsAdding(true);
addLog('info', 'Starting token account addition');
try {
let token = newToken.trim();
if (!token) {
token = TokenManager.getToken();
addLog('debug', 'Using current account token');
}
if (!token.startsWith("Bot ") && !token.match(/^[A-Za-z0-9_-]{24,}\.[A-Za-z0-9_-]{6}\.[A-Za-z0-9_-]{27,}$/)) {
addLog('error', 'Invalid token format provided');
showToast("Invalid token format", 1);
setIsAdding(false);
return;
}
addLog('debug', 'Fetching user info from Discord API');
const response = await fetch("https://discord.com/api/v9/users/@me", {
headers: { "Authorization": token, "Content-Type": "application/json" }
});
if (!response.ok) {
addLog('error', 'Discord API request failed', { status: response.status, statusText: response.statusText });
showToast("Invalid or expired token", 1);
setIsAdding(false);
return;
}
const user = await response.json();
addLog('info', 'Successfully retrieved user info', { username: user.username, id: user.id });
const userInfo = {
id: user.id,
username: user.username,
discriminator: user.discriminator,
avatar: user.avatar,
displayName: user.global_name || user.username
};
if (storage.accounts[userInfo.id]) {
addLog('warn', 'Account already exists', { username: userInfo.username });
showToast(`Account ${userInfo.username} already saved`, 1);
setIsAdding(false);
return;
}
const newAccount = { ...userInfo, token: token, addedAt: Date.now() };
storage.accounts[userInfo.id] = newAccount;
if (!storage.accountOrder.includes(userInfo.id)) {
storage.accountOrder.push(userInfo.id);
}
setNewToken("");
addLog('info', 'Account added successfully via token', { username: userInfo.username });
showToast(`Account ${userInfo.username} added!`, 0);
} catch (e) {
addLog('error', 'Failed to add account via token', { error: e.message, stack: e.stack });
console.error("Add account error:", e);
showToast("Failed to add account", 1);
}
setIsAdding(false);
};
const forceLogout = async () => {
showConfirmationAlert({
title: "Force Logout",
content: "This will logout your current session by using an invalid token. Your saved accounts will remain intact. Continue?",
confirmText: "Force Logout",
cancelText: "Cancel",
confirmColor: "brand",
onConfirm: async () => {
try {
addLog('info', 'Starting force logout');
const fakeToken = "MTExMTExMTExMTExMTExMTEx.GxxxXx.xXxXxXxXxXxXxXxXxXxXxXxXxXxXx";
await findByProps("login", "logout", "switchAccountToken").switchAccountToken(fakeToken);
addLog('info', 'Force logout completed successfully');
showToast("Force logout successful - you can now login to a different account", 0);
} catch (e) {
addLog('warn', 'Force logout completed with error', { error: e.message });
console.error("Force logout error:", e);
showToast("Force logout completed", 0);
}
}
});
};
const addAccountWithCredentials = async (storage, email, password, setEmail, setPassword, setShowAddDialog, setIsAddingDynamic) => {
if (!email.trim() || !password.trim()) {
showToast("Please enter both email and password", 1);
return;
}
setIsAddingDynamic(true);
addLog('info', 'Starting credential-based account addition', { email: email.trim() });
try {
const response = await fetch("https://discord.com/api/v9/auth/login", {
method: "POST",
headers: {
"Content-Type": "application/json",
"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36"
},
body: JSON.stringify({
login: email.trim(),
password: password.trim()
})
});
const loginData = await response.json();
if (!response.ok || !loginData.token) {
addLog('error', 'Discord login failed', {
status: response.status,
message: loginData.message,
errors: loginData.errors,
captchaRequired: !!loginData.captcha_key
});
// Provide user-friendly error messages
let errorMessage = "Login failed";
if (loginData.captcha_key) {
errorMessage = "Captcha required - please login through Discord first";
} else if (loginData.message) {
// Clean up common Discord API error messages
const msg = loginData.message.toLowerCase();
if (msg.includes('invalid') && (msg.includes('email') || msg.includes('phone') || msg.includes('login'))) {
errorMessage = "Invalid email or username";
} else if (msg.includes('password')) {
errorMessage = "Invalid password";
} else if (msg.includes('account')) {
errorMessage = "Account issue - check your credentials";
} else if (msg.includes('rate limit') || msg.includes('too many')) {
errorMessage = "Too many attempts - please wait and try again";
} else if (msg.includes('mfa') || msg.includes('2fa') || msg.includes('verification')) {
errorMessage = "2FA/MFA accounts not supported via credentials";
} else {
errorMessage = "Login failed - check your credentials";
}
} else if (loginData.errors) {
// Handle field-specific errors
const errors = loginData.errors;
if (errors.login) {
errorMessage = "Invalid email or username";
} else if (errors.password) {
errorMessage = "Invalid password";
} else {
errorMessage = "Invalid credentials";
}
} else if (response.status === 401) {
errorMessage = "Invalid credentials";
} else if (response.status === 429) {
errorMessage = "Rate limited - please wait and try again";
} else if (response.status >= 500) {
errorMessage = "Discord servers are having issues - try again later";
}
showToast(errorMessage, 1);
setIsAddingDynamic(false);
return;
}
addLog('debug', 'Login successful, fetching user info');
const userResponse = await fetch("https://discord.com/api/v9/users/@me", {
headers: { "Authorization": loginData.token }
});
if (!userResponse.ok) {
addLog('error', 'Failed to get user info after login', { status: userResponse.status });
showToast("Login succeeded but failed to get user info - check logs", 1);
setIsAddingDynamic(false);
return;
}
const user = await userResponse.json();
if (storage.accounts[user.id]) {
addLog('warn', 'Account already exists', { username: user.username });
showToast(`Account ${user.username} already saved`, 1);
setIsAddingDynamic(false);
return;
}
const newAccount = {
id: user.id,
username: user.username,
discriminator: user.discriminator,
avatar: user.avatar,
displayName: user.global_name || user.username,
token: loginData.token,
addedAt: Date.now()
};
storage.accounts[user.id] = newAccount;
if (!storage.accountOrder.includes(user.id)) {
storage.accountOrder.push(user.id);
}
setEmail("");
setPassword("");
setShowAddDialog(false);
addLog('info', 'Account added successfully via credentials', { username: user.username });
showToast(`Account ${user.username} added successfully!`, 0);
} catch (e) {
addLog('error', 'Credential login failed', { error: e.message, stack: e.stack });
console.error("Login error:", e);
// Network or other errors
let errorMessage = "Login failed - check logs for more info";
if (e.message.includes('network') || e.message.includes('fetch')) {
errorMessage = "Network error - check your connection";
} else if (e.message.includes('timeout')) {
errorMessage = "Request timed out - try again";
}
showToast(errorMessage, 1);
}
setIsAddingDynamic(false);
};
export {
exportAccounts,
importAccounts,
setExportPassword,
removeExportPassword,
addAccountWithToken,
addAccountWithCredentials,
forceLogout
};