- 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
64 lines
2.2 KiB
JavaScript
64 lines
2.2 KiB
JavaScript
/**
|
|
* 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;
|