github-actions[bot] commited on
Commit
8314b51
·
1 Parent(s): 8e1e21b

Update from GitHub Actions

Browse files
functions/api/mail/activate.ts ADDED
@@ -0,0 +1,86 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+
2
+ import { authApiToken, authMiddleware } from "../../utils/auth.js";
3
+ import { addCorsHeaders } from "../../utils/cors.js";
4
+ import { get_access_token, activateMailbox, syncMailbox } from '../../utils/mail';
5
+
6
+ export const onRequest = async (context: RouteContext): Promise<Response> => {
7
+ const request = context.request;
8
+ const env: Env = context.env;
9
+
10
+ const authResponse = await authMiddleware(request, env);
11
+ const apiResponse = await authApiToken(request, env);
12
+ if (authResponse && apiResponse) {
13
+ return addCorsHeaders(authResponse);
14
+ }
15
+
16
+ if (request.method === 'OPTIONS') {
17
+ return new Response(null, {
18
+ status: 200,
19
+ headers: {
20
+ 'Access-Control-Allow-Origin': '*',
21
+ 'Access-Control-Allow-Methods': 'POST, OPTIONS',
22
+ 'Access-Control-Allow-Headers': 'Content-Type, Authorization'
23
+ }
24
+ });
25
+ }
26
+
27
+ if (request.method !== 'POST') {
28
+ return new Response('Method not allowed', { status: 405 });
29
+ }
30
+
31
+ try {
32
+ const { email } = await request.json() as any;
33
+ if (!email) {
34
+ throw new Error("Email is required");
35
+ }
36
+
37
+ // 从KV获取刷新令牌
38
+ const tokenInfoStr = await env.KV.get(`refresh_token_${email}`);
39
+ if (!tokenInfoStr) {
40
+ throw new Error("No refresh token found for this email");
41
+ }
42
+
43
+ const tokenInfo = JSON.parse(tokenInfoStr);
44
+ const access_token = await get_access_token(tokenInfo, env.ENTRA_CLIENT_ID, env.ENTRA_CLIENT_SECRET);
45
+
46
+ // 执行邮箱激活操作
47
+ console.log(`开始激活邮箱: ${email}`);
48
+ await activateMailbox(access_token);
49
+ await syncMailbox(access_token);
50
+
51
+ // 等待同步完成
52
+ await new Promise(resolve => setTimeout(resolve, 3000));
53
+
54
+ return new Response(
55
+ JSON.stringify({
56
+ success: true,
57
+ message: "邮箱激活完成",
58
+ email: email,
59
+ timestamp: new Date().toISOString()
60
+ }),
61
+ {
62
+ status: 200,
63
+ headers: {
64
+ 'Content-Type': 'application/json',
65
+ 'Access-Control-Allow-Origin': '*'
66
+ }
67
+ }
68
+ );
69
+ } catch (error: any) {
70
+ console.error('邮箱激活失败:', error);
71
+ return new Response(
72
+ JSON.stringify({
73
+ success: false,
74
+ error: error.message,
75
+ message: "邮箱激活失败"
76
+ }),
77
+ {
78
+ status: 500,
79
+ headers: {
80
+ 'Content-Type': 'application/json',
81
+ 'Access-Control-Allow-Origin': '*'
82
+ }
83
+ }
84
+ );
85
+ }
86
+ };
functions/api/mail/login.ts CHANGED
@@ -19,7 +19,7 @@ export const onRequest = async (context: RouteContext): Promise<Response> => {
19
  }
20
 
21
  const authService = new AuthService(env);
22
- const result = await authService.authenticateEmail(email);
23
 
24
  if (!result.success) {
25
  throw new Error(result.error);
 
19
  }
20
 
21
  const authService = new AuthService(env);
22
+ const result = await authService.loginMail(email);
23
 
24
  if (!result.success) {
25
  throw new Error(result.error);
functions/api/mail/new.ts CHANGED
@@ -41,7 +41,7 @@ export const onRequest = async (context: RouteContext): Promise<Response> => {
41
  }
42
  const tokenInfo = JSON.parse(tokenInfoStr);
43
  const access_token = await get_access_token(tokenInfo, env.ENTRA_CLIENT_ID, env.ENTRA_CLIENT_SECRET);
44
- const emails = await getEmails(access_token, 1); // 只获取最新的一封邮件
45
  return new Response(
46
  JSON.stringify(emails[0] || null),
47
  {
 
41
  }
42
  const tokenInfo = JSON.parse(tokenInfoStr);
43
  const access_token = await get_access_token(tokenInfo, env.ENTRA_CLIENT_ID, env.ENTRA_CLIENT_SECRET);
44
+ const emails = await getEmails(access_token, 1, true); // 只获取最新的一封邮件,强制激活邮箱
45
  return new Response(
46
  JSON.stringify(emails[0] || null),
47
  {
functions/utils/authService.ts CHANGED
@@ -66,6 +66,31 @@ export class AuthService {
66
  `&state=${email}`;
67
  }
68
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
69
  private async handleLoginProcess(page: Page, account: Account, authUrl: string) {
70
  await page.goto(authUrl);
71
  await page.fill('input[type="email"]', account.email);
 
66
  `&state=${email}`;
67
  }
68
 
69
+ public async loginMail(email: string): Promise<{ success: boolean; error?: string }> {
70
+ try {
71
+ const accountsStr = await this.env.KV.get("accounts");
72
+ const accounts: Account[] = accountsStr ? JSON.parse(accountsStr) : [];
73
+ const account = accounts.find(a => a.email === email);
74
+
75
+ if (!account) {
76
+ throw new Error("Account not found");
77
+ }
78
+ const browser = await BrowserManager.getInstance();
79
+ const context = await browser.newContext();
80
+ const page = await context.newPage();
81
+ await this.handleLoginProcess(page, account, "https://outlook.live.com/mail/0/?prompt=select_account");
82
+ await this.handleMultiFactorAuth(page, account);
83
+ await this.confirmLogin(page, account);
84
+
85
+ return { success: true };
86
+ } catch (error: any) {
87
+ return {
88
+ success: false,
89
+ error: error.message
90
+ };
91
+ }
92
+ }
93
+
94
  private async handleLoginProcess(page: Page, account: Account, authUrl: string) {
95
  await page.goto(authUrl);
96
  await page.fill('input[type="email"]', account.email);
functions/utils/mail.ts CHANGED
@@ -172,13 +172,100 @@ async function parseEmail(email: any): Promise<ParsedEmail> {
172
  }
173
  }
174
 
175
- export async function getEmails(accessToken: string, limit = 50): Promise<ParsedEmail[]> {
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
176
  const endpoint = 'https://graph.microsoft.com/v1.0/me/messages';
177
- const response = await fetch(`${endpoint}?$top=${limit}`, {
 
 
 
 
 
 
 
 
178
  method: 'GET',
179
  headers: {
180
  'Authorization': `Bearer ${accessToken}`,
181
- 'Content-Type': 'application/json'
 
182
  }
183
  });
184
 
 
172
  }
173
  }
174
 
175
+ /**
176
+ * 激活邮箱 - 通过多种方式唤醒可能休眠的邮箱
177
+ */
178
+ export async function activateMailbox(accessToken: string): Promise<void> {
179
+ try {
180
+ // 方法1: 获取用户配置文件信息 - 这会触发用户会话
181
+ await fetch('https://graph.microsoft.com/v1.0/me', {
182
+ method: 'GET',
183
+ headers: {
184
+ 'Authorization': `Bearer ${accessToken}`,
185
+ 'Content-Type': 'application/json'
186
+ }
187
+ });
188
+
189
+ // 方法2: 获取邮箱设置 - 这会激活邮箱服务
190
+ await fetch('https://graph.microsoft.com/v1.0/me/mailboxSettings', {
191
+ method: 'GET',
192
+ headers: {
193
+ 'Authorization': `Bearer ${accessToken}`,
194
+ 'Content-Type': 'application/json'
195
+ }
196
+ });
197
+
198
+ // 方法3: 获取邮件文件夹 - 这会触发邮箱同步
199
+ await fetch('https://graph.microsoft.com/v1.0/me/mailFolders', {
200
+ method: 'GET',
201
+ headers: {
202
+ 'Authorization': `Bearer ${accessToken}`,
203
+ 'Content-Type': 'application/json'
204
+ }
205
+ });
206
+
207
+ // 方法4: 检查收件箱状态
208
+ await fetch('https://graph.microsoft.com/v1.0/me/mailFolders/inbox', {
209
+ method: 'GET',
210
+ headers: {
211
+ 'Authorization': `Bearer ${accessToken}`,
212
+ 'Content-Type': 'application/json'
213
+ }
214
+ });
215
+
216
+ console.log('邮箱激活操作完成');
217
+ } catch (error) {
218
+ console.warn('邮箱激活过程中出现错误:', error);
219
+ // 不抛出错误,因为激活失败不应该阻止后续的邮件获取
220
+ }
221
+ }
222
+
223
+ /**
224
+ * 强制同步邮箱 - 使用delta查询来触发同步
225
+ */
226
+ export async function syncMailbox(accessToken: string): Promise<void> {
227
+ try {
228
+ // 使用delta查询来强制同步邮箱
229
+ const deltaEndpoint = 'https://graph.microsoft.com/v1.0/me/messages/delta';
230
+ await fetch(`${deltaEndpoint}?$top=1`, {
231
+ method: 'GET',
232
+ headers: {
233
+ 'Authorization': `Bearer ${accessToken}`,
234
+ 'Content-Type': 'application/json'
235
+ }
236
+ });
237
+
238
+ console.log('邮箱同步操作完成');
239
+ } catch (error) {
240
+ console.warn('邮箱同步过程中出现错误:', error);
241
+ }
242
+ }
243
+
244
+ export async function getEmails(accessToken: string, limit = 50, forceActivate = false): Promise<ParsedEmail[]> {
245
+ // 如果需要强制激活邮箱
246
+ if (forceActivate) {
247
+ await activateMailbox(accessToken);
248
+ await syncMailbox(accessToken);
249
+
250
+ // 等待一小段时间让同步生效
251
+ await new Promise(resolve => setTimeout(resolve, 2000));
252
+ }
253
+
254
  const endpoint = 'https://graph.microsoft.com/v1.0/me/messages';
255
+
256
+ // 添加更多查询参数来确保获取最新邮件
257
+ const queryParams = new URLSearchParams({
258
+ '$top': limit.toString(),
259
+ '$orderby': 'receivedDateTime desc',
260
+ '$select': 'id,subject,from,toRecipients,createdDateTime,receivedDateTime,sentDateTime,lastModifiedDateTime,body,importance,isRead,isDraft,hasAttachments,webLink,bodyPreview,categories,internetMessageId'
261
+ });
262
+
263
+ const response = await fetch(`${endpoint}?${queryParams}`, {
264
  method: 'GET',
265
  headers: {
266
  'Authorization': `Bearer ${accessToken}`,
267
+ 'Content-Type': 'application/json',
268
+ 'Prefer': 'outlook.timezone="Asia/Shanghai"' // 设置时区
269
  }
270
  });
271
 
functions/utils/mailboxActivator.ts ADDED
@@ -0,0 +1,244 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /**
2
+ * 邮箱激活器 - 专门处理邮箱休眠问题
3
+ */
4
+
5
+ import { get_access_token, getEmails, activateMailbox, syncMailbox } from './mail';
6
+
7
+ export interface ActivationResult {
8
+ success: boolean;
9
+ activated: boolean;
10
+ emailCount: number;
11
+ latestEmailTime?: string;
12
+ error?: string;
13
+ activationMethods: string[];
14
+ }
15
+
16
+ export class MailboxActivator {
17
+ private accessToken: string;
18
+
19
+ constructor(accessToken: string) {
20
+ this.accessToken = accessToken;
21
+ }
22
+
23
+ /**
24
+ * 检测邮箱是否可能处于休眠状态
25
+ */
26
+ async detectDormantState(): Promise<{ isDormant: boolean; reason: string }> {
27
+ try {
28
+ // 1. 尝试获取最新邮件
29
+ const emails = await getEmails(this.accessToken, 5, false);
30
+
31
+ if (emails.length === 0) {
32
+ return { isDormant: true, reason: "邮箱中没有邮件" };
33
+ }
34
+
35
+ // 2. 检查最新邮件的时间
36
+ const latestEmail = emails[0];
37
+ const latestTime = new Date(latestEmail.date.received || latestEmail.date.created);
38
+ const now = new Date();
39
+ const hoursDiff = (now.getTime() - latestTime.getTime()) / (1000 * 60 * 60);
40
+
41
+ // 如果最新邮件超过24小时,可能处于休眠状态
42
+ if (hoursDiff > 24) {
43
+ return { isDormant: true, reason: `最新邮件时间过旧: ${hoursDiff.toFixed(1)}小时前` };
44
+ }
45
+
46
+ // 3. 检查邮件数量是否异常少
47
+ if (emails.length < 3) {
48
+ return { isDormant: true, reason: "邮件数量异常少" };
49
+ }
50
+
51
+ return { isDormant: false, reason: "邮箱状态正常" };
52
+ } catch (error) {
53
+ return { isDormant: true, reason: `检测失败: ${error}` };
54
+ }
55
+ }
56
+
57
+ /**
58
+ * 执行全面的邮箱激活
59
+ */
60
+ async performFullActivation(): Promise<ActivationResult> {
61
+ const activationMethods: string[] = [];
62
+ let activated = false;
63
+
64
+ try {
65
+ console.log('开始执行邮箱激活...');
66
+
67
+ // 方法1: 基础激活
68
+ try {
69
+ await activateMailbox(this.accessToken);
70
+ activationMethods.push('基础激活');
71
+ } catch (error) {
72
+ console.warn('基础激活失败:', error);
73
+ }
74
+
75
+ // 方法2: 强制同步
76
+ try {
77
+ await syncMailbox(this.accessToken);
78
+ activationMethods.push('强制同步');
79
+ } catch (error) {
80
+ console.warn('强制同步失败:', error);
81
+ }
82
+
83
+ // 方法3: 深度激活 - 访问多个端点
84
+ try {
85
+ await this.deepActivation();
86
+ activationMethods.push('深度激活');
87
+ } catch (error) {
88
+ console.warn('深度激活失败:', error);
89
+ }
90
+
91
+ // 方法4: 模拟用户活动
92
+ try {
93
+ await this.simulateUserActivity();
94
+ activationMethods.push('模拟用户活动');
95
+ } catch (error) {
96
+ console.warn('模拟用户活动失败:', error);
97
+ }
98
+
99
+ // 等待激活生效
100
+ await new Promise(resolve => setTimeout(resolve, 5000));
101
+
102
+ // 验证激活效果
103
+ const emails = await getEmails(this.accessToken, 10, false);
104
+ const emailCount = emails.length;
105
+ const latestEmailTime = emails.length > 0 ? emails[0].date.received : undefined;
106
+
107
+ activated = activationMethods.length > 0;
108
+
109
+ return {
110
+ success: true,
111
+ activated,
112
+ emailCount,
113
+ latestEmailTime,
114
+ activationMethods
115
+ };
116
+
117
+ } catch (error: any) {
118
+ return {
119
+ success: false,
120
+ activated: false,
121
+ emailCount: 0,
122
+ error: error.message,
123
+ activationMethods
124
+ };
125
+ }
126
+ }
127
+
128
+ /**
129
+ * 深度激活 - 访问更多Microsoft Graph端点
130
+ */
131
+ private async deepActivation(): Promise<void> {
132
+ const endpoints = [
133
+ 'https://graph.microsoft.com/v1.0/me/calendar',
134
+ 'https://graph.microsoft.com/v1.0/me/contacts',
135
+ 'https://graph.microsoft.com/v1.0/me/drive',
136
+ 'https://graph.microsoft.com/v1.0/me/mailFolders/inbox/messages?$top=1',
137
+ 'https://graph.microsoft.com/v1.0/me/mailFolders/sentitems',
138
+ 'https://graph.microsoft.com/v1.0/me/mailFolders/drafts'
139
+ ];
140
+
141
+ const promises = endpoints.map(endpoint =>
142
+ fetch(endpoint, {
143
+ method: 'GET',
144
+ headers: {
145
+ 'Authorization': `Bearer ${this.accessToken}`,
146
+ 'Content-Type': 'application/json'
147
+ }
148
+ }).catch(error => {
149
+ console.warn(`访问端点失败 ${endpoint}:`, error);
150
+ })
151
+ );
152
+
153
+ await Promise.allSettled(promises);
154
+ }
155
+
156
+ /**
157
+ * 模拟用户活动
158
+ */
159
+ private async simulateUserActivity(): Promise<void> {
160
+ try {
161
+ // 1. 获取邮箱设置
162
+ await fetch('https://graph.microsoft.com/v1.0/me/mailboxSettings', {
163
+ method: 'GET',
164
+ headers: {
165
+ 'Authorization': `Bearer ${this.accessToken}`,
166
+ 'Content-Type': 'application/json'
167
+ }
168
+ });
169
+
170
+ // 2. 获取用户照片(触发用户会话)
171
+ await fetch('https://graph.microsoft.com/v1.0/me/photo', {
172
+ method: 'GET',
173
+ headers: {
174
+ 'Authorization': `Bearer ${this.accessToken}`
175
+ }
176
+ }).catch(() => {}); // 忽略错误,因为用户可能没有照片
177
+
178
+ // 3. 获取最近活动
179
+ await fetch('https://graph.microsoft.com/v1.0/me/activities/recent', {
180
+ method: 'GET',
181
+ headers: {
182
+ 'Authorization': `Bearer ${this.accessToken}`,
183
+ 'Content-Type': 'application/json'
184
+ }
185
+ }).catch(() => {}); // 忽略错误
186
+
187
+ // 4. 检查邮件规则
188
+ await fetch('https://graph.microsoft.com/v1.0/me/mailFolders/inbox/messageRules', {
189
+ method: 'GET',
190
+ headers: {
191
+ 'Authorization': `Bearer ${this.accessToken}`,
192
+ 'Content-Type': 'application/json'
193
+ }
194
+ }).catch(() => {}); // 忽略错误
195
+
196
+ } catch (error) {
197
+ console.warn('模拟用户活动时出错:', error);
198
+ }
199
+ }
200
+
201
+ /**
202
+ * 智能激活 - 根据检测结果决定激活策略
203
+ */
204
+ async smartActivation(): Promise<ActivationResult> {
205
+ // 首先检测邮箱状态
206
+ const dormantCheck = await this.detectDormantState();
207
+
208
+ if (!dormantCheck.isDormant) {
209
+ // 邮箱状态正常,只做轻量级激活
210
+ try {
211
+ await activateMailbox(this.accessToken);
212
+ const emails = await getEmails(this.accessToken, 5, false);
213
+
214
+ return {
215
+ success: true,
216
+ activated: true,
217
+ emailCount: emails.length,
218
+ latestEmailTime: emails.length > 0 ? emails[0].date.received : undefined,
219
+ activationMethods: ['轻量级激活']
220
+ };
221
+ } catch (error: any) {
222
+ return {
223
+ success: false,
224
+ activated: false,
225
+ emailCount: 0,
226
+ error: error.message,
227
+ activationMethods: []
228
+ };
229
+ }
230
+ } else {
231
+ // 邮箱可能休眠,执行全面激活
232
+ console.log(`检测到邮箱可能休眠: ${dormantCheck.reason}`);
233
+ return await this.performFullActivation();
234
+ }
235
+ }
236
+ }
237
+
238
+ /**
239
+ * 便捷函数:激活指定邮箱
240
+ */
241
+ export async function activateMailboxSmart(accessToken: string): Promise<ActivationResult> {
242
+ const activator = new MailboxActivator(accessToken);
243
+ return await activator.smartActivation();
244
+ }
index.ts CHANGED
@@ -14,12 +14,14 @@ import { fileURLToPath } from 'url'
14
  import { dirname } from 'path'
15
  import { getTenantAccessToken, sendFeishuMessageText } from './functions/utils/feishu.js'
16
  import { get_access_token, getEmails } from './functions/utils/mail.js'
 
17
 
18
  // 导入所有路由处理函数
19
  import { onRequest as handleAccount } from './functions/api/account.js'
20
  import { onRequest as handleLogin } from './functions/api/login.js'
21
  import { onRequest as handleSetting } from './functions/api/setting.js'
22
  import { onRequest as handleIP } from './functions/api/ip.js'
 
23
  import { onRequest as handleMailAuth } from './functions/api/mail/auth.js'
24
  import { onRequest as handleMailCallback } from './functions/api/mail/callback.js'
25
  import { onRequest as handleMailAll } from './functions/api/mail/all.js'
@@ -27,6 +29,7 @@ import { onRequest as handleMailNew } from './functions/api/mail/new.js'
27
  import { onRequest as handleMailSend } from './functions/api/mail/send.js'
28
  import { onRequest as handleBatch } from './functions/api/mail/batch.js'
29
  import { onRequest as handleMailStatus } from './functions/api/mail/status.js'
 
30
  dotenv.config({ path: ['.env', '.env.local'], override: true });
31
  const isDev = process.env.NODE_ENV === 'development'
32
 
@@ -139,6 +142,9 @@ app.all('/api/*', async (c) => {
139
  case '/api/ip':
140
  response = await handleIP(context);
141
  break;
 
 
 
142
  case '/api/mail/auth':
143
  response = await handleMailAuth(context);
144
  break;
@@ -160,6 +166,9 @@ app.all('/api/*', async (c) => {
160
  case '/api/mail/batch':
161
  response = await handleBatch(context);
162
  break;
 
 
 
163
  default:
164
  return c.json({ error: 'Route not found' }, 404);
165
  }
@@ -245,8 +254,13 @@ async function checkEmailsForNewMessages(env: Env) {
245
  const tokenInfo = JSON.parse(tokenInfoStr);
246
  const access_token = await get_access_token(tokenInfo, env.ENTRA_CLIENT_ID, env.ENTRA_CLIENT_SECRET);
247
 
 
 
 
 
 
248
  // 获取最新邮件
249
- const emails = await getEmails(access_token, 1);
250
  if (emails.length === 0) {
251
  console.log(`邮箱 ${monitor.email} 没有邮件`);
252
  continue;
 
14
  import { dirname } from 'path'
15
  import { getTenantAccessToken, sendFeishuMessageText } from './functions/utils/feishu.js'
16
  import { get_access_token, getEmails } from './functions/utils/mail.js'
17
+ import { activateMailboxSmart } from './functions/utils/mailboxActivator.js'
18
 
19
  // 导入所有路由处理函数
20
  import { onRequest as handleAccount } from './functions/api/account.js'
21
  import { onRequest as handleLogin } from './functions/api/login.js'
22
  import { onRequest as handleSetting } from './functions/api/setting.js'
23
  import { onRequest as handleIP } from './functions/api/ip.js'
24
+ import { onRequest as handleMailLogin } from './functions/api/mail/login.js'
25
  import { onRequest as handleMailAuth } from './functions/api/mail/auth.js'
26
  import { onRequest as handleMailCallback } from './functions/api/mail/callback.js'
27
  import { onRequest as handleMailAll } from './functions/api/mail/all.js'
 
29
  import { onRequest as handleMailSend } from './functions/api/mail/send.js'
30
  import { onRequest as handleBatch } from './functions/api/mail/batch.js'
31
  import { onRequest as handleMailStatus } from './functions/api/mail/status.js'
32
+ import { onRequest as handleMailActivate } from './functions/api/mail/activate.js'
33
  dotenv.config({ path: ['.env', '.env.local'], override: true });
34
  const isDev = process.env.NODE_ENV === 'development'
35
 
 
142
  case '/api/ip':
143
  response = await handleIP(context);
144
  break;
145
+ case '/api/mail/login':
146
+ response = await handleMailLogin(context);
147
+ break;
148
  case '/api/mail/auth':
149
  response = await handleMailAuth(context);
150
  break;
 
166
  case '/api/mail/batch':
167
  response = await handleBatch(context);
168
  break;
169
+ case '/api/mail/activate':
170
+ response = await handleMailActivate(context);
171
+ break;
172
  default:
173
  return c.json({ error: 'Route not found' }, 404);
174
  }
 
254
  const tokenInfo = JSON.parse(tokenInfoStr);
255
  const access_token = await get_access_token(tokenInfo, env.ENTRA_CLIENT_ID, env.ENTRA_CLIENT_SECRET);
256
 
257
+ // 使用智能激活器激活邮箱
258
+ console.log(`开始智能激活邮箱: ${monitor.email}`);
259
+ const activationResult = await activateMailboxSmart(access_token);
260
+ console.log(`邮箱 ${monitor.email} 激活结果:`, activationResult);
261
+
262
  // 获取最新邮件
263
+ const emails = await getEmails(access_token, 1, false);
264
  if (emails.length === 0) {
265
  console.log(`邮箱 ${monitor.email} 没有邮件`);
266
  continue;
src/services/mailApi.ts CHANGED
@@ -38,6 +38,18 @@ export const mailApi = {
38
  return handleResponse(response);
39
  },
40
 
 
 
 
 
 
 
 
 
 
 
 
 
41
  async getLatestMails(email: string) {
42
  const response = await fetch(
43
  `${API_BASE_URL}/api/mail/new`,
 
38
  return handleResponse(response);
39
  },
40
 
41
+ async activateMailbox(email: string) {
42
+ const response = await fetch(
43
+ `${API_BASE_URL}/api/mail/activate`,
44
+ {
45
+ headers: getHeaders(),
46
+ method: 'POST',
47
+ body: JSON.stringify({ email })
48
+ }
49
+ );
50
+ return handleResponse(response);
51
+ },
52
+
53
  async getLatestMails(email: string) {
54
  const response = await fetch(
55
  `${API_BASE_URL}/api/mail/new`,
src/views/MailView.vue CHANGED
@@ -32,6 +32,7 @@ const columns = [
32
  const actionOptions = (row: Account) => [
33
  { content: '查看认证', value: 'check', onClick: () => handleCheckAuth(row) },
34
  { content: '刷新认证', value: 'refresh', onClick: () => handleRefreshAuth(row) },
 
35
  { content: '最新邮件', value: 'latest', onClick: () => handleLatestMails(row) },
36
  { content: '所有邮件', value: 'all', onClick: () => handleAllMails(row) },
37
  { content: '发送邮件', value: 'send', onClick: () => handleSendMail(row) },
@@ -271,6 +272,23 @@ const handleLoginMail = async (row: Account) => {
271
  }
272
  };
273
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
274
 
275
  </script>
276
 
@@ -292,6 +310,7 @@ const handleLoginMail = async (row: Account) => {
292
  <div class="hidden md:flex flex-wrap gap-2">
293
  <t-button size="small" variant="outline" @click="handleCheckAuth(row)">查看认证</t-button>
294
  <t-button size="small" variant="outline" @click="handleRefreshAuth(row)">刷新认证</t-button>
 
295
  <t-button size="small" variant="outline" @click="handleLatestMails(row)">最新邮件</t-button>
296
  <t-button size="small" variant="outline" @click="handleAllMails(row)">所有邮件</t-button>
297
  <t-button size="small" variant="outline" @click="handleSendMail(row)">发送邮件</t-button>
 
32
  const actionOptions = (row: Account) => [
33
  { content: '查看认证', value: 'check', onClick: () => handleCheckAuth(row) },
34
  { content: '刷新认证', value: 'refresh', onClick: () => handleRefreshAuth(row) },
35
+ { content: '激活邮箱', value: 'activate', onClick: () => handleActivateMailbox(row) },
36
  { content: '最新邮件', value: 'latest', onClick: () => handleLatestMails(row) },
37
  { content: '所有邮件', value: 'all', onClick: () => handleAllMails(row) },
38
  { content: '发送邮件', value: 'send', onClick: () => handleSendMail(row) },
 
272
  }
273
  };
274
 
275
+ // 添加激活邮箱处理函数
276
+ const handleActivateMailbox = async (row: Account) => {
277
+ try {
278
+ loading.value = true;
279
+ const result = await mailApi.activateMailbox(row.email);
280
+ if (result.success) {
281
+ MessagePlugin.success(`邮箱激活成功: ${result.message}`);
282
+ } else {
283
+ MessagePlugin.error(`邮箱激活失败: ${result.message}`);
284
+ }
285
+ } catch (error: any) {
286
+ MessagePlugin.error(`邮箱激活失败: ${error.message}`);
287
+ } finally {
288
+ loading.value = false;
289
+ }
290
+ };
291
+
292
 
293
  </script>
294
 
 
310
  <div class="hidden md:flex flex-wrap gap-2">
311
  <t-button size="small" variant="outline" @click="handleCheckAuth(row)">查看认证</t-button>
312
  <t-button size="small" variant="outline" @click="handleRefreshAuth(row)">刷新认证</t-button>
313
+ <t-button size="small" variant="outline" @click="handleActivateMailbox(row)" theme="warning">激活邮箱</t-button>
314
  <t-button size="small" variant="outline" @click="handleLatestMails(row)">最新邮件</t-button>
315
  <t-button size="small" variant="outline" @click="handleAllMails(row)">所有邮件</t-button>
316
  <t-button size="small" variant="outline" @click="handleSendMail(row)">发送邮件</t-button>