opencode-qwen-oauth 1.0.1 → 1.1.0

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.
@@ -0,0 +1,5 @@
1
+ /**
2
+ * Browser utilities for opening URLs
3
+ */
4
+ export declare function openBrowser(url: string): void;
5
+ //# sourceMappingURL=browser.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"browser.d.ts","sourceRoot":"","sources":["../src/browser.ts"],"names":[],"mappings":"AAAA;;GAEG;AAIH,wBAAgB,WAAW,CAAC,GAAG,EAAE,MAAM,GAAG,IAAI,CAmB7C"}
@@ -0,0 +1,24 @@
1
+ /**
2
+ * Browser utilities for opening URLs
3
+ */
4
+ import { spawn } from "node:child_process";
5
+ export function openBrowser(url) {
6
+ try {
7
+ const platform = process.platform;
8
+ const command = platform === "darwin"
9
+ ? "open"
10
+ : platform === "win32"
11
+ ? "rundll32"
12
+ : "xdg-open";
13
+ const args = platform === "win32" ? ["url.dll,FileProtocolHandler", url] : [url];
14
+ const child = spawn(command, args, {
15
+ stdio: "ignore",
16
+ detached: true,
17
+ });
18
+ child.unref?.();
19
+ }
20
+ catch {
21
+ // Ignore errors
22
+ }
23
+ }
24
+ //# sourceMappingURL=browser.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"browser.js","sourceRoot":"","sources":["../src/browser.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAAE,KAAK,EAAE,MAAM,oBAAoB,CAAC;AAE3C,MAAM,UAAU,WAAW,CAAC,GAAW;IACrC,IAAI,CAAC;QACH,MAAM,QAAQ,GAAG,OAAO,CAAC,QAAQ,CAAC;QAClC,MAAM,OAAO,GACX,QAAQ,KAAK,QAAQ;YACnB,CAAC,CAAC,MAAM;YACR,CAAC,CAAC,QAAQ,KAAK,OAAO;gBACpB,CAAC,CAAC,UAAU;gBACZ,CAAC,CAAC,UAAU,CAAC;QACnB,MAAM,IAAI,GACR,QAAQ,KAAK,OAAO,CAAC,CAAC,CAAC,CAAC,6BAA6B,EAAE,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC;QACtE,MAAM,KAAK,GAAG,KAAK,CAAC,OAAO,EAAE,IAAI,EAAE;YACjC,KAAK,EAAE,QAAQ;YACf,QAAQ,EAAE,IAAI;SACf,CAAC,CAAC;QACH,KAAK,CAAC,KAAK,EAAE,EAAE,CAAC;IAClB,CAAC;IAAC,MAAM,CAAC;QACP,gBAAgB;IAClB,CAAC;AACH,CAAC"}
@@ -0,0 +1,10 @@
1
+ /**
2
+ * Constants for Qwen OAuth Plugin
3
+ */
4
+ export declare const QWEN_OAUTH_BASE_URL = "https://chat.qwen.ai";
5
+ export declare const QWEN_DEVICE_CODE_ENDPOINT = "/api/v1/oauth2/device/code";
6
+ export declare const QWEN_TOKEN_ENDPOINT = "/api/v1/oauth2/token";
7
+ export declare const QWEN_CLIENT_ID = "f0304373b74a44d2b584a3fb70ca9e56";
8
+ export declare const QWEN_SCOPES: string[];
9
+ export declare const QWEN_API_BASE_URL = "https://portal.qwen.ai/v1";
10
+ //# sourceMappingURL=constants.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"constants.d.ts","sourceRoot":"","sources":["../src/constants.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,eAAO,MAAM,mBAAmB,yBAAyB,CAAC;AAC1D,eAAO,MAAM,yBAAyB,+BAA+B,CAAC;AACtE,eAAO,MAAM,mBAAmB,yBAAyB,CAAC;AAC1D,eAAO,MAAM,cAAc,qCAAqC,CAAC;AACjE,eAAO,MAAM,WAAW,UAAqD,CAAC;AAC9E,eAAO,MAAM,iBAAiB,8BAA8B,CAAC"}
@@ -0,0 +1,10 @@
1
+ /**
2
+ * Constants for Qwen OAuth Plugin
3
+ */
4
+ export const QWEN_OAUTH_BASE_URL = "https://chat.qwen.ai";
5
+ export const QWEN_DEVICE_CODE_ENDPOINT = "/api/v1/oauth2/device/code";
6
+ export const QWEN_TOKEN_ENDPOINT = "/api/v1/oauth2/token";
7
+ export const QWEN_CLIENT_ID = "f0304373b74a44d2b584a3fb70ca9e56";
8
+ export const QWEN_SCOPES = ["openid", "profile", "email", "model.completion"];
9
+ export const QWEN_API_BASE_URL = "https://portal.qwen.ai/v1";
10
+ //# sourceMappingURL=constants.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"constants.js","sourceRoot":"","sources":["../src/constants.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,MAAM,CAAC,MAAM,mBAAmB,GAAG,sBAAsB,CAAC;AAC1D,MAAM,CAAC,MAAM,yBAAyB,GAAG,4BAA4B,CAAC;AACtE,MAAM,CAAC,MAAM,mBAAmB,GAAG,sBAAsB,CAAC;AAC1D,MAAM,CAAC,MAAM,cAAc,GAAG,kCAAkC,CAAC;AACjE,MAAM,CAAC,MAAM,WAAW,GAAG,CAAC,QAAQ,EAAE,SAAS,EAAE,OAAO,EAAE,kBAAkB,CAAC,CAAC;AAC9E,MAAM,CAAC,MAAM,iBAAiB,GAAG,2BAA2B,CAAC"}
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,KAAK,EAAE,MAAM,EAAe,MAAM,qBAAqB,CAAC;AAoQ/D,eAAO,MAAM,eAAe,EAAE,MAiG7B,CAAC;AAEF,eAAe,eAAe,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,KAAK,EAAE,MAAM,EAAe,MAAM,qBAAqB,CAAC;AAM/D,eAAO,MAAM,eAAe,EAAE,MAiG7B,CAAC;AAEF,eAAe,eAAe,CAAC"}
package/dist/index.js CHANGED
@@ -4,177 +4,10 @@
4
4
  *
5
5
  * @packageDocumentation
6
6
  */
7
- import { createHash, randomBytes } from "node:crypto";
8
- import { spawn } from "node:child_process";
9
- import { appendFileSync, mkdirSync, existsSync } from "node:fs";
10
- import { join } from "node:path";
11
- import { homedir } from "node:os";
12
- // ============================================
13
- // Constants
14
- // ============================================
15
- const QWEN_OAUTH_BASE_URL = "https://chat.qwen.ai";
16
- const QWEN_DEVICE_CODE_ENDPOINT = "/api/v1/oauth2/device/code";
17
- const QWEN_TOKEN_ENDPOINT = "/api/v1/oauth2/token";
18
- const QWEN_CLIENT_ID = "f0304373b74a44d2b584a3fb70ca9e56";
19
- const QWEN_SCOPES = ["openid", "profile", "email", "model.completion"];
20
- const QWEN_API_BASE_URL = "https://portal.qwen.ai/v1";
21
- // ============================================
22
- // Logging
23
- // ============================================
24
- function getLogDir() {
25
- const xdgConfig = process.env.XDG_CONFIG_HOME || join(homedir(), ".config");
26
- return join(xdgConfig, "opencode", "logs");
27
- }
28
- function getLogFilePath() {
29
- return join(getLogDir(), "qwen-oauth.log");
30
- }
31
- function ensureLogDir() {
32
- const logDir = getLogDir();
33
- if (!existsSync(logDir)) {
34
- mkdirSync(logDir, { recursive: true, mode: 0o700 });
35
- }
36
- }
37
- function writeLog(message) {
38
- try {
39
- ensureLogDir();
40
- const timestamp = new Date().toISOString();
41
- const logLine = `[${timestamp}] ${message}\n`;
42
- appendFileSync(getLogFilePath(), logLine, { encoding: "utf-8" });
43
- }
44
- catch {
45
- // Silently ignore log write errors
46
- }
47
- }
48
- const DEBUG = process.env.QWEN_OAUTH_DEBUG === "true" ||
49
- process.env.QWEN_OAUTH_DEBUG === "1";
50
- function debugLog(message, data) {
51
- const logMessage = data ? `${message} ${JSON.stringify(data)}` : message;
52
- writeLog(logMessage);
53
- }
54
- // ============================================
55
- // PKCE
56
- // ============================================
57
- function base64UrlEncode(buffer) {
58
- return buffer
59
- .toString("base64")
60
- .replace(/\+/g, "-")
61
- .replace(/\//g, "_")
62
- .replace(/=+$/, "");
63
- }
64
- function createPkcePair() {
65
- const verifier = base64UrlEncode(randomBytes(32));
66
- const challenge = base64UrlEncode(createHash("sha256").update(verifier).digest());
67
- return { verifier, challenge };
68
- }
69
- // ============================================
70
- // Browser
71
- // ============================================
72
- function openBrowser(url) {
73
- try {
74
- const platform = process.platform;
75
- const command = platform === "darwin"
76
- ? "open"
77
- : platform === "win32"
78
- ? "rundll32"
79
- : "xdg-open";
80
- const args = platform === "win32" ? ["url.dll,FileProtocolHandler", url] : [url];
81
- const child = spawn(command, args, {
82
- stdio: "ignore",
83
- detached: true,
84
- });
85
- child.unref?.();
86
- }
87
- catch {
88
- // Ignore errors
89
- }
90
- }
91
- async function authorizeDevice() {
92
- const { verifier, challenge } = createPkcePair();
93
- const params = new URLSearchParams({
94
- client_id: QWEN_CLIENT_ID,
95
- scope: QWEN_SCOPES.join(" "),
96
- code_challenge: challenge,
97
- code_challenge_method: "S256",
98
- });
99
- const response = await fetch(`${QWEN_OAUTH_BASE_URL}${QWEN_DEVICE_CODE_ENDPOINT}`, {
100
- method: "POST",
101
- headers: { "Content-Type": "application/x-www-form-urlencoded" },
102
- body: params.toString(),
103
- });
104
- if (!response.ok) {
105
- throw new Error(`Failed to start device flow: ${response.statusText}`);
106
- }
107
- const data = (await response.json());
108
- return {
109
- device_code: data.device_code,
110
- user_code: data.user_code,
111
- verification_uri: data.verification_uri,
112
- verification_uri_complete: data.verification_uri_complete,
113
- expires_in: data.expires_in,
114
- interval: data.interval || 5,
115
- verifier,
116
- };
117
- }
118
- async function pollForToken(deviceCode, codeVerifier, intervalSeconds, expiresIn) {
119
- const timeoutMs = expiresIn * 1000;
120
- const startTime = Date.now();
121
- let currentInterval = intervalSeconds * 1000;
122
- debugLog("Starting token polling", { timeoutMs, interval: currentInterval });
123
- while (Date.now() - startTime < timeoutMs) {
124
- await new Promise((resolve) => setTimeout(resolve, currentInterval));
125
- const params = new URLSearchParams({
126
- client_id: QWEN_CLIENT_ID,
127
- grant_type: "urn:ietf:params:oauth:grant-type:device_code",
128
- device_code: deviceCode,
129
- code_verifier: codeVerifier,
130
- });
131
- debugLog("Polling for token...");
132
- const response = await fetch(`${QWEN_OAUTH_BASE_URL}${QWEN_TOKEN_ENDPOINT}`, {
133
- method: "POST",
134
- headers: { "Content-Type": "application/x-www-form-urlencoded" },
135
- body: params.toString(),
136
- });
137
- if (response.ok) {
138
- const data = (await response.json());
139
- debugLog("Token received successfully");
140
- return {
141
- success: true,
142
- access_token: data.access_token,
143
- refresh_token: data.refresh_token,
144
- expires_in: data.expires_in,
145
- };
146
- }
147
- const error = (await response.json().catch(() => ({})));
148
- if (error.error === "authorization_pending") {
149
- debugLog("Authorization pending, retrying...");
150
- continue;
151
- }
152
- if (error.error === "slow_down") {
153
- currentInterval += 5000;
154
- debugLog("Server requested slow down, new interval:", {
155
- interval: currentInterval,
156
- });
157
- continue;
158
- }
159
- if (error.error === "expired_token") {
160
- debugLog("Device code expired");
161
- return {
162
- success: false,
163
- error: "Device code expired. Please try again.",
164
- };
165
- }
166
- debugLog(`Token polling failed: ${error.error_description || "unknown error"}`);
167
- return {
168
- success: false,
169
- error: error.error_description || "Authentication failed",
170
- };
171
- }
172
- debugLog("Polling timeout exceeded");
173
- return { success: false, error: "Polling timeout - device code expired" };
174
- }
175
- // ============================================
176
- // Plugin
177
- // ============================================
7
+ import { QWEN_API_BASE_URL } from "./constants.js";
8
+ import { debugLog } from "./logger.js";
9
+ import { openBrowser } from "./browser.js";
10
+ import { authorizeDevice, pollForToken } from "./oauth.js";
178
11
  export const QwenOAuthPlugin = async ({ project, client, $, directory, worktree, }) => {
179
12
  debugLog("Plugin initialized", {
180
13
  directory,
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,6 @@
1
+ /**
2
+ * Logging utilities for Qwen OAuth Plugin
3
+ */
4
+ export declare const DEBUG: boolean;
5
+ export declare function debugLog(message: string, data?: Record<string, unknown>): void;
6
+ //# sourceMappingURL=logger.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"logger.d.ts","sourceRoot":"","sources":["../src/logger.ts"],"names":[],"mappings":"AAAA;;GAEG;AAiCH,eAAO,MAAM,KAAK,SAEoB,CAAC;AAEvC,wBAAgB,QAAQ,CAAC,OAAO,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,IAAI,CAG9E"}
package/dist/logger.js ADDED
@@ -0,0 +1,37 @@
1
+ /**
2
+ * Logging utilities for Qwen OAuth Plugin
3
+ */
4
+ import { appendFileSync, mkdirSync, existsSync } from "node:fs";
5
+ import { join } from "node:path";
6
+ import { homedir } from "node:os";
7
+ function getLogDir() {
8
+ const xdgConfig = process.env.XDG_CONFIG_HOME || join(homedir(), ".config");
9
+ return join(xdgConfig, "opencode", "logs");
10
+ }
11
+ function getLogFilePath() {
12
+ return join(getLogDir(), "qwen-oauth.log");
13
+ }
14
+ function ensureLogDir() {
15
+ const logDir = getLogDir();
16
+ if (!existsSync(logDir)) {
17
+ mkdirSync(logDir, { recursive: true, mode: 0o700 });
18
+ }
19
+ }
20
+ function writeLog(message) {
21
+ try {
22
+ ensureLogDir();
23
+ const timestamp = new Date().toISOString();
24
+ const logLine = `[${timestamp}] ${message}\n`;
25
+ appendFileSync(getLogFilePath(), logLine, { encoding: "utf-8" });
26
+ }
27
+ catch {
28
+ // Silently ignore log write errors
29
+ }
30
+ }
31
+ export const DEBUG = process.env.QWEN_OAUTH_DEBUG === "true" ||
32
+ process.env.QWEN_OAUTH_DEBUG === "1";
33
+ export function debugLog(message, data) {
34
+ const logMessage = data ? `${message} ${JSON.stringify(data)}` : message;
35
+ writeLog(logMessage);
36
+ }
37
+ //# sourceMappingURL=logger.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"logger.js","sourceRoot":"","sources":["../src/logger.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAAE,cAAc,EAAE,SAAS,EAAE,UAAU,EAAE,MAAM,SAAS,CAAC;AAChE,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AACjC,OAAO,EAAE,OAAO,EAAE,MAAM,SAAS,CAAC;AAElC,SAAS,SAAS;IAChB,MAAM,SAAS,GAAG,OAAO,CAAC,GAAG,CAAC,eAAe,IAAI,IAAI,CAAC,OAAO,EAAE,EAAE,SAAS,CAAC,CAAC;IAC5E,OAAO,IAAI,CAAC,SAAS,EAAE,UAAU,EAAE,MAAM,CAAC,CAAC;AAC7C,CAAC;AAED,SAAS,cAAc;IACrB,OAAO,IAAI,CAAC,SAAS,EAAE,EAAE,gBAAgB,CAAC,CAAC;AAC7C,CAAC;AAED,SAAS,YAAY;IACnB,MAAM,MAAM,GAAG,SAAS,EAAE,CAAC;IAC3B,IAAI,CAAC,UAAU,CAAC,MAAM,CAAC,EAAE,CAAC;QACxB,SAAS,CAAC,MAAM,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,IAAI,EAAE,KAAK,EAAE,CAAC,CAAC;IACtD,CAAC;AACH,CAAC;AAED,SAAS,QAAQ,CAAC,OAAe;IAC/B,IAAI,CAAC;QACH,YAAY,EAAE,CAAC;QACf,MAAM,SAAS,GAAG,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE,CAAC;QAC3C,MAAM,OAAO,GAAG,IAAI,SAAS,KAAK,OAAO,IAAI,CAAC;QAC9C,cAAc,CAAC,cAAc,EAAE,EAAE,OAAO,EAAE,EAAE,QAAQ,EAAE,OAAO,EAAE,CAAC,CAAC;IACnE,CAAC;IAAC,MAAM,CAAC;QACP,mCAAmC;IACrC,CAAC;AACH,CAAC;AAED,MAAM,CAAC,MAAM,KAAK,GAChB,OAAO,CAAC,GAAG,CAAC,gBAAgB,KAAK,MAAM;IACvC,OAAO,CAAC,GAAG,CAAC,gBAAgB,KAAK,GAAG,CAAC;AAEvC,MAAM,UAAU,QAAQ,CAAC,OAAe,EAAE,IAA8B;IACtE,MAAM,UAAU,GAAG,IAAI,CAAC,CAAC,CAAC,GAAG,OAAO,IAAI,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC,CAAC,OAAO,CAAC;IACzE,QAAQ,CAAC,UAAU,CAAC,CAAC;AACvB,CAAC"}
@@ -0,0 +1,21 @@
1
+ /**
2
+ * OAuth Device Flow implementation for Qwen
3
+ */
4
+ export interface DeviceAuthorization {
5
+ device_code: string;
6
+ user_code: string;
7
+ verification_uri: string;
8
+ verification_uri_complete: string;
9
+ expires_in: number;
10
+ interval: number;
11
+ verifier: string;
12
+ }
13
+ export declare function authorizeDevice(): Promise<DeviceAuthorization>;
14
+ export declare function pollForToken(deviceCode: string, codeVerifier: string, intervalSeconds: number, expiresIn: number): Promise<{
15
+ success: boolean;
16
+ access_token?: string;
17
+ refresh_token?: string;
18
+ expires_in?: number;
19
+ error?: string;
20
+ }>;
21
+ //# sourceMappingURL=oauth.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"oauth.d.ts","sourceRoot":"","sources":["../src/oauth.ts"],"names":[],"mappings":"AAAA;;GAEG;AAYH,MAAM,WAAW,mBAAmB;IAClC,WAAW,EAAE,MAAM,CAAC;IACpB,SAAS,EAAE,MAAM,CAAC;IAClB,gBAAgB,EAAE,MAAM,CAAC;IACzB,yBAAyB,EAAE,MAAM,CAAC;IAClC,UAAU,EAAE,MAAM,CAAC;IACnB,QAAQ,EAAE,MAAM,CAAC;IACjB,QAAQ,EAAE,MAAM,CAAC;CAClB;AAiBD,wBAAsB,eAAe,IAAI,OAAO,CAAC,mBAAmB,CAAC,CAiCpE;AAED,wBAAsB,YAAY,CAChC,UAAU,EAAE,MAAM,EAClB,YAAY,EAAE,MAAM,EACpB,eAAe,EAAE,MAAM,EACvB,SAAS,EAAE,MAAM,GAChB,OAAO,CAAC;IACT,OAAO,EAAE,OAAO,CAAC;IACjB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB,CAAC,CA4ED"}
package/dist/oauth.js ADDED
@@ -0,0 +1,91 @@
1
+ /**
2
+ * OAuth Device Flow implementation for Qwen
3
+ */
4
+ import { QWEN_OAUTH_BASE_URL, QWEN_DEVICE_CODE_ENDPOINT, QWEN_TOKEN_ENDPOINT, QWEN_CLIENT_ID, QWEN_SCOPES, } from "./constants.js";
5
+ import { createPkcePair } from "./pkce.js";
6
+ import { debugLog } from "./logger.js";
7
+ export async function authorizeDevice() {
8
+ const { verifier, challenge } = createPkcePair();
9
+ const params = new URLSearchParams({
10
+ client_id: QWEN_CLIENT_ID,
11
+ scope: QWEN_SCOPES.join(" "),
12
+ code_challenge: challenge,
13
+ code_challenge_method: "S256",
14
+ });
15
+ const response = await fetch(`${QWEN_OAUTH_BASE_URL}${QWEN_DEVICE_CODE_ENDPOINT}`, {
16
+ method: "POST",
17
+ headers: { "Content-Type": "application/x-www-form-urlencoded" },
18
+ body: params.toString(),
19
+ });
20
+ if (!response.ok) {
21
+ throw new Error(`Failed to start device flow: ${response.statusText}`);
22
+ }
23
+ const data = (await response.json());
24
+ return {
25
+ device_code: data.device_code,
26
+ user_code: data.user_code,
27
+ verification_uri: data.verification_uri,
28
+ verification_uri_complete: data.verification_uri_complete,
29
+ expires_in: data.expires_in,
30
+ interval: data.interval || 5,
31
+ verifier,
32
+ };
33
+ }
34
+ export async function pollForToken(deviceCode, codeVerifier, intervalSeconds, expiresIn) {
35
+ const timeoutMs = expiresIn * 1000;
36
+ const startTime = Date.now();
37
+ let currentInterval = intervalSeconds * 1000;
38
+ debugLog("Starting token polling", { timeoutMs, interval: currentInterval });
39
+ while (Date.now() - startTime < timeoutMs) {
40
+ await new Promise((resolve) => setTimeout(resolve, currentInterval));
41
+ const params = new URLSearchParams({
42
+ client_id: QWEN_CLIENT_ID,
43
+ grant_type: "urn:ietf:params:oauth:grant-type:device_code",
44
+ device_code: deviceCode,
45
+ code_verifier: codeVerifier,
46
+ });
47
+ debugLog("Polling for token...");
48
+ const response = await fetch(`${QWEN_OAUTH_BASE_URL}${QWEN_TOKEN_ENDPOINT}`, {
49
+ method: "POST",
50
+ headers: { "Content-Type": "application/x-www-form-urlencoded" },
51
+ body: params.toString(),
52
+ });
53
+ if (response.ok) {
54
+ const data = (await response.json());
55
+ debugLog("Token received successfully");
56
+ return {
57
+ success: true,
58
+ access_token: data.access_token,
59
+ refresh_token: data.refresh_token,
60
+ expires_in: data.expires_in,
61
+ };
62
+ }
63
+ const error = (await response.json().catch(() => ({})));
64
+ if (error.error === "authorization_pending") {
65
+ debugLog("Authorization pending, retrying...");
66
+ continue;
67
+ }
68
+ if (error.error === "slow_down") {
69
+ currentInterval += 5000;
70
+ debugLog("Server requested slow down, new interval:", {
71
+ interval: currentInterval,
72
+ });
73
+ continue;
74
+ }
75
+ if (error.error === "expired_token") {
76
+ debugLog("Device code expired");
77
+ return {
78
+ success: false,
79
+ error: "Device code expired. Please try again.",
80
+ };
81
+ }
82
+ debugLog(`Token polling failed: ${error.error_description || "unknown error"}`);
83
+ return {
84
+ success: false,
85
+ error: error.error_description || "Authentication failed",
86
+ };
87
+ }
88
+ debugLog("Polling timeout exceeded");
89
+ return { success: false, error: "Polling timeout - device code expired" };
90
+ }
91
+ //# sourceMappingURL=oauth.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"oauth.js","sourceRoot":"","sources":["../src/oauth.ts"],"names":[],"mappings":"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"}
package/dist/pkce.d.ts ADDED
@@ -0,0 +1,8 @@
1
+ /**
2
+ * PKCE (Proof Key for Code Exchange) utilities
3
+ */
4
+ export declare function createPkcePair(): {
5
+ verifier: string;
6
+ challenge: string;
7
+ };
8
+ //# sourceMappingURL=pkce.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"pkce.d.ts","sourceRoot":"","sources":["../src/pkce.ts"],"names":[],"mappings":"AAAA;;GAEG;AAYH,wBAAgB,cAAc,IAAI;IAAE,QAAQ,EAAE,MAAM,CAAC;IAAC,SAAS,EAAE,MAAM,CAAA;CAAE,CAMxE"}
package/dist/pkce.js ADDED
@@ -0,0 +1,17 @@
1
+ /**
2
+ * PKCE (Proof Key for Code Exchange) utilities
3
+ */
4
+ import { createHash, randomBytes } from "node:crypto";
5
+ function base64UrlEncode(buffer) {
6
+ return buffer
7
+ .toString("base64")
8
+ .replace(/\+/g, "-")
9
+ .replace(/\//g, "_")
10
+ .replace(/=+$/, "");
11
+ }
12
+ export function createPkcePair() {
13
+ const verifier = base64UrlEncode(randomBytes(32));
14
+ const challenge = base64UrlEncode(createHash("sha256").update(verifier).digest());
15
+ return { verifier, challenge };
16
+ }
17
+ //# sourceMappingURL=pkce.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"pkce.js","sourceRoot":"","sources":["../src/pkce.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAAE,UAAU,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AAEtD,SAAS,eAAe,CAAC,MAAc;IACrC,OAAO,MAAM;SACV,QAAQ,CAAC,QAAQ,CAAC;SAClB,OAAO,CAAC,KAAK,EAAE,GAAG,CAAC;SACnB,OAAO,CAAC,KAAK,EAAE,GAAG,CAAC;SACnB,OAAO,CAAC,KAAK,EAAE,EAAE,CAAC,CAAC;AACxB,CAAC;AAED,MAAM,UAAU,cAAc;IAC5B,MAAM,QAAQ,GAAG,eAAe,CAAC,WAAW,CAAC,EAAE,CAAC,CAAC,CAAC;IAClD,MAAM,SAAS,GAAG,eAAe,CAC/B,UAAU,CAAC,QAAQ,CAAC,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC,MAAM,EAAE,CAC/C,CAAC;IACF,OAAO,EAAE,QAAQ,EAAE,SAAS,EAAE,CAAC;AACjC,CAAC"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "opencode-qwen-oauth",
3
- "version": "1.0.1",
3
+ "version": "1.1.0",
4
4
  "description": "Qwen OAuth authentication plugin for OpenCode - authenticate with Qwen.ai using OAuth device flow",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",