@cortexkit/anthropic-auth-core 1.2.0 → 1.2.2
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/accounts.js +36 -14
- package/dist/constants.d.ts +1 -1
- package/dist/constants.js +1 -1
- package/package.json +1 -1
package/dist/accounts.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { createHash, randomUUID } from 'node:crypto';
|
|
2
|
-
import { mkdir, readFile, rename, rm, writeFile } from 'node:fs/promises';
|
|
2
|
+
import { mkdir, readFile, rename, rm, stat, writeFile } from 'node:fs/promises';
|
|
3
3
|
import { homedir } from 'node:os';
|
|
4
4
|
import { dirname, join } from 'node:path';
|
|
5
5
|
import { ClaudeOAuthRefreshError, refreshClaudeOAuthToken } from "./auth.js";
|
|
@@ -21,6 +21,7 @@ const DEFAULT_MINIMUM_REMAINING = {
|
|
|
21
21
|
};
|
|
22
22
|
const DEFAULT_FAIL_CLOSED_ON_UNKNOWN_QUOTA = true;
|
|
23
23
|
const BACKGROUND_TICK_MS = 60_000;
|
|
24
|
+
const BACKGROUND_TICK_JITTER_MS = 60_000;
|
|
24
25
|
function getConfigDir() {
|
|
25
26
|
if (process.env.OPENCODE_CONFIG_DIR?.trim()) {
|
|
26
27
|
return process.env.OPENCODE_CONFIG_DIR.trim();
|
|
@@ -162,46 +163,64 @@ export async function saveAccounts(storage, path = getAccountStoragePath()) {
|
|
|
162
163
|
}
|
|
163
164
|
export async function acquireRefreshFileLock(options) {
|
|
164
165
|
const accountPath = options.path ?? getAccountStoragePath();
|
|
165
|
-
const
|
|
166
|
-
const
|
|
166
|
+
const lockPath = `${accountPath}.${options.name}.lock`;
|
|
167
|
+
const legacyOwnerPath = join(lockPath, 'owner.json');
|
|
167
168
|
const ownerId = randomUUID();
|
|
168
169
|
const now = options.now ?? Date.now;
|
|
170
|
+
async function readOwner() {
|
|
171
|
+
try {
|
|
172
|
+
return JSON.parse(await readFile(lockPath, 'utf8'));
|
|
173
|
+
}
|
|
174
|
+
catch (error) {
|
|
175
|
+
const code = error.code;
|
|
176
|
+
if (code !== 'EISDIR')
|
|
177
|
+
throw error;
|
|
178
|
+
return JSON.parse(await readFile(legacyOwnerPath, 'utf8'));
|
|
179
|
+
}
|
|
180
|
+
}
|
|
169
181
|
async function tryAcquire() {
|
|
170
182
|
try {
|
|
171
|
-
await
|
|
172
|
-
await writeFile(ownerPath, `${JSON.stringify({ ownerId, expiresAt: now() + options.ttlMs })}\n`, { encoding: 'utf8', mode: 0o600 });
|
|
183
|
+
await writeFile(lockPath, `${JSON.stringify({ ownerId, expiresAt: now() + options.ttlMs })}\n`, { encoding: 'utf8', mode: 0o600, flag: 'wx' });
|
|
173
184
|
return true;
|
|
174
185
|
}
|
|
175
186
|
catch (error) {
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
187
|
+
const code = error.code;
|
|
188
|
+
if (code === 'EEXIST' || code === 'EISDIR')
|
|
189
|
+
return false;
|
|
190
|
+
throw error;
|
|
179
191
|
}
|
|
180
192
|
}
|
|
181
193
|
if (!(await tryAcquire())) {
|
|
182
194
|
try {
|
|
183
|
-
const owner =
|
|
195
|
+
const owner = await readOwner();
|
|
184
196
|
if (Number(owner?.expiresAt) > now())
|
|
185
197
|
return null;
|
|
186
198
|
}
|
|
187
199
|
catch {
|
|
188
|
-
|
|
200
|
+
try {
|
|
201
|
+
const current = await stat(lockPath);
|
|
202
|
+
if (current.mtimeMs + options.ttlMs > Date.now())
|
|
203
|
+
return null;
|
|
204
|
+
}
|
|
205
|
+
catch {
|
|
206
|
+
return null;
|
|
207
|
+
}
|
|
189
208
|
}
|
|
190
|
-
await rm(
|
|
209
|
+
await rm(lockPath, { recursive: true, force: true }).catch(() => { });
|
|
191
210
|
if (!(await tryAcquire()))
|
|
192
211
|
return null;
|
|
193
212
|
}
|
|
194
213
|
return {
|
|
195
214
|
release: async () => {
|
|
196
215
|
try {
|
|
197
|
-
const owner =
|
|
216
|
+
const owner = await readOwner();
|
|
198
217
|
if (owner?.ownerId !== ownerId)
|
|
199
218
|
return;
|
|
200
219
|
}
|
|
201
220
|
catch {
|
|
202
221
|
return;
|
|
203
222
|
}
|
|
204
|
-
await rm(
|
|
223
|
+
await rm(lockPath, { recursive: true, force: true }).catch(() => { });
|
|
205
224
|
},
|
|
206
225
|
};
|
|
207
226
|
}
|
|
@@ -327,6 +346,9 @@ function quotaEnabled(storage) {
|
|
|
327
346
|
function refreshEnabled(storage) {
|
|
328
347
|
return storage?.refresh?.enabled !== false;
|
|
329
348
|
}
|
|
349
|
+
function jitterMs(maxMs) {
|
|
350
|
+
return Math.floor(Math.random() * Math.max(0, maxMs));
|
|
351
|
+
}
|
|
330
352
|
function refreshBeforeExpiryMs(storage) {
|
|
331
353
|
const minutes = storage?.refresh?.refreshBeforeExpiryMinutes ??
|
|
332
354
|
DEFAULT_REFRESH_BEFORE_EXPIRY_MINUTES;
|
|
@@ -531,7 +553,7 @@ export class FallbackAccountManager {
|
|
|
531
553
|
if (!this.refreshTimer) {
|
|
532
554
|
this.refreshTimer = setInterval(() => {
|
|
533
555
|
void run().catch(() => { });
|
|
534
|
-
}, BACKGROUND_TICK_MS);
|
|
556
|
+
}, BACKGROUND_TICK_MS + jitterMs(BACKGROUND_TICK_JITTER_MS));
|
|
535
557
|
if ('unref' in this.refreshTimer)
|
|
536
558
|
this.refreshTimer.unref();
|
|
537
559
|
}
|
package/dist/constants.d.ts
CHANGED
|
@@ -4,7 +4,7 @@ export declare const AUTHORIZE_URLS: {
|
|
|
4
4
|
readonly max: "https://claude.ai/oauth/authorize";
|
|
5
5
|
};
|
|
6
6
|
export declare const CODE_CALLBACK_URL = "https://platform.claude.com/oauth/code/callback";
|
|
7
|
-
export declare const TOKEN_URL = "https://
|
|
7
|
+
export declare const TOKEN_URL = "https://api.anthropic.com/v1/oauth/token";
|
|
8
8
|
export declare const OAUTH_SCOPES: string[];
|
|
9
9
|
export declare const TOOL_PREFIX = "mcp_";
|
|
10
10
|
export declare const REQUIRED_BETAS: string[];
|
package/dist/constants.js
CHANGED
|
@@ -4,7 +4,7 @@ export const AUTHORIZE_URLS = {
|
|
|
4
4
|
max: 'https://claude.ai/oauth/authorize',
|
|
5
5
|
};
|
|
6
6
|
export const CODE_CALLBACK_URL = 'https://platform.claude.com/oauth/code/callback';
|
|
7
|
-
export const TOKEN_URL = 'https://
|
|
7
|
+
export const TOKEN_URL = 'https://api.anthropic.com/v1/oauth/token';
|
|
8
8
|
export const OAUTH_SCOPES = [
|
|
9
9
|
'org:create_api_key',
|
|
10
10
|
'user:profile',
|