mirror of
https://git.sanhost.net/sanasol/hytale-f2p.git
synced 2026-03-01 08:11:52 -03:00
feat: identity protection UI, duplicate guards, name-lock enforcement (v2.4.6)
- Add password set/change/remove with loading states and double-click prevention - Add protected identity deletion flow (server-side password removal first) - Add restore flow for password-protected UUIDs (verify password before saving) - Add UUID duplicate checks in setUuidForUser (prevent accidental overwrites) - Add name-locked error handling in launch flow (server enforces registered name) - Sync shield icon across all identity mutation paths - Refresh identity dropdown after all password/identity operations - Propagate force flag through IPC for legitimate overwrites Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
21
main.js
21
main.js
@@ -532,10 +532,10 @@ ipcMain.handle('launch-game', async (event, playerName, javaPath, installPath, g
|
||||
|
||||
// Check if UUID has password before launching
|
||||
let launchOptions = {};
|
||||
const { getAuthServerUrl, getUuidForUser } = require('./backend/core/config');
|
||||
const launchUuid = getUuidForUser(playerName);
|
||||
try {
|
||||
const { getAuthServerUrl } = require('./backend/core/config');
|
||||
const { getUuidForUser } = require('./backend/core/config');
|
||||
const uuid = getUuidForUser(playerName);
|
||||
const uuid = launchUuid;
|
||||
const authServerUrl = getAuthServerUrl();
|
||||
const statusResp = await fetch(`${authServerUrl}/player/password/status/${uuid}`);
|
||||
if (statusResp.ok) {
|
||||
@@ -574,7 +574,7 @@ ipcMain.handle('launch-game', async (event, playerName, javaPath, installPath, g
|
||||
}
|
||||
|
||||
if (error.passwordRequired) {
|
||||
return { success: false, passwordRequired: true, error: 'Password required' };
|
||||
return { success: false, passwordRequired: true, uuid: launchUuid, error: 'Password required' };
|
||||
}
|
||||
if (error.lockedOut) {
|
||||
return { success: false, error: 'Too many failed attempts. Try again in ' + Math.ceil((error.lockoutSeconds || 900) / 60) + ' minutes.' };
|
||||
@@ -582,6 +582,9 @@ ipcMain.handle('launch-game', async (event, playerName, javaPath, installPath, g
|
||||
if (error.usernameTaken) {
|
||||
return { success: false, usernameTaken: true, error: errorMessage };
|
||||
}
|
||||
if (error.nameLocked) {
|
||||
return { success: false, nameLocked: true, registeredName: error.registeredName, error: error.message };
|
||||
}
|
||||
|
||||
return { success: false, error: errorMessage };
|
||||
}
|
||||
@@ -625,6 +628,9 @@ ipcMain.handle('launch-game-with-password', async (event, playerName, javaPath,
|
||||
if (error.usernameTaken) {
|
||||
return { success: false, usernameTaken: true, error: error.message || error.toString() };
|
||||
}
|
||||
if (error.nameLocked) {
|
||||
return { success: false, nameLocked: true, registeredName: error.registeredName, error: error.message };
|
||||
}
|
||||
return { success: false, error: error.message || error.toString() };
|
||||
}
|
||||
});
|
||||
@@ -1423,9 +1429,12 @@ ipcMain.handle('get-all-uuid-mappings', async () => {
|
||||
}
|
||||
});
|
||||
|
||||
ipcMain.handle('set-uuid-for-user', async (event, username, uuid) => {
|
||||
ipcMain.handle('set-uuid-for-user', async (event, username, uuid, force) => {
|
||||
try {
|
||||
await setUuidForUser(username, uuid);
|
||||
const result = setUuidForUser(username, uuid, { force: !!force });
|
||||
if (result && result.success === false) {
|
||||
return result; // { success: false, error: 'duplicate', existingUuid }
|
||||
}
|
||||
return { success: true };
|
||||
} catch (error) {
|
||||
console.error('Error setting UUID for user:', error);
|
||||
|
||||
Reference in New Issue
Block a user