From 56d35bb82fba66c88efdac886030add8a080fdfc Mon Sep 17 00:00:00 2001 From: ibratabian17 Date: Thu, 20 Mar 2025 19:07:33 +0700 Subject: [PATCH] Add validation for Authorization header and improve error handling in profile update --- core/route/account.js | 24 ++++++++++++++------- core/route/ubiservices.js | 44 +++++++++++++++++++-------------------- 2 files changed, 38 insertions(+), 30 deletions(-) diff --git a/core/route/account.js b/core/route/account.js index bb42936..924b47d 100644 --- a/core/route/account.js +++ b/core/route/account.js @@ -276,6 +276,10 @@ module.exports = { app.post("/profile/v2/profiles", (req, res) => { try { const ticket = req.header("Authorization"); + if (!ticket) { + return res.status(400).send("Authorization header is required"); + } + const content = req.body; content.ticket = ticket; const dataFilePath = path.join(getSavefilePath(), `/account/profiles/user.json`); @@ -288,14 +292,17 @@ module.exports = { // Find matching profile by name or ticket const matchedProfileId = Object.keys(decryptedData).find(profileId => { const userProfile = decryptedData[profileId]; - return userProfile.name === content.name || userProfile.ticket === ticket; + return userProfile && (userProfile.name === content.name || userProfile.ticket === ticket); }); + console.log('ACC Found: ', matchedProfileId) + if (matchedProfileId) { const userProfile = decryptedData[matchedProfileId]; + const previousName = userProfile.name; - if (!matchedProfileId.name && userProfile.name) { - console.log('[ACC] New User Registered: ', userProfile.name) + if (!previousName && content.name) { + console.log('[ACC] New User Registered: ', content.name); } // Merge new content into existing user profile, overriding or adding properties @@ -303,20 +310,21 @@ module.exports = { // Save updated user profile data decryptedData[matchedProfileId] = userProfile; - console.error("[ACC] Updated User ", matchedProfileId); + console.log("[ACC] Updated User ", matchedProfileId); saveUserData(dataFilePath, decryptedData); // Regenerate Leaderboard List - const leaderboardlist = generateLeaderboard(decryptedData) + const leaderboardlist = generateLeaderboard(decryptedData); saveLeaderboard(leaderboardlist, false); - res.send(decryptedData[matchedProfileId]); + res.status(200).send(decryptedData[matchedProfileId]); } else { - console.error("[ACC] Can't Find UUID: ", matchedProfileId); + console.error("[ACC] Can't Find UUID: ", content.name || 'Unknown'); res.status(404).send("Profile not found."); } } catch (err) { - console.log(err) + console.error("[ACC] Error processing profile update:", err); + res.status(500).send("Internal server error"); } }); diff --git a/core/route/ubiservices.js b/core/route/ubiservices.js index 75dfab8..ebe2177 100644 --- a/core/route/ubiservices.js +++ b/core/route/ubiservices.js @@ -94,12 +94,12 @@ exports.initroute = (app, express, server) => { app.post("/v3/profiles/sessions", async (req, res) => { const clientIp = getClientIp(req); const clientIpCountry = getCountryFromIp(clientIp); - + // Helper to generate session data const generateSessionData = (profileId, username, clientIp, clientIpCountry, ticket) => { const now = new Date(); const expiration = new Date(now.getTime() + 3 * 60 * 60 * 1000); // 3 hours - + const data = { platformType: "uplay", ticket, @@ -119,68 +119,68 @@ exports.initroute = (app, express, server) => { }; return data; }; - + // Remove Host header const headers = { ...req.headers }; delete headers.host; - + const customAuthData = parseCustomAuthHeader(headers.authorization); - + if (customAuthData) { console.log("[ACC] CustomAuth detected, verifying..."); - + const { profileId, username, email, password } = customAuthData; const userData = getUserData(profileId); const ticket = `CustomAuth${headers.authorization.split(" t=")[1]}` - - if (userData && userData.password === password) { + + if (userData && userData.password && userData.email && userData.password === password) { console.log("[ACC] CustomAuth login: ", atob(username)); - updateUser(profileId, { username: atob(username), email, password, userId: profileId, ticket: `Ubi_v1 ${ticket}`}); + updateUser(profileId, { username: atob(username), email, password, userId: profileId, ticket: `Ubi_v1 ${ticket}` }); const sessionData = generateSessionData(profileId, username, clientIp, clientIpCountry, ticket) res.send(sessionData); return; - } - - if (!userData) { + } else if (!userData || !userData.password || !userData.email) { console.log("[ACC] CustomAuth register: ", atob(username)); updateUser(profileId, { username: atob(username), email, password, userId: profileId, ticket: `Ubi_v1 ${ticket}` }); res.send(generateSessionData(profileId, atob(username), clientIp, clientIpCountry, ticket)); return; + } else { + console.log("[ACC] CustomAuth login, Invalid Credentials: ", atob(username)); } } - + try { console.log("[ACC] Fetching Ticket From Official Server"); const response = await axios.post(`${prodwsurl}/v3/profiles/sessions`, req.body, { headers }); - + res.send(response.data); console.log("[ACC] Using Official Ticket"); - + // Update user mappings addUserId(response.data.profileId, response.data.userId); updateUserTicket(response.data.profileId, `Ubi_v1 ${response.data.ticket}`); } catch (error) { console.log("[ACC] Error fetching from Ubisoft services", error.message); - + if (ipCache[clientIp]) { console.log(`[ACC] Returning cached session for IP ${clientIp}`); return res.send(ipCache[clientIp]); } - + const profileId = uuidv4(); const userTicket = generateFalseTicket(); cachedTicket[userTicket] = profileId; - + console.log("[ACC] Generating Fake Session for", profileId); - + const fakeSession = generateSessionData(profileId, "NintendoSwitch", clientIp, clientIpCountry, userTicket); ipCache[clientIp] = fakeSession; - + res.send(fakeSession); } }); - - + + // Handle session deletion app.delete("/v3/profiles/sessions", (req, res) => { res.send();