opencode-qwen-oauth 1.1.0 → 2.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.
- package/README.md +67 -4
- package/dist/browser.d.ts +5 -0
- package/dist/browser.d.ts.map +1 -1
- package/dist/browser.js +71 -8
- package/dist/browser.js.map +1 -1
- package/dist/config.d.ts +23 -0
- package/dist/config.d.ts.map +1 -0
- package/dist/config.js +25 -0
- package/dist/config.js.map +1 -0
- package/dist/errors.d.ts +40 -0
- package/dist/errors.d.ts.map +1 -0
- package/dist/errors.js +85 -0
- package/dist/errors.js.map +1 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +122 -36
- package/dist/index.js.map +1 -1
- package/dist/logger.d.ts +9 -0
- package/dist/logger.d.ts.map +1 -1
- package/dist/logger.js +46 -4
- package/dist/logger.js.map +1 -1
- package/dist/mutex.d.ts +30 -0
- package/dist/mutex.d.ts.map +1 -0
- package/dist/mutex.js +90 -0
- package/dist/mutex.js.map +1 -0
- package/dist/oauth.d.ts +12 -0
- package/dist/oauth.d.ts.map +1 -1
- package/dist/oauth.js +264 -50
- package/dist/oauth.js.map +1 -1
- package/dist/retry.d.ts +18 -0
- package/dist/retry.d.ts.map +1 -0
- package/dist/retry.js +74 -0
- package/dist/retry.js.map +1 -0
- package/dist/validation.d.ts +44 -0
- package/dist/validation.d.ts.map +1 -0
- package/dist/validation.js +147 -0
- package/dist/validation.js.map +1 -0
- package/package.json +5 -4
package/dist/logger.js
CHANGED
|
@@ -4,6 +4,14 @@
|
|
|
4
4
|
import { appendFileSync, mkdirSync, existsSync } from "node:fs";
|
|
5
5
|
import { join } from "node:path";
|
|
6
6
|
import { homedir } from "node:os";
|
|
7
|
+
import { sanitizeLogData } from "./validation.js";
|
|
8
|
+
export var LogLevel;
|
|
9
|
+
(function (LogLevel) {
|
|
10
|
+
LogLevel[LogLevel["DEBUG"] = 0] = "DEBUG";
|
|
11
|
+
LogLevel[LogLevel["INFO"] = 1] = "INFO";
|
|
12
|
+
LogLevel[LogLevel["WARN"] = 2] = "WARN";
|
|
13
|
+
LogLevel[LogLevel["ERROR"] = 3] = "ERROR";
|
|
14
|
+
})(LogLevel || (LogLevel = {}));
|
|
7
15
|
function getLogDir() {
|
|
8
16
|
const xdgConfig = process.env.XDG_CONFIG_HOME || join(homedir(), ".config");
|
|
9
17
|
return join(xdgConfig, "opencode", "logs");
|
|
@@ -17,11 +25,37 @@ function ensureLogDir() {
|
|
|
17
25
|
mkdirSync(logDir, { recursive: true, mode: 0o700 });
|
|
18
26
|
}
|
|
19
27
|
}
|
|
20
|
-
function
|
|
28
|
+
function getCurrentLogLevel() {
|
|
29
|
+
const level = process.env.QWEN_OAUTH_LOG_LEVEL?.toUpperCase();
|
|
30
|
+
switch (level) {
|
|
31
|
+
case "ERROR":
|
|
32
|
+
return LogLevel.ERROR;
|
|
33
|
+
case "WARN":
|
|
34
|
+
return LogLevel.WARN;
|
|
35
|
+
case "INFO":
|
|
36
|
+
return LogLevel.INFO;
|
|
37
|
+
case "DEBUG":
|
|
38
|
+
return LogLevel.DEBUG;
|
|
39
|
+
default:
|
|
40
|
+
// Default to INFO, unless DEBUG env var is set
|
|
41
|
+
return process.env.QWEN_OAUTH_DEBUG === "true"
|
|
42
|
+
? LogLevel.DEBUG
|
|
43
|
+
: LogLevel.INFO;
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
function writeLog(level, message, data) {
|
|
21
47
|
try {
|
|
48
|
+
const currentLevel = getCurrentLogLevel();
|
|
49
|
+
if (level < currentLevel) {
|
|
50
|
+
return; // Skip logs below current level
|
|
51
|
+
}
|
|
22
52
|
ensureLogDir();
|
|
23
53
|
const timestamp = new Date().toISOString();
|
|
24
|
-
const
|
|
54
|
+
const levelName = LogLevel[level];
|
|
55
|
+
// Sanitize sensitive data
|
|
56
|
+
const sanitizedData = data ? sanitizeLogData(data) : undefined;
|
|
57
|
+
const dataStr = sanitizedData ? ` ${JSON.stringify(sanitizedData)}` : "";
|
|
58
|
+
const logLine = `[${timestamp}] [${levelName}] ${message}${dataStr}\n`;
|
|
25
59
|
appendFileSync(getLogFilePath(), logLine, { encoding: "utf-8" });
|
|
26
60
|
}
|
|
27
61
|
catch {
|
|
@@ -31,7 +65,15 @@ function writeLog(message) {
|
|
|
31
65
|
export const DEBUG = process.env.QWEN_OAUTH_DEBUG === "true" ||
|
|
32
66
|
process.env.QWEN_OAUTH_DEBUG === "1";
|
|
33
67
|
export function debugLog(message, data) {
|
|
34
|
-
|
|
35
|
-
|
|
68
|
+
writeLog(LogLevel.DEBUG, message, data);
|
|
69
|
+
}
|
|
70
|
+
export function infoLog(message, data) {
|
|
71
|
+
writeLog(LogLevel.INFO, message, data);
|
|
72
|
+
}
|
|
73
|
+
export function warnLog(message, data) {
|
|
74
|
+
writeLog(LogLevel.WARN, message, data);
|
|
75
|
+
}
|
|
76
|
+
export function errorLog(message, data) {
|
|
77
|
+
writeLog(LogLevel.ERROR, message, data);
|
|
36
78
|
}
|
|
37
79
|
//# sourceMappingURL=logger.js.map
|
package/dist/logger.js.map
CHANGED
|
@@ -1 +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;
|
|
1
|
+
{"version":3,"file":"logger.js","sourceRoot":"","sources":["../src/logger.ts"],"names":[],"mappings":"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"}
|
package/dist/mutex.d.ts
ADDED
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Simple mutex implementation for preventing race conditions
|
|
3
|
+
*/
|
|
4
|
+
export declare class Mutex {
|
|
5
|
+
private locked;
|
|
6
|
+
private queue;
|
|
7
|
+
acquire(): Promise<void>;
|
|
8
|
+
release(): void;
|
|
9
|
+
runExclusive<T>(fn: () => Promise<T>): Promise<T>;
|
|
10
|
+
isLocked(): boolean;
|
|
11
|
+
}
|
|
12
|
+
/**
|
|
13
|
+
* Rate limiter to prevent rapid successive calls
|
|
14
|
+
*/
|
|
15
|
+
export declare class RateLimiter {
|
|
16
|
+
private lastCall;
|
|
17
|
+
private minInterval;
|
|
18
|
+
constructor(minIntervalMs?: number);
|
|
19
|
+
throttle(): Promise<void>;
|
|
20
|
+
}
|
|
21
|
+
/**
|
|
22
|
+
* Debouncer to prevent rapid repeated calls
|
|
23
|
+
*/
|
|
24
|
+
export declare class Debouncer {
|
|
25
|
+
private timeoutId;
|
|
26
|
+
private lastCallTime;
|
|
27
|
+
debounce<T extends (...args: any[]) => any>(fn: T, delayMs?: number): (...args: Parameters<T>) => Promise<ReturnType<T>>;
|
|
28
|
+
getLastCallTime(): number;
|
|
29
|
+
}
|
|
30
|
+
//# sourceMappingURL=mutex.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"mutex.d.ts","sourceRoot":"","sources":["../src/mutex.ts"],"names":[],"mappings":"AAAA;;GAEG;AAIH,qBAAa,KAAK;IAChB,OAAO,CAAC,MAAM,CAAS;IACvB,OAAO,CAAC,KAAK,CAAyB;IAEhC,OAAO,IAAI,OAAO,CAAC,IAAI,CAAC;IAW9B,OAAO,IAAI,IAAI;IAST,YAAY,CAAC,CAAC,EAAE,EAAE,EAAE,MAAM,OAAO,CAAC,CAAC,CAAC,GAAG,OAAO,CAAC,CAAC,CAAC;IASvD,QAAQ,IAAI,OAAO;CAGpB;AAED;;GAEG;AACH,qBAAa,WAAW;IACtB,OAAO,CAAC,QAAQ,CAAa;IAC7B,OAAO,CAAC,WAAW,CAAS;gBAEhB,aAAa,GAAE,MAAa;IAIlC,QAAQ,IAAI,OAAO,CAAC,IAAI,CAAC;CAYhC;AAED;;GAEG;AACH,qBAAa,SAAS;IACpB,OAAO,CAAC,SAAS,CAA8C;IAC/D,OAAO,CAAC,YAAY,CAAa;IAEjC,QAAQ,CAAC,CAAC,SAAS,CAAC,GAAG,IAAI,EAAE,GAAG,EAAE,KAAK,GAAG,EACxC,EAAE,EAAE,CAAC,EACL,OAAO,GAAE,MAAY,GACpB,CAAC,GAAG,IAAI,EAAE,UAAU,CAAC,CAAC,CAAC,KAAK,OAAO,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC;IAoBrD,eAAe,IAAI,MAAM;CAG1B"}
|
package/dist/mutex.js
ADDED
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Simple mutex implementation for preventing race conditions
|
|
3
|
+
*/
|
|
4
|
+
import { debugLog } from "./logger.js";
|
|
5
|
+
export class Mutex {
|
|
6
|
+
locked = false;
|
|
7
|
+
queue = [];
|
|
8
|
+
async acquire() {
|
|
9
|
+
return new Promise((resolve) => {
|
|
10
|
+
if (!this.locked) {
|
|
11
|
+
this.locked = true;
|
|
12
|
+
resolve();
|
|
13
|
+
}
|
|
14
|
+
else {
|
|
15
|
+
this.queue.push(resolve);
|
|
16
|
+
}
|
|
17
|
+
});
|
|
18
|
+
}
|
|
19
|
+
release() {
|
|
20
|
+
if (this.queue.length > 0) {
|
|
21
|
+
const resolve = this.queue.shift();
|
|
22
|
+
resolve();
|
|
23
|
+
}
|
|
24
|
+
else {
|
|
25
|
+
this.locked = false;
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
async runExclusive(fn) {
|
|
29
|
+
await this.acquire();
|
|
30
|
+
try {
|
|
31
|
+
return await fn();
|
|
32
|
+
}
|
|
33
|
+
finally {
|
|
34
|
+
this.release();
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
isLocked() {
|
|
38
|
+
return this.locked;
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
/**
|
|
42
|
+
* Rate limiter to prevent rapid successive calls
|
|
43
|
+
*/
|
|
44
|
+
export class RateLimiter {
|
|
45
|
+
lastCall = 0;
|
|
46
|
+
minInterval;
|
|
47
|
+
constructor(minIntervalMs = 1000) {
|
|
48
|
+
this.minInterval = minIntervalMs;
|
|
49
|
+
}
|
|
50
|
+
async throttle() {
|
|
51
|
+
const now = Date.now();
|
|
52
|
+
const timeSinceLastCall = now - this.lastCall;
|
|
53
|
+
if (timeSinceLastCall < this.minInterval) {
|
|
54
|
+
const waitTime = this.minInterval - timeSinceLastCall;
|
|
55
|
+
debugLog(`Rate limiting: waiting ${waitTime}ms`);
|
|
56
|
+
await new Promise((resolve) => setTimeout(resolve, waitTime));
|
|
57
|
+
}
|
|
58
|
+
this.lastCall = Date.now();
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
/**
|
|
62
|
+
* Debouncer to prevent rapid repeated calls
|
|
63
|
+
*/
|
|
64
|
+
export class Debouncer {
|
|
65
|
+
timeoutId = null;
|
|
66
|
+
lastCallTime = 0;
|
|
67
|
+
debounce(fn, delayMs = 500) {
|
|
68
|
+
return (...args) => {
|
|
69
|
+
return new Promise((resolve, reject) => {
|
|
70
|
+
if (this.timeoutId) {
|
|
71
|
+
clearTimeout(this.timeoutId);
|
|
72
|
+
}
|
|
73
|
+
this.timeoutId = setTimeout(async () => {
|
|
74
|
+
try {
|
|
75
|
+
const result = await fn(...args);
|
|
76
|
+
this.lastCallTime = Date.now();
|
|
77
|
+
resolve(result);
|
|
78
|
+
}
|
|
79
|
+
catch (error) {
|
|
80
|
+
reject(error);
|
|
81
|
+
}
|
|
82
|
+
}, delayMs);
|
|
83
|
+
});
|
|
84
|
+
};
|
|
85
|
+
}
|
|
86
|
+
getLastCallTime() {
|
|
87
|
+
return this.lastCallTime;
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
//# sourceMappingURL=mutex.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"mutex.js","sourceRoot":"","sources":["../src/mutex.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAAE,QAAQ,EAAE,MAAM,aAAa,CAAC;AAEvC,MAAM,OAAO,KAAK;IACR,MAAM,GAAG,KAAK,CAAC;IACf,KAAK,GAAsB,EAAE,CAAC;IAEtC,KAAK,CAAC,OAAO;QACX,OAAO,IAAI,OAAO,CAAC,CAAC,OAAO,EAAE,EAAE;YAC7B,IAAI,CAAC,IAAI,CAAC,MAAM,EAAE,CAAC;gBACjB,IAAI,CAAC,MAAM,GAAG,IAAI,CAAC;gBACnB,OAAO,EAAE,CAAC;YACZ,CAAC;iBAAM,CAAC;gBACN,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;YAC3B,CAAC;QACH,CAAC,CAAC,CAAC;IACL,CAAC;IAED,OAAO;QACL,IAAI,IAAI,CAAC,KAAK,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YAC1B,MAAM,OAAO,GAAG,IAAI,CAAC,KAAK,CAAC,KAAK,EAAG,CAAC;YACpC,OAAO,EAAE,CAAC;QACZ,CAAC;aAAM,CAAC;YACN,IAAI,CAAC,MAAM,GAAG,KAAK,CAAC;QACtB,CAAC;IACH,CAAC;IAED,KAAK,CAAC,YAAY,CAAI,EAAoB;QACxC,MAAM,IAAI,CAAC,OAAO,EAAE,CAAC;QACrB,IAAI,CAAC;YACH,OAAO,MAAM,EAAE,EAAE,CAAC;QACpB,CAAC;gBAAS,CAAC;YACT,IAAI,CAAC,OAAO,EAAE,CAAC;QACjB,CAAC;IACH,CAAC;IAED,QAAQ;QACN,OAAO,IAAI,CAAC,MAAM,CAAC;IACrB,CAAC;CACF;AAED;;GAEG;AACH,MAAM,OAAO,WAAW;IACd,QAAQ,GAAW,CAAC,CAAC;IACrB,WAAW,CAAS;IAE5B,YAAY,gBAAwB,IAAI;QACtC,IAAI,CAAC,WAAW,GAAG,aAAa,CAAC;IACnC,CAAC;IAED,KAAK,CAAC,QAAQ;QACZ,MAAM,GAAG,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;QACvB,MAAM,iBAAiB,GAAG,GAAG,GAAG,IAAI,CAAC,QAAQ,CAAC;QAE9C,IAAI,iBAAiB,GAAG,IAAI,CAAC,WAAW,EAAE,CAAC;YACzC,MAAM,QAAQ,GAAG,IAAI,CAAC,WAAW,GAAG,iBAAiB,CAAC;YACtD,QAAQ,CAAC,0BAA0B,QAAQ,IAAI,CAAC,CAAC;YACjD,MAAM,IAAI,OAAO,CAAC,CAAC,OAAO,EAAE,EAAE,CAAC,UAAU,CAAC,OAAO,EAAE,QAAQ,CAAC,CAAC,CAAC;QAChE,CAAC;QAED,IAAI,CAAC,QAAQ,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;IAC7B,CAAC;CACF;AAED;;GAEG;AACH,MAAM,OAAO,SAAS;IACZ,SAAS,GAAyC,IAAI,CAAC;IACvD,YAAY,GAAW,CAAC,CAAC;IAEjC,QAAQ,CACN,EAAK,EACL,UAAkB,GAAG;QAErB,OAAO,CAAC,GAAG,IAAmB,EAA0B,EAAE;YACxD,OAAO,IAAI,OAAO,CAAC,CAAC,OAAO,EAAE,MAAM,EAAE,EAAE;gBACrC,IAAI,IAAI,CAAC,SAAS,EAAE,CAAC;oBACnB,YAAY,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC;gBAC/B,CAAC;gBAED,IAAI,CAAC,SAAS,GAAG,UAAU,CAAC,KAAK,IAAI,EAAE;oBACrC,IAAI,CAAC;wBACH,MAAM,MAAM,GAAG,MAAM,EAAE,CAAC,GAAG,IAAI,CAAC,CAAC;wBACjC,IAAI,CAAC,YAAY,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;wBAC/B,OAAO,CAAC,MAAM,CAAC,CAAC;oBAClB,CAAC;oBAAC,OAAO,KAAK,EAAE,CAAC;wBACf,MAAM,CAAC,KAAK,CAAC,CAAC;oBAChB,CAAC;gBACH,CAAC,EAAE,OAAO,CAAC,CAAC;YACd,CAAC,CAAC,CAAC;QACL,CAAC,CAAC;IACJ,CAAC;IAED,eAAe;QACb,OAAO,IAAI,CAAC,YAAY,CAAC;IAC3B,CAAC;CACF"}
|
package/dist/oauth.d.ts
CHANGED
|
@@ -18,4 +18,16 @@ export declare function pollForToken(deviceCode: string, codeVerifier: string, i
|
|
|
18
18
|
expires_in?: number;
|
|
19
19
|
error?: string;
|
|
20
20
|
}>;
|
|
21
|
+
/**
|
|
22
|
+
* Refresh an expired access token using a refresh token
|
|
23
|
+
* Uses mutex to prevent race conditions when multiple requests
|
|
24
|
+
* try to refresh the token simultaneously
|
|
25
|
+
*/
|
|
26
|
+
export declare function refreshAccessToken(refreshToken: string): Promise<{
|
|
27
|
+
success: boolean;
|
|
28
|
+
access_token?: string;
|
|
29
|
+
refresh_token?: string;
|
|
30
|
+
expires_in?: number;
|
|
31
|
+
error?: string;
|
|
32
|
+
}>;
|
|
21
33
|
//# sourceMappingURL=oauth.d.ts.map
|
package/dist/oauth.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"oauth.d.ts","sourceRoot":"","sources":["../src/oauth.ts"],"names":[],"mappings":"AAAA;;GAEG;
|
|
1
|
+
{"version":3,"file":"oauth.d.ts","sourceRoot":"","sources":["../src/oauth.ts"],"names":[],"mappings":"AAAA;;GAEG;AAqCH,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;AAmBD,wBAAsB,eAAe,IAAI,OAAO,CAAC,mBAAmB,CAAC,CAwEpE;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,CAgKD;AAED;;;;GAIG;AACH,wBAAsB,kBAAkB,CACtC,YAAY,EAAE,MAAM,GACnB,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,CAyGD"}
|
package/dist/oauth.js
CHANGED
|
@@ -3,8 +3,18 @@
|
|
|
3
3
|
*/
|
|
4
4
|
import { QWEN_OAUTH_BASE_URL, QWEN_DEVICE_CODE_ENDPOINT, QWEN_TOKEN_ENDPOINT, QWEN_CLIENT_ID, QWEN_SCOPES, } from "./constants.js";
|
|
5
5
|
import { createPkcePair } from "./pkce.js";
|
|
6
|
-
import { debugLog } from "./logger.js";
|
|
6
|
+
import { debugLog, warnLog } from "./logger.js";
|
|
7
|
+
import { fetchWithRetry } from "./retry.js";
|
|
8
|
+
import { DeviceFlowError, NetworkError, } from "./errors.js";
|
|
9
|
+
import { validateDeviceCode, validateUserCode, validateToken, validateTokenType, validateExpiresIn, validateInterval, validateQwenUrl, validateOAuthError, } from "./validation.js";
|
|
10
|
+
import { getConfig } from "./config.js";
|
|
11
|
+
import { Mutex } from "./mutex.js";
|
|
12
|
+
// Global mutex for token refresh to prevent race conditions
|
|
13
|
+
const tokenRefreshMutex = new Mutex();
|
|
14
|
+
// Track active polling operations
|
|
15
|
+
const activePollingOperations = new Set();
|
|
7
16
|
export async function authorizeDevice() {
|
|
17
|
+
const config = getConfig();
|
|
8
18
|
const { verifier, challenge } = createPkcePair();
|
|
9
19
|
const params = new URLSearchParams({
|
|
10
20
|
client_id: QWEN_CLIENT_ID,
|
|
@@ -12,80 +22,284 @@ export async function authorizeDevice() {
|
|
|
12
22
|
code_challenge: challenge,
|
|
13
23
|
code_challenge_method: "S256",
|
|
14
24
|
});
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
25
|
+
try {
|
|
26
|
+
const url = `${QWEN_OAUTH_BASE_URL}${QWEN_DEVICE_CODE_ENDPOINT}`;
|
|
27
|
+
debugLog("Requesting device authorization", { url });
|
|
28
|
+
const response = await fetchWithRetry(url, {
|
|
29
|
+
method: "POST",
|
|
30
|
+
headers: { "Content-Type": "application/x-www-form-urlencoded" },
|
|
31
|
+
body: params.toString(),
|
|
32
|
+
}, {
|
|
33
|
+
maxRetries: config.maxRetries,
|
|
34
|
+
baseDelay: config.baseRetryDelay,
|
|
35
|
+
maxDelay: config.maxRetryDelay,
|
|
36
|
+
timeout: config.timeout,
|
|
37
|
+
});
|
|
38
|
+
const data = (await response.json());
|
|
39
|
+
// Validate response data
|
|
40
|
+
validateDeviceCode(data.device_code);
|
|
41
|
+
validateUserCode(data.user_code);
|
|
42
|
+
validateExpiresIn(data.expires_in);
|
|
43
|
+
const interval = data.interval || 5;
|
|
44
|
+
validateInterval(interval);
|
|
45
|
+
// Validate URLs
|
|
46
|
+
if (!validateQwenUrl(data.verification_uri)) {
|
|
47
|
+
throw new DeviceFlowError("Invalid verification URI received from server");
|
|
48
|
+
}
|
|
49
|
+
debugLog("Device authorization successful", {
|
|
50
|
+
user_code: data.user_code,
|
|
51
|
+
expires_in: data.expires_in,
|
|
52
|
+
});
|
|
53
|
+
return {
|
|
54
|
+
device_code: data.device_code,
|
|
55
|
+
user_code: data.user_code,
|
|
56
|
+
verification_uri: data.verification_uri,
|
|
57
|
+
verification_uri_complete: data.verification_uri_complete,
|
|
58
|
+
expires_in: data.expires_in,
|
|
59
|
+
interval,
|
|
60
|
+
verifier,
|
|
61
|
+
};
|
|
62
|
+
}
|
|
63
|
+
catch (error) {
|
|
64
|
+
debugLog("Device authorization failed", { error: String(error) });
|
|
65
|
+
if (error instanceof DeviceFlowError || error instanceof NetworkError) {
|
|
66
|
+
throw error;
|
|
67
|
+
}
|
|
68
|
+
throw new DeviceFlowError(`Failed to start device flow: ${error instanceof Error ? error.message : String(error)}`);
|
|
22
69
|
}
|
|
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
70
|
}
|
|
34
71
|
export async function pollForToken(deviceCode, codeVerifier, intervalSeconds, expiresIn) {
|
|
72
|
+
// Validate inputs
|
|
73
|
+
try {
|
|
74
|
+
validateDeviceCode(deviceCode);
|
|
75
|
+
validateInterval(intervalSeconds);
|
|
76
|
+
validateExpiresIn(expiresIn);
|
|
77
|
+
}
|
|
78
|
+
catch (error) {
|
|
79
|
+
debugLog("Invalid polling parameters", { error: String(error) });
|
|
80
|
+
return {
|
|
81
|
+
success: false,
|
|
82
|
+
error: error instanceof Error ? error.message : "Invalid parameters",
|
|
83
|
+
};
|
|
84
|
+
}
|
|
85
|
+
// Prevent multiple concurrent polling for same device code
|
|
86
|
+
if (activePollingOperations.has(deviceCode)) {
|
|
87
|
+
warnLog("Polling already in progress for this device code", { deviceCode });
|
|
88
|
+
return {
|
|
89
|
+
success: false,
|
|
90
|
+
error: "Authorization already in progress",
|
|
91
|
+
};
|
|
92
|
+
}
|
|
93
|
+
// Register this polling operation
|
|
94
|
+
activePollingOperations.add(deviceCode);
|
|
35
95
|
const timeoutMs = expiresIn * 1000;
|
|
36
96
|
const startTime = Date.now();
|
|
37
97
|
let currentInterval = intervalSeconds * 1000;
|
|
98
|
+
let pollAttempts = 0;
|
|
38
99
|
debugLog("Starting token polling", { timeoutMs, interval: currentInterval });
|
|
100
|
+
// Ensure cleanup on exit
|
|
101
|
+
const cleanup = () => {
|
|
102
|
+
activePollingOperations.delete(deviceCode);
|
|
103
|
+
};
|
|
39
104
|
while (Date.now() - startTime < timeoutMs) {
|
|
40
105
|
await new Promise((resolve) => setTimeout(resolve, currentInterval));
|
|
106
|
+
pollAttempts++;
|
|
41
107
|
const params = new URLSearchParams({
|
|
42
108
|
client_id: QWEN_CLIENT_ID,
|
|
43
109
|
grant_type: "urn:ietf:params:oauth:grant-type:device_code",
|
|
44
110
|
device_code: deviceCode,
|
|
45
111
|
code_verifier: codeVerifier,
|
|
46
112
|
});
|
|
47
|
-
debugLog(
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
113
|
+
debugLog(`Polling attempt ${pollAttempts}...`);
|
|
114
|
+
try {
|
|
115
|
+
const response = await fetch(`${QWEN_OAUTH_BASE_URL}${QWEN_TOKEN_ENDPOINT}`, {
|
|
116
|
+
method: "POST",
|
|
117
|
+
headers: { "Content-Type": "application/x-www-form-urlencoded" },
|
|
118
|
+
body: params.toString(),
|
|
119
|
+
});
|
|
120
|
+
if (response.ok) {
|
|
121
|
+
const data = (await response.json());
|
|
122
|
+
// Validate token response
|
|
123
|
+
try {
|
|
124
|
+
validateToken(data.access_token);
|
|
125
|
+
// For device flow, refresh_token is required on initial auth
|
|
126
|
+
if (!data.refresh_token) {
|
|
127
|
+
throw new Error("No refresh token returned");
|
|
128
|
+
}
|
|
129
|
+
validateToken(data.refresh_token);
|
|
130
|
+
validateExpiresIn(data.expires_in);
|
|
131
|
+
// Validate token_type if provided (optional for compatibility)
|
|
132
|
+
if (data.token_type) {
|
|
133
|
+
validateTokenType(data.token_type);
|
|
134
|
+
}
|
|
135
|
+
}
|
|
136
|
+
catch (validationError) {
|
|
137
|
+
debugLog("Invalid token response", {
|
|
138
|
+
error: String(validationError),
|
|
139
|
+
});
|
|
140
|
+
cleanup();
|
|
141
|
+
return {
|
|
142
|
+
success: false,
|
|
143
|
+
error: "Received invalid token from server",
|
|
144
|
+
};
|
|
145
|
+
}
|
|
146
|
+
debugLog("Token received successfully", { pollAttempts });
|
|
147
|
+
cleanup();
|
|
148
|
+
return {
|
|
149
|
+
success: true,
|
|
150
|
+
access_token: data.access_token,
|
|
151
|
+
refresh_token: data.refresh_token,
|
|
152
|
+
expires_in: data.expires_in,
|
|
153
|
+
};
|
|
154
|
+
}
|
|
155
|
+
// Handle error responses
|
|
156
|
+
const errorData = await response.json().catch(() => ({}));
|
|
157
|
+
const oauthError = validateOAuthError(errorData);
|
|
158
|
+
if (oauthError.error === "authorization_pending") {
|
|
159
|
+
debugLog("Authorization pending, retrying...");
|
|
160
|
+
continue;
|
|
161
|
+
}
|
|
162
|
+
if (oauthError.error === "slow_down") {
|
|
163
|
+
currentInterval += 5000;
|
|
164
|
+
debugLog("Server requested slow down", {
|
|
165
|
+
newInterval: currentInterval,
|
|
166
|
+
});
|
|
167
|
+
continue;
|
|
168
|
+
}
|
|
169
|
+
if (oauthError.error === "expired_token") {
|
|
170
|
+
debugLog("Device code expired");
|
|
171
|
+
cleanup();
|
|
172
|
+
return {
|
|
173
|
+
success: false,
|
|
174
|
+
error: "Device code expired. Please try again.",
|
|
175
|
+
};
|
|
176
|
+
}
|
|
177
|
+
if (oauthError.error === "access_denied") {
|
|
178
|
+
debugLog("User denied authorization");
|
|
179
|
+
cleanup();
|
|
180
|
+
return {
|
|
181
|
+
success: false,
|
|
182
|
+
error: "Authorization was denied",
|
|
183
|
+
};
|
|
184
|
+
}
|
|
185
|
+
debugLog(`Token polling failed: ${oauthError.error}`, {
|
|
186
|
+
description: oauthError.error_description,
|
|
187
|
+
});
|
|
188
|
+
cleanup();
|
|
189
|
+
return {
|
|
190
|
+
success: false,
|
|
191
|
+
error: oauthError.error_description || oauthError.error,
|
|
192
|
+
};
|
|
193
|
+
}
|
|
194
|
+
catch (error) {
|
|
195
|
+
debugLog("Network error during polling", { error: String(error) });
|
|
196
|
+
// Continue polling on network errors
|
|
197
|
+
if (Date.now() - startTime < timeoutMs) {
|
|
198
|
+
continue;
|
|
199
|
+
}
|
|
200
|
+
cleanup();
|
|
201
|
+
return {
|
|
202
|
+
success: false,
|
|
203
|
+
error: "Network error occurred during authentication",
|
|
204
|
+
};
|
|
205
|
+
}
|
|
206
|
+
}
|
|
207
|
+
debugLog("Polling timeout exceeded", { attempts: pollAttempts });
|
|
208
|
+
cleanup();
|
|
209
|
+
return { success: false, error: "Polling timeout - device code expired" };
|
|
210
|
+
}
|
|
211
|
+
/**
|
|
212
|
+
* Refresh an expired access token using a refresh token
|
|
213
|
+
* Uses mutex to prevent race conditions when multiple requests
|
|
214
|
+
* try to refresh the token simultaneously
|
|
215
|
+
*/
|
|
216
|
+
export async function refreshAccessToken(refreshToken) {
|
|
217
|
+
// Use mutex to ensure only one refresh happens at a time
|
|
218
|
+
return tokenRefreshMutex.runExclusive(async () => {
|
|
219
|
+
try {
|
|
220
|
+
validateToken(refreshToken);
|
|
221
|
+
}
|
|
222
|
+
catch (error) {
|
|
223
|
+
return {
|
|
224
|
+
success: false,
|
|
225
|
+
error: "Invalid refresh token",
|
|
226
|
+
};
|
|
227
|
+
}
|
|
228
|
+
// Check if a refresh is already in progress
|
|
229
|
+
if (tokenRefreshMutex.isLocked()) {
|
|
230
|
+
debugLog("Token refresh already in progress, waiting...");
|
|
231
|
+
}
|
|
232
|
+
const config = getConfig();
|
|
233
|
+
try {
|
|
234
|
+
const params = new URLSearchParams({
|
|
235
|
+
client_id: QWEN_CLIENT_ID,
|
|
236
|
+
grant_type: "refresh_token",
|
|
237
|
+
refresh_token: refreshToken,
|
|
238
|
+
});
|
|
239
|
+
debugLog("Refreshing access token");
|
|
240
|
+
const response = await fetchWithRetry(`${QWEN_OAUTH_BASE_URL}${QWEN_TOKEN_ENDPOINT}`, {
|
|
241
|
+
method: "POST",
|
|
242
|
+
headers: { "Content-Type": "application/x-www-form-urlencoded" },
|
|
243
|
+
body: params.toString(),
|
|
244
|
+
}, {
|
|
245
|
+
maxRetries: config.maxRetries,
|
|
246
|
+
timeout: config.timeout,
|
|
247
|
+
});
|
|
248
|
+
// Check for OAuth error responses
|
|
249
|
+
if (!response.ok) {
|
|
250
|
+
const errorData = await response.json().catch(() => ({}));
|
|
251
|
+
const oauthError = validateOAuthError(errorData);
|
|
252
|
+
debugLog("OAuth error during token refresh", {
|
|
253
|
+
error: oauthError.error,
|
|
254
|
+
description: oauthError.error_description,
|
|
255
|
+
});
|
|
256
|
+
// Handle specific OAuth errors
|
|
257
|
+
if (oauthError.error === "invalid_grant") {
|
|
258
|
+
return {
|
|
259
|
+
success: false,
|
|
260
|
+
error: "Invalid refresh token or client_id",
|
|
261
|
+
};
|
|
262
|
+
}
|
|
263
|
+
if (oauthError.error === "invalid_client") {
|
|
264
|
+
return {
|
|
265
|
+
success: false,
|
|
266
|
+
error: "Invalid client_id",
|
|
267
|
+
};
|
|
268
|
+
}
|
|
269
|
+
return {
|
|
270
|
+
success: false,
|
|
271
|
+
error: oauthError.error_description || oauthError.error || "Token refresh failed",
|
|
272
|
+
};
|
|
273
|
+
}
|
|
54
274
|
const data = (await response.json());
|
|
55
|
-
|
|
275
|
+
// Validate new tokens
|
|
276
|
+
validateToken(data.access_token);
|
|
277
|
+
validateExpiresIn(data.expires_in);
|
|
278
|
+
// Validate token_type if provided (optional for compatibility)
|
|
279
|
+
if (data.token_type) {
|
|
280
|
+
validateTokenType(data.token_type);
|
|
281
|
+
}
|
|
282
|
+
// Per RFC 6749: refresh_token is optional in refresh response
|
|
283
|
+
// If not provided, continue using the old refresh token
|
|
284
|
+
const newRefreshToken = data.refresh_token || refreshToken;
|
|
285
|
+
validateToken(newRefreshToken);
|
|
286
|
+
debugLog("Token refresh successful", {
|
|
287
|
+
new_refresh_token: !!data.refresh_token,
|
|
288
|
+
});
|
|
56
289
|
return {
|
|
57
290
|
success: true,
|
|
58
291
|
access_token: data.access_token,
|
|
59
|
-
refresh_token:
|
|
292
|
+
refresh_token: newRefreshToken,
|
|
60
293
|
expires_in: data.expires_in,
|
|
61
294
|
};
|
|
62
295
|
}
|
|
63
|
-
|
|
64
|
-
|
|
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");
|
|
296
|
+
catch (error) {
|
|
297
|
+
debugLog("Token refresh failed", { error: String(error) });
|
|
77
298
|
return {
|
|
78
299
|
success: false,
|
|
79
|
-
error:
|
|
300
|
+
error: error instanceof Error ? error.message : "Token refresh failed",
|
|
80
301
|
};
|
|
81
302
|
}
|
|
82
|
-
|
|
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" };
|
|
303
|
+
});
|
|
90
304
|
}
|
|
91
305
|
//# sourceMappingURL=oauth.js.map
|
package/dist/oauth.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"oauth.js","sourceRoot":"","sources":["../src/oauth.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EACL,mBAAmB,EACnB,yBAAyB,EACzB,mBAAmB,EACnB,cAAc,EACd,WAAW,GACZ,MAAM,gBAAgB,CAAC;AACxB,OAAO,EAAE,cAAc,EAAE,MAAM,WAAW,CAAC;AAC3C,OAAO,EAAE,QAAQ,EAAE,MAAM,aAAa,CAAC;
|
|
1
|
+
{"version":3,"file":"oauth.js","sourceRoot":"","sources":["../src/oauth.ts"],"names":[],"mappings":"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"}
|
package/dist/retry.d.ts
ADDED
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Retry logic with exponential backoff for network requests
|
|
3
|
+
*/
|
|
4
|
+
export interface RetryOptions {
|
|
5
|
+
maxRetries?: number;
|
|
6
|
+
baseDelay?: number;
|
|
7
|
+
maxDelay?: number;
|
|
8
|
+
timeout?: number;
|
|
9
|
+
}
|
|
10
|
+
/**
|
|
11
|
+
* Retry a function with exponential backoff
|
|
12
|
+
*/
|
|
13
|
+
export declare function retryWithBackoff<T>(fn: () => Promise<T>, options?: RetryOptions): Promise<T>;
|
|
14
|
+
/**
|
|
15
|
+
* Retry fetch with exponential backoff
|
|
16
|
+
*/
|
|
17
|
+
export declare function fetchWithRetry(url: string, init?: RequestInit, options?: RetryOptions): Promise<Response>;
|
|
18
|
+
//# sourceMappingURL=retry.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"retry.d.ts","sourceRoot":"","sources":["../src/retry.ts"],"names":[],"mappings":"AAAA;;GAEG;AAKH,MAAM,WAAW,YAAY;IAC3B,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AASD;;GAEG;AACH,wBAAsB,gBAAgB,CAAC,CAAC,EACtC,EAAE,EAAE,MAAM,OAAO,CAAC,CAAC,CAAC,EACpB,OAAO,GAAE,YAAiB,GACzB,OAAO,CAAC,CAAC,CAAC,CAqDZ;AAED;;GAEG;AACH,wBAAsB,cAAc,CAClC,GAAG,EAAE,MAAM,EACX,IAAI,CAAC,EAAE,WAAW,EAClB,OAAO,GAAE,YAAiB,GACzB,OAAO,CAAC,QAAQ,CAAC,CAwBnB"}
|