feat: Add OAuth Device Flow login to bypass Cloudflare
- src/device-login.js: New module implementing Epic Games OAuth Device Flow - src/logger.js: Simple logger module for consistent logging - src/config.js: Add deviceAuthClientId and deviceAuthSecret config - epic-claimer-new.js: Use OAuth Device Flow instead of browser login - Cloudflare bypass: Device Flow uses API, user logs in own browser - Based on: https://github.com/claabs/epicgames-freegames-node How it works: 1. Get client credentials from Epic OAuth API 2. Get device authorization code with verification URL 3. Send user notification with login link 4. User clicks link and logs in (handles Cloudflare manually) 5. Poll for authorization completion 6. Save and use access/refresh tokens 7. Tokens auto-refresh on expiry Benefits: - No Cloudflare issues (no bot detection) - Persistent tokens (no repeated logins) - Works in headless mode - More reliable than browser automation
This commit is contained in:
parent
f1d647bcb2
commit
393f70d409
4 changed files with 361 additions and 103 deletions
64
src/logger.js
Normal file
64
src/logger.js
Normal file
|
|
@ -0,0 +1,64 @@
|
|||
/**
|
||||
* Simple logger for free-games-claimer
|
||||
*/
|
||||
|
||||
const LOG_LEVELS = {
|
||||
trace: 0,
|
||||
debug: 1,
|
||||
info: 2,
|
||||
warn: 3,
|
||||
error: 4,
|
||||
};
|
||||
|
||||
const currentLevel = process.env.LOG_LEVEL
|
||||
? LOG_LEVELS[process.env.LOG_LEVEL.toLowerCase()]
|
||||
: LOG_LEVELS.info;
|
||||
|
||||
function formatMessage(level, module, message, data) {
|
||||
const timestamp = new Date().toISOString();
|
||||
const moduleStr = module ? `[${module}] ` : '';
|
||||
const dataStr = data && Object.keys(data).length > 0 ? ' ' + JSON.stringify(data) : '';
|
||||
return `${timestamp} ${level.toUpperCase().padEnd(5)} ${moduleStr}${message}${dataStr}`;
|
||||
}
|
||||
|
||||
function createLogger(module) {
|
||||
return {
|
||||
trace: (dataOrMessage, message) => {
|
||||
if (currentLevel <= LOG_LEVELS.trace) {
|
||||
const [data, msg] = typeof dataOrMessage === 'string' ? [null, dataOrMessage] : [dataOrMessage, message];
|
||||
console.log(formatMessage('trace', module, msg || '', data));
|
||||
}
|
||||
},
|
||||
debug: (dataOrMessage, message) => {
|
||||
if (currentLevel <= LOG_LEVELS.debug) {
|
||||
const [data, msg] = typeof dataOrMessage === 'string' ? [null, dataOrMessage] : [dataOrMessage, message];
|
||||
console.log(formatMessage('debug', module, msg || '', data));
|
||||
}
|
||||
},
|
||||
info: (dataOrMessage, message) => {
|
||||
if (currentLevel <= LOG_LEVELS.info) {
|
||||
const [data, msg] = typeof dataOrMessage === 'string' ? [null, dataOrMessage] : [dataOrMessage, message];
|
||||
console.log(formatMessage('info', module, msg || '', data));
|
||||
}
|
||||
},
|
||||
warn: (dataOrMessage, message) => {
|
||||
if (currentLevel <= LOG_LEVELS.warn) {
|
||||
const [data, msg] = typeof dataOrMessage === 'string' ? [null, dataOrMessage] : [dataOrMessage, message];
|
||||
console.log(formatMessage('warn', module, msg || '', data));
|
||||
}
|
||||
},
|
||||
error: (dataOrMessage, message) => {
|
||||
if (currentLevel <= LOG_LEVELS.error) {
|
||||
const [data, msg] = typeof dataOrMessage === 'string' ? [null, dataOrMessage] : [dataOrMessage, message];
|
||||
console.log(formatMessage('error', module, msg || '', data));
|
||||
}
|
||||
},
|
||||
child: childData => {
|
||||
const childModule = childData?.module || module;
|
||||
return createLogger(childModule);
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
const logger = createLogger('root');
|
||||
export default logger;
|
||||
Loading…
Add table
Add a link
Reference in a new issue