@vybestack/llxprt-code-auth 0.10.0-nightly.260613.1adad3b34
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/dist/.last_build +0 -0
- package/dist/index.d.ts +10 -0
- package/dist/index.js +11 -0
- package/dist/index.js.map +1 -0
- package/dist/src/auth-precedence-resolver.d.ts +147 -0
- package/dist/src/auth-precedence-resolver.js +542 -0
- package/dist/src/auth-precedence-resolver.js.map +1 -0
- package/dist/src/flows/anthropic-device-flow.d.ts +57 -0
- package/dist/src/flows/anthropic-device-flow.js +231 -0
- package/dist/src/flows/anthropic-device-flow.js.map +1 -0
- package/dist/src/flows/codex-device-flow.d.ts +114 -0
- package/dist/src/flows/codex-device-flow.js +437 -0
- package/dist/src/flows/codex-device-flow.js.map +1 -0
- package/dist/src/flows/qwen-device-flow.d.ts +45 -0
- package/dist/src/flows/qwen-device-flow.js +183 -0
- package/dist/src/flows/qwen-device-flow.js.map +1 -0
- package/dist/src/index.d.ts +34 -0
- package/dist/src/index.js +26 -0
- package/dist/src/index.js.map +1 -0
- package/dist/src/interfaces/debug-logger.d.ts +31 -0
- package/dist/src/interfaces/debug-logger.js +6 -0
- package/dist/src/interfaces/debug-logger.js.map +1 -0
- package/dist/src/interfaces/index.d.ts +18 -0
- package/dist/src/interfaces/index.js +10 -0
- package/dist/src/interfaces/index.js.map +1 -0
- package/dist/src/interfaces/provider-key-storage.d.ts +26 -0
- package/dist/src/interfaces/provider-key-storage.js +6 -0
- package/dist/src/interfaces/provider-key-storage.js.map +1 -0
- package/dist/src/interfaces/runtime-context.d.ts +37 -0
- package/dist/src/interfaces/runtime-context.js +6 -0
- package/dist/src/interfaces/runtime-context.js.map +1 -0
- package/dist/src/interfaces/secure-store.d.ts +47 -0
- package/dist/src/interfaces/secure-store.js +6 -0
- package/dist/src/interfaces/secure-store.js.map +1 -0
- package/dist/src/interfaces/settings-service.d.ts +25 -0
- package/dist/src/interfaces/settings-service.js +6 -0
- package/dist/src/interfaces/settings-service.js.map +1 -0
- package/dist/src/keyring-token-store.d.ts +96 -0
- package/dist/src/keyring-token-store.js +391 -0
- package/dist/src/keyring-token-store.js.map +1 -0
- package/dist/src/oauth-errors.d.ts +173 -0
- package/dist/src/oauth-errors.js +465 -0
- package/dist/src/oauth-errors.js.map +1 -0
- package/dist/src/precedence.d.ts +115 -0
- package/dist/src/precedence.js +278 -0
- package/dist/src/precedence.js.map +1 -0
- package/dist/src/proxy/framing.d.ts +35 -0
- package/dist/src/proxy/framing.js +86 -0
- package/dist/src/proxy/framing.js.map +1 -0
- package/dist/src/proxy/proxy-provider-key-storage.d.ts +23 -0
- package/dist/src/proxy/proxy-provider-key-storage.js +41 -0
- package/dist/src/proxy/proxy-provider-key-storage.js.map +1 -0
- package/dist/src/proxy/proxy-socket-client.d.ts +43 -0
- package/dist/src/proxy/proxy-socket-client.js +219 -0
- package/dist/src/proxy/proxy-socket-client.js.map +1 -0
- package/dist/src/proxy/proxy-token-store.d.ts +39 -0
- package/dist/src/proxy/proxy-token-store.js +87 -0
- package/dist/src/proxy/proxy-token-store.js.map +1 -0
- package/dist/src/token-merge.d.ts +16 -0
- package/dist/src/token-merge.js +13 -0
- package/dist/src/token-merge.js.map +1 -0
- package/dist/src/token-sanitization.d.ts +16 -0
- package/dist/src/token-sanitization.js +10 -0
- package/dist/src/token-sanitization.js.map +1 -0
- package/dist/src/token-store.d.ts +93 -0
- package/dist/src/token-store.js +7 -0
- package/dist/src/token-store.js.map +1 -0
- package/dist/src/types.d.ts +204 -0
- package/dist/src/types.js +86 -0
- package/dist/src/types.js.map +1 -0
- package/package.json +42 -0
|
@@ -0,0 +1,183 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @license
|
|
3
|
+
* Copyright 2025 Vybestack LLC
|
|
4
|
+
* SPDX-License-Identifier: Apache-2.0
|
|
5
|
+
*/
|
|
6
|
+
import { randomBytes, createHash } from 'crypto';
|
|
7
|
+
import { DeviceCodeResponseSchema, TokenResponseSchema, } from '../types.js';
|
|
8
|
+
/**
|
|
9
|
+
* Qwen OAuth device flow implementation
|
|
10
|
+
*/
|
|
11
|
+
export class QwenDeviceFlow {
|
|
12
|
+
config;
|
|
13
|
+
pkceVerifier = '';
|
|
14
|
+
constructor(config) {
|
|
15
|
+
this.config = config;
|
|
16
|
+
}
|
|
17
|
+
/**
|
|
18
|
+
* Initiates the device authorization flow
|
|
19
|
+
* @returns Promise resolving to device code response
|
|
20
|
+
*/
|
|
21
|
+
async initiateDeviceFlow() {
|
|
22
|
+
// Generate PKCE parameters
|
|
23
|
+
const pkce = this.generatePKCE();
|
|
24
|
+
this.pkceVerifier = pkce.verifier;
|
|
25
|
+
// Prepare request parameters
|
|
26
|
+
const params = new URLSearchParams({
|
|
27
|
+
client_id: this.config.clientId,
|
|
28
|
+
code_challenge: pkce.challenge,
|
|
29
|
+
code_challenge_method: 'S256',
|
|
30
|
+
});
|
|
31
|
+
// Only add scope if it's not empty
|
|
32
|
+
if (this.config.scopes.length > 0) {
|
|
33
|
+
params.append('scope', this.config.scopes.join(' '));
|
|
34
|
+
}
|
|
35
|
+
// Make HTTP request
|
|
36
|
+
const response = await fetch(this.config.authorizationEndpoint, {
|
|
37
|
+
method: 'POST',
|
|
38
|
+
headers: {
|
|
39
|
+
'Content-Type': 'application/x-www-form-urlencoded',
|
|
40
|
+
Accept: 'application/json',
|
|
41
|
+
},
|
|
42
|
+
body: params.toString(),
|
|
43
|
+
});
|
|
44
|
+
if (!response.ok) {
|
|
45
|
+
throw new Error(`HTTP ${response.status}: ${response.statusText}`);
|
|
46
|
+
}
|
|
47
|
+
const data = await response.json();
|
|
48
|
+
// Validate response with Zod schema
|
|
49
|
+
const validatedResponse = DeviceCodeResponseSchema.parse(data);
|
|
50
|
+
return validatedResponse;
|
|
51
|
+
}
|
|
52
|
+
/**
|
|
53
|
+
* Polls the authorization server for an access token
|
|
54
|
+
* @param deviceCode Device code from initiation response
|
|
55
|
+
* @returns Promise resolving to OAuth token
|
|
56
|
+
*/
|
|
57
|
+
async pollForToken(deviceCode) {
|
|
58
|
+
const maxDuration = 15 * 60 * 1000; // 15 minutes in milliseconds
|
|
59
|
+
const startTime = Date.now();
|
|
60
|
+
let interval = 5000; // Start with 5 seconds
|
|
61
|
+
while (Date.now() - startTime < maxDuration) {
|
|
62
|
+
const params = new URLSearchParams({
|
|
63
|
+
grant_type: 'urn:ietf:params:oauth:grant-type:device_code',
|
|
64
|
+
device_code: deviceCode,
|
|
65
|
+
client_id: this.config.clientId,
|
|
66
|
+
code_verifier: this.pkceVerifier,
|
|
67
|
+
});
|
|
68
|
+
try {
|
|
69
|
+
const response = await fetch(this.config.tokenEndpoint, {
|
|
70
|
+
method: 'POST',
|
|
71
|
+
headers: {
|
|
72
|
+
'Content-Type': 'application/x-www-form-urlencoded',
|
|
73
|
+
Accept: 'application/json',
|
|
74
|
+
},
|
|
75
|
+
body: params.toString(),
|
|
76
|
+
});
|
|
77
|
+
if (response.ok) {
|
|
78
|
+
const data = await response.json();
|
|
79
|
+
// Validate response with Zod schema
|
|
80
|
+
const validatedResponse = TokenResponseSchema.parse(data);
|
|
81
|
+
// Calculate expiry timestamp
|
|
82
|
+
const now = Math.floor(Date.now() / 1000);
|
|
83
|
+
const expiresIn = validatedResponse.expires_in === undefined ||
|
|
84
|
+
validatedResponse.expires_in === 0
|
|
85
|
+
? 3600
|
|
86
|
+
: validatedResponse.expires_in; // Default to 1 hour if not provided
|
|
87
|
+
const expiry = now + expiresIn;
|
|
88
|
+
return {
|
|
89
|
+
access_token: validatedResponse.access_token,
|
|
90
|
+
token_type: 'Bearer',
|
|
91
|
+
expiry,
|
|
92
|
+
refresh_token: validatedResponse.refresh_token,
|
|
93
|
+
scope: validatedResponse.scope ?? undefined, // Convert null to undefined
|
|
94
|
+
resource_url: validatedResponse.resource_url, // Include the API endpoint from Qwen
|
|
95
|
+
};
|
|
96
|
+
}
|
|
97
|
+
// Handle error responses
|
|
98
|
+
const errorData = (await response.json());
|
|
99
|
+
if (errorData.error === 'access_denied') {
|
|
100
|
+
throw new Error('access_denied');
|
|
101
|
+
}
|
|
102
|
+
else if (errorData.error === 'expired_token') {
|
|
103
|
+
throw new Error('expired_token');
|
|
104
|
+
}
|
|
105
|
+
else if (errorData.error === 'slow_down') {
|
|
106
|
+
// Increase polling interval by 5 seconds and continue
|
|
107
|
+
interval += 5000;
|
|
108
|
+
}
|
|
109
|
+
else if (errorData.error !== 'authorization_pending') {
|
|
110
|
+
throw new Error(`HTTP ${response.status}: ${response.statusText}`);
|
|
111
|
+
}
|
|
112
|
+
// Continue polling - wait for the interval before next attempt
|
|
113
|
+
await new Promise((resolve) => setTimeout(resolve, interval));
|
|
114
|
+
}
|
|
115
|
+
catch (error) {
|
|
116
|
+
// For network errors, apply exponential backoff
|
|
117
|
+
if (error instanceof Error && error.message.includes('fetch failed')) {
|
|
118
|
+
interval = Math.min(interval * 1.5, 60000); // Max 60 seconds
|
|
119
|
+
await new Promise((resolve) => setTimeout(resolve, interval));
|
|
120
|
+
continue;
|
|
121
|
+
}
|
|
122
|
+
// Re-throw other errors (like access_denied, expired_token)
|
|
123
|
+
throw error;
|
|
124
|
+
}
|
|
125
|
+
}
|
|
126
|
+
// If we reach here, we've exceeded the maximum polling duration
|
|
127
|
+
throw new Error('Polling timeout exceeded');
|
|
128
|
+
}
|
|
129
|
+
/**
|
|
130
|
+
* Refreshes an expired access token
|
|
131
|
+
* @param refreshToken Valid refresh token
|
|
132
|
+
* @returns Promise resolving to new OAuth token
|
|
133
|
+
*/
|
|
134
|
+
async refreshToken(refreshToken) {
|
|
135
|
+
const params = new URLSearchParams({
|
|
136
|
+
grant_type: 'refresh_token',
|
|
137
|
+
refresh_token: refreshToken,
|
|
138
|
+
client_id: this.config.clientId,
|
|
139
|
+
});
|
|
140
|
+
const response = await fetch(this.config.tokenEndpoint, {
|
|
141
|
+
method: 'POST',
|
|
142
|
+
headers: {
|
|
143
|
+
'Content-Type': 'application/x-www-form-urlencoded',
|
|
144
|
+
Accept: 'application/json',
|
|
145
|
+
},
|
|
146
|
+
body: params.toString(),
|
|
147
|
+
});
|
|
148
|
+
if (!response.ok) {
|
|
149
|
+
throw new Error(`HTTP ${response.status}: ${response.statusText}`);
|
|
150
|
+
}
|
|
151
|
+
const data = await response.json();
|
|
152
|
+
// Validate response with Zod schema
|
|
153
|
+
const validatedResponse = TokenResponseSchema.parse(data);
|
|
154
|
+
// Calculate expiry timestamp with 30-second buffer
|
|
155
|
+
const now = Math.floor(Date.now() / 1000);
|
|
156
|
+
const expiresIn = validatedResponse.expires_in === undefined ||
|
|
157
|
+
validatedResponse.expires_in === 0
|
|
158
|
+
? 3600
|
|
159
|
+
: validatedResponse.expires_in; // Default to 1 hour if not provided
|
|
160
|
+
const expiry = now + expiresIn - 30; // 30-second buffer
|
|
161
|
+
return {
|
|
162
|
+
access_token: validatedResponse.access_token,
|
|
163
|
+
token_type: 'Bearer',
|
|
164
|
+
expiry,
|
|
165
|
+
// eslint-disable-next-line @typescript-eslint/prefer-nullish-coalescing -- intentional falsy coalescing: empty string refresh_token means "not provided"
|
|
166
|
+
refresh_token: validatedResponse.refresh_token || refreshToken,
|
|
167
|
+
scope: validatedResponse.scope ?? undefined, // Convert null to undefined
|
|
168
|
+
resource_url: validatedResponse.resource_url, // Include the API endpoint from Qwen
|
|
169
|
+
};
|
|
170
|
+
}
|
|
171
|
+
/**
|
|
172
|
+
* Generates PKCE code verifier and challenge
|
|
173
|
+
* @returns Object containing verifier and challenge strings
|
|
174
|
+
*/
|
|
175
|
+
generatePKCE() {
|
|
176
|
+
// Generate 32 random bytes for verifier
|
|
177
|
+
const verifier = randomBytes(32).toString('base64url');
|
|
178
|
+
// Create SHA-256 hash of verifier for challenge
|
|
179
|
+
const challenge = createHash('sha256').update(verifier).digest('base64url');
|
|
180
|
+
return { verifier, challenge };
|
|
181
|
+
}
|
|
182
|
+
}
|
|
183
|
+
//# sourceMappingURL=qwen-device-flow.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"qwen-device-flow.js","sourceRoot":"","sources":["../../../src/flows/qwen-device-flow.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @plan:PLAN-20260608-ISSUE1586.P03
|
|
3
|
+
* @plan:PLAN-20260608-ISSUE1586.P09
|
|
4
|
+
* @requirement:REQ-AUTH-001.2, REQ-AUTH-001.3, REQ-API-001.4
|
|
5
|
+
*/
|
|
6
|
+
/**
|
|
7
|
+
* @license
|
|
8
|
+
* Copyright 2025 Google LLC
|
|
9
|
+
* SPDX-License-Identifier: Apache-2.0
|
|
10
|
+
*/
|
|
11
|
+
export type * from './interfaces/index.js';
|
|
12
|
+
export type { OAuthToken, CodexOAuthToken, AuthStatus, BucketStats, DeviceCodeResponse, } from './types.js';
|
|
13
|
+
export { OAuthTokenSchema, CodexOAuthTokenSchema, AuthStatusSchema, BucketStatsSchema, DeviceCodeResponseSchema, } from './types.js';
|
|
14
|
+
export type { TokenStore } from './token-store.js';
|
|
15
|
+
export { KeyringTokenStore } from './keyring-token-store.js';
|
|
16
|
+
export { OAuthError, OAuthErrorFactory, OAuthErrorCategory, OAuthErrorType, RetryHandler, GracefulErrorHandler, } from './oauth-errors.js';
|
|
17
|
+
export type { RetryConfig } from './oauth-errors.js';
|
|
18
|
+
export { mergeRefreshedToken } from './token-merge.js';
|
|
19
|
+
export type { OAuthTokenWithExtras } from './token-merge.js';
|
|
20
|
+
export { sanitizeTokenForProxy } from './token-sanitization.js';
|
|
21
|
+
export type { SanitizedOAuthToken } from './token-sanitization.js';
|
|
22
|
+
export { AuthPrecedenceResolver } from './auth-precedence-resolver.js';
|
|
23
|
+
export { flushRuntimeAuthScope, resolveProfileId, buildCacheKey, ensureRuntimeState, recordCacheHit, recordCacheMiss, getValidCachedEntry, registerSettingsSubscriptions, invalidateMatchingEntries, storeRuntimeScopedToken, invalidateEntry, runtimeScopedStates, } from './precedence.js';
|
|
24
|
+
export type { AuthPrecedenceConfig, OAuthManager, OAuthTokenRequestMetadata, RuntimeAuthScopeFlushResult, RuntimeAuthScopeCacheEntrySummary, RuntimeScopedAuthEntry, RuntimeScopedState, } from './precedence.js';
|
|
25
|
+
export { AnthropicDeviceFlow } from './flows/anthropic-device-flow.js';
|
|
26
|
+
export { CodexDeviceFlow, CODEX_CONFIG } from './flows/codex-device-flow.js';
|
|
27
|
+
export { QwenDeviceFlow } from './flows/qwen-device-flow.js';
|
|
28
|
+
export type { DeviceFlowConfig } from './flows/qwen-device-flow.js';
|
|
29
|
+
export { encodeFrame, FrameDecoder, FrameError, MAX_FRAME_SIZE, PARTIAL_FRAME_TIMEOUT_MS, } from './proxy/framing.js';
|
|
30
|
+
export type { FrameDecoderOptions } from './proxy/framing.js';
|
|
31
|
+
export { ProxySocketClient, REQUEST_TIMEOUT_MS, IDLE_TIMEOUT_MS, PROTOCOL_VERSION, } from './proxy/proxy-socket-client.js';
|
|
32
|
+
export type { ProxyResponse } from './proxy/proxy-socket-client.js';
|
|
33
|
+
export { ProxyTokenStore } from './proxy/proxy-token-store.js';
|
|
34
|
+
export { ProxyProviderKeyStorage } from './proxy/proxy-provider-key-storage.js';
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @plan:PLAN-20260608-ISSUE1586.P03
|
|
3
|
+
* @plan:PLAN-20260608-ISSUE1586.P09
|
|
4
|
+
* @requirement:REQ-AUTH-001.2, REQ-AUTH-001.3, REQ-API-001.4
|
|
5
|
+
*/
|
|
6
|
+
export { OAuthTokenSchema, CodexOAuthTokenSchema, AuthStatusSchema, BucketStatsSchema, DeviceCodeResponseSchema, } from './types.js';
|
|
7
|
+
// ─── Keyring Token Store ─────────────────────────────────────────────────────
|
|
8
|
+
export { KeyringTokenStore } from './keyring-token-store.js';
|
|
9
|
+
// ─── OAuth Errors ────────────────────────────────────────────────────────────
|
|
10
|
+
export { OAuthError, OAuthErrorFactory, OAuthErrorCategory, OAuthErrorType, RetryHandler, GracefulErrorHandler, } from './oauth-errors.js';
|
|
11
|
+
// ─── Token Utilities ─────────────────────────────────────────────────────────
|
|
12
|
+
export { mergeRefreshedToken } from './token-merge.js';
|
|
13
|
+
export { sanitizeTokenForProxy } from './token-sanitization.js';
|
|
14
|
+
// ─── Precedence / Auth Resolution ────────────────────────────────────────────
|
|
15
|
+
export { AuthPrecedenceResolver } from './auth-precedence-resolver.js';
|
|
16
|
+
export { flushRuntimeAuthScope, resolveProfileId, buildCacheKey, ensureRuntimeState, recordCacheHit, recordCacheMiss, getValidCachedEntry, registerSettingsSubscriptions, invalidateMatchingEntries, storeRuntimeScopedToken, invalidateEntry, runtimeScopedStates, } from './precedence.js';
|
|
17
|
+
// ─── Device Flows ────────────────────────────────────────────────────────────
|
|
18
|
+
export { AnthropicDeviceFlow } from './flows/anthropic-device-flow.js';
|
|
19
|
+
export { CodexDeviceFlow, CODEX_CONFIG } from './flows/codex-device-flow.js';
|
|
20
|
+
export { QwenDeviceFlow } from './flows/qwen-device-flow.js';
|
|
21
|
+
// ─── Proxy Infrastructure ────────────────────────────────────────────────────
|
|
22
|
+
export { encodeFrame, FrameDecoder, FrameError, MAX_FRAME_SIZE, PARTIAL_FRAME_TIMEOUT_MS, } from './proxy/framing.js';
|
|
23
|
+
export { ProxySocketClient, REQUEST_TIMEOUT_MS, IDLE_TIMEOUT_MS, PROTOCOL_VERSION, } from './proxy/proxy-socket-client.js';
|
|
24
|
+
export { ProxyTokenStore } from './proxy/proxy-token-store.js';
|
|
25
|
+
export { ProxyProviderKeyStorage } from './proxy/proxy-provider-key-storage.js';
|
|
26
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAsBH,OAAO,EACL,gBAAgB,EAChB,qBAAqB,EACrB,gBAAgB,EAChB,iBAAiB,EACjB,wBAAwB,GACzB,MAAM,YAAY,CAAC;AAKpB,gFAAgF;AAChF,OAAO,EAAE,iBAAiB,EAAE,MAAM,0BAA0B,CAAC;AAE7D,gFAAgF;AAChF,OAAO,EACL,UAAU,EACV,iBAAiB,EACjB,kBAAkB,EAClB,cAAc,EACd,YAAY,EACZ,oBAAoB,GACrB,MAAM,mBAAmB,CAAC;AAG3B,gFAAgF;AAChF,OAAO,EAAE,mBAAmB,EAAE,MAAM,kBAAkB,CAAC;AAGvD,OAAO,EAAE,qBAAqB,EAAE,MAAM,yBAAyB,CAAC;AAGhE,gFAAgF;AAChF,OAAO,EAAE,sBAAsB,EAAE,MAAM,+BAA+B,CAAC;AAEvE,OAAO,EACL,qBAAqB,EACrB,gBAAgB,EAChB,aAAa,EACb,kBAAkB,EAClB,cAAc,EACd,eAAe,EACf,mBAAmB,EACnB,6BAA6B,EAC7B,yBAAyB,EACzB,uBAAuB,EACvB,eAAe,EACf,mBAAmB,GACpB,MAAM,iBAAiB,CAAC;AAYzB,gFAAgF;AAChF,OAAO,EAAE,mBAAmB,EAAE,MAAM,kCAAkC,CAAC;AACvE,OAAO,EAAE,eAAe,EAAE,YAAY,EAAE,MAAM,8BAA8B,CAAC;AAC7E,OAAO,EAAE,cAAc,EAAE,MAAM,6BAA6B,CAAC;AAG7D,gFAAgF;AAChF,OAAO,EACL,WAAW,EACX,YAAY,EACZ,UAAU,EACV,cAAc,EACd,wBAAwB,GACzB,MAAM,oBAAoB,CAAC;AAG5B,OAAO,EACL,iBAAiB,EACjB,kBAAkB,EAClB,eAAe,EACf,gBAAgB,GACjB,MAAM,gCAAgC,CAAC;AAGxC,OAAO,EAAE,eAAe,EAAE,MAAM,8BAA8B,CAAC;AAC/D,OAAO,EAAE,uBAAuB,EAAE,MAAM,uCAAuC,CAAC"}
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @plan:PLAN-20260608-ISSUE1586.P06
|
|
3
|
+
* @requirement:REQ-INTF-001.4
|
|
4
|
+
*/
|
|
5
|
+
/**
|
|
6
|
+
* @license
|
|
7
|
+
* Copyright 2025 Google LLC
|
|
8
|
+
* SPDX-License-Identifier: Apache-2.0
|
|
9
|
+
*/
|
|
10
|
+
/**
|
|
11
|
+
* Interface for debug/error/warn logging, replacing direct DebugLogger imports.
|
|
12
|
+
*
|
|
13
|
+
* The method shape is derived from P00a preflight grep of actual logger usages
|
|
14
|
+
* in auth-relevant files (auth-precedence-resolver.ts, precedence.ts,
|
|
15
|
+
* keyring-token-store.ts, codex-device-flow.ts). Core's DebugLogger structurally
|
|
16
|
+
* satisfies this interface.
|
|
17
|
+
*
|
|
18
|
+
* The module-level debugLogger singleton (from ../utils/debugLogger.js) and
|
|
19
|
+
* DebugLogger class constructor (from ../debug/index.js) are core factory
|
|
20
|
+
* concerns — auth receives an IDebugLogger instance via DI injection, not
|
|
21
|
+
* the factory.
|
|
22
|
+
*
|
|
23
|
+
* @plan:PLAN-20260608-ISSUE1586.P06
|
|
24
|
+
* @requirement:REQ-INTF-001.4
|
|
25
|
+
*/
|
|
26
|
+
export interface IDebugLogger {
|
|
27
|
+
debug(...args: unknown[]): void;
|
|
28
|
+
error(...args: unknown[]): void;
|
|
29
|
+
warn(...args: unknown[]): void;
|
|
30
|
+
log(...args: unknown[]): void;
|
|
31
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"debug-logger.js","sourceRoot":"","sources":["../../../src/interfaces/debug-logger.ts"],"names":[],"mappings":"AAAA;;;GAGG"}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @plan:PLAN-20260608-ISSUE1586.P06
|
|
3
|
+
* @requirement:REQ-INTF-001.1
|
|
4
|
+
* @requirement:REQ-INTF-001.2
|
|
5
|
+
* @requirement:REQ-INTF-001.3
|
|
6
|
+
* @requirement:REQ-INTF-001.4
|
|
7
|
+
* @requirement:REQ-INTF-001.5
|
|
8
|
+
*/
|
|
9
|
+
/**
|
|
10
|
+
* @license
|
|
11
|
+
* Copyright 2025 Google LLC
|
|
12
|
+
* SPDX-License-Identifier: Apache-2.0
|
|
13
|
+
*/
|
|
14
|
+
export type { ISecureStore, ISecureStoreError, SecureStoreErrorCode, } from './secure-store.js';
|
|
15
|
+
export type { ISettingsService } from './settings-service.js';
|
|
16
|
+
export type { IProviderKeyStorage } from './provider-key-storage.js';
|
|
17
|
+
export type { IDebugLogger } from './debug-logger.js';
|
|
18
|
+
export type { IProviderRuntimeContext, GetActiveRuntimeContext, } from './runtime-context.js';
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/interfaces/index.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG"}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @plan:PLAN-20260608-ISSUE1586.P06
|
|
3
|
+
* @requirement:REQ-INTF-001.3
|
|
4
|
+
*/
|
|
5
|
+
/**
|
|
6
|
+
* @license
|
|
7
|
+
* Copyright 2025 Google LLC
|
|
8
|
+
* SPDX-License-Identifier: Apache-2.0
|
|
9
|
+
*/
|
|
10
|
+
/**
|
|
11
|
+
* Instance contract for provider key storage.
|
|
12
|
+
*
|
|
13
|
+
* This interface defines the shape of a provider key storage object.
|
|
14
|
+
* AuthPrecedenceResolver accepts an IProviderKeyStorage instance via
|
|
15
|
+
* DI injection. Core's getProviderKeyStorage() factory produces an
|
|
16
|
+
* object satisfying this interface — the factory is a core concern,
|
|
17
|
+
* not an auth interface.
|
|
18
|
+
*
|
|
19
|
+
* @plan:PLAN-20260608-ISSUE1586.P06
|
|
20
|
+
* @requirement:REQ-INTF-001.3
|
|
21
|
+
*/
|
|
22
|
+
export interface IProviderKeyStorage {
|
|
23
|
+
getKey(provider: string): Promise<string | null>;
|
|
24
|
+
listKeys(): Promise<string[]>;
|
|
25
|
+
hasKey(provider: string): Promise<boolean>;
|
|
26
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"provider-key-storage.js","sourceRoot":"","sources":["../../../src/interfaces/provider-key-storage.ts"],"names":[],"mappings":"AAAA;;;GAGG"}
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @plan:PLAN-20260608-ISSUE1586.P06
|
|
3
|
+
* @requirement:REQ-INTF-001.5
|
|
4
|
+
*/
|
|
5
|
+
/**
|
|
6
|
+
* @license
|
|
7
|
+
* Copyright 2025 Google LLC
|
|
8
|
+
* SPDX-License-Identifier: Apache-2.0
|
|
9
|
+
*/
|
|
10
|
+
import type { ISettingsService } from './settings-service.js';
|
|
11
|
+
/**
|
|
12
|
+
* Interface for provider runtime context, replacing direct ProviderRuntimeContext imports.
|
|
13
|
+
*
|
|
14
|
+
* Used by precedence.ts (type-only) and auth-precedence-resolver.ts (type + function call).
|
|
15
|
+
* Includes metadata field per P02b remediation (C-CB-06 alignment).
|
|
16
|
+
*
|
|
17
|
+
* The injected function `getActiveRuntimeContext?: () => IProviderRuntimeContext | null`
|
|
18
|
+
* replaces the static `getActiveProviderRuntimeContext()` import from core.
|
|
19
|
+
*
|
|
20
|
+
* @plan:PLAN-20260608-ISSUE1586.P06
|
|
21
|
+
* @requirement:REQ-INTF-001.5
|
|
22
|
+
*/
|
|
23
|
+
export interface IProviderRuntimeContext {
|
|
24
|
+
settingsService: ISettingsService;
|
|
25
|
+
config?: unknown;
|
|
26
|
+
runtimeId?: string;
|
|
27
|
+
metadata?: Record<string, unknown>;
|
|
28
|
+
}
|
|
29
|
+
/**
|
|
30
|
+
* Factory type for obtaining the active runtime context.
|
|
31
|
+
* Injected into AuthPrecedenceResolver via DI to decouple from
|
|
32
|
+
* core's getActiveProviderRuntimeContext static import.
|
|
33
|
+
*
|
|
34
|
+
* @plan:PLAN-20260608-ISSUE1586.P06
|
|
35
|
+
* @requirement:REQ-INTF-001.5
|
|
36
|
+
*/
|
|
37
|
+
export type GetActiveRuntimeContext = (() => IProviderRuntimeContext | null) | undefined;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"runtime-context.js","sourceRoot":"","sources":["../../../src/interfaces/runtime-context.ts"],"names":[],"mappings":"AAAA;;;GAGG"}
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @plan:PLAN-20260608-ISSUE1586.P06
|
|
3
|
+
* @requirement:REQ-INTF-001.1
|
|
4
|
+
*/
|
|
5
|
+
/**
|
|
6
|
+
* @license
|
|
7
|
+
* Copyright 2025 Google LLC
|
|
8
|
+
* SPDX-License-Identifier: Apache-2.0
|
|
9
|
+
*/
|
|
10
|
+
/**
|
|
11
|
+
* Error codes for secure store operations.
|
|
12
|
+
* Derived from core SecureStore error handling evidence (P01 dependency-audit).
|
|
13
|
+
*/
|
|
14
|
+
export type SecureStoreErrorCode = 'UNAVAILABLE' | 'LOCKED' | 'DENIED' | 'CORRUPT' | 'TIMEOUT' | 'NOT_FOUND';
|
|
15
|
+
/**
|
|
16
|
+
* Error shape thrown/rejected by ISecureStore operations.
|
|
17
|
+
* Matches core's SecureStoreError structure used in keyring-token-store.ts
|
|
18
|
+
* catch blocks (error.code, error.remediation).
|
|
19
|
+
*/
|
|
20
|
+
export interface ISecureStoreError extends Error {
|
|
21
|
+
code: SecureStoreErrorCode;
|
|
22
|
+
remediation: string;
|
|
23
|
+
}
|
|
24
|
+
/**
|
|
25
|
+
* Interface for persistent secure token storage.
|
|
26
|
+
*
|
|
27
|
+
* KeyringTokenStore delegates storage operations to an ISecureStore instance
|
|
28
|
+
* injected via DI. Core provides the concrete SecureStore implementation
|
|
29
|
+
* backed by @napi-rs/keyring.
|
|
30
|
+
*
|
|
31
|
+
* Method signatures match core SecureStore's public API:
|
|
32
|
+
* - get (L347 usage in keyring-token-store.ts)
|
|
33
|
+
* - set (L330 usage)
|
|
34
|
+
* - delete (L395 usage)
|
|
35
|
+
* - list (L414, L437 usage)
|
|
36
|
+
* - has (L657 in core SecureStore)
|
|
37
|
+
*
|
|
38
|
+
* @plan:PLAN-20260608-ISSUE1586.P06
|
|
39
|
+
* @requirement:REQ-INTF-001.1
|
|
40
|
+
*/
|
|
41
|
+
export interface ISecureStore {
|
|
42
|
+
get(key: string): Promise<string | null>;
|
|
43
|
+
set(key: string, value: string): Promise<void>;
|
|
44
|
+
delete(key: string): Promise<boolean>;
|
|
45
|
+
list(): Promise<string[]>;
|
|
46
|
+
has(key: string): Promise<boolean>;
|
|
47
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"secure-store.js","sourceRoot":"","sources":["../../../src/interfaces/secure-store.ts"],"names":[],"mappings":"AAAA;;;GAGG"}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @plan:PLAN-20260608-ISSUE1586.P06
|
|
3
|
+
* @requirement:REQ-INTF-001.2
|
|
4
|
+
*/
|
|
5
|
+
/**
|
|
6
|
+
* @license
|
|
7
|
+
* Copyright 2025 Google LLC
|
|
8
|
+
* SPDX-License-Identifier: Apache-2.0
|
|
9
|
+
*/
|
|
10
|
+
/**
|
|
11
|
+
* Interface for settings access, replacing direct SettingsService imports.
|
|
12
|
+
*
|
|
13
|
+
* AuthPrecedenceResolver uses ISettingsService to look up provider settings
|
|
14
|
+
* and listen for settings change events. Core's SettingsService structurally
|
|
15
|
+
* satisfies this interface — no adapter needed.
|
|
16
|
+
*
|
|
17
|
+
* @plan:PLAN-20260608-ISSUE1586.P06
|
|
18
|
+
* @requirement:REQ-INTF-001.2
|
|
19
|
+
*/
|
|
20
|
+
export interface ISettingsService {
|
|
21
|
+
get(key: string): unknown;
|
|
22
|
+
getProviderSettings(providerName: string): Record<string, unknown>;
|
|
23
|
+
on(event: string, handler: (...args: unknown[]) => void): void;
|
|
24
|
+
off(event: string, handler: (...args: unknown[]) => void): void;
|
|
25
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"settings-service.js","sourceRoot":"","sources":["../../../src/interfaces/settings-service.ts"],"names":[],"mappings":"AAAA;;;GAGG"}
|
|
@@ -0,0 +1,96 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @license
|
|
3
|
+
* Copyright 2025 Vybestack LLC
|
|
4
|
+
* SPDX-License-Identifier: Apache-2.0
|
|
5
|
+
*/
|
|
6
|
+
import { type OAuthToken, type BucketStats } from './types.js';
|
|
7
|
+
import { type TokenStore } from './token-store.js';
|
|
8
|
+
import { type ISecureStore } from './interfaces/secure-store.js';
|
|
9
|
+
import { type IDebugLogger } from './interfaces/debug-logger.js';
|
|
10
|
+
/**
|
|
11
|
+
* Keyring-backed token store with filesystem advisory locks.
|
|
12
|
+
*
|
|
13
|
+
* @internal **DO NOT instantiate directly in consumer code.**
|
|
14
|
+
* Use `createTokenStore()` from `credential-store-factory.ts` instead.
|
|
15
|
+
*
|
|
16
|
+
* @plan PLAN-20260213-KEYRINGTOKENSTORE.P06, PLAN-20260608-ISSUE1586.P11
|
|
17
|
+
* @plan PLAN-20250214-CREDPROXY.P36
|
|
18
|
+
*/
|
|
19
|
+
export declare class KeyringTokenStore implements TokenStore {
|
|
20
|
+
private static readonly NO_OP_LOGGER;
|
|
21
|
+
private readonly secureStore;
|
|
22
|
+
private readonly logger;
|
|
23
|
+
private readonly lockDir;
|
|
24
|
+
constructor(options?: {
|
|
25
|
+
secureStore?: ISecureStore;
|
|
26
|
+
logger?: IDebugLogger;
|
|
27
|
+
lockDir?: string;
|
|
28
|
+
});
|
|
29
|
+
private validateName;
|
|
30
|
+
private accountKey;
|
|
31
|
+
/**
|
|
32
|
+
* Non-cryptographic FNV-1a hash for debug log identifiers.
|
|
33
|
+
*/
|
|
34
|
+
private hashIdentifier;
|
|
35
|
+
private lockFilePath;
|
|
36
|
+
private authLockFilePath;
|
|
37
|
+
/**
|
|
38
|
+
* Ensures the lock directory exists.
|
|
39
|
+
*/
|
|
40
|
+
private ensureLockDir;
|
|
41
|
+
/**
|
|
42
|
+
* Shared lock acquisition logic used by both refresh and auth locks.
|
|
43
|
+
*/
|
|
44
|
+
private acquireLock;
|
|
45
|
+
private tryCreateLock;
|
|
46
|
+
private checkExistingLock;
|
|
47
|
+
private releaseLock;
|
|
48
|
+
/**
|
|
49
|
+
* Validates and persists an OAuth token to ISecureStore.
|
|
50
|
+
*/
|
|
51
|
+
saveToken(provider: string, token: OAuthToken, bucket?: string): Promise<void>;
|
|
52
|
+
/**
|
|
53
|
+
* Retrieves and validates an OAuth token from ISecureStore.
|
|
54
|
+
*/
|
|
55
|
+
getToken(provider: string, bucket?: string): Promise<OAuthToken | null>;
|
|
56
|
+
/**
|
|
57
|
+
* Removes a token from ISecureStore. Best-effort — errors are swallowed.
|
|
58
|
+
*/
|
|
59
|
+
removeToken(provider: string, bucket?: string): Promise<void>;
|
|
60
|
+
/**
|
|
61
|
+
* Lists all unique provider names from ISecureStore keys.
|
|
62
|
+
*/
|
|
63
|
+
listProviders(): Promise<string[]>;
|
|
64
|
+
/**
|
|
65
|
+
* Lists all bucket names for a given provider.
|
|
66
|
+
*/
|
|
67
|
+
listBuckets(provider: string): Promise<string[]>;
|
|
68
|
+
/**
|
|
69
|
+
* Returns placeholder bucket statistics if a token exists for the given bucket.
|
|
70
|
+
*/
|
|
71
|
+
getBucketStats(provider: string, bucket: string): Promise<BucketStats | null>;
|
|
72
|
+
/**
|
|
73
|
+
* Acquires a filesystem-based advisory lock for token refresh.
|
|
74
|
+
*/
|
|
75
|
+
acquireRefreshLock(provider: string, options?: {
|
|
76
|
+
waitMs?: number;
|
|
77
|
+
staleMs?: number;
|
|
78
|
+
bucket?: string;
|
|
79
|
+
}): Promise<boolean>;
|
|
80
|
+
/**
|
|
81
|
+
* Releases a filesystem-based advisory lock. Idempotent.
|
|
82
|
+
*/
|
|
83
|
+
releaseRefreshLock(provider: string, bucket?: string): Promise<void>;
|
|
84
|
+
/**
|
|
85
|
+
* Acquires a filesystem-based advisory lock for interactive authentication.
|
|
86
|
+
*/
|
|
87
|
+
acquireAuthLock(provider: string, options?: {
|
|
88
|
+
waitMs?: number;
|
|
89
|
+
staleMs?: number;
|
|
90
|
+
bucket?: string;
|
|
91
|
+
}): Promise<boolean>;
|
|
92
|
+
/**
|
|
93
|
+
* Releases the auth lock for a provider. Idempotent.
|
|
94
|
+
*/
|
|
95
|
+
releaseAuthLock(provider: string, bucket?: string): Promise<void>;
|
|
96
|
+
}
|