feat: implement userInfo() and cdn*() API calls into UI
This commit is contained in:
parent
1ddb12c6e8
commit
660bfb058d
102
app.js
102
app.js
@ -772,6 +772,9 @@ app.post('/api/user', async (req, res) => {
|
|||||||
case 'friendsList':
|
case 'friendsList':
|
||||||
data = await fetchWithTimeout(() => API.Me.friendsList());
|
data = await fetchWithTimeout(() => API.Me.friendsList());
|
||||||
break;
|
break;
|
||||||
|
case 'userInfo':
|
||||||
|
data = await fetchWithTimeout(() => API.Me.userInfo());
|
||||||
|
break;
|
||||||
// case "settings":
|
// case "settings":
|
||||||
// data = await fetchWithTimeout(() =>
|
// data = await fetchWithTimeout(() =>
|
||||||
// API.Me.settings(username, platform)
|
// API.Me.settings(username, platform)
|
||||||
@ -807,6 +810,105 @@ app.post('/api/user', async (req, res) => {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// API endpoint for CDN-related API calls
|
||||||
|
app.post('/api/cdn', async (req, res) => {
|
||||||
|
logger.debug('Received request for /api/cdn');
|
||||||
|
logger.debug(
|
||||||
|
`Request IP: ${
|
||||||
|
req.headers['x-forwarded-for'] || req.ip || req.connection.remoteAddress
|
||||||
|
}`
|
||||||
|
);
|
||||||
|
logger.debug(
|
||||||
|
`Request JSON: ${JSON.stringify({
|
||||||
|
cdnCall: req.body.cdnCall,
|
||||||
|
})}`
|
||||||
|
);
|
||||||
|
|
||||||
|
try {
|
||||||
|
let { ssoToken, cdnCall } = req.body;
|
||||||
|
|
||||||
|
/*
|
||||||
|
logger.debug(
|
||||||
|
`Request details - User Call: ${cdnCall}`
|
||||||
|
);
|
||||||
|
|
||||||
|
logger.debug("=== USER DATA REQUEST ===");
|
||||||
|
logger.debug(`CDN Call: ${cdnCall}`);
|
||||||
|
logger.debug("========================="); */
|
||||||
|
|
||||||
|
const defaultToken = demoTracker.getDefaultSsoToken();
|
||||||
|
if (!ssoToken && defaultToken) {
|
||||||
|
ssoToken = defaultToken;
|
||||||
|
logger.info('Using default SSO token for demo mode');
|
||||||
|
} else if (!ssoToken) {
|
||||||
|
return res.status(200).json({
|
||||||
|
status: 'error',
|
||||||
|
message: 'SSO Token is required',
|
||||||
|
timestamp: global.Utils.toIsoString(new Date()),
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
await ensureLogin(ssoToken);
|
||||||
|
} catch (loginError) {
|
||||||
|
return res.status(200).json({
|
||||||
|
status: 'error',
|
||||||
|
error_type: 'LoginError',
|
||||||
|
message: 'SSO token login failed',
|
||||||
|
details: loginError.message || 'Unknown login error',
|
||||||
|
timestamp: global.Utils.toIsoString(new Date()),
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
// Create a wrapped function for each API call to handle timeout
|
||||||
|
const fetchWithTimeout = async (apiFn) => {
|
||||||
|
return Promise.race([
|
||||||
|
apiFn(),
|
||||||
|
timeoutPromise(30000), // 30 second timeout
|
||||||
|
]);
|
||||||
|
};
|
||||||
|
|
||||||
|
try {
|
||||||
|
logger.debug(`Attempting to fetch CDN data for ${cdnCall}`);
|
||||||
|
let data;
|
||||||
|
|
||||||
|
// Fetch user data based on cdnCall
|
||||||
|
switch (cdnCall) {
|
||||||
|
case 'accolades':
|
||||||
|
data = await fetchWithTimeout(() => API.CDN.accolades());
|
||||||
|
break;
|
||||||
|
case 'allCDNData':
|
||||||
|
data = await fetchWithTimeout(() => API.CDN.allCDNData());
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
return res.status(200).json({
|
||||||
|
status: 'error',
|
||||||
|
message: 'Invalid user API call selected',
|
||||||
|
timestamp: global.Utils.toIsoString(new Date()),
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
demoTracker.incrementDemoCounter(req, ssoToken);
|
||||||
|
|
||||||
|
return res.json({
|
||||||
|
// status: "success",
|
||||||
|
data: data,
|
||||||
|
timestamp: global.Utils.toIsoString(new Date()),
|
||||||
|
});
|
||||||
|
} catch (apiError) {
|
||||||
|
return handleApiError(apiError, res);
|
||||||
|
}
|
||||||
|
} catch (serverError) {
|
||||||
|
return res.status(200).json({
|
||||||
|
status: 'server_error',
|
||||||
|
message: 'The server encountered an unexpected error',
|
||||||
|
error_details: serverError.message || 'Unknown server error',
|
||||||
|
timestamp: global.Utils.toIsoString(new Date()),
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
// API endpoint for fuzzy search
|
// API endpoint for fuzzy search
|
||||||
app.post('/api/search', async (req, res) => {
|
app.post('/api/search', async (req, res) => {
|
||||||
logger.debug('Received request for /api/search');
|
logger.debug('Received request for /api/search');
|
||||||
|
@ -68,6 +68,7 @@
|
|||||||
<div class="tab active" data-tab="stats">Player</div>
|
<div class="tab active" data-tab="stats">Player</div>
|
||||||
<div class="tab" data-tab="matches">Matches</div>
|
<div class="tab" data-tab="matches">Matches</div>
|
||||||
<div class="tab" data-tab="user">User Info</div>
|
<div class="tab" data-tab="user">User Info</div>
|
||||||
|
<div class="tab" data-tab="cdn">CDN</div>
|
||||||
<div class="tab" data-tab="other">Search</div>
|
<div class="tab" data-tab="other">Search</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
@ -285,7 +286,9 @@
|
|||||||
|
|
||||||
<div class="button-group">
|
<div class="button-group">
|
||||||
<button id="fetchMatches">Fetch Recent Match History</button>
|
<button id="fetchMatches">Fetch Recent Match History</button>
|
||||||
<button id="fetchMatchInfo">Fetch Match Details</button>
|
<button id="fetchMatchInfo">
|
||||||
|
Fetch Match Details (Requires MatchID)
|
||||||
|
</button>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div id="tutorial" class="tutorial">
|
<div id="tutorial" class="tutorial">
|
||||||
@ -355,16 +358,15 @@
|
|||||||
<div class="form-group">
|
<div class="form-group">
|
||||||
<label for="userCall">API Request:</label>
|
<label for="userCall">API Request:</label>
|
||||||
<select id="userCall">
|
<select id="userCall">
|
||||||
<option value="codPoints">COD Points</option>
|
<option value="userInfo">User Info (Logged In User Only)</option>
|
||||||
<option value="connectedAccounts">Connected Accounts</option>
|
<option value="codPoints">COD Points (Logged In User Only)</option>
|
||||||
<option value="eventFeed">Event Feed (Logged In User Only)</option>
|
<option value="connectedAccounts">Connected Accounts (Logged In User Only)</option>
|
||||||
<option value="friendFeed">
|
|
||||||
Friend Feed (Logged In User Only)
|
|
||||||
</option>
|
|
||||||
<option value="identities">Identities (Logged In User Only)</option>
|
<option value="identities">Identities (Logged In User Only)</option>
|
||||||
<option value="friendsList">
|
<option value="friendsList">
|
||||||
Friends List (Logged In User Only)
|
Friends List (Logged In User Only)
|
||||||
</option>
|
</option>
|
||||||
|
<option value="eventFeed">Event Feed (Logged In User Only)</option>
|
||||||
|
<option value="friendFeed">Friend Feed</option>
|
||||||
<!-- <option value="settings">Settings</option> -->
|
<!-- <option value="settings">Settings</option> -->
|
||||||
</select>
|
</select>
|
||||||
</div>
|
</div>
|
||||||
@ -413,6 +415,60 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<!-- CDN tab -->
|
||||||
|
<div class="tab-content" id="cdn-tab">
|
||||||
|
<div class="form-group">
|
||||||
|
<label for="cdnCall">API Request:</label>
|
||||||
|
<select id="cdnCall">
|
||||||
|
<option value="accolades">Accolade List</option>
|
||||||
|
<option value="allCDNData">CDN Data List</option>
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<button id="fetchCDNData">Fetch CDN Content</button>
|
||||||
|
|
||||||
|
<div id="tutorial" class="tutorial">
|
||||||
|
<h2>Authentication Setup</h2>
|
||||||
|
<h3>Obtaining Your SSO Token</h3>
|
||||||
|
<ol>
|
||||||
|
<li>
|
||||||
|
Log in to
|
||||||
|
<a href="https://profile.callofduty.com" target="_blank"
|
||||||
|
>Call of Duty</a
|
||||||
|
>
|
||||||
|
</li>
|
||||||
|
<li>Open developer tools (F12 or right-click → Inspect)</li>
|
||||||
|
<li>
|
||||||
|
Navigate to: <b>Application</b> → <b>Storage</b> →
|
||||||
|
<b>Cookies</b> → <b>https://profile.callofduty.com</b>
|
||||||
|
</li>
|
||||||
|
<li>Copy the value of <code>ACT_SSO_COOKIE</code></li>
|
||||||
|
<li>Paste this value into SSO Token</li>
|
||||||
|
</ol>
|
||||||
|
|
||||||
|
<h3>Changing Account API Privacy Settings</h3>
|
||||||
|
<ol>
|
||||||
|
<li>
|
||||||
|
Log in to
|
||||||
|
<a href="https://profile.callofduty.com" target="_blank"
|
||||||
|
>Call of Duty</a
|
||||||
|
>
|
||||||
|
</li>
|
||||||
|
<li>Navigate to the <b>Privacy & Security</b> tab</li>
|
||||||
|
<li>
|
||||||
|
Scroll down to the <b>Game Data and Profile Privacy</b> section
|
||||||
|
</li>
|
||||||
|
<li>
|
||||||
|
Set the following options to "<b>ALL</b>":
|
||||||
|
<ul>
|
||||||
|
<li><b>Game Tag Searchable</b></li>
|
||||||
|
<li><b>Game Play Data</b></li>
|
||||||
|
</ul>
|
||||||
|
</li>
|
||||||
|
</ol>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
<!-- Search tab -->
|
<!-- Search tab -->
|
||||||
<div class="tab-content" id="other-tab">
|
<div class="tab-content" id="other-tab">
|
||||||
<div class="form-group">
|
<div class="form-group">
|
||||||
|
@ -272,6 +272,9 @@ function triggerActiveTabButton() {
|
|||||||
case 'user':
|
case 'user':
|
||||||
document.getElementById('fetchUserInfo').click();
|
document.getElementById('fetchUserInfo').click();
|
||||||
break;
|
break;
|
||||||
|
case 'cdn':
|
||||||
|
document.getElementById('fetchCDNData').click();
|
||||||
|
break;
|
||||||
case 'other':
|
case 'other':
|
||||||
document.getElementById('fuzzySearch').click();
|
document.getElementById('fuzzySearch').click();
|
||||||
break;
|
break;
|
||||||
@ -799,6 +802,22 @@ document.getElementById('fetchUserInfo').addEventListener('click', async () => {
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// Fetch CDN Data
|
||||||
|
document.getElementById('fetchCDNData').addEventListener('click', async () => {
|
||||||
|
const ssoToken = document.getElementById('ssoToken').value.trim();
|
||||||
|
const cdnCall = document.getElementById('cdnCall').value;
|
||||||
|
|
||||||
|
const sanitize = document.getElementById('sanitizeOption').checked;
|
||||||
|
const replaceKeys = document.getElementById('replaceKeysOption').checked;
|
||||||
|
|
||||||
|
await window.backendAPI.fetchData('/api/cdn', {
|
||||||
|
ssoToken,
|
||||||
|
cdnCall,
|
||||||
|
sanitize,
|
||||||
|
replaceKeys,
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
// Fuzzy search
|
// Fuzzy search
|
||||||
document.getElementById('fuzzySearch').addEventListener('click', async () => {
|
document.getElementById('fuzzySearch').addEventListener('click', async () => {
|
||||||
const username = document.getElementById('searchUsername').value.trim();
|
const username = document.getElementById('searchUsername').value.trim();
|
||||||
|
@ -1589,8 +1589,22 @@ const CDN = new DB();
|
|||||||
const Misc = new ALT();
|
const Misc = new ALT();
|
||||||
|
|
||||||
export {
|
export {
|
||||||
CDN, ColdWar, disableDebugMode, enableDebugMode, friendActions, login, Me, Misc, ModernWarfare,
|
CDN,
|
||||||
|
ColdWar,
|
||||||
|
disableDebugMode,
|
||||||
|
enableDebugMode,
|
||||||
|
friendActions,
|
||||||
|
login,
|
||||||
|
Me,
|
||||||
|
Misc,
|
||||||
|
ModernWarfare,
|
||||||
ModernWarfare2,
|
ModernWarfare2,
|
||||||
ModernWarfare3, platforms, Store, telescopeLogin, Vanguard, Warzone, Warzone2, WarzoneMobile
|
ModernWarfare3,
|
||||||
|
platforms,
|
||||||
|
Store,
|
||||||
|
telescopeLogin,
|
||||||
|
Vanguard,
|
||||||
|
Warzone,
|
||||||
|
Warzone2,
|
||||||
|
WarzoneMobile,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -5,7 +5,7 @@ document.addEventListener('DOMContentLoaded', function () {
|
|||||||
{ id: 'username', key: 'cod_username' },
|
{ id: 'username', key: 'cod_username' },
|
||||||
{ id: 'platform', key: 'cod_platform' },
|
{ id: 'platform', key: 'cod_platform' },
|
||||||
{ id: 'game', key: 'cod_game' },
|
{ id: 'game', key: 'cod_game' },
|
||||||
{ id: 'apiCall', key: 'cod_apiCall' },
|
{ id: 'userCall', key: 'cod_userCall' },
|
||||||
|
|
||||||
// Matches tab
|
// Matches tab
|
||||||
{ id: 'matchUsername', key: 'cod_matchUsername' },
|
{ id: 'matchUsername', key: 'cod_matchUsername' },
|
||||||
|
@ -9,8 +9,8 @@ import {
|
|||||||
} from './index.js';
|
} from './index.js';
|
||||||
import fs from 'fs';
|
import fs from 'fs';
|
||||||
|
|
||||||
// Me { communityMapDataForMapMode(game, platform, mode, mapID, gamemode), userInfo() };
|
// Me { communityMapDataForMapMode(game, platform, mode, mapID, gamemode) };
|
||||||
// CDN { accolades(), allCDNData() };
|
|
||||||
// ModernWarfare: { bundleInfo(game, platform, lookupType, gamertag), matchHeatMap(game, platform, matchID), bpProg(game, platform, lookupType, gamertag) };
|
// ModernWarfare: { bundleInfo(game, platform, lookupType, gamertag), matchHeatMap(game, platform, matchID), bpProg(game, platform, lookupType, gamertag) };
|
||||||
// ColdWar: { bundleInfo(game, platform, lookupType, gamertag), matchHeatMap(game, platform, matchID), bpProg(game, platform, lookupType, gamertag) };
|
// ColdWar: { bundleInfo(game, platform, lookupType, gamertag), matchHeatMap(game, platform, matchID), bpProg(game, platform, lookupType, gamertag) };
|
||||||
// Vanguard: { bundleInfo(game, platform, lookupType, gamertag), matchHeatMap(game, platform, matchID), bpProg(game, platform, lookupType, gamertag) };
|
// Vanguard: { bundleInfo(game, platform, lookupType, gamertag), matchHeatMap(game, platform, matchID), bpProg(game, platform, lookupType, gamertag) };
|
||||||
|
Loading…
x
Reference in New Issue
Block a user