domain-reg / lib /token-scheduler.js
cz4ehs
Deploy Zone.ID Domain API 2025-12-07
03cdf80
const { PrismaClient } = require('@prisma/client');
const { ZoneIdAPI } = require('./zoneid-api');
const prisma = new PrismaClient();
const REFRESH_INTERVAL_MS = 3 * 24 * 60 * 60 * 1000;
const REFRESH_CHECK_INTERVAL_MS = 6 * 60 * 60 * 1000;
async function refreshAccountToken(account) {
console.log(`[TokenScheduler] Refreshing token for account: ${account.email}`);
if (!account.refreshToken) {
console.log(`[TokenScheduler] Account ${account.email} has no refresh token, skipping`);
return { success: false, reason: 'no_token' };
}
const api = new ZoneIdAPI();
api.setRefreshTokenCookie(account.refreshToken);
try {
const response = await api.refreshAccessToken();
if (response && response.token) {
console.log(`[TokenScheduler] Successfully refreshed token for ${account.email}`);
await prisma.account.update({
where: { id: account.id },
data: { updatedAt: new Date() }
});
return { success: true };
}
return { success: true, note: 'Token validated' };
} catch (err) {
console.error(`[TokenScheduler] Failed to refresh token for ${account.email}:`, err.message);
if (err.response?.status === 401 || err.message.includes('expired')) {
console.log(`[TokenScheduler] Marking account ${account.email} as needing re-authentication`);
await prisma.account.update({
where: { id: account.id },
data: { status: 'token_expired' }
});
return { success: false, reason: 'token_expired' };
}
return { success: false, reason: err.message };
}
}
async function refreshAllAccountTokens() {
console.log('[TokenScheduler] Starting token refresh cycle for all accounts...');
const accounts = await prisma.account.findMany({
where: {
status: 'active',
refreshToken: { not: null }
}
});
console.log(`[TokenScheduler] Found ${accounts.length} active accounts with tokens`);
const results = {
total: accounts.length,
success: 0,
failed: 0,
skipped: 0,
details: []
};
for (const account of accounts) {
try {
await new Promise(r => setTimeout(r, 2000));
const result = await refreshAccountToken(account);
if (result.success) {
results.success++;
} else if (result.reason === 'no_token') {
results.skipped++;
} else {
results.failed++;
}
results.details.push({
accountId: account.id,
email: account.email,
...result
});
} catch (err) {
console.error(`[TokenScheduler] Unexpected error for ${account.email}:`, err.message);
results.failed++;
results.details.push({
accountId: account.id,
email: account.email,
success: false,
reason: err.message
});
}
}
console.log(`[TokenScheduler] Refresh cycle complete: ${results.success} success, ${results.failed} failed, ${results.skipped} skipped`);
return results;
}
let schedulerInterval = null;
function startTokenScheduler() {
if (schedulerInterval) {
console.log('[TokenScheduler] Scheduler already running');
return;
}
console.log(`[TokenScheduler] Starting scheduler (check interval: ${REFRESH_CHECK_INTERVAL_MS / 1000 / 60 / 60} hours)`);
setTimeout(() => {
refreshAllAccountTokens().catch(err => {
console.error('[TokenScheduler] Initial refresh failed:', err.message);
});
}, 60000);
schedulerInterval = setInterval(() => {
refreshAllAccountTokens().catch(err => {
console.error('[TokenScheduler] Scheduled refresh failed:', err.message);
});
}, REFRESH_CHECK_INTERVAL_MS);
console.log('[TokenScheduler] Scheduler started successfully');
}
function stopTokenScheduler() {
if (schedulerInterval) {
clearInterval(schedulerInterval);
schedulerInterval = null;
console.log('[TokenScheduler] Scheduler stopped');
}
}
module.exports = {
refreshAccountToken,
refreshAllAccountTokens,
startTokenScheduler,
stopTokenScheduler,
REFRESH_INTERVAL_MS,
REFRESH_CHECK_INTERVAL_MS
};