larkcc 0.1.0 → 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/CHANGELOG.md +6 -0
- package/dist/index.js +0 -0
- package/package.json +1 -1
- package/dist/oauth.d.ts +0 -19
- package/dist/oauth.js +0 -142
- package/dist/oauth.js.map +0 -1
package/CHANGELOG.md
CHANGED
|
@@ -5,6 +5,12 @@ All notable changes to this project will be documented in this file.
|
|
|
5
5
|
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),
|
|
6
6
|
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
|
7
7
|
|
|
8
|
+
## [0.1.1] - 2025-03-24
|
|
9
|
+
|
|
10
|
+
### Changed
|
|
11
|
+
|
|
12
|
+
- Add GitHub Actions CI/CD for automated npm releases
|
|
13
|
+
|
|
8
14
|
## [0.1.0] - 2025-03-24
|
|
9
15
|
|
|
10
16
|
### Added
|
package/dist/index.js
CHANGED
|
File without changes
|
package/package.json
CHANGED
package/dist/oauth.d.ts
DELETED
|
@@ -1,19 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* 飞书 OAuth 授权模块
|
|
3
|
-
* 用于获取 user_access_token 以访问用户的个人云空间
|
|
4
|
-
*/
|
|
5
|
-
/**
|
|
6
|
-
* 生成授权链接(使用 OOB 方式,无需配置回调地址)
|
|
7
|
-
*/
|
|
8
|
-
export declare function generateAuthUrl(appId: string): string;
|
|
9
|
-
/**
|
|
10
|
-
* 获取有效的 user_access_token
|
|
11
|
-
* - 如果 token 有效,直接返回
|
|
12
|
-
* - 如果 token 过期但 refresh_token 有效,刷新后返回
|
|
13
|
-
* - 如果都过期,返回 null 需要重新授权
|
|
14
|
-
*/
|
|
15
|
-
export declare function getValidUserToken(appId: string, appSecret: string, profile?: string): Promise<string | null>;
|
|
16
|
-
/**
|
|
17
|
-
* 执行 OAuth 授权流程
|
|
18
|
-
*/
|
|
19
|
-
export declare function doOAuthFlow(appId: string, appSecret: string, profile?: string): Promise<string>;
|
package/dist/oauth.js
DELETED
|
@@ -1,142 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* 飞书 OAuth 授权模块
|
|
3
|
-
* 用于获取 user_access_token 以访问用户的个人云空间
|
|
4
|
-
*/
|
|
5
|
-
import * as readline from "readline";
|
|
6
|
-
import { loadAuthToken, saveAuthToken } from "./config.js";
|
|
7
|
-
// 飞书 OAuth 配置
|
|
8
|
-
const AUTH_URL = "https://open.feishu.cn/open-apis/authen/v1/authorize";
|
|
9
|
-
const TOKEN_URL = "https://open.feishu.cn/open-apis/authen/v2/oauth/token";
|
|
10
|
-
// 所需权限:云文档读写
|
|
11
|
-
const REQUIRED_SCOPES = ["drive:file", "drive:file:upload", "docs:doc", "offline_access"];
|
|
12
|
-
/**
|
|
13
|
-
* 生成授权链接(使用 OOB 方式,无需配置回调地址)
|
|
14
|
-
*/
|
|
15
|
-
export function generateAuthUrl(appId) {
|
|
16
|
-
const params = new URLSearchParams({
|
|
17
|
-
app_id: appId,
|
|
18
|
-
redirect_uri: "urn:ietf:wg:oauth:2.0:oob",
|
|
19
|
-
scope: REQUIRED_SCOPES.join(" "),
|
|
20
|
-
});
|
|
21
|
-
return `${AUTH_URL}?${params.toString()}`;
|
|
22
|
-
}
|
|
23
|
-
/**
|
|
24
|
-
* 等待用户输入授权码
|
|
25
|
-
*/
|
|
26
|
-
function waitForCodeInput() {
|
|
27
|
-
const rl = readline.createInterface({
|
|
28
|
-
input: process.stdin,
|
|
29
|
-
output: process.stdout,
|
|
30
|
-
});
|
|
31
|
-
return new Promise((resolve, reject) => {
|
|
32
|
-
// 5 分钟超时
|
|
33
|
-
const timeout = setTimeout(() => {
|
|
34
|
-
rl.close();
|
|
35
|
-
reject(new Error("授权超时,请重试"));
|
|
36
|
-
}, 5 * 60 * 1000);
|
|
37
|
-
rl.question("\n请输入浏览器中显示的授权码: ", (code) => {
|
|
38
|
-
clearTimeout(timeout);
|
|
39
|
-
rl.close();
|
|
40
|
-
resolve(code.trim());
|
|
41
|
-
});
|
|
42
|
-
});
|
|
43
|
-
}
|
|
44
|
-
/**
|
|
45
|
-
* 用授权码换取 access_token
|
|
46
|
-
*/
|
|
47
|
-
async function exchangeCodeForToken(appId, appSecret, code) {
|
|
48
|
-
const res = await fetch(TOKEN_URL, {
|
|
49
|
-
method: "POST",
|
|
50
|
-
headers: { "Content-Type": "application/json" },
|
|
51
|
-
body: JSON.stringify({
|
|
52
|
-
grant_type: "authorization_code",
|
|
53
|
-
client_id: appId,
|
|
54
|
-
client_secret: appSecret,
|
|
55
|
-
code,
|
|
56
|
-
}),
|
|
57
|
-
});
|
|
58
|
-
const data = await res.json();
|
|
59
|
-
if (data.code !== 0) {
|
|
60
|
-
throw new Error(`获取 token 失败: ${data.msg || JSON.stringify(data)}`);
|
|
61
|
-
}
|
|
62
|
-
const now = Date.now();
|
|
63
|
-
return {
|
|
64
|
-
access_token: data.access_token,
|
|
65
|
-
refresh_token: data.refresh_token,
|
|
66
|
-
expires_at: now + (data.expires_in * 1000),
|
|
67
|
-
refresh_expires_at: now + (data.refresh_token_expires_in * 1000),
|
|
68
|
-
};
|
|
69
|
-
}
|
|
70
|
-
/**
|
|
71
|
-
* 刷新 access_token
|
|
72
|
-
*/
|
|
73
|
-
async function refreshAccessToken(appId, appSecret, refreshToken) {
|
|
74
|
-
const res = await fetch(TOKEN_URL, {
|
|
75
|
-
method: "POST",
|
|
76
|
-
headers: { "Content-Type": "application/json" },
|
|
77
|
-
body: JSON.stringify({
|
|
78
|
-
grant_type: "refresh_token",
|
|
79
|
-
client_id: appId,
|
|
80
|
-
client_secret: appSecret,
|
|
81
|
-
refresh_token: refreshToken,
|
|
82
|
-
}),
|
|
83
|
-
});
|
|
84
|
-
const data = await res.json();
|
|
85
|
-
if (data.code !== 0) {
|
|
86
|
-
throw new Error(`刷新 token 失败: ${data.msg || JSON.stringify(data)}`);
|
|
87
|
-
}
|
|
88
|
-
const now = Date.now();
|
|
89
|
-
return {
|
|
90
|
-
access_token: data.access_token,
|
|
91
|
-
refresh_token: data.refresh_token,
|
|
92
|
-
expires_at: now + (data.expires_in * 1000),
|
|
93
|
-
refresh_expires_at: now + (data.refresh_token_expires_in * 1000),
|
|
94
|
-
};
|
|
95
|
-
}
|
|
96
|
-
/**
|
|
97
|
-
* 获取有效的 user_access_token
|
|
98
|
-
* - 如果 token 有效,直接返回
|
|
99
|
-
* - 如果 token 过期但 refresh_token 有效,刷新后返回
|
|
100
|
-
* - 如果都过期,返回 null 需要重新授权
|
|
101
|
-
*/
|
|
102
|
-
export async function getValidUserToken(appId, appSecret, profile) {
|
|
103
|
-
const token = loadAuthToken(profile);
|
|
104
|
-
if (!token)
|
|
105
|
-
return null;
|
|
106
|
-
const now = Date.now();
|
|
107
|
-
// access_token 还有效(提前 5 分钟刷新)
|
|
108
|
-
if (token.expires_at > now + 5 * 60 * 1000) {
|
|
109
|
-
return token.access_token;
|
|
110
|
-
}
|
|
111
|
-
// refresh_token 还有效,尝试刷新
|
|
112
|
-
if (token.refresh_expires_at > now) {
|
|
113
|
-
try {
|
|
114
|
-
const newToken = await refreshAccessToken(appId, appSecret, token.refresh_token);
|
|
115
|
-
saveAuthToken(newToken, profile);
|
|
116
|
-
return newToken.access_token;
|
|
117
|
-
}
|
|
118
|
-
catch {
|
|
119
|
-
return null;
|
|
120
|
-
}
|
|
121
|
-
}
|
|
122
|
-
// 都过期了
|
|
123
|
-
return null;
|
|
124
|
-
}
|
|
125
|
-
/**
|
|
126
|
-
* 执行 OAuth 授权流程
|
|
127
|
-
*/
|
|
128
|
-
export async function doOAuthFlow(appId, appSecret, profile) {
|
|
129
|
-
console.log("\n🔐 需要授权访问您的云文档");
|
|
130
|
-
console.log("请在浏览器中打开以下链接进行授权:\n");
|
|
131
|
-
console.log(generateAuthUrl(appId));
|
|
132
|
-
console.log("\n授权后,请将浏览器中显示的授权码粘贴到此处。");
|
|
133
|
-
// 等待用户输入授权码
|
|
134
|
-
const code = await waitForCodeInput();
|
|
135
|
-
console.log("✅ 已获取授权码,正在换取 token...");
|
|
136
|
-
// 换取 token
|
|
137
|
-
const token = await exchangeCodeForToken(appId, appSecret, code);
|
|
138
|
-
saveAuthToken(token, profile);
|
|
139
|
-
console.log("✅ 授权成功!\n");
|
|
140
|
-
return token.access_token;
|
|
141
|
-
}
|
|
142
|
-
//# sourceMappingURL=oauth.js.map
|
package/dist/oauth.js.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"oauth.js","sourceRoot":"","sources":["../src/oauth.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,KAAK,QAAQ,MAAM,UAAU,CAAC;AACrC,OAAO,EAAa,aAAa,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAEtE,cAAc;AACd,MAAM,QAAQ,GAAG,sDAAsD,CAAC;AACxE,MAAM,SAAS,GAAG,wDAAwD,CAAC;AAE3E,aAAa;AACb,MAAM,eAAe,GAAG,CAAC,YAAY,EAAE,mBAAmB,EAAE,UAAU,EAAE,gBAAgB,CAAC,CAAC;AAE1F;;GAEG;AACH,MAAM,UAAU,eAAe,CAAC,KAAa;IAC3C,MAAM,MAAM,GAAG,IAAI,eAAe,CAAC;QACjC,MAAM,EAAE,KAAK;QACb,YAAY,EAAE,2BAA2B;QACzC,KAAK,EAAE,eAAe,CAAC,IAAI,CAAC,GAAG,CAAC;KACjC,CAAC,CAAC;IACH,OAAO,GAAG,QAAQ,IAAI,MAAM,CAAC,QAAQ,EAAE,EAAE,CAAC;AAC5C,CAAC;AAED;;GAEG;AACH,SAAS,gBAAgB;IACvB,MAAM,EAAE,GAAG,QAAQ,CAAC,eAAe,CAAC;QAClC,KAAK,EAAE,OAAO,CAAC,KAAK;QACpB,MAAM,EAAE,OAAO,CAAC,MAAM;KACvB,CAAC,CAAC;IAEH,OAAO,IAAI,OAAO,CAAC,CAAC,OAAO,EAAE,MAAM,EAAE,EAAE;QACrC,SAAS;QACT,MAAM,OAAO,GAAG,UAAU,CAAC,GAAG,EAAE;YAC9B,EAAE,CAAC,KAAK,EAAE,CAAC;YACX,MAAM,CAAC,IAAI,KAAK,CAAC,UAAU,CAAC,CAAC,CAAC;QAChC,CAAC,EAAE,CAAC,GAAG,EAAE,GAAG,IAAI,CAAC,CAAC;QAElB,EAAE,CAAC,QAAQ,CAAC,mBAAmB,EAAE,CAAC,IAAI,EAAE,EAAE;YACxC,YAAY,CAAC,OAAO,CAAC,CAAC;YACtB,EAAE,CAAC,KAAK,EAAE,CAAC;YACX,OAAO,CAAC,IAAI,CAAC,IAAI,EAAE,CAAC,CAAC;QACvB,CAAC,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;AACL,CAAC;AAED;;GAEG;AACH,KAAK,UAAU,oBAAoB,CACjC,KAAa,EACb,SAAiB,EACjB,IAAY;IAEZ,MAAM,GAAG,GAAG,MAAM,KAAK,CAAC,SAAS,EAAE;QACjC,MAAM,EAAE,MAAM;QACd,OAAO,EAAE,EAAE,cAAc,EAAE,kBAAkB,EAAE;QAC/C,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC;YACnB,UAAU,EAAE,oBAAoB;YAChC,SAAS,EAAE,KAAK;YAChB,aAAa,EAAE,SAAS;YACxB,IAAI;SACL,CAAC;KACH,CAAC,CAAC;IAEH,MAAM,IAAI,GAAG,MAAM,GAAG,CAAC,IAAI,EAAS,CAAC;IAErC,IAAI,IAAI,CAAC,IAAI,KAAK,CAAC,EAAE,CAAC;QACpB,MAAM,IAAI,KAAK,CAAC,gBAAgB,IAAI,CAAC,GAAG,IAAI,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;IACtE,CAAC;IAED,MAAM,GAAG,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;IACvB,OAAO;QACL,YAAY,EAAE,IAAI,CAAC,YAAY;QAC/B,aAAa,EAAE,IAAI,CAAC,aAAa;QACjC,UAAU,EAAE,GAAG,GAAG,CAAC,IAAI,CAAC,UAAU,GAAG,IAAI,CAAC;QAC1C,kBAAkB,EAAE,GAAG,GAAG,CAAC,IAAI,CAAC,wBAAwB,GAAG,IAAI,CAAC;KACjE,CAAC;AACJ,CAAC;AAED;;GAEG;AACH,KAAK,UAAU,kBAAkB,CAC/B,KAAa,EACb,SAAiB,EACjB,YAAoB;IAEpB,MAAM,GAAG,GAAG,MAAM,KAAK,CAAC,SAAS,EAAE;QACjC,MAAM,EAAE,MAAM;QACd,OAAO,EAAE,EAAE,cAAc,EAAE,kBAAkB,EAAE;QAC/C,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC;YACnB,UAAU,EAAE,eAAe;YAC3B,SAAS,EAAE,KAAK;YAChB,aAAa,EAAE,SAAS;YACxB,aAAa,EAAE,YAAY;SAC5B,CAAC;KACH,CAAC,CAAC;IAEH,MAAM,IAAI,GAAG,MAAM,GAAG,CAAC,IAAI,EAAS,CAAC;IAErC,IAAI,IAAI,CAAC,IAAI,KAAK,CAAC,EAAE,CAAC;QACpB,MAAM,IAAI,KAAK,CAAC,gBAAgB,IAAI,CAAC,GAAG,IAAI,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;IACtE,CAAC;IAED,MAAM,GAAG,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;IACvB,OAAO;QACL,YAAY,EAAE,IAAI,CAAC,YAAY;QAC/B,aAAa,EAAE,IAAI,CAAC,aAAa;QACjC,UAAU,EAAE,GAAG,GAAG,CAAC,IAAI,CAAC,UAAU,GAAG,IAAI,CAAC;QAC1C,kBAAkB,EAAE,GAAG,GAAG,CAAC,IAAI,CAAC,wBAAwB,GAAG,IAAI,CAAC;KACjE,CAAC;AACJ,CAAC;AAED;;;;;GAKG;AACH,MAAM,CAAC,KAAK,UAAU,iBAAiB,CACrC,KAAa,EACb,SAAiB,EACjB,OAAgB;IAEhB,MAAM,KAAK,GAAG,aAAa,CAAC,OAAO,CAAC,CAAC;IACrC,IAAI,CAAC,KAAK;QAAE,OAAO,IAAI,CAAC;IAExB,MAAM,GAAG,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;IAEvB,8BAA8B;IAC9B,IAAI,KAAK,CAAC,UAAU,GAAG,GAAG,GAAG,CAAC,GAAG,EAAE,GAAG,IAAI,EAAE,CAAC;QAC3C,OAAO,KAAK,CAAC,YAAY,CAAC;IAC5B,CAAC;IAED,yBAAyB;IACzB,IAAI,KAAK,CAAC,kBAAkB,GAAG,GAAG,EAAE,CAAC;QACnC,IAAI,CAAC;YACH,MAAM,QAAQ,GAAG,MAAM,kBAAkB,CAAC,KAAK,EAAE,SAAS,EAAE,KAAK,CAAC,aAAa,CAAC,CAAC;YACjF,aAAa,CAAC,QAAQ,EAAE,OAAO,CAAC,CAAC;YACjC,OAAO,QAAQ,CAAC,YAAY,CAAC;QAC/B,CAAC;QAAC,MAAM,CAAC;YACP,OAAO,IAAI,CAAC;QACd,CAAC;IACH,CAAC;IAED,OAAO;IACP,OAAO,IAAI,CAAC;AACd,CAAC;AAED;;GAEG;AACH,MAAM,CAAC,KAAK,UAAU,WAAW,CAC/B,KAAa,EACb,SAAiB,EACjB,OAAgB;IAEhB,OAAO,CAAC,GAAG,CAAC,kBAAkB,CAAC,CAAC;IAChC,OAAO,CAAC,GAAG,CAAC,qBAAqB,CAAC,CAAC;IACnC,OAAO,CAAC,GAAG,CAAC,eAAe,CAAC,KAAK,CAAC,CAAC,CAAC;IACpC,OAAO,CAAC,GAAG,CAAC,0BAA0B,CAAC,CAAC;IAExC,YAAY;IACZ,MAAM,IAAI,GAAG,MAAM,gBAAgB,EAAE,CAAC;IACtC,OAAO,CAAC,GAAG,CAAC,wBAAwB,CAAC,CAAC;IAEtC,WAAW;IACX,MAAM,KAAK,GAAG,MAAM,oBAAoB,CAAC,KAAK,EAAE,SAAS,EAAE,IAAI,CAAC,CAAC;IACjE,aAAa,CAAC,KAAK,EAAE,OAAO,CAAC,CAAC;IAC9B,OAAO,CAAC,GAAG,CAAC,WAAW,CAAC,CAAC;IAEzB,OAAO,KAAK,CAAC,YAAY,CAAC;AAC5B,CAAC"}
|