feat(outlook): 添加 Outlook MCP 集成支持并优化分页功能

- 新增 NANO_OUTLOOK_MCP_URL 和 NANO_OUTLOOK_MCP_SERVER_ID 环境变量配置
- 实现 Outlook 邮件和日历的分页查询功能,添加安全参数验证
- 为 app-instance 创建脚本添加 Outlook MCP 服务器 ID 参数
- 更新前端 Outlook 页面实现邮件列表和日历事件的分页浏览
- 添加 Git 忽略文件配置和 Docker 挂载路径修复

BREAKING CHANGE: Outlook 集成现在需要配置 MCP URL 和服务器 ID 环境变量
This commit is contained in:
2026-03-16 17:01:58 +08:00
parent 04501fea22
commit b3767dd4ab
20 changed files with 1671 additions and 83 deletions

View File

@ -4,6 +4,7 @@ const AUTHZ_API_BASE_URL = (process.env.AUTHZ_API_BASE_URL || 'http://127.0.0.1:
const DEPLOY_API_BASE_URL = (process.env.DEPLOY_API_BASE_URL || 'http://127.0.0.1:8090').trim().replace(/\/+$/, '');
const DEPLOY_API_TOKEN = (process.env.DEPLOY_API_TOKEN || '').trim();
const REQUEST_TIMEOUT_MS = 15000;
const REGISTER_REQUEST_TIMEOUT_MS = 90000;
type JsonObject = Record<string, unknown>;
@ -24,9 +25,9 @@ function asString(value: unknown): string {
return typeof value === 'string' ? value.trim() : '';
}
async function fetchJson<T>(url: string, init?: RequestInit): Promise<T> {
async function fetchJson<T>(url: string, init?: RequestInit, timeoutMs = REQUEST_TIMEOUT_MS): Promise<T> {
const controller = new AbortController();
const timeoutId = setTimeout(() => controller.abort(), REQUEST_TIMEOUT_MS);
const timeoutId = setTimeout(() => controller.abort(), timeoutMs);
try {
const response = await fetch(url, {
@ -80,13 +81,15 @@ export async function callDeployControl<T>(path: string, payload: JsonObject): P
});
}
export async function callAuthzService<T>(path: string, payload: JsonObject): Promise<T> {
export async function callAuthzService<T>(path: string, payload: JsonObject, timeoutMs = REQUEST_TIMEOUT_MS): Promise<T> {
return fetchJson<T>(`${AUTHZ_API_BASE_URL}${path}`, {
method: 'POST',
body: JSON.stringify(payload),
});
}, timeoutMs);
}
export { REGISTER_REQUEST_TIMEOUT_MS };
export async function callInstanceApi<T>(apiBaseUrl: string, path: string, payload: JsonObject): Promise<T> {
const baseUrl = apiBaseUrl.trim().replace(/\/+$/, '');
if (!baseUrl) {