File size: 4,151 Bytes
03cdf80
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
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
};