opencode-codebuddy-external-auth 1.0.3 → 1.0.4

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.
Files changed (2) hide show
  1. package/dist/plugin.js +34 -16
  2. package/package.json +1 -1
package/dist/plugin.js CHANGED
@@ -44,19 +44,27 @@ function createAuthenticatedFetch(accessToken, userId) {
44
44
  // ============================================================================
45
45
  /**
46
46
  * Request auth state from server - the state is generated by server, not client!
47
- * This matches the behavior of `codebuddy /login` command
47
+ *
48
+ * 关键发现:
49
+ * 1. 使用 POST 方法,不是 GET
50
+ * 2. 路径是 /v2/plugin/auth/state,不是 /plugin/auth/state
51
+ * 3. 需要设置 X-No-Authorization 等 Headers
48
52
  */
49
53
  async function requestAuthState() {
50
- // 构造与 codebuddy CLI 相同的请求
51
- // codebuddy 输出的 URL: https://copilot.tencent.com/login?platform=CLI&state=xxx&ioa=1
52
54
  const params = new URLSearchParams({
53
55
  platform: CONFIG.platform,
54
56
  ioa: "1",
55
57
  });
56
- const response = await fetch(`${CONFIG.serverUrl}/plugin/auth/state?${params.toString()}`, {
57
- method: "GET",
58
+ const response = await fetch(`${CONFIG.serverUrl}/v2/plugin/auth/state?${params.toString()}`, {
59
+ method: "POST", // 关键:使用 POST 方法
58
60
  headers: {
59
- Accept: "application/json",
61
+ "Accept": "application/json",
62
+ "Content-Type": "application/json",
63
+ // 这些 Headers 告诉服务端跳过认证检查
64
+ "X-No-Authorization": "true",
65
+ "X-No-User-Id": "true",
66
+ "X-No-Enterprise-Id": "true",
67
+ "X-No-Department-Info": "true",
60
68
  },
61
69
  });
62
70
  if (!response.ok) {
@@ -64,11 +72,11 @@ async function requestAuthState() {
64
72
  throw new Error(`Auth state request failed: ${response.status} - ${text}`);
65
73
  }
66
74
  const data = await response.json();
67
- if (!data.data?.state) {
75
+ if (data.code !== 0 || !data.data?.state) {
68
76
  throw new Error(`Invalid auth state response: ${JSON.stringify(data)}`);
69
77
  }
70
- // 构造登录 URL(与 codebuddy CLI 输出的格式一致)
71
- const loginUrl = data.data.url ||
78
+ // 使用服务端返回的 authUrl,或构造默认 URL
79
+ const loginUrl = data.data.authUrl ||
72
80
  `${CONFIG.serverUrl}/login?platform=${CONFIG.platform}&state=${data.data.state}&ioa=1`;
73
81
  return {
74
82
  state: data.data.state,
@@ -77,6 +85,8 @@ async function requestAuthState() {
77
85
  }
78
86
  /**
79
87
  * Poll for token after user completes browser authentication
88
+ *
89
+ * 注意:token 端点也需要使用 /v2 前缀
80
90
  */
81
91
  async function pollForToken(state, expiresAt, signal) {
82
92
  const pollInterval = 3000; // 3 seconds
@@ -86,16 +96,20 @@ async function pollForToken(state, expiresAt, signal) {
86
96
  }
87
97
  await sleep(pollInterval);
88
98
  try {
89
- const response = await fetch(`${CONFIG.serverUrl}/plugin/auth/token?state=${state}`, {
99
+ const response = await fetch(`${CONFIG.serverUrl}/v2/plugin/auth/token?state=${state}`, {
90
100
  method: "GET",
91
101
  headers: {
92
- Accept: "application/json",
102
+ "Accept": "application/json",
103
+ "X-No-Authorization": "true",
104
+ "X-No-User-Id": "true",
105
+ "X-No-Enterprise-Id": "true",
106
+ "X-No-Department-Info": "true",
93
107
  },
94
108
  signal,
95
109
  });
96
110
  if (response.ok) {
97
111
  const data = await response.json();
98
- if (data.data?.accessToken) {
112
+ if (data.code === 0 && data.data?.accessToken) {
99
113
  return data.data;
100
114
  }
101
115
  }
@@ -115,11 +129,12 @@ async function pollForToken(state, expiresAt, signal) {
115
129
  */
116
130
  async function refreshAccessToken(refreshToken) {
117
131
  try {
118
- const response = await fetch(`${CONFIG.serverUrl}/plugin/auth/token/refresh`, {
132
+ const response = await fetch(`${CONFIG.serverUrl}/v2/plugin/auth/token/refresh`, {
119
133
  method: "POST",
120
134
  headers: {
121
135
  "Content-Type": "application/json",
122
- Authorization: `Bearer ${refreshToken}`,
136
+ "Accept": "application/json",
137
+ "Authorization": `Bearer ${refreshToken}`,
123
138
  },
124
139
  });
125
140
  if (!response.ok) {
@@ -127,6 +142,10 @@ async function refreshAccessToken(refreshToken) {
127
142
  return null;
128
143
  }
129
144
  const data = await response.json();
145
+ if (data.code !== 0) {
146
+ console.warn(`[codebuddy-external] Token refresh error: ${data.msg}`);
147
+ return null;
148
+ }
130
149
  return data.data || null;
131
150
  }
132
151
  catch (error) {
@@ -173,8 +192,7 @@ const CodeBuddyExternalAuthPlugin = async (_input) => {
173
192
  label: "IOA 登录 (浏览器)",
174
193
  type: "oauth",
175
194
  async authorize() {
176
- // 关键修改:从服务端获取 state,而不是客户端生成
177
- // 这与 codebuddy CLI 的 /login 命令行为一致
195
+ // 从服务端获取 state(服务端生成,非客户端)
178
196
  const authState = await requestAuthState();
179
197
  const expiresAt = Date.now() + 10 * 60 * 1000; // 10 minutes
180
198
  return {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "opencode-codebuddy-external-auth",
3
- "version": "1.0.3",
3
+ "version": "1.0.4",
4
4
  "description": "OpenCode plugin for CodeBuddy External (IOA) authentication",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",