diff --git a/epic-claimer-new.js b/epic-claimer-new.js index 2b82ef2..31cd309 100644 --- a/epic-claimer-new.js +++ b/epic-claimer-new.js @@ -47,11 +47,16 @@ const fetchFreeGamesAPI = async () => { const pollForTokens = async (deviceCode, maxAttempts = 30) => { for (let i = 0; i < maxAttempts; i++) { try { - const response = await axios.post('https://account-public-service-prod.ol.epicgames.com/account/api/oauth/token', { - grant_type: 'urn:ietf:params:oauth:grant-type:device_code', - device_code: deviceCode, - client_id: '98f7e42c2e3a4f86a74eb43fbb41ed39', - client_secret: '0a2449a2-001a-451e-afec-3e812901c4d7', + const params = new URLSearchParams(); + params.append('grant_type', 'urn:ietf:params:oauth:grant-type:device_code'); + params.append('device_code', deviceCode); + params.append('client_id', '98f7e42c2e3a4f86a74eb43fbb41ed39'); + params.append('client_secret', '0a2449a2-001a-451e-afec-3e812901c4d7'); + + const response = await axios.post('https://account-public-service-prod.ol.epicgames.com/account/api/oauth/token', params.toString(), { + headers: { + 'Content-Type': 'application/x-www-form-urlencoded', + }, }); if (response.data?.access_token) { console.log('✅ OAuth successful'); @@ -84,6 +89,48 @@ const exchangeTokenForCookies = async accessToken => { return cookies; }; +// Get client credentials token (first step of OAuth flow) +const getClientCredentialsToken = async () => { + try { + const response = await axios.post('https://account-public-service-prod.ol.epicgames.com/account/api/oauth/token', { + grant_type: 'client_credentials', + }, { + auth: { + username: '98f7e42c2e3a4f86a74eb43fbb41ed39', + password: '0a2449a2-001a-451e-afec-3e812901c4d7', + }, + headers: { + 'Content-Type': 'application/x-www-form-urlencoded', + }, + }); + return response.data.access_token; + } catch (error) { + console.error('Failed to get client credentials token:', error.response?.status || error.message); + throw error; + } +}; + +// Get device authorization code (second step of OAuth flow) +const getDeviceAuthorizationCode = async (clientCredentialsToken) => { + try { + const params = new URLSearchParams(); + params.append('prompt', 'login'); + + const response = await axios.post('https://account-public-service-prod.ol.epicgames.com/account/api/oauth/deviceAuthorization', params.toString(), { + headers: { + Authorization: `Bearer ${clientCredentialsToken}`, + 'Content-Type': 'application/x-www-form-urlencoded', + }, + }); + console.log('Device authorization response:', response.data); + return response.data; + } catch (error) { + console.error('Failed to get device authorization code:', error.response?.status || error.message); + console.error('Error response data:', error.response?.data); + throw error; + } +}; + // Get valid authentication const getValidAuth = async ({ otpKey, reuseCookies, cookiesPath }) => { if (reuseCookies && existsSync(cookiesPath)) { @@ -96,25 +143,13 @@ const getValidAuth = async ({ otpKey, reuseCookies, cookiesPath }) => { } console.log('🔐 Starting fresh OAuth device flow (manual approval required)...'); - let deviceResponse; - try { - const params = new URLSearchParams(); - params.append('clientId', '98f7e42c2e3a4f86a74eb43fbb41ed39'); - params.append('clientSecret', '0a2449a2-001a-451e-afec-3e812901c4d7'); - params.append('scope', 'account.basicprofile account.userentitlements'); + // Step 1: Get client credentials token + const clientCredentialsToken = await getClientCredentialsToken(); + console.log('✅ Got client credentials token'); - deviceResponse = await axios.post('https://account-public-service-prod.ol.epicgames.com/account/api/oauth/deviceAuthorization', params.toString(), { - headers: { - 'Content-Type': 'application/x-www-form-urlencoded', - }, - }); - } catch (error) { - console.error('Device code flow failed (fallback to manual login):', error.response?.status || error.message); - return { bearerToken: null, cookies: [] }; - } - - const { deviceCode, userCode, verificationUriComplete } = deviceResponse.data; + // Step 2: Get device authorization code + const { deviceCode, userCode, verificationUriComplete } = await getDeviceAuthorizationCode(clientCredentialsToken); console.log(`📱 Open: ${verificationUriComplete}`); console.log(`💳 Code: ${userCode}`); @@ -124,11 +159,16 @@ const getValidAuth = async ({ otpKey, reuseCookies, cookiesPath }) => { const totpCode = authenticator.generate(otpKey); console.log(`🔑 TOTP Code (generated): ${totpCode}`); try { - const refreshed = await axios.post('https://account-public-service-prod.ol.epicgames.com/account/api/oauth/token', { - grant_type: 'refresh_token', - refresh_token: tokens.refresh_token, - client_id: '98f7e42c2e3a4f86a74eb43fbb41ed39', - client_secret: '0a2449a2-001a-451e-afec-3e812901c4d7', + const params = new URLSearchParams(); + params.append('grant_type', 'refresh_token'); + params.append('refresh_token', tokens.refresh_token); + params.append('client_id', '98f7e42c2e3a4f86a74eb43fbb41ed39'); + params.append('client_secret', '0a2449a2-001a-451e-afec-3e812901c4d7'); + + const refreshed = await axios.post('https://account-public-service-prod.ol.epicgames.com/account/api/oauth/token', params.toString(), { + headers: { + 'Content-Type': 'application/x-www-form-urlencoded', + }, }); tokens.access_token = refreshed.data.access_token; } catch {