opencode-codebuddy-external-auth 1.0.21 → 1.0.22

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 +69 -12
  2. package/package.json +1 -1
package/dist/plugin.js CHANGED
@@ -9,7 +9,7 @@ const CONFIG = {
9
9
  // IOA 版本使用 copilot.tencent.com 进行认证
10
10
  serverUrl: "https://copilot.tencent.com",
11
11
  // 真实对话 API 路径
12
- chatCompletionsPath: "/v2/chat/completions",
12
+ chatCompletionsPath: "/v2/plugin/chat/completions",
13
13
  // 平台标识
14
14
  platform: "CLI",
15
15
  appVersion: "2.37.20",
@@ -39,6 +39,35 @@ function generateUuid() {
39
39
  }
40
40
  return `${Date.now()}-${Math.random().toString(16).slice(2)}`;
41
41
  }
42
+ function generateHexId(length) {
43
+ const bytes = Math.ceil(length / 2);
44
+ const buffer = new Uint8Array(bytes);
45
+ if (globalThis.crypto?.getRandomValues) {
46
+ globalThis.crypto.getRandomValues(buffer);
47
+ }
48
+ else {
49
+ for (let i = 0; i < buffer.length; i += 1) {
50
+ buffer[i] = Math.floor(Math.random() * 256);
51
+ }
52
+ }
53
+ return Array.from(buffer)
54
+ .map((b) => b.toString(16).padStart(2, "0"))
55
+ .join("")
56
+ .slice(0, length);
57
+ }
58
+ function buildTraceHeaders() {
59
+ const traceId = generateHexId(32);
60
+ const spanId = generateHexId(16);
61
+ const parentSpanId = generateHexId(16);
62
+ const sampled = "1";
63
+ return {
64
+ "X-B3-TraceId": traceId,
65
+ "X-B3-ParentSpanId": parentSpanId,
66
+ "X-B3-SpanId": spanId,
67
+ "X-B3-Sampled": sampled,
68
+ b3: `${traceId}-${spanId}-${sampled}-${parentSpanId}`,
69
+ };
70
+ }
42
71
  function decodeJwtPayload(token) {
43
72
  try {
44
73
  const parts = token.split(".");
@@ -204,10 +233,25 @@ function pickFallbackModel(models) {
204
233
  return "glm-4.7-ioa";
205
234
  return models[0] || "";
206
235
  }
236
+ function buildEnterpriseHeaders(accessToken) {
237
+ const tenantId = cachedTenantId || resolveTenantId(accessToken);
238
+ const enterpriseId = cachedEnterpriseId || resolveEnterpriseId(accessToken);
239
+ const resolvedTenantId = tenantId || enterpriseId;
240
+ if (tenantId)
241
+ cachedTenantId = tenantId;
242
+ if (enterpriseId)
243
+ cachedEnterpriseId = enterpriseId;
244
+ const headers = {};
245
+ if (resolvedTenantId)
246
+ headers["X-Tenant-Id"] = resolvedTenantId;
247
+ if (enterpriseId)
248
+ headers["X-Enterprise-Id"] = enterpriseId;
249
+ return headers;
250
+ }
207
251
  async function buildAuthHeaders(accessToken) {
208
252
  const payload = decodeJwtPayload(accessToken);
209
253
  const roles = payload?.realm_access?.roles || payload?.resource_access?.account?.roles;
210
- const tenantId = cachedTenantId || resolveTenantId(accessToken);
254
+ let tenantId = cachedTenantId || resolveTenantId(accessToken);
211
255
  let enterpriseId = cachedEnterpriseId || resolveEnterpriseId(accessToken);
212
256
  const userId = cachedUserId || resolveUserId(accessToken);
213
257
  if (!enterpriseId) {
@@ -217,6 +261,9 @@ async function buildAuthHeaders(accessToken) {
217
261
  cachedModelIds = config.models;
218
262
  }
219
263
  }
264
+ if (!tenantId && enterpriseId) {
265
+ tenantId = enterpriseId;
266
+ }
220
267
  if (tenantId)
221
268
  cachedTenantId = tenantId;
222
269
  if (enterpriseId)
@@ -243,6 +290,8 @@ async function buildAuthHeaders(accessToken) {
243
290
  const conversationId = generateUuid();
244
291
  const messageId = generateUuid();
245
292
  const requestId = messageId;
293
+ const traceHeaders = buildTraceHeaders();
294
+ const encodedUserId = userId ? encodeURIComponent(userId) : "";
246
295
  const headers = {
247
296
  "Accept": "application/json",
248
297
  "Content-Type": "application/json",
@@ -259,13 +308,14 @@ async function buildAuthHeaders(accessToken) {
259
308
  "X-Domain": CONFIG.domain,
260
309
  "X-Product": CONFIG.product,
261
310
  "User-Agent": `CLI/${CONFIG.appVersion} CodeBuddy/${CONFIG.appVersion}`,
311
+ ...traceHeaders,
262
312
  };
263
313
  if (tenantId)
264
314
  headers["X-Tenant-Id"] = tenantId;
265
315
  if (enterpriseId)
266
316
  headers["X-Enterprise-Id"] = enterpriseId;
267
- if (userId)
268
- headers["X-User-Id"] = userId;
317
+ if (encodedUserId)
318
+ headers["X-User-Id"] = encodedUserId;
269
319
  return headers;
270
320
  }
271
321
  /**
@@ -503,7 +553,7 @@ async function executeViaAuthApi(openaiRequest, auth) {
503
553
  };
504
554
  let response = await doRequest(accessToken);
505
555
  if ((response.status === 401 || response.status === 403) && auth.refresh) {
506
- const refreshed = await refreshAccessToken(auth.refresh);
556
+ const refreshed = await refreshAccessToken(auth.refresh, accessToken);
507
557
  if (refreshed?.accessToken) {
508
558
  accessToken = refreshed.accessToken;
509
559
  response = await doRequest(accessToken);
@@ -716,15 +766,22 @@ async function pollForToken(state, expiresAt, signal) {
716
766
  /**
717
767
  * Refresh the access token
718
768
  */
719
- async function refreshAccessToken(refreshToken) {
769
+ async function refreshAccessToken(refreshToken, accessToken) {
720
770
  try {
771
+ const traceHeaders = buildTraceHeaders();
772
+ const headers = {
773
+ "Content-Type": "application/json",
774
+ "Accept": "application/json",
775
+ "X-Refresh-Token": refreshToken,
776
+ ...traceHeaders,
777
+ };
778
+ if (accessToken) {
779
+ headers["Authorization"] = `Bearer ${accessToken}`;
780
+ Object.assign(headers, buildEnterpriseHeaders(accessToken));
781
+ }
721
782
  const response = await fetch(`${CONFIG.serverUrl}/v2/plugin/auth/token/refresh`, {
722
783
  method: "POST",
723
- headers: {
724
- "Content-Type": "application/json",
725
- "Accept": "application/json",
726
- "Authorization": `Bearer ${refreshToken}`,
727
- },
784
+ headers,
728
785
  });
729
786
  if (!response.ok) {
730
787
  console.warn(`[codebuddy-external] Token refresh failed: ${response.status}`);
@@ -766,7 +823,7 @@ const CodeBuddyExternalAuthPlugin = async (_input) => {
766
823
  if (auth.type !== "oauth" || !auth.refresh) {
767
824
  return null;
768
825
  }
769
- const tokenData = await refreshAccessToken(auth.refresh);
826
+ const tokenData = await refreshAccessToken(auth.refresh, auth.access);
770
827
  if (!tokenData) {
771
828
  return null;
772
829
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "opencode-codebuddy-external-auth",
3
- "version": "1.0.21",
3
+ "version": "1.0.22",
4
4
  "description": "OpenCode plugin for CodeBuddy External (IOA) authentication",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",