@zhin.js/plugin-calendar 0.0.0-stage → 0.1.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +189 -2
- package/commands/calendar/auth/index.js +26 -0
- package/commands/calendar/auth/index.ts +29 -0
- package/commands/calendar/logout/index.js +18 -0
- package/commands/calendar/logout/index.ts +18 -0
- package/commands/calendar/status/index.js +10 -0
- package/commands/calendar/status/index.ts +10 -0
- package/lib/caldav.d.ts +18 -0
- package/lib/caldav.d.ts.map +1 -0
- package/lib/caldav.js +167 -0
- package/lib/caldav.js.map +1 -0
- package/lib/chat-auth.d.ts +49 -0
- package/lib/chat-auth.d.ts.map +1 -0
- package/lib/chat-auth.js +233 -0
- package/lib/chat-auth.js.map +1 -0
- package/lib/cli/auth.d.ts +3 -0
- package/lib/cli/auth.d.ts.map +1 -0
- package/lib/cli/auth.js +182 -0
- package/lib/cli/auth.js.map +1 -0
- package/lib/config.d.ts +87 -0
- package/lib/config.d.ts.map +1 -0
- package/lib/config.js +95 -0
- package/lib/config.js.map +1 -0
- package/lib/credential-store.d.ts +30 -0
- package/lib/credential-store.d.ts.map +1 -0
- package/lib/credential-store.js +42 -0
- package/lib/credential-store.js.map +1 -0
- package/lib/free-time.d.ts +13 -0
- package/lib/free-time.d.ts.map +1 -0
- package/lib/free-time.js +96 -0
- package/lib/free-time.js.map +1 -0
- package/lib/http-callback.d.ts +13 -0
- package/lib/http-callback.d.ts.map +1 -0
- package/lib/http-callback.js +26 -0
- package/lib/http-callback.js.map +1 -0
- package/lib/index.d.ts +32 -0
- package/lib/index.d.ts.map +1 -0
- package/lib/index.js +122 -0
- package/lib/index.js.map +1 -0
- package/lib/oauth-auth.d.ts +37 -0
- package/lib/oauth-auth.d.ts.map +1 -0
- package/lib/oauth-auth.js +91 -0
- package/lib/oauth-auth.js.map +1 -0
- package/lib/oauth-session.d.ts +27 -0
- package/lib/oauth-session.d.ts.map +1 -0
- package/lib/oauth-session.js +43 -0
- package/lib/oauth-session.js.map +1 -0
- package/lib/oauth.d.ts +28 -0
- package/lib/oauth.d.ts.map +1 -0
- package/lib/oauth.js +200 -0
- package/lib/oauth.js.map +1 -0
- package/lib/runtime.d.ts +11 -0
- package/lib/runtime.d.ts.map +1 -0
- package/lib/runtime.js +3 -0
- package/lib/runtime.js.map +1 -0
- package/lib/secrets.d.ts +3 -0
- package/lib/secrets.d.ts.map +1 -0
- package/lib/secrets.js +6 -0
- package/lib/secrets.js.map +1 -0
- package/lib/time.d.ts +37 -0
- package/lib/time.d.ts.map +1 -0
- package/lib/time.js +118 -0
- package/lib/time.js.map +1 -0
- package/lib/token-manager.d.ts +71 -0
- package/lib/token-manager.d.ts.map +1 -0
- package/lib/token-manager.js +239 -0
- package/lib/token-manager.js.map +1 -0
- package/lib/tool-errors.d.ts +6 -0
- package/lib/tool-errors.d.ts.map +1 -0
- package/lib/tool-errors.js +17 -0
- package/lib/tool-errors.js.map +1 -0
- package/lib/types.d.ts +28 -0
- package/lib/types.d.ts.map +1 -0
- package/lib/types.js +2 -0
- package/lib/types.js.map +1 -0
- package/package.json +112 -3
- package/plugin.js +72 -0
- package/skills/calendar-scheduling/SKILL.md +38 -0
- package/skills/calendar-scheduling/tools/create_event/index.js +38 -0
- package/skills/calendar-scheduling/tools/create_event/index.ts +41 -0
- package/skills/calendar-scheduling/tools/find_free_time/index.js +46 -0
- package/skills/calendar-scheduling/tools/find_free_time/index.ts +50 -0
- package/skills/calendar-scheduling/tools/list_events/index.js +32 -0
- package/skills/calendar-scheduling/tools/list_events/index.ts +42 -0
- package/src/caldav.ts +198 -0
- package/src/chat-auth.ts +336 -0
- package/src/cli/auth.ts +235 -0
- package/src/config.ts +108 -0
- package/src/credential-store.ts +79 -0
- package/src/free-time.ts +128 -0
- package/src/http-callback.ts +55 -0
- package/src/index.ts +193 -0
- package/src/oauth-auth.ts +145 -0
- package/src/oauth-session.ts +65 -0
- package/src/oauth.ts +298 -0
- package/src/runtime.ts +16 -0
- package/src/secrets.ts +5 -0
- package/src/time.ts +167 -0
- package/src/token-manager.ts +358 -0
- package/src/tool-errors.ts +18 -0
- package/src/types.ts +37 -0
package/lib/chat-auth.js
ADDED
|
@@ -0,0 +1,233 @@
|
|
|
1
|
+
import { buildAuthorizeUrl, createOAuthState, createPkcePair, exchangeAuthorizationCode, } from "./oauth-auth.js";
|
|
2
|
+
import { OAuthSessionRegistry, OAUTH_SESSION_TTL_MS } from "./oauth-session.js";
|
|
3
|
+
import { cleanSecret } from "./secrets.js";
|
|
4
|
+
import { authCommandFor, } from "./token-manager.js";
|
|
5
|
+
export const DEFAULT_OAUTH_CALLBACK_PATH = "/calendar/oauth/callback";
|
|
6
|
+
export const OAUTH_PROVIDERS = [
|
|
7
|
+
"google",
|
|
8
|
+
"microsoft",
|
|
9
|
+
];
|
|
10
|
+
const PROVIDER_DISPLAY_NAME = {
|
|
11
|
+
google: "Google 日历",
|
|
12
|
+
microsoft: "Outlook 日历",
|
|
13
|
+
};
|
|
14
|
+
export function parseOAuthProvider(value) {
|
|
15
|
+
const normalized = String(value ?? "")
|
|
16
|
+
.trim()
|
|
17
|
+
.toLowerCase();
|
|
18
|
+
if (normalized === "google") {
|
|
19
|
+
return "google";
|
|
20
|
+
}
|
|
21
|
+
if (normalized === "microsoft" || normalized === "outlook") {
|
|
22
|
+
return "microsoft";
|
|
23
|
+
}
|
|
24
|
+
return undefined;
|
|
25
|
+
}
|
|
26
|
+
/** Joins a base URL and the callback path, tolerating extra/missing slashes. */
|
|
27
|
+
export function buildRedirectUri(baseUrl, callbackPath) {
|
|
28
|
+
const trimmedBase = baseUrl.trim().replace(/\/+$/, "");
|
|
29
|
+
const normalizedPath = `/${callbackPath.trim().replace(/^\/+/, "")}`;
|
|
30
|
+
return `${trimmedBase}${normalizedPath}`;
|
|
31
|
+
}
|
|
32
|
+
/** Turns a listening address into a browser-reachable local origin. */
|
|
33
|
+
export function localOriginFromAddress(address) {
|
|
34
|
+
const wildcardHosts = new Set(["0.0.0.0", "::", "[::]", ""]);
|
|
35
|
+
const host = wildcardHosts.has(address.host) ? "127.0.0.1" : address.host;
|
|
36
|
+
const formattedHost = host.includes(":") && !host.startsWith("[") ? `[${host}]` : host;
|
|
37
|
+
return `${address.protocol}://${formattedHost}:${address.port}`;
|
|
38
|
+
}
|
|
39
|
+
export class CalendarAuthService {
|
|
40
|
+
#config;
|
|
41
|
+
#managers;
|
|
42
|
+
#credentials;
|
|
43
|
+
#notify;
|
|
44
|
+
#resolveRedirectUri;
|
|
45
|
+
#fetch;
|
|
46
|
+
#sessions;
|
|
47
|
+
constructor(options) {
|
|
48
|
+
this.#config = options.config;
|
|
49
|
+
this.#managers = options.managers;
|
|
50
|
+
this.#credentials = options.credentials;
|
|
51
|
+
this.#notify = options.notify;
|
|
52
|
+
this.#resolveRedirectUri = options.resolveRedirectUri;
|
|
53
|
+
this.#fetch = options.fetchImpl;
|
|
54
|
+
this.#sessions = new OAuthSessionRegistry({ now: options.now });
|
|
55
|
+
}
|
|
56
|
+
/** Handles `calendar auth <provider>` and returns the chat reply. */
|
|
57
|
+
async startAuthorization(provider, requester) {
|
|
58
|
+
const displayName = PROVIDER_DISPLAY_NAME[provider];
|
|
59
|
+
if (!this.#credentials) {
|
|
60
|
+
return "日历授权需要数据库(databaseHostToken)来保存 refresh_token,当前不可用。";
|
|
61
|
+
}
|
|
62
|
+
const client = this.#clientCredentials(provider);
|
|
63
|
+
if (!client) {
|
|
64
|
+
return this.#missingClientMessage(provider);
|
|
65
|
+
}
|
|
66
|
+
const redirectUri = this.#resolveRedirectUri();
|
|
67
|
+
if (!redirectUri) {
|
|
68
|
+
return "未找到 HTTP 服务地址:请启用 zhin 的 HTTP Host,或在 plugins.calendar.oauth_redirect_base_url 配置外部可访问地址。";
|
|
69
|
+
}
|
|
70
|
+
const pkce = createPkcePair();
|
|
71
|
+
const state = createOAuthState();
|
|
72
|
+
this.#sessions.create({
|
|
73
|
+
provider,
|
|
74
|
+
state,
|
|
75
|
+
codeVerifier: pkce.verifier,
|
|
76
|
+
redirectUri,
|
|
77
|
+
requester,
|
|
78
|
+
});
|
|
79
|
+
const authorizeUrl = buildAuthorizeUrl({
|
|
80
|
+
provider,
|
|
81
|
+
clientId: client.clientId,
|
|
82
|
+
redirectUri,
|
|
83
|
+
state,
|
|
84
|
+
codeChallenge: pkce.challenge,
|
|
85
|
+
tenant: client.tenant,
|
|
86
|
+
});
|
|
87
|
+
const validMinutes = Math.round(OAUTH_SESSION_TTL_MS / 60_000);
|
|
88
|
+
return [
|
|
89
|
+
`请在浏览器打开下面的链接完成${displayName}授权(${validMinutes} 分钟内有效,只能使用一次):`,
|
|
90
|
+
authorizeUrl,
|
|
91
|
+
"",
|
|
92
|
+
`回调地址:${redirectUri}`,
|
|
93
|
+
"该地址必须能从打开链接的浏览器访问,并已登记在 OAuth 客户端的重定向 URI 中。",
|
|
94
|
+
].join("\n");
|
|
95
|
+
}
|
|
96
|
+
/** Handles the OAuth redirect back to the HTTP host. */
|
|
97
|
+
async handleCallback(searchParams) {
|
|
98
|
+
const state = searchParams.get("state") ?? "";
|
|
99
|
+
const session = state ? this.#sessions.consume(state) : undefined;
|
|
100
|
+
if (!session) {
|
|
101
|
+
return {
|
|
102
|
+
statusCode: 400,
|
|
103
|
+
message: "授权链接无效、已使用或已过期,请在聊天中重新发送 calendar auth 命令。",
|
|
104
|
+
};
|
|
105
|
+
}
|
|
106
|
+
const provider = session.provider;
|
|
107
|
+
const displayName = PROVIDER_DISPLAY_NAME[provider];
|
|
108
|
+
const oauthError = searchParams.get("error");
|
|
109
|
+
if (oauthError) {
|
|
110
|
+
const description = searchParams.get("error_description") ?? "";
|
|
111
|
+
const detail = `${oauthError} ${description}`.trim();
|
|
112
|
+
await this.#notifySafely(session.requester.target, `${displayName}授权失败:${detail}`);
|
|
113
|
+
return { statusCode: 400, message: `授权失败:${detail}` };
|
|
114
|
+
}
|
|
115
|
+
const code = searchParams.get("code") ?? "";
|
|
116
|
+
const client = this.#clientCredentials(provider);
|
|
117
|
+
if (!code || !client || !this.#credentials) {
|
|
118
|
+
return {
|
|
119
|
+
statusCode: 400,
|
|
120
|
+
message: "缺少授权码或客户端配置,请重新授权。",
|
|
121
|
+
};
|
|
122
|
+
}
|
|
123
|
+
try {
|
|
124
|
+
const tokens = await exchangeAuthorizationCode({
|
|
125
|
+
provider,
|
|
126
|
+
clientId: client.clientId,
|
|
127
|
+
clientSecret: client.clientSecret || undefined,
|
|
128
|
+
tenant: client.tenant,
|
|
129
|
+
redirectUri: session.redirectUri,
|
|
130
|
+
code,
|
|
131
|
+
codeVerifier: session.codeVerifier,
|
|
132
|
+
fetchImpl: this.#fetch,
|
|
133
|
+
});
|
|
134
|
+
await this.#credentials.save(provider, tokens.refreshToken, session.requester);
|
|
135
|
+
this.#managers[provider]?.setRefreshToken(tokens.refreshToken);
|
|
136
|
+
}
|
|
137
|
+
catch (error) {
|
|
138
|
+
const reason = error instanceof Error ? error.message : String(error);
|
|
139
|
+
await this.#notifySafely(session.requester.target, `${displayName}授权失败:${reason}`);
|
|
140
|
+
return { statusCode: 502, message: `授权失败:${reason}` };
|
|
141
|
+
}
|
|
142
|
+
const providerHint = this.#config.provider === provider
|
|
143
|
+
? ""
|
|
144
|
+
: `\n注意:当前 plugins.calendar.provider 是 ${this.#config.provider},日历工具不会使用 ${provider}。`;
|
|
145
|
+
await this.#notifySafely(session.requester.target, `${displayName}授权成功,refresh_token 已保存到插件数据库。${providerHint}`);
|
|
146
|
+
return { statusCode: 200, message: "授权成功,可以关闭此页回到聊天。" };
|
|
147
|
+
}
|
|
148
|
+
/** Handles `calendar status`. */
|
|
149
|
+
async describeStatus() {
|
|
150
|
+
const lines = [`当前 provider:${this.#config.provider}`];
|
|
151
|
+
for (const provider of OAUTH_PROVIDERS) {
|
|
152
|
+
lines.push(await this.#describeProvider(provider));
|
|
153
|
+
}
|
|
154
|
+
return lines.join("\n");
|
|
155
|
+
}
|
|
156
|
+
/** Handles `calendar logout <provider>`: removes the stored token. */
|
|
157
|
+
async logout(provider) {
|
|
158
|
+
const displayName = PROVIDER_DISPLAY_NAME[provider];
|
|
159
|
+
if (!this.#credentials) {
|
|
160
|
+
return "数据库不可用,没有可删除的授权。";
|
|
161
|
+
}
|
|
162
|
+
await this.#credentials.delete(provider);
|
|
163
|
+
this.#managers[provider]?.clearTokens();
|
|
164
|
+
return `已删除${displayName}在插件数据库中的授权。若 .env 里仍有 refresh_token,重载配置后会继续作为后备使用。`;
|
|
165
|
+
}
|
|
166
|
+
/** Called by the token manager once when the refresh token is rejected. */
|
|
167
|
+
async notifyAuthorizationLost(provider, message) {
|
|
168
|
+
const credential = await this.#credentials?.get(provider);
|
|
169
|
+
const owner = credential?.authorized_by;
|
|
170
|
+
if (!owner) {
|
|
171
|
+
return;
|
|
172
|
+
}
|
|
173
|
+
await this.#notifySafely(owner.target, message);
|
|
174
|
+
}
|
|
175
|
+
async #describeProvider(provider) {
|
|
176
|
+
const displayName = PROVIDER_DISPLAY_NAME[provider];
|
|
177
|
+
if (!this.#clientCredentials(provider)) {
|
|
178
|
+
return `${displayName}:未配置 client_id`;
|
|
179
|
+
}
|
|
180
|
+
const credential = await this.#credentials?.get(provider);
|
|
181
|
+
const manager = this.#managers[provider];
|
|
182
|
+
if (manager?.authorizationLost) {
|
|
183
|
+
return `${displayName}:授权已失效,请发送「${authCommandFor(provider)}」`;
|
|
184
|
+
}
|
|
185
|
+
if (credential) {
|
|
186
|
+
return `${displayName}:已授权(数据库,${credential.authorized_at})`;
|
|
187
|
+
}
|
|
188
|
+
if (manager?.hasRefreshToken) {
|
|
189
|
+
return `${displayName}:使用配置/环境变量中的 refresh_token`;
|
|
190
|
+
}
|
|
191
|
+
return `${displayName}:未授权,请发送「${authCommandFor(provider)}」`;
|
|
192
|
+
}
|
|
193
|
+
#clientCredentials(provider) {
|
|
194
|
+
if (provider === "google") {
|
|
195
|
+
const google = this.#config.google;
|
|
196
|
+
const clientId = cleanSecret(google?.client_id ?? "");
|
|
197
|
+
const clientSecret = cleanSecret(google?.client_secret ?? "");
|
|
198
|
+
if (!clientId || !clientSecret) {
|
|
199
|
+
return undefined;
|
|
200
|
+
}
|
|
201
|
+
return { clientId, clientSecret, tenant: "common" };
|
|
202
|
+
}
|
|
203
|
+
const microsoft = this.#config.microsoft;
|
|
204
|
+
const clientId = cleanSecret(microsoft?.client_id ?? "");
|
|
205
|
+
if (!clientId) {
|
|
206
|
+
return undefined;
|
|
207
|
+
}
|
|
208
|
+
return {
|
|
209
|
+
clientId,
|
|
210
|
+
clientSecret: cleanSecret(microsoft?.client_secret ?? ""),
|
|
211
|
+
tenant: microsoft?.tenant || "common",
|
|
212
|
+
};
|
|
213
|
+
}
|
|
214
|
+
#missingClientMessage(provider) {
|
|
215
|
+
if (provider === "google") {
|
|
216
|
+
return "请先在 plugins.calendar.google 配置 client_id 和 client_secret(例如 ${GOOGLE_CALENDAR_CLIENT_ID} / ${GOOGLE_CALENDAR_CLIENT_SECRET})。";
|
|
217
|
+
}
|
|
218
|
+
return "请先在 plugins.calendar.microsoft 配置 client_id(例如 ${MS_GRAPH_CLIENT_ID})。";
|
|
219
|
+
}
|
|
220
|
+
async #notifySafely(target, text) {
|
|
221
|
+
if (!this.#notify) {
|
|
222
|
+
return;
|
|
223
|
+
}
|
|
224
|
+
try {
|
|
225
|
+
await this.#notify(target, text);
|
|
226
|
+
}
|
|
227
|
+
catch (error) {
|
|
228
|
+
const reason = error instanceof Error ? error.message : String(error);
|
|
229
|
+
console.warn(`[calendar] 发送授权通知失败:${reason}`);
|
|
230
|
+
}
|
|
231
|
+
}
|
|
232
|
+
}
|
|
233
|
+
//# sourceMappingURL=chat-auth.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"chat-auth.js","sourceRoot":"","sources":["../src/chat-auth.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"auth.d.ts","sourceRoot":"","sources":["../../src/cli/auth.ts"],"names":[],"mappings":""}
|
package/lib/cli/auth.js
ADDED
|
@@ -0,0 +1,182 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
/**
|
|
3
|
+
* One-time OAuth loopback helper for Google Calendar / Microsoft Graph.
|
|
4
|
+
*
|
|
5
|
+
* After installing the package:
|
|
6
|
+
* npx zhin-calendar-auth google
|
|
7
|
+
* npx zhin-calendar-auth microsoft
|
|
8
|
+
*
|
|
9
|
+
* Inside the zhin monorepo:
|
|
10
|
+
* pnpm --filter @zhin.js/plugin-calendar auth google
|
|
11
|
+
*
|
|
12
|
+
* Reads credentials from process.env only (does not load .env files).
|
|
13
|
+
* Prints the refresh token for the user to paste into their env and never writes files.
|
|
14
|
+
*/
|
|
15
|
+
import { createServer, } from "node:http";
|
|
16
|
+
import { spawn } from "node:child_process";
|
|
17
|
+
import { buildAuthorizeUrl, createOAuthState, createPkcePair, exchangeAuthorizationCode, } from "../oauth-auth.js";
|
|
18
|
+
const DEFAULT_CALLBACK_PORT = 53682;
|
|
19
|
+
function printUsageAndExit() {
|
|
20
|
+
console.error(`用法:npx zhin-calendar-auth <google|microsoft>
|
|
21
|
+
|
|
22
|
+
环境变量:
|
|
23
|
+
google: GOOGLE_CALENDAR_CLIENT_ID, GOOGLE_CALENDAR_CLIENT_SECRET
|
|
24
|
+
microsoft: MS_GRAPH_CLIENT_ID, 可选 MS_GRAPH_CLIENT_SECRET, 可选 MS_GRAPH_TENANT (默认 common)
|
|
25
|
+
|
|
26
|
+
回调地址固定为 http://127.0.0.1:<port>/callback (默认端口 ${DEFAULT_CALLBACK_PORT},可用 CALENDAR_OAUTH_PORT 覆盖)。
|
|
27
|
+
完成后只打印 refresh_token,请手动写入 .env;本工具不会改写任何文件。`);
|
|
28
|
+
process.exit(1);
|
|
29
|
+
}
|
|
30
|
+
function getBrowserCommand(url) {
|
|
31
|
+
if (process.platform === "darwin") {
|
|
32
|
+
return { command: "open", args: [url] };
|
|
33
|
+
}
|
|
34
|
+
if (process.platform === "win32") {
|
|
35
|
+
return { command: "cmd", args: ["/c", "start", "", url] };
|
|
36
|
+
}
|
|
37
|
+
return { command: "xdg-open", args: [url] };
|
|
38
|
+
}
|
|
39
|
+
function openBrowser(url) {
|
|
40
|
+
const { command, args } = getBrowserCommand(url);
|
|
41
|
+
try {
|
|
42
|
+
const child = spawn(command, args, { detached: true, stdio: "ignore" });
|
|
43
|
+
child.on("error", () => {
|
|
44
|
+
console.error("无法自动打开浏览器,请手动访问上面的 URL。");
|
|
45
|
+
});
|
|
46
|
+
child.unref();
|
|
47
|
+
}
|
|
48
|
+
catch {
|
|
49
|
+
console.error("无法自动打开浏览器,请手动访问上面的 URL。");
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
function sendText(response, statusCode, text) {
|
|
53
|
+
response.writeHead(statusCode, {
|
|
54
|
+
"content-type": "text/plain; charset=utf-8",
|
|
55
|
+
});
|
|
56
|
+
response.end(text);
|
|
57
|
+
}
|
|
58
|
+
function waitForAuthorizationCode(port, expectedState) {
|
|
59
|
+
return new Promise((resolve, reject) => {
|
|
60
|
+
const server = createServer((request, response) => {
|
|
61
|
+
const fail = (statusCode, text, error) => {
|
|
62
|
+
sendText(response, statusCode, text);
|
|
63
|
+
server.close();
|
|
64
|
+
reject(error);
|
|
65
|
+
};
|
|
66
|
+
try {
|
|
67
|
+
const callbackUrl = new URL(request.url ?? "/", "http://127.0.0.1");
|
|
68
|
+
if (callbackUrl.pathname !== "/callback") {
|
|
69
|
+
sendText(response, 404, "not found");
|
|
70
|
+
return;
|
|
71
|
+
}
|
|
72
|
+
const oauthError = callbackUrl.searchParams.get("error");
|
|
73
|
+
if (oauthError) {
|
|
74
|
+
const description = callbackUrl.searchParams.get("error_description") ?? "";
|
|
75
|
+
fail(400, `授权失败:${oauthError}\n可以关闭此页。`, new Error(`OAuth error: ${oauthError} ${description}`.trim()));
|
|
76
|
+
return;
|
|
77
|
+
}
|
|
78
|
+
const state = callbackUrl.searchParams.get("state") ?? "";
|
|
79
|
+
if (state !== expectedState) {
|
|
80
|
+
fail(400, "state 不匹配,请重试。", new Error("OAuth state mismatch"));
|
|
81
|
+
return;
|
|
82
|
+
}
|
|
83
|
+
const code = callbackUrl.searchParams.get("code") ?? "";
|
|
84
|
+
if (!code) {
|
|
85
|
+
fail(400, "missing code", new Error("missing code"));
|
|
86
|
+
return;
|
|
87
|
+
}
|
|
88
|
+
response.writeHead(200, {
|
|
89
|
+
"content-type": "text/html; charset=utf-8",
|
|
90
|
+
});
|
|
91
|
+
response.end('<!doctype html><meta charset="utf-8"><title>OK</title><p>授权成功,可以关闭此页回到终端。</p>');
|
|
92
|
+
server.close();
|
|
93
|
+
resolve(code);
|
|
94
|
+
}
|
|
95
|
+
catch (error) {
|
|
96
|
+
server.close();
|
|
97
|
+
reject(error);
|
|
98
|
+
}
|
|
99
|
+
});
|
|
100
|
+
server.on("error", reject);
|
|
101
|
+
server.listen(port, "127.0.0.1", () => {
|
|
102
|
+
console.error(`等待回调 http://127.0.0.1:${port}/callback …`);
|
|
103
|
+
});
|
|
104
|
+
});
|
|
105
|
+
}
|
|
106
|
+
function readEnv(name) {
|
|
107
|
+
return process.env[name]?.trim() ?? "";
|
|
108
|
+
}
|
|
109
|
+
function parseProvider(value) {
|
|
110
|
+
const normalized = (value ?? "").toLowerCase();
|
|
111
|
+
if (normalized === "google" || normalized === "microsoft") {
|
|
112
|
+
return normalized;
|
|
113
|
+
}
|
|
114
|
+
return printUsageAndExit();
|
|
115
|
+
}
|
|
116
|
+
async function main() {
|
|
117
|
+
const provider = parseProvider(process.argv[2]);
|
|
118
|
+
const isGoogle = provider === "google";
|
|
119
|
+
const port = Number(process.env.CALENDAR_OAUTH_PORT ?? DEFAULT_CALLBACK_PORT);
|
|
120
|
+
const redirectUri = `http://127.0.0.1:${port}/callback`;
|
|
121
|
+
const clientIdEnvName = isGoogle
|
|
122
|
+
? "GOOGLE_CALENDAR_CLIENT_ID"
|
|
123
|
+
: "MS_GRAPH_CLIENT_ID";
|
|
124
|
+
const clientSecretEnvName = isGoogle
|
|
125
|
+
? "GOOGLE_CALENDAR_CLIENT_SECRET"
|
|
126
|
+
: "MS_GRAPH_CLIENT_SECRET";
|
|
127
|
+
const refreshTokenEnvName = isGoogle
|
|
128
|
+
? "GOOGLE_CALENDAR_REFRESH_TOKEN"
|
|
129
|
+
: "MS_GRAPH_REFRESH_TOKEN";
|
|
130
|
+
const clientId = readEnv(clientIdEnvName);
|
|
131
|
+
const clientSecret = readEnv(clientSecretEnvName);
|
|
132
|
+
const tenant = readEnv("MS_GRAPH_TENANT") || "common";
|
|
133
|
+
if (!clientId) {
|
|
134
|
+
console.error(`请先 export ${clientIdEnvName}=...`);
|
|
135
|
+
process.exit(1);
|
|
136
|
+
}
|
|
137
|
+
if (isGoogle && !clientSecret) {
|
|
138
|
+
console.error(`Google 需要 export ${clientSecretEnvName}=...`);
|
|
139
|
+
process.exit(1);
|
|
140
|
+
}
|
|
141
|
+
const pkce = createPkcePair();
|
|
142
|
+
const state = createOAuthState();
|
|
143
|
+
const authorizeUrl = buildAuthorizeUrl({
|
|
144
|
+
provider,
|
|
145
|
+
clientId,
|
|
146
|
+
redirectUri,
|
|
147
|
+
state,
|
|
148
|
+
codeChallenge: pkce.challenge,
|
|
149
|
+
tenant,
|
|
150
|
+
});
|
|
151
|
+
console.error("\n将打开浏览器完成登录。若未自动打开,请复制以下 URL:\n");
|
|
152
|
+
console.error(authorizeUrl);
|
|
153
|
+
console.error("");
|
|
154
|
+
const codePromise = waitForAuthorizationCode(port, state);
|
|
155
|
+
openBrowser(authorizeUrl);
|
|
156
|
+
const code = await codePromise;
|
|
157
|
+
const tokens = await exchangeAuthorizationCode({
|
|
158
|
+
provider,
|
|
159
|
+
clientId,
|
|
160
|
+
clientSecret: clientSecret || undefined,
|
|
161
|
+
tenant,
|
|
162
|
+
redirectUri,
|
|
163
|
+
code,
|
|
164
|
+
codeVerifier: pkce.verifier,
|
|
165
|
+
});
|
|
166
|
+
const output = [
|
|
167
|
+
"",
|
|
168
|
+
"===== 请把下面的值写入环境变量(不要提交到 git)=====",
|
|
169
|
+
`${refreshTokenEnvName}=${tokens.refreshToken}`,
|
|
170
|
+
"====================================================",
|
|
171
|
+
"",
|
|
172
|
+
"",
|
|
173
|
+
].join("\n");
|
|
174
|
+
process.stdout.write(output);
|
|
175
|
+
console.error("本工具不会写入 .env。请手动粘贴后重启/重载配置。");
|
|
176
|
+
}
|
|
177
|
+
main().catch((error) => {
|
|
178
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
179
|
+
console.error(message);
|
|
180
|
+
process.exit(1);
|
|
181
|
+
});
|
|
182
|
+
//# sourceMappingURL=auth.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"auth.js","sourceRoot":"","sources":["../../src/cli/auth.ts"],"names":[],"mappings":"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"}
|
package/lib/config.d.ts
ADDED
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
import { Schema } from "zhin.js";
|
|
2
|
+
export declare const calendarConfig: Schema<Schema.InputRecord<{
|
|
3
|
+
provider: Schema<"caldav" | "none" | "google" | "microsoft", "caldav" | "none" | "google" | "microsoft"> & Schema.Present;
|
|
4
|
+
timezone: Schema<string, string> & Schema.Present;
|
|
5
|
+
work_day_start: Schema<string, string> & Schema.Present;
|
|
6
|
+
work_day_end: Schema<string, string> & Schema.Present;
|
|
7
|
+
oauth_redirect_base_url: Schema<string, string> & Schema.Present;
|
|
8
|
+
oauth_callback_path: Schema<string, string> & Schema.Present;
|
|
9
|
+
caldav: Schema<Schema.InputRecord<{
|
|
10
|
+
enabled: Schema<boolean, boolean> & Schema.Present;
|
|
11
|
+
calendar_url: Schema<string, string> & Schema.Present;
|
|
12
|
+
username: Schema<string, string> & Schema.Present;
|
|
13
|
+
password: Schema<string, string> & Schema.Present;
|
|
14
|
+
}>, {
|
|
15
|
+
enabled: boolean;
|
|
16
|
+
calendar_url: string;
|
|
17
|
+
username: string;
|
|
18
|
+
password: string;
|
|
19
|
+
} & {}>;
|
|
20
|
+
google: Schema<Schema.InputRecord<{
|
|
21
|
+
enabled: Schema<boolean, boolean> & Schema.Present;
|
|
22
|
+
client_id: Schema<string, string> & Schema.Present;
|
|
23
|
+
client_secret: Schema<string, string> & Schema.Present;
|
|
24
|
+
refresh_token: Schema<string, string> & Schema.Present;
|
|
25
|
+
calendar_id: Schema<string, string> & Schema.Present;
|
|
26
|
+
token_file: Schema<string, string> & Schema.Present;
|
|
27
|
+
}>, {
|
|
28
|
+
enabled: boolean;
|
|
29
|
+
client_id: string;
|
|
30
|
+
client_secret: string;
|
|
31
|
+
refresh_token: string;
|
|
32
|
+
calendar_id: string;
|
|
33
|
+
token_file: string;
|
|
34
|
+
} & {}>;
|
|
35
|
+
microsoft: Schema<Schema.InputRecord<{
|
|
36
|
+
enabled: Schema<boolean, boolean> & Schema.Present;
|
|
37
|
+
client_id: Schema<string, string> & Schema.Present;
|
|
38
|
+
client_secret: Schema<string, string> & Schema.Present;
|
|
39
|
+
refresh_token: Schema<string, string> & Schema.Present;
|
|
40
|
+
tenant: Schema<string, string> & Schema.Present;
|
|
41
|
+
calendar_id: Schema<string, string> & Schema.Present;
|
|
42
|
+
token_file: Schema<string, string> & Schema.Present;
|
|
43
|
+
}>, {
|
|
44
|
+
enabled: boolean;
|
|
45
|
+
client_id: string;
|
|
46
|
+
client_secret: string;
|
|
47
|
+
refresh_token: string;
|
|
48
|
+
tenant: string;
|
|
49
|
+
calendar_id: string;
|
|
50
|
+
token_file: string;
|
|
51
|
+
} & {}>;
|
|
52
|
+
}>, {
|
|
53
|
+
provider: "caldav" | "none" | "google" | "microsoft";
|
|
54
|
+
timezone: string;
|
|
55
|
+
work_day_start: string;
|
|
56
|
+
work_day_end: string;
|
|
57
|
+
oauth_redirect_base_url: string;
|
|
58
|
+
oauth_callback_path: string;
|
|
59
|
+
} & {
|
|
60
|
+
caldav?: ({
|
|
61
|
+
enabled: boolean;
|
|
62
|
+
calendar_url: string;
|
|
63
|
+
username: string;
|
|
64
|
+
password: string;
|
|
65
|
+
} & {}) | undefined;
|
|
66
|
+
google?: ({
|
|
67
|
+
enabled: boolean;
|
|
68
|
+
client_id: string;
|
|
69
|
+
client_secret: string;
|
|
70
|
+
refresh_token: string;
|
|
71
|
+
calendar_id: string;
|
|
72
|
+
token_file: string;
|
|
73
|
+
} & {}) | undefined;
|
|
74
|
+
microsoft?: ({
|
|
75
|
+
enabled: boolean;
|
|
76
|
+
client_id: string;
|
|
77
|
+
client_secret: string;
|
|
78
|
+
refresh_token: string;
|
|
79
|
+
tenant: string;
|
|
80
|
+
calendar_id: string;
|
|
81
|
+
token_file: string;
|
|
82
|
+
} & {}) | undefined;
|
|
83
|
+
}>;
|
|
84
|
+
export type CalendarConfig = Schema.Output<typeof calendarConfig>;
|
|
85
|
+
export declare function assertCalendarTimezone(timezone: string): void;
|
|
86
|
+
export { cleanSecret } from "./secrets.js";
|
|
87
|
+
//# sourceMappingURL=config.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,SAAS,CAAC;AAEjC,eAAO,MAAM,cAAc;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EA2FzB,CAAC;AAEH,MAAM,MAAM,cAAc,GAAG,MAAM,CAAC,MAAM,CAAC,OAAO,cAAc,CAAC,CAAC;AAElE,wBAAgB,sBAAsB,CAAC,QAAQ,EAAE,MAAM,GAAG,IAAI,CAQ7D;AAED,OAAO,EAAE,WAAW,EAAE,MAAM,cAAc,CAAC"}
|
package/lib/config.js
ADDED
|
@@ -0,0 +1,95 @@
|
|
|
1
|
+
import { Schema } from "zhin.js";
|
|
2
|
+
export const calendarConfig = Schema.object({
|
|
3
|
+
provider: Schema.union([
|
|
4
|
+
Schema.const("none"),
|
|
5
|
+
Schema.const("caldav"),
|
|
6
|
+
Schema.const("google"),
|
|
7
|
+
Schema.const("microsoft"),
|
|
8
|
+
])
|
|
9
|
+
.default("none")
|
|
10
|
+
.description("日历后端;none 时工具返回未启用提示")
|
|
11
|
+
.effect("reload"),
|
|
12
|
+
timezone: Schema.string()
|
|
13
|
+
.default("Asia/Manila")
|
|
14
|
+
.description("解释无偏移时间与展示用的 IANA 时区")
|
|
15
|
+
.effect("reload"),
|
|
16
|
+
work_day_start: Schema.string().default("09:00").effect("reload"),
|
|
17
|
+
work_day_end: Schema.string().default("18:00").effect("reload"),
|
|
18
|
+
oauth_redirect_base_url: Schema.string()
|
|
19
|
+
.default("")
|
|
20
|
+
.description("聊天授权回调的外部基础地址(如 https://bot.example.com);留空时使用 zhin HTTP Host 的本机地址")
|
|
21
|
+
.effect("reload"),
|
|
22
|
+
oauth_callback_path: Schema.string()
|
|
23
|
+
.default("/calendar/oauth/callback")
|
|
24
|
+
.description("聊天授权回调路由,挂在 zhin HTTP Host 上;反向代理/隧道只转发部分路径时可调整")
|
|
25
|
+
.effect("reload"),
|
|
26
|
+
caldav: Schema.object({
|
|
27
|
+
enabled: Schema.boolean().default(false),
|
|
28
|
+
calendar_url: Schema.string()
|
|
29
|
+
.default("")
|
|
30
|
+
.description("日历 collection URL")
|
|
31
|
+
.effect("reload"),
|
|
32
|
+
username: Schema.string().default("").effect("reload"),
|
|
33
|
+
password: Schema.string().default("").effect("reload"),
|
|
34
|
+
}),
|
|
35
|
+
google: Schema.object({
|
|
36
|
+
enabled: Schema.boolean().default(false),
|
|
37
|
+
client_id: Schema.string()
|
|
38
|
+
.default("")
|
|
39
|
+
.description("${GOOGLE_CALENDAR_CLIENT_ID}")
|
|
40
|
+
.effect("reload"),
|
|
41
|
+
client_secret: Schema.string()
|
|
42
|
+
.default("")
|
|
43
|
+
.description("${GOOGLE_CALENDAR_CLIENT_SECRET}")
|
|
44
|
+
.effect("reload"),
|
|
45
|
+
refresh_token: Schema.string()
|
|
46
|
+
.default("")
|
|
47
|
+
.description("${GOOGLE_CALENDAR_REFRESH_TOKEN};用 auth google 获取")
|
|
48
|
+
.effect("reload"),
|
|
49
|
+
calendar_id: Schema.string()
|
|
50
|
+
.default("primary")
|
|
51
|
+
.description("日历 ID,默认 primary;可换成其它日历的 id")
|
|
52
|
+
.effect("reload"),
|
|
53
|
+
token_file: Schema.string()
|
|
54
|
+
.default("")
|
|
55
|
+
.description("可选:持久化轮换后的 refresh_token 的 JSON 路径(如 data/calendar-google-token.json)")
|
|
56
|
+
.effect("reload"),
|
|
57
|
+
}),
|
|
58
|
+
microsoft: Schema.object({
|
|
59
|
+
enabled: Schema.boolean().default(false),
|
|
60
|
+
client_id: Schema.string()
|
|
61
|
+
.default("")
|
|
62
|
+
.description("${MS_GRAPH_CLIENT_ID}")
|
|
63
|
+
.effect("reload"),
|
|
64
|
+
client_secret: Schema.string()
|
|
65
|
+
.default("")
|
|
66
|
+
.description("可选;公共客户端可留空。${MS_GRAPH_CLIENT_SECRET}")
|
|
67
|
+
.effect("reload"),
|
|
68
|
+
refresh_token: Schema.string()
|
|
69
|
+
.default("")
|
|
70
|
+
.description("${MS_GRAPH_REFRESH_TOKEN};用 auth microsoft 获取")
|
|
71
|
+
.effect("reload"),
|
|
72
|
+
tenant: Schema.string()
|
|
73
|
+
.default("common")
|
|
74
|
+
.description("Azure tenant,默认 common")
|
|
75
|
+
.effect("reload"),
|
|
76
|
+
calendar_id: Schema.string()
|
|
77
|
+
.default("")
|
|
78
|
+
.description("留空或 primary/me = 默认日历;否则为 Graph calendar id")
|
|
79
|
+
.effect("reload"),
|
|
80
|
+
token_file: Schema.string()
|
|
81
|
+
.default("")
|
|
82
|
+
.description("可选:持久化轮换后的 refresh_token 的 JSON 路径(如 data/calendar-ms-token.json)")
|
|
83
|
+
.effect("reload"),
|
|
84
|
+
}),
|
|
85
|
+
});
|
|
86
|
+
export function assertCalendarTimezone(timezone) {
|
|
87
|
+
try {
|
|
88
|
+
new Intl.DateTimeFormat("zh-CN", { timeZone: timezone }).format(0);
|
|
89
|
+
}
|
|
90
|
+
catch {
|
|
91
|
+
throw new TypeError(`calendar timezone 必须是有效的 IANA 时区:${timezone}`);
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
export { cleanSecret } from "./secrets.js";
|
|
95
|
+
//# sourceMappingURL=config.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"config.js","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"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"}
|