@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,219 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @license
|
|
3
|
+
* Copyright 2025 Vybestack LLC
|
|
4
|
+
* SPDX-License-Identifier: Apache-2.0
|
|
5
|
+
*/
|
|
6
|
+
/**
|
|
7
|
+
* Unix domain socket client for credential proxy protocol.
|
|
8
|
+
*
|
|
9
|
+
* @plan PLAN-20250214-CREDPROXY.P03
|
|
10
|
+
* @requirement R6.1-R6.5, R24.1, R24.2
|
|
11
|
+
* @pseudocode analysis/pseudocode/001-framing-protocol.md
|
|
12
|
+
*/
|
|
13
|
+
import * as net from 'node:net';
|
|
14
|
+
import * as crypto from 'node:crypto';
|
|
15
|
+
import { encodeFrame, FrameDecoder } from './framing.js';
|
|
16
|
+
export const REQUEST_TIMEOUT_MS = 30000;
|
|
17
|
+
export const IDLE_TIMEOUT_MS = 300000;
|
|
18
|
+
export const PROTOCOL_VERSION = 1;
|
|
19
|
+
export class ProxySocketClient {
|
|
20
|
+
socketPath;
|
|
21
|
+
socket = null;
|
|
22
|
+
decoder = new FrameDecoder({
|
|
23
|
+
onPartialFrameTimeout: () => this.handlePartialFrameTimeout(),
|
|
24
|
+
});
|
|
25
|
+
pendingRequests = new Map();
|
|
26
|
+
handshakeComplete = false;
|
|
27
|
+
idleTimer = null;
|
|
28
|
+
connectingPromise = null;
|
|
29
|
+
handshakeResolver = null;
|
|
30
|
+
constructor(socketPath) {
|
|
31
|
+
this.socketPath = socketPath;
|
|
32
|
+
}
|
|
33
|
+
async ensureConnected() {
|
|
34
|
+
if (this.socket !== null && this.handshakeComplete) {
|
|
35
|
+
this.resetIdleTimer();
|
|
36
|
+
return;
|
|
37
|
+
}
|
|
38
|
+
if (this.connectingPromise) {
|
|
39
|
+
await this.connectingPromise;
|
|
40
|
+
return;
|
|
41
|
+
}
|
|
42
|
+
this.connectingPromise = this.connectAndHandshake();
|
|
43
|
+
try {
|
|
44
|
+
await this.connectingPromise;
|
|
45
|
+
}
|
|
46
|
+
finally {
|
|
47
|
+
this.connectingPromise = null;
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
isConnected() {
|
|
51
|
+
return this.socket !== null && this.handshakeComplete;
|
|
52
|
+
}
|
|
53
|
+
async request(op, payload) {
|
|
54
|
+
if (!this.isConnected()) {
|
|
55
|
+
await this.ensureConnected();
|
|
56
|
+
}
|
|
57
|
+
else {
|
|
58
|
+
this.resetIdleTimer();
|
|
59
|
+
}
|
|
60
|
+
return this.sendRequest(op, payload);
|
|
61
|
+
}
|
|
62
|
+
sendRequest(op, payload) {
|
|
63
|
+
const id = crypto.randomUUID();
|
|
64
|
+
const frame = { v: PROTOCOL_VERSION, id, op, payload };
|
|
65
|
+
const promise = new Promise((resolve, reject) => {
|
|
66
|
+
const timer = setTimeout(() => {
|
|
67
|
+
this.pendingRequests.delete(id);
|
|
68
|
+
reject(new Error(`Request timed out after ${REQUEST_TIMEOUT_MS}ms`));
|
|
69
|
+
}, REQUEST_TIMEOUT_MS);
|
|
70
|
+
this.pendingRequests.set(id, { resolve, reject, timer });
|
|
71
|
+
});
|
|
72
|
+
this.socket.write(encodeFrame(frame));
|
|
73
|
+
this.resetIdleTimer();
|
|
74
|
+
return promise;
|
|
75
|
+
}
|
|
76
|
+
close() {
|
|
77
|
+
this.cancelIdleTimer();
|
|
78
|
+
this.destroy('Client closed');
|
|
79
|
+
}
|
|
80
|
+
gracefulClose() {
|
|
81
|
+
this.handshakeComplete = false;
|
|
82
|
+
// Reject any pending requests
|
|
83
|
+
for (const [, pending] of this.pendingRequests) {
|
|
84
|
+
clearTimeout(pending.timer);
|
|
85
|
+
pending.reject(new Error('Connection closing'));
|
|
86
|
+
}
|
|
87
|
+
this.pendingRequests.clear();
|
|
88
|
+
if (this.handshakeResolver) {
|
|
89
|
+
const resolver = this.handshakeResolver;
|
|
90
|
+
this.handshakeResolver = null;
|
|
91
|
+
resolver.reject(new Error('Connection closing'));
|
|
92
|
+
}
|
|
93
|
+
if (this.socket !== null) {
|
|
94
|
+
// Remove listeners to prevent stale close events from affecting new connections
|
|
95
|
+
this.socket.removeAllListeners();
|
|
96
|
+
this.socket.end();
|
|
97
|
+
this.socket = null;
|
|
98
|
+
}
|
|
99
|
+
this.decoder.reset();
|
|
100
|
+
}
|
|
101
|
+
async connectAndHandshake() {
|
|
102
|
+
await this.connect();
|
|
103
|
+
await this.handshake();
|
|
104
|
+
}
|
|
105
|
+
async connect() {
|
|
106
|
+
this.socket = net.createConnection(this.socketPath);
|
|
107
|
+
this.decoder = new FrameDecoder({
|
|
108
|
+
onPartialFrameTimeout: () => this.handlePartialFrameTimeout(),
|
|
109
|
+
});
|
|
110
|
+
this.socket.on('data', (chunk) => this.onData(chunk));
|
|
111
|
+
this.socket.on('error', (err) => this.onError(err));
|
|
112
|
+
this.socket.on('close', () => this.onClose());
|
|
113
|
+
await new Promise((resolve, reject) => {
|
|
114
|
+
this.socket.once('connect', resolve);
|
|
115
|
+
this.socket.once('error', reject);
|
|
116
|
+
});
|
|
117
|
+
}
|
|
118
|
+
async handshake() {
|
|
119
|
+
const request = {
|
|
120
|
+
v: PROTOCOL_VERSION,
|
|
121
|
+
op: 'handshake',
|
|
122
|
+
payload: { minVersion: 1, maxVersion: 1 },
|
|
123
|
+
};
|
|
124
|
+
this.socket.write(encodeFrame(request));
|
|
125
|
+
const response = await new Promise((resolve, reject) => {
|
|
126
|
+
this.handshakeResolver = { resolve, reject };
|
|
127
|
+
const timer = setTimeout(() => {
|
|
128
|
+
this.handshakeResolver = null;
|
|
129
|
+
reject(new Error(`Handshake timed out after ${REQUEST_TIMEOUT_MS}ms`));
|
|
130
|
+
}, REQUEST_TIMEOUT_MS);
|
|
131
|
+
const originalResolve = this.handshakeResolver.resolve;
|
|
132
|
+
this.handshakeResolver.resolve = (value) => {
|
|
133
|
+
clearTimeout(timer);
|
|
134
|
+
originalResolve(value);
|
|
135
|
+
};
|
|
136
|
+
const originalReject = this.handshakeResolver.reject;
|
|
137
|
+
this.handshakeResolver.reject = (reason) => {
|
|
138
|
+
clearTimeout(timer);
|
|
139
|
+
originalReject(reason);
|
|
140
|
+
};
|
|
141
|
+
});
|
|
142
|
+
if (response.ok !== true) {
|
|
143
|
+
throw new Error('Version mismatch: ' + (response.error ?? 'unknown error'));
|
|
144
|
+
}
|
|
145
|
+
this.handshakeComplete = true;
|
|
146
|
+
this.resetIdleTimer();
|
|
147
|
+
}
|
|
148
|
+
onData(chunk) {
|
|
149
|
+
try {
|
|
150
|
+
const frames = this.decoder.feed(chunk);
|
|
151
|
+
for (const frame of frames) {
|
|
152
|
+
if (this.handshakeResolver) {
|
|
153
|
+
const resolver = this.handshakeResolver;
|
|
154
|
+
this.handshakeResolver = null;
|
|
155
|
+
resolver.resolve(frame);
|
|
156
|
+
continue;
|
|
157
|
+
}
|
|
158
|
+
this.resolvePendingRequest(frame);
|
|
159
|
+
}
|
|
160
|
+
}
|
|
161
|
+
catch {
|
|
162
|
+
this.destroy('Frame decode error');
|
|
163
|
+
}
|
|
164
|
+
}
|
|
165
|
+
resolvePendingRequest(frame) {
|
|
166
|
+
const id = frame.id;
|
|
167
|
+
if (!id) {
|
|
168
|
+
return;
|
|
169
|
+
}
|
|
170
|
+
const pending = this.pendingRequests.get(id);
|
|
171
|
+
if (pending) {
|
|
172
|
+
clearTimeout(pending.timer);
|
|
173
|
+
this.pendingRequests.delete(id);
|
|
174
|
+
pending.resolve(frame);
|
|
175
|
+
}
|
|
176
|
+
}
|
|
177
|
+
onError(_err) {
|
|
178
|
+
this.destroy('Credential proxy connection lost. Restart the session.');
|
|
179
|
+
}
|
|
180
|
+
onClose() {
|
|
181
|
+
if (this.handshakeComplete || this.handshakeResolver) {
|
|
182
|
+
this.destroy('Credential proxy connection lost. Restart the session.');
|
|
183
|
+
}
|
|
184
|
+
}
|
|
185
|
+
handlePartialFrameTimeout() {
|
|
186
|
+
this.destroy('Credential proxy partial frame timeout. Connection will be reset.');
|
|
187
|
+
}
|
|
188
|
+
destroy(message) {
|
|
189
|
+
this.cancelIdleTimer();
|
|
190
|
+
for (const [, pending] of this.pendingRequests) {
|
|
191
|
+
clearTimeout(pending.timer);
|
|
192
|
+
pending.reject(new Error(message));
|
|
193
|
+
}
|
|
194
|
+
this.pendingRequests.clear();
|
|
195
|
+
this.handshakeComplete = false;
|
|
196
|
+
if (this.socket !== null) {
|
|
197
|
+
this.socket.destroy();
|
|
198
|
+
this.socket = null;
|
|
199
|
+
}
|
|
200
|
+
this.decoder.reset();
|
|
201
|
+
if (this.handshakeResolver) {
|
|
202
|
+
const resolver = this.handshakeResolver;
|
|
203
|
+
this.handshakeResolver = null;
|
|
204
|
+
resolver.reject(new Error(message));
|
|
205
|
+
}
|
|
206
|
+
}
|
|
207
|
+
resetIdleTimer() {
|
|
208
|
+
this.cancelIdleTimer();
|
|
209
|
+
this.idleTimer = setTimeout(() => this.gracefulClose(), IDLE_TIMEOUT_MS);
|
|
210
|
+
this.idleTimer.unref();
|
|
211
|
+
}
|
|
212
|
+
cancelIdleTimer() {
|
|
213
|
+
if (this.idleTimer !== null) {
|
|
214
|
+
clearTimeout(this.idleTimer);
|
|
215
|
+
this.idleTimer = null;
|
|
216
|
+
}
|
|
217
|
+
}
|
|
218
|
+
}
|
|
219
|
+
//# sourceMappingURL=proxy-socket-client.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"proxy-socket-client.js","sourceRoot":"","sources":["../../../src/proxy/proxy-socket-client.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @license
|
|
3
|
+
* Copyright 2025 Vybestack LLC
|
|
4
|
+
* SPDX-License-Identifier: Apache-2.0
|
|
5
|
+
*/
|
|
6
|
+
/**
|
|
7
|
+
* Token store that proxies all operations through a Unix domain socket
|
|
8
|
+
* to the host-side credential proxy server. Used inside sandbox containers.
|
|
9
|
+
*
|
|
10
|
+
* @plan PLAN-20250214-CREDPROXY.P09
|
|
11
|
+
* @requirement R2.1, R8.1-R8.9, R23.3, R29.1-R29.4
|
|
12
|
+
* @pseudocode analysis/pseudocode/003-proxy-token-store.md
|
|
13
|
+
*/
|
|
14
|
+
import { type OAuthToken, type BucketStats } from '../types.js';
|
|
15
|
+
import { type TokenStore } from '../token-store.js';
|
|
16
|
+
import { ProxySocketClient } from './proxy-socket-client.js';
|
|
17
|
+
export declare class ProxyTokenStore implements TokenStore {
|
|
18
|
+
private readonly client;
|
|
19
|
+
constructor(socketPath: string);
|
|
20
|
+
getToken(provider: string, bucket?: string): Promise<OAuthToken | null>;
|
|
21
|
+
saveToken(provider: string, token: OAuthToken, bucket?: string): Promise<void>;
|
|
22
|
+
removeToken(provider: string, bucket?: string): Promise<void>;
|
|
23
|
+
listProviders(): Promise<string[]>;
|
|
24
|
+
listBuckets(provider: string): Promise<string[]>;
|
|
25
|
+
getBucketStats(provider: string, bucket: string): Promise<BucketStats | null>;
|
|
26
|
+
acquireRefreshLock(_provider: string, _options?: {
|
|
27
|
+
waitMs?: number;
|
|
28
|
+
staleMs?: number;
|
|
29
|
+
bucket?: string;
|
|
30
|
+
}): Promise<boolean>;
|
|
31
|
+
releaseRefreshLock(_provider: string, _bucket?: string): Promise<void>;
|
|
32
|
+
acquireAuthLock(_provider: string, _options?: {
|
|
33
|
+
waitMs?: number;
|
|
34
|
+
staleMs?: number;
|
|
35
|
+
bucket?: string;
|
|
36
|
+
}): Promise<boolean>;
|
|
37
|
+
releaseAuthLock(_provider: string, _bucket?: string): Promise<void>;
|
|
38
|
+
getClient(): ProxySocketClient;
|
|
39
|
+
}
|
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @license
|
|
3
|
+
* Copyright 2025 Vybestack LLC
|
|
4
|
+
* SPDX-License-Identifier: Apache-2.0
|
|
5
|
+
*/
|
|
6
|
+
import { ProxySocketClient } from './proxy-socket-client.js';
|
|
7
|
+
export class ProxyTokenStore {
|
|
8
|
+
client;
|
|
9
|
+
constructor(socketPath) {
|
|
10
|
+
this.client = new ProxySocketClient(socketPath);
|
|
11
|
+
}
|
|
12
|
+
async getToken(provider, bucket) {
|
|
13
|
+
const response = await this.client.request('get_token', {
|
|
14
|
+
provider,
|
|
15
|
+
bucket,
|
|
16
|
+
});
|
|
17
|
+
if (!response.ok && response.code === 'NOT_FOUND')
|
|
18
|
+
return null;
|
|
19
|
+
if (!response.ok)
|
|
20
|
+
throw new Error(response.error ?? 'proxy error');
|
|
21
|
+
return response.data;
|
|
22
|
+
}
|
|
23
|
+
async saveToken(provider, token, bucket) {
|
|
24
|
+
const response = await this.client.request('save_token', {
|
|
25
|
+
provider,
|
|
26
|
+
bucket,
|
|
27
|
+
token,
|
|
28
|
+
});
|
|
29
|
+
if (!response.ok)
|
|
30
|
+
throw new Error(response.error ?? 'proxy error');
|
|
31
|
+
}
|
|
32
|
+
async removeToken(provider, bucket) {
|
|
33
|
+
const response = await this.client.request('remove_token', {
|
|
34
|
+
provider,
|
|
35
|
+
bucket,
|
|
36
|
+
});
|
|
37
|
+
if (!response.ok)
|
|
38
|
+
throw new Error(response.error ?? 'proxy error');
|
|
39
|
+
}
|
|
40
|
+
async listProviders() {
|
|
41
|
+
const response = await this.client.request('list_providers', {});
|
|
42
|
+
if (!response.ok)
|
|
43
|
+
throw new Error(response.error ?? 'proxy error');
|
|
44
|
+
return response.data.providers;
|
|
45
|
+
}
|
|
46
|
+
async listBuckets(provider) {
|
|
47
|
+
const response = await this.client.request('list_buckets', { provider });
|
|
48
|
+
if (!response.ok)
|
|
49
|
+
throw new Error(response.error ?? 'proxy error');
|
|
50
|
+
return response.data.buckets;
|
|
51
|
+
}
|
|
52
|
+
async getBucketStats(provider, bucket) {
|
|
53
|
+
const response = await this.client.request('get_bucket_stats', {
|
|
54
|
+
provider,
|
|
55
|
+
bucket,
|
|
56
|
+
});
|
|
57
|
+
if (!response.ok && response.code === 'NOT_FOUND')
|
|
58
|
+
return null;
|
|
59
|
+
if (!response.ok)
|
|
60
|
+
throw new Error(response.error ?? 'proxy error');
|
|
61
|
+
const data = response.data;
|
|
62
|
+
return {
|
|
63
|
+
bucket,
|
|
64
|
+
// eslint-disable-next-line @typescript-eslint/no-unnecessary-condition -- Proxy payloads can omit persisted bucket stats.
|
|
65
|
+
requestCount: data.requestCount ?? 0,
|
|
66
|
+
// eslint-disable-next-line @typescript-eslint/no-unnecessary-condition -- Proxy payloads can omit persisted bucket stats.
|
|
67
|
+
percentage: data.percentage ?? 0,
|
|
68
|
+
lastUsed: data.lastUsed,
|
|
69
|
+
};
|
|
70
|
+
}
|
|
71
|
+
async acquireRefreshLock(_provider, _options) {
|
|
72
|
+
return true;
|
|
73
|
+
}
|
|
74
|
+
async releaseRefreshLock(_provider, _bucket) {
|
|
75
|
+
// No-op: refresh coordination happens on host
|
|
76
|
+
}
|
|
77
|
+
async acquireAuthLock(_provider, _options) {
|
|
78
|
+
return true;
|
|
79
|
+
}
|
|
80
|
+
async releaseAuthLock(_provider, _bucket) {
|
|
81
|
+
// No-op: auth coordination happens on host
|
|
82
|
+
}
|
|
83
|
+
getClient() {
|
|
84
|
+
return this.client;
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
//# sourceMappingURL=proxy-token-store.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"proxy-token-store.js","sourceRoot":"","sources":["../../../src/proxy/proxy-token-store.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @license
|
|
3
|
+
* Copyright 2025 Vybestack LLC
|
|
4
|
+
* SPDX-License-Identifier: Apache-2.0
|
|
5
|
+
*/
|
|
6
|
+
/**
|
|
7
|
+
* Token merge utility for credential refresh operations.
|
|
8
|
+
* Extracted from OAuthManager for shared use by proxy server.
|
|
9
|
+
*
|
|
10
|
+
* @plan PLAN-20250214-CREDPROXY.P06
|
|
11
|
+
* @requirement R12.1, R12.2, R12.3, R12.4, R12.5
|
|
12
|
+
* @pseudocode analysis/pseudocode/002-token-sanitization-merge.md
|
|
13
|
+
*/
|
|
14
|
+
import { type OAuthToken } from './types.js';
|
|
15
|
+
export type OAuthTokenWithExtras = OAuthToken & Record<string, unknown>;
|
|
16
|
+
export declare function mergeRefreshedToken(current: OAuthTokenWithExtras, next: Partial<OAuthTokenWithExtras>): OAuthTokenWithExtras;
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @license
|
|
3
|
+
* Copyright 2025 Vybestack LLC
|
|
4
|
+
* SPDX-License-Identifier: Apache-2.0
|
|
5
|
+
*/
|
|
6
|
+
export function mergeRefreshedToken(current, next) {
|
|
7
|
+
const merged = { ...current, ...next };
|
|
8
|
+
if (next.refresh_token === undefined || next.refresh_token === '') {
|
|
9
|
+
merged.refresh_token = current.refresh_token;
|
|
10
|
+
}
|
|
11
|
+
return merged;
|
|
12
|
+
}
|
|
13
|
+
//# sourceMappingURL=token-merge.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"token-merge.js","sourceRoot":"","sources":["../../src/token-merge.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAeH,MAAM,UAAU,mBAAmB,CACjC,OAA6B,EAC7B,IAAmC;IAEnC,MAAM,MAAM,GAAG,EAAE,GAAG,OAAO,EAAE,GAAG,IAAI,EAAE,CAAC;IACvC,IAAI,IAAI,CAAC,aAAa,KAAK,SAAS,IAAI,IAAI,CAAC,aAAa,KAAK,EAAE,EAAE,CAAC;QAClE,MAAM,CAAC,aAAa,GAAG,OAAO,CAAC,aAAa,CAAC;IAC/C,CAAC;IACD,OAAO,MAAM,CAAC;AAChB,CAAC"}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @license
|
|
3
|
+
* Copyright 2025 Vybestack LLC
|
|
4
|
+
* SPDX-License-Identifier: Apache-2.0
|
|
5
|
+
*/
|
|
6
|
+
/**
|
|
7
|
+
* Token sanitization for credential proxy security boundary.
|
|
8
|
+
* Strips refresh_token from all data crossing the Unix socket.
|
|
9
|
+
*
|
|
10
|
+
* @plan PLAN-20250214-CREDPROXY.P06
|
|
11
|
+
* @requirement R10.1, R10.2, R10.3
|
|
12
|
+
* @pseudocode analysis/pseudocode/002-token-sanitization-merge.md
|
|
13
|
+
*/
|
|
14
|
+
import { type OAuthToken } from './types.js';
|
|
15
|
+
export type SanitizedOAuthToken = Omit<OAuthToken, 'refresh_token'> & Record<string, unknown>;
|
|
16
|
+
export declare function sanitizeTokenForProxy(token: OAuthToken): SanitizedOAuthToken;
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @license
|
|
3
|
+
* Copyright 2025 Vybestack LLC
|
|
4
|
+
* SPDX-License-Identifier: Apache-2.0
|
|
5
|
+
*/
|
|
6
|
+
export function sanitizeTokenForProxy(token) {
|
|
7
|
+
const { refresh_token: _refresh_token, ...sanitized } = token;
|
|
8
|
+
return sanitized;
|
|
9
|
+
}
|
|
10
|
+
//# sourceMappingURL=token-sanitization.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"token-sanitization.js","sourceRoot":"","sources":["../../src/token-sanitization.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAgBH,MAAM,UAAU,qBAAqB,CAAC,KAAiB;IACrD,MAAM,EAAE,aAAa,EAAE,cAAc,EAAE,GAAG,SAAS,EAAE,GAAG,KAAK,CAAC;IAC9D,OAAO,SAAS,CAAC;AACnB,CAAC"}
|
|
@@ -0,0 +1,93 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @license
|
|
3
|
+
* Copyright 2025 Vybestack LLC
|
|
4
|
+
* SPDX-License-Identifier: Apache-2.0
|
|
5
|
+
*/
|
|
6
|
+
/**
|
|
7
|
+
* @plan PLAN-20260213-KEYRINGTOKENSTORE.P10
|
|
8
|
+
* @requirement R13.2
|
|
9
|
+
*/
|
|
10
|
+
import { type OAuthToken, type BucketStats } from './types.js';
|
|
11
|
+
/**
|
|
12
|
+
* Interface for multi-provider OAuth token storage
|
|
13
|
+
*/
|
|
14
|
+
export interface TokenStore {
|
|
15
|
+
/**
|
|
16
|
+
* Save an OAuth token for a specific provider
|
|
17
|
+
* @param provider - The provider name (e.g., 'gemini', 'qwen')
|
|
18
|
+
* @param token - The OAuth token to save
|
|
19
|
+
* @param bucket - Optional bucket name for multi-account support
|
|
20
|
+
*/
|
|
21
|
+
saveToken(provider: string, token: OAuthToken, bucket?: string): Promise<void>;
|
|
22
|
+
/**
|
|
23
|
+
* Retrieve an OAuth token for a specific provider
|
|
24
|
+
* @param provider - The provider name
|
|
25
|
+
* @param bucket - Optional bucket name for multi-account support
|
|
26
|
+
* @returns The token if found, null otherwise
|
|
27
|
+
*/
|
|
28
|
+
getToken(provider: string, bucket?: string): Promise<OAuthToken | null>;
|
|
29
|
+
/**
|
|
30
|
+
* Remove an OAuth token for a specific provider
|
|
31
|
+
* @param provider - The provider name
|
|
32
|
+
* @param bucket - Optional bucket name for multi-account support
|
|
33
|
+
*/
|
|
34
|
+
removeToken(provider: string, bucket?: string): Promise<void>;
|
|
35
|
+
/**
|
|
36
|
+
* List all providers that have stored tokens
|
|
37
|
+
* @returns Array of provider names with stored tokens
|
|
38
|
+
*/
|
|
39
|
+
listProviders(): Promise<string[]>;
|
|
40
|
+
/**
|
|
41
|
+
* List all buckets for a specific provider
|
|
42
|
+
* @param provider - The provider name
|
|
43
|
+
* @returns Array of bucket names for the provider
|
|
44
|
+
*/
|
|
45
|
+
listBuckets(provider: string): Promise<string[]>;
|
|
46
|
+
/**
|
|
47
|
+
* Get usage statistics for a specific bucket
|
|
48
|
+
* @param provider - The provider name
|
|
49
|
+
* @param bucket - The bucket name
|
|
50
|
+
* @returns Bucket statistics if available, null otherwise
|
|
51
|
+
*/
|
|
52
|
+
getBucketStats(provider: string, bucket: string): Promise<BucketStats | null>;
|
|
53
|
+
/**
|
|
54
|
+
* Acquire a refresh lock for a provider to prevent concurrent refreshes
|
|
55
|
+
* @param provider - The provider name
|
|
56
|
+
* @param options - Optional configuration for lock behavior
|
|
57
|
+
* - waitMs: Maximum time to wait for lock
|
|
58
|
+
* - staleMs: Threshold for considering a lock stale
|
|
59
|
+
* - bucket: Optional bucket name for multi-account support
|
|
60
|
+
* @returns true if lock was acquired, false otherwise
|
|
61
|
+
*/
|
|
62
|
+
acquireRefreshLock(provider: string, options?: {
|
|
63
|
+
waitMs?: number;
|
|
64
|
+
staleMs?: number;
|
|
65
|
+
bucket?: string;
|
|
66
|
+
}): Promise<boolean>;
|
|
67
|
+
/**
|
|
68
|
+
* Release the refresh lock for a provider
|
|
69
|
+
* @param provider - The provider name
|
|
70
|
+
* @param bucket - Optional bucket name for multi-account support
|
|
71
|
+
*/
|
|
72
|
+
releaseRefreshLock(provider: string, bucket?: string): Promise<void>;
|
|
73
|
+
/**
|
|
74
|
+
* Acquire an auth lock for a provider to prevent concurrent interactive authentication
|
|
75
|
+
* @param provider - The provider name
|
|
76
|
+
* @param options - Optional configuration for lock behavior
|
|
77
|
+
* - waitMs: Maximum time to wait for lock (default: 60000ms)
|
|
78
|
+
* - staleMs: Threshold for considering a lock stale (default: 360000ms)
|
|
79
|
+
* - bucket: Optional bucket name for multi-account support
|
|
80
|
+
* @returns true if lock was acquired, false otherwise
|
|
81
|
+
*/
|
|
82
|
+
acquireAuthLock(provider: string, options?: {
|
|
83
|
+
waitMs?: number;
|
|
84
|
+
staleMs?: number;
|
|
85
|
+
bucket?: string;
|
|
86
|
+
}): Promise<boolean>;
|
|
87
|
+
/**
|
|
88
|
+
* Release the auth lock for a provider
|
|
89
|
+
* @param provider - The provider name
|
|
90
|
+
* @param bucket - Optional bucket name for multi-account support
|
|
91
|
+
*/
|
|
92
|
+
releaseAuthLock(provider: string, bucket?: string): Promise<void>;
|
|
93
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"token-store.js","sourceRoot":"","sources":["../../src/token-store.ts"],"names":[],"mappings":"AAAA;;;;GAIG"}
|