@omnicross/subscriptions 0.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/LICENSE +21 -0
- package/NOTICE +45 -0
- package/README.md +15 -0
- package/dist/index.cjs +1679 -0
- package/dist/index.d.cts +868 -0
- package/dist/index.d.ts +868 -0
- package/dist/index.js +1639 -0
- package/dist/oauth.cjs +396 -0
- package/dist/oauth.d.cts +131 -0
- package/dist/oauth.d.ts +131 -0
- package/dist/oauth.js +363 -0
- package/package.json +58 -0
package/dist/oauth.cjs
ADDED
|
@@ -0,0 +1,396 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __create = Object.create;
|
|
3
|
+
var __defProp = Object.defineProperty;
|
|
4
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
5
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
6
|
+
var __getProtoOf = Object.getPrototypeOf;
|
|
7
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
8
|
+
var __export = (target, all) => {
|
|
9
|
+
for (var name in all)
|
|
10
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
11
|
+
};
|
|
12
|
+
var __copyProps = (to, from, except, desc) => {
|
|
13
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
14
|
+
for (let key of __getOwnPropNames(from))
|
|
15
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
16
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
17
|
+
}
|
|
18
|
+
return to;
|
|
19
|
+
};
|
|
20
|
+
var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
|
|
21
|
+
// If the importer is in node compatibility mode or this is not an ESM
|
|
22
|
+
// file that has been converted to a CommonJS file using a Babel-
|
|
23
|
+
// compatible transform (i.e. "__esModule" has not been set), then set
|
|
24
|
+
// "default" to the CommonJS "module.exports" for node compatibility.
|
|
25
|
+
isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
|
|
26
|
+
mod
|
|
27
|
+
));
|
|
28
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
29
|
+
|
|
30
|
+
// src/oauth/index.ts
|
|
31
|
+
var oauth_exports = {};
|
|
32
|
+
__export(oauth_exports, {
|
|
33
|
+
claudeOAuth: () => claude_exports,
|
|
34
|
+
codexOAuth: () => codex_exports,
|
|
35
|
+
geminiOAuth: () => gemini_exports
|
|
36
|
+
});
|
|
37
|
+
module.exports = __toCommonJS(oauth_exports);
|
|
38
|
+
|
|
39
|
+
// src/oauth/flows/claude.ts
|
|
40
|
+
var claude_exports = {};
|
|
41
|
+
__export(claude_exports, {
|
|
42
|
+
exchangeCodeForTokens: () => exchangeCodeForTokens,
|
|
43
|
+
exchangeSetupTokenCode: () => exchangeSetupTokenCode,
|
|
44
|
+
generateAuthParams: () => generateAuthParams,
|
|
45
|
+
generateSetupTokenParams: () => generateSetupTokenParams,
|
|
46
|
+
refreshAccessToken: () => refreshAccessToken
|
|
47
|
+
});
|
|
48
|
+
var import_node_crypto = __toESM(require("crypto"), 1);
|
|
49
|
+
|
|
50
|
+
// src/oauth/fetchPort.ts
|
|
51
|
+
function errorMessage(error, errorDescription) {
|
|
52
|
+
if (errorDescription) return errorDescription;
|
|
53
|
+
if (typeof error === "string") return error;
|
|
54
|
+
if (error && typeof error === "object") {
|
|
55
|
+
const e = error;
|
|
56
|
+
if (typeof e.message === "string" && e.message) return e.message;
|
|
57
|
+
if (typeof e.error_description === "string" && e.error_description) {
|
|
58
|
+
return e.error_description;
|
|
59
|
+
}
|
|
60
|
+
return JSON.stringify(error);
|
|
61
|
+
}
|
|
62
|
+
return String(error);
|
|
63
|
+
}
|
|
64
|
+
async function postForm(fetchImpl, url, params, parseErrorMessage) {
|
|
65
|
+
const response = await fetchImpl(url, {
|
|
66
|
+
method: "POST",
|
|
67
|
+
headers: { "Content-Type": "application/x-www-form-urlencoded" },
|
|
68
|
+
body: params.toString()
|
|
69
|
+
});
|
|
70
|
+
const responseData = await response.text();
|
|
71
|
+
let data;
|
|
72
|
+
try {
|
|
73
|
+
data = JSON.parse(responseData);
|
|
74
|
+
} catch {
|
|
75
|
+
throw new Error(parseErrorMessage);
|
|
76
|
+
}
|
|
77
|
+
if (data.error) {
|
|
78
|
+
throw new Error(errorMessage(data.error, data.error_description));
|
|
79
|
+
}
|
|
80
|
+
return data;
|
|
81
|
+
}
|
|
82
|
+
async function postJson(fetchImpl, url, body, parseErrorMessage, extraHeaders = {}) {
|
|
83
|
+
const response = await fetchImpl(url, {
|
|
84
|
+
method: "POST",
|
|
85
|
+
headers: { "Content-Type": "application/json", ...extraHeaders },
|
|
86
|
+
body: JSON.stringify(body)
|
|
87
|
+
});
|
|
88
|
+
const responseData = await response.text();
|
|
89
|
+
let data;
|
|
90
|
+
try {
|
|
91
|
+
data = JSON.parse(responseData);
|
|
92
|
+
} catch {
|
|
93
|
+
throw new Error(parseErrorMessage);
|
|
94
|
+
}
|
|
95
|
+
if (data.error) {
|
|
96
|
+
throw new Error(errorMessage(data.error, data.error_description));
|
|
97
|
+
}
|
|
98
|
+
return data;
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
// src/oauth/flows/claude.ts
|
|
102
|
+
var CLAUDE_TOKEN_HEADERS = {
|
|
103
|
+
"User-Agent": "claude-cli/1.0.56 (external, cli)",
|
|
104
|
+
Accept: "application/json, text/plain, */*",
|
|
105
|
+
"Accept-Language": "en-US,en;q=0.9",
|
|
106
|
+
Referer: "https://claude.ai/",
|
|
107
|
+
Origin: "https://claude.ai"
|
|
108
|
+
};
|
|
109
|
+
var CLAUDE_OAUTH_CONFIG = {
|
|
110
|
+
clientId: "9d1c250a-e61b-44d9-88ed-5944d1962f5e",
|
|
111
|
+
authorizationEndpoint: "https://claude.ai/oauth/authorize",
|
|
112
|
+
// The token endpoint stays on console.anthropic.com (still the live value —
|
|
113
|
+
// matches the official Claude Code CLI / claude-relay-service reference); only
|
|
114
|
+
// the OAuth callback moved to platform.claude.com (2026). The redirect_uri MUST
|
|
115
|
+
// match what the client is registered for AND match between authorize + token
|
|
116
|
+
// exchange. Scopes mirror the live Claude Code authorize URL.
|
|
117
|
+
tokenEndpoint: "https://console.anthropic.com/v1/oauth/token",
|
|
118
|
+
redirectUri: "https://platform.claude.com/oauth/code/callback",
|
|
119
|
+
scopes: [
|
|
120
|
+
"org:create_api_key",
|
|
121
|
+
"user:profile",
|
|
122
|
+
"user:inference",
|
|
123
|
+
"user:sessions:claude_code",
|
|
124
|
+
"user:mcp_servers",
|
|
125
|
+
"user:file_upload"
|
|
126
|
+
]
|
|
127
|
+
};
|
|
128
|
+
var SETUP_TOKEN_CONFIG = {
|
|
129
|
+
scopes: ["user:inference"]
|
|
130
|
+
// Only inference permission, no API key creation
|
|
131
|
+
};
|
|
132
|
+
function generatePkce() {
|
|
133
|
+
const codeVerifier = import_node_crypto.default.randomBytes(32).toString("base64url");
|
|
134
|
+
const codeChallenge = import_node_crypto.default.createHash("sha256").update(codeVerifier).digest("base64url");
|
|
135
|
+
const state = import_node_crypto.default.randomBytes(16).toString("hex");
|
|
136
|
+
return { codeVerifier, codeChallenge, state };
|
|
137
|
+
}
|
|
138
|
+
function generateAuthParams() {
|
|
139
|
+
const { codeVerifier, codeChallenge, state } = generatePkce();
|
|
140
|
+
const params = new URLSearchParams({
|
|
141
|
+
code: "true",
|
|
142
|
+
client_id: CLAUDE_OAUTH_CONFIG.clientId,
|
|
143
|
+
response_type: "code",
|
|
144
|
+
redirect_uri: CLAUDE_OAUTH_CONFIG.redirectUri,
|
|
145
|
+
scope: CLAUDE_OAUTH_CONFIG.scopes.join(" "),
|
|
146
|
+
code_challenge: codeChallenge,
|
|
147
|
+
code_challenge_method: "S256",
|
|
148
|
+
state
|
|
149
|
+
});
|
|
150
|
+
const authUrl = `${CLAUDE_OAUTH_CONFIG.authorizationEndpoint}?${params.toString()}`;
|
|
151
|
+
return { authUrl, codeVerifier, state };
|
|
152
|
+
}
|
|
153
|
+
function generateSetupTokenParams() {
|
|
154
|
+
const { codeVerifier, codeChallenge, state } = generatePkce();
|
|
155
|
+
const params = new URLSearchParams({
|
|
156
|
+
code: "true",
|
|
157
|
+
client_id: CLAUDE_OAUTH_CONFIG.clientId,
|
|
158
|
+
response_type: "code",
|
|
159
|
+
redirect_uri: CLAUDE_OAUTH_CONFIG.redirectUri,
|
|
160
|
+
scope: SETUP_TOKEN_CONFIG.scopes.join(" "),
|
|
161
|
+
code_challenge: codeChallenge,
|
|
162
|
+
code_challenge_method: "S256",
|
|
163
|
+
state
|
|
164
|
+
});
|
|
165
|
+
const authUrl = `${CLAUDE_OAUTH_CONFIG.authorizationEndpoint}?${params.toString()}`;
|
|
166
|
+
return { authUrl, codeVerifier, state };
|
|
167
|
+
}
|
|
168
|
+
async function exchangeCodeForTokens(request, fetchImpl) {
|
|
169
|
+
const { authorizationCode, codeVerifier, state } = request;
|
|
170
|
+
const code = authorizationCode.split("#")[0]?.split("&")[0] ?? authorizationCode;
|
|
171
|
+
const data = await postJson(
|
|
172
|
+
fetchImpl,
|
|
173
|
+
CLAUDE_OAUTH_CONFIG.tokenEndpoint,
|
|
174
|
+
{
|
|
175
|
+
grant_type: "authorization_code",
|
|
176
|
+
client_id: CLAUDE_OAUTH_CONFIG.clientId,
|
|
177
|
+
code,
|
|
178
|
+
code_verifier: codeVerifier,
|
|
179
|
+
redirect_uri: CLAUDE_OAUTH_CONFIG.redirectUri,
|
|
180
|
+
state
|
|
181
|
+
},
|
|
182
|
+
"Failed to parse token response",
|
|
183
|
+
CLAUDE_TOKEN_HEADERS
|
|
184
|
+
);
|
|
185
|
+
return {
|
|
186
|
+
accessToken: data.access_token,
|
|
187
|
+
// The authorization_code grant always returns a refresh_token; the original
|
|
188
|
+
// helper read it from an untyped `data` and declared the field `string`.
|
|
189
|
+
refreshToken: data.refresh_token,
|
|
190
|
+
expiresIn: data.expires_in,
|
|
191
|
+
scopes: data.scope?.split(" ") || CLAUDE_OAUTH_CONFIG.scopes
|
|
192
|
+
};
|
|
193
|
+
}
|
|
194
|
+
async function exchangeSetupTokenCode(request, fetchImpl) {
|
|
195
|
+
const { authorizationCode, codeVerifier, state } = request;
|
|
196
|
+
const code = authorizationCode.split("#")[0]?.split("&")[0] ?? authorizationCode;
|
|
197
|
+
const data = await postJson(
|
|
198
|
+
fetchImpl,
|
|
199
|
+
CLAUDE_OAUTH_CONFIG.tokenEndpoint,
|
|
200
|
+
{
|
|
201
|
+
grant_type: "authorization_code",
|
|
202
|
+
client_id: CLAUDE_OAUTH_CONFIG.clientId,
|
|
203
|
+
code,
|
|
204
|
+
code_verifier: codeVerifier,
|
|
205
|
+
redirect_uri: CLAUDE_OAUTH_CONFIG.redirectUri,
|
|
206
|
+
state
|
|
207
|
+
},
|
|
208
|
+
"Failed to parse setup token response",
|
|
209
|
+
CLAUDE_TOKEN_HEADERS
|
|
210
|
+
);
|
|
211
|
+
return {
|
|
212
|
+
accessToken: data.access_token,
|
|
213
|
+
expiresIn: data.expires_in,
|
|
214
|
+
scopes: data.scope?.split(" ") || SETUP_TOKEN_CONFIG.scopes
|
|
215
|
+
};
|
|
216
|
+
}
|
|
217
|
+
async function refreshAccessToken(refreshToken, fetchImpl) {
|
|
218
|
+
const data = await postJson(
|
|
219
|
+
fetchImpl,
|
|
220
|
+
CLAUDE_OAUTH_CONFIG.tokenEndpoint,
|
|
221
|
+
{
|
|
222
|
+
grant_type: "refresh_token",
|
|
223
|
+
client_id: CLAUDE_OAUTH_CONFIG.clientId,
|
|
224
|
+
refresh_token: refreshToken
|
|
225
|
+
},
|
|
226
|
+
"Failed to parse refresh response",
|
|
227
|
+
CLAUDE_TOKEN_HEADERS
|
|
228
|
+
);
|
|
229
|
+
return {
|
|
230
|
+
accessToken: data.access_token,
|
|
231
|
+
refreshToken: data.refresh_token || refreshToken,
|
|
232
|
+
expiresIn: data.expires_in
|
|
233
|
+
};
|
|
234
|
+
}
|
|
235
|
+
|
|
236
|
+
// src/oauth/flows/codex.ts
|
|
237
|
+
var codex_exports = {};
|
|
238
|
+
__export(codex_exports, {
|
|
239
|
+
exchangeCodeForTokens: () => exchangeCodeForTokens2,
|
|
240
|
+
generateAuthParams: () => generateAuthParams2,
|
|
241
|
+
refreshAccessToken: () => refreshAccessToken2
|
|
242
|
+
});
|
|
243
|
+
var import_node_crypto2 = __toESM(require("crypto"), 1);
|
|
244
|
+
var CODEX_OAUTH_CONFIG = {
|
|
245
|
+
clientId: "app_EMoamEEZ73f0CkXaXp7hrann",
|
|
246
|
+
authorizationEndpoint: "https://auth.openai.com/oauth/authorize",
|
|
247
|
+
tokenEndpoint: "https://auth.openai.com/oauth/token",
|
|
248
|
+
redirectUri: "http://localhost:1455/auth/callback",
|
|
249
|
+
scopes: ["openid", "profile", "email", "offline_access"]
|
|
250
|
+
};
|
|
251
|
+
function generateAuthParams2() {
|
|
252
|
+
const codeVerifier = import_node_crypto2.default.randomBytes(64).toString("hex");
|
|
253
|
+
const codeChallenge = import_node_crypto2.default.createHash("sha256").update(codeVerifier).digest("base64url");
|
|
254
|
+
const state = import_node_crypto2.default.randomBytes(16).toString("hex");
|
|
255
|
+
const params = new URLSearchParams({
|
|
256
|
+
response_type: "code",
|
|
257
|
+
client_id: CODEX_OAUTH_CONFIG.clientId,
|
|
258
|
+
redirect_uri: CODEX_OAUTH_CONFIG.redirectUri,
|
|
259
|
+
scope: CODEX_OAUTH_CONFIG.scopes.join(" "),
|
|
260
|
+
code_challenge: codeChallenge,
|
|
261
|
+
code_challenge_method: "S256",
|
|
262
|
+
state
|
|
263
|
+
});
|
|
264
|
+
const authUrl = `${CODEX_OAUTH_CONFIG.authorizationEndpoint}?${params.toString()}`;
|
|
265
|
+
return { authUrl, codeVerifier, state };
|
|
266
|
+
}
|
|
267
|
+
async function exchangeCodeForTokens2(request, fetchImpl) {
|
|
268
|
+
const { authorizationCode, codeVerifier } = request;
|
|
269
|
+
const params = new URLSearchParams({
|
|
270
|
+
grant_type: "authorization_code",
|
|
271
|
+
client_id: CODEX_OAUTH_CONFIG.clientId,
|
|
272
|
+
code: authorizationCode,
|
|
273
|
+
code_verifier: codeVerifier,
|
|
274
|
+
redirect_uri: CODEX_OAUTH_CONFIG.redirectUri
|
|
275
|
+
});
|
|
276
|
+
const data = await postForm(
|
|
277
|
+
fetchImpl,
|
|
278
|
+
CODEX_OAUTH_CONFIG.tokenEndpoint,
|
|
279
|
+
params,
|
|
280
|
+
"Failed to parse token response"
|
|
281
|
+
);
|
|
282
|
+
return {
|
|
283
|
+
accessToken: data.access_token,
|
|
284
|
+
// authorization_code grant returns both; the original helper read them from
|
|
285
|
+
// an untyped `data` and declared the fields `string`.
|
|
286
|
+
refreshToken: data.refresh_token,
|
|
287
|
+
idToken: data.id_token,
|
|
288
|
+
expiresIn: data.expires_in
|
|
289
|
+
};
|
|
290
|
+
}
|
|
291
|
+
async function refreshAccessToken2(refreshToken, fetchImpl) {
|
|
292
|
+
const params = new URLSearchParams({
|
|
293
|
+
grant_type: "refresh_token",
|
|
294
|
+
client_id: CODEX_OAUTH_CONFIG.clientId,
|
|
295
|
+
refresh_token: refreshToken,
|
|
296
|
+
scope: "openid profile email"
|
|
297
|
+
});
|
|
298
|
+
const data = await postForm(
|
|
299
|
+
fetchImpl,
|
|
300
|
+
CODEX_OAUTH_CONFIG.tokenEndpoint,
|
|
301
|
+
params,
|
|
302
|
+
"Failed to parse refresh response"
|
|
303
|
+
);
|
|
304
|
+
return {
|
|
305
|
+
accessToken: data.access_token,
|
|
306
|
+
idToken: data.id_token,
|
|
307
|
+
refreshToken: data.refresh_token || refreshToken,
|
|
308
|
+
expiresIn: data.expires_in || 3600
|
|
309
|
+
};
|
|
310
|
+
}
|
|
311
|
+
|
|
312
|
+
// src/oauth/flows/gemini.ts
|
|
313
|
+
var gemini_exports = {};
|
|
314
|
+
__export(gemini_exports, {
|
|
315
|
+
exchangeCodeForTokens: () => exchangeCodeForTokens3,
|
|
316
|
+
generateAuthParams: () => generateAuthParams3,
|
|
317
|
+
refreshAccessToken: () => refreshAccessToken3
|
|
318
|
+
});
|
|
319
|
+
var import_node_crypto3 = __toESM(require("crypto"), 1);
|
|
320
|
+
var GEMINI_OAUTH_CONFIG = {
|
|
321
|
+
clientId: "681255809395-oo8ft2oprdrnp9e3aqf6av3hmdib135j.apps.googleusercontent.com",
|
|
322
|
+
// The Gemini CLI's *public* installed-app OAuth client secret (mirrors the
|
|
323
|
+
// upstream CLI). Per Google's OAuth docs, native-app client secrets are not
|
|
324
|
+
// treated as confidential — not a leaked key.
|
|
325
|
+
clientSecret: "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",
|
|
326
|
+
// allowlist-secret
|
|
327
|
+
authorizationEndpoint: "https://accounts.google.com/o/oauth2/v2/auth",
|
|
328
|
+
tokenEndpoint: "https://oauth2.googleapis.com/token",
|
|
329
|
+
redirectUri: "urn:ietf:wg:oauth:2.0:oob",
|
|
330
|
+
scopes: ["https://www.googleapis.com/auth/cloud-platform"]
|
|
331
|
+
};
|
|
332
|
+
function generateAuthParams3() {
|
|
333
|
+
const codeVerifier = import_node_crypto3.default.randomBytes(32).toString("base64url");
|
|
334
|
+
const codeChallenge = import_node_crypto3.default.createHash("sha256").update(codeVerifier).digest("base64url");
|
|
335
|
+
const state = import_node_crypto3.default.randomBytes(16).toString("hex");
|
|
336
|
+
const params = new URLSearchParams({
|
|
337
|
+
client_id: GEMINI_OAUTH_CONFIG.clientId,
|
|
338
|
+
redirect_uri: GEMINI_OAUTH_CONFIG.redirectUri,
|
|
339
|
+
scope: GEMINI_OAUTH_CONFIG.scopes.join(" "),
|
|
340
|
+
response_type: "code",
|
|
341
|
+
code_challenge: codeChallenge,
|
|
342
|
+
code_challenge_method: "S256",
|
|
343
|
+
state,
|
|
344
|
+
access_type: "offline",
|
|
345
|
+
prompt: "consent"
|
|
346
|
+
});
|
|
347
|
+
const authUrl = `${GEMINI_OAUTH_CONFIG.authorizationEndpoint}?${params.toString()}`;
|
|
348
|
+
return { authUrl, codeVerifier, state };
|
|
349
|
+
}
|
|
350
|
+
async function exchangeCodeForTokens3(authorizationCode, codeVerifier, fetchImpl) {
|
|
351
|
+
const params = new URLSearchParams({
|
|
352
|
+
grant_type: "authorization_code",
|
|
353
|
+
client_id: GEMINI_OAUTH_CONFIG.clientId,
|
|
354
|
+
client_secret: GEMINI_OAUTH_CONFIG.clientSecret,
|
|
355
|
+
code: authorizationCode,
|
|
356
|
+
code_verifier: codeVerifier,
|
|
357
|
+
redirect_uri: GEMINI_OAUTH_CONFIG.redirectUri
|
|
358
|
+
});
|
|
359
|
+
const data = await postForm(
|
|
360
|
+
fetchImpl,
|
|
361
|
+
GEMINI_OAUTH_CONFIG.tokenEndpoint,
|
|
362
|
+
params,
|
|
363
|
+
"Failed to parse token response"
|
|
364
|
+
);
|
|
365
|
+
return {
|
|
366
|
+
accessToken: data.access_token,
|
|
367
|
+
// authorization_code grant returns a refresh_token; the original helper read
|
|
368
|
+
// it from an untyped `data` and declared the field `string`.
|
|
369
|
+
refreshToken: data.refresh_token,
|
|
370
|
+
expiresIn: data.expires_in
|
|
371
|
+
};
|
|
372
|
+
}
|
|
373
|
+
async function refreshAccessToken3(refreshToken, fetchImpl) {
|
|
374
|
+
const params = new URLSearchParams({
|
|
375
|
+
grant_type: "refresh_token",
|
|
376
|
+
client_id: GEMINI_OAUTH_CONFIG.clientId,
|
|
377
|
+
client_secret: GEMINI_OAUTH_CONFIG.clientSecret,
|
|
378
|
+
refresh_token: refreshToken
|
|
379
|
+
});
|
|
380
|
+
const data = await postForm(
|
|
381
|
+
fetchImpl,
|
|
382
|
+
GEMINI_OAUTH_CONFIG.tokenEndpoint,
|
|
383
|
+
params,
|
|
384
|
+
"Failed to parse refresh response"
|
|
385
|
+
);
|
|
386
|
+
return {
|
|
387
|
+
accessToken: data.access_token,
|
|
388
|
+
expiresIn: data.expires_in
|
|
389
|
+
};
|
|
390
|
+
}
|
|
391
|
+
// Annotate the CommonJS export names for ESM import in node:
|
|
392
|
+
0 && (module.exports = {
|
|
393
|
+
claudeOAuth,
|
|
394
|
+
codexOAuth,
|
|
395
|
+
geminiOAuth
|
|
396
|
+
});
|
package/dist/oauth.d.cts
ADDED
|
@@ -0,0 +1,131 @@
|
|
|
1
|
+
import { TokenExchangeRequest, OAuthParams } from '@omnicross/contracts/account-tokens-types';
|
|
2
|
+
|
|
3
|
+
/** Injectable fetch so tests can mock the network without a live endpoint. */
|
|
4
|
+
type FetchLike = (url: string, init: RequestInit) => Promise<Response>;
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* Claude OAuth flow — host-clean PKCE logic.
|
|
8
|
+
*
|
|
9
|
+
* Pure logic only: authorize-URL construction, PKCE generation, authorization-
|
|
10
|
+
* code exchange, setup-token exchange, and refresh. Every network request goes
|
|
11
|
+
* through an INJECTED `FetchLike` port — NO `electron`, NO `net`, NO host path
|
|
12
|
+
* (a desktop host can inject an electron-net adapter; the daemon injects global
|
|
13
|
+
* `fetch`). Claude `code=true`, `state` carried in exchange, setup-token has no
|
|
14
|
+
* refresh_token. Reference: claude-relay-service `src/utils/oauthHelper.js`.
|
|
15
|
+
*
|
|
16
|
+
* @module @omnicross/subscriptions/oauth/flows/claude
|
|
17
|
+
*/
|
|
18
|
+
|
|
19
|
+
/** Generate OAuth authorization parameters (PKCE). */
|
|
20
|
+
declare function generateAuthParams$2(): OAuthParams;
|
|
21
|
+
/**
|
|
22
|
+
* Generate Setup Token authorization parameters (PKCE). Setup Token has minimal
|
|
23
|
+
* permissions (user:inference only) but longer expiry; no refresh token is
|
|
24
|
+
* returned — the user re-authorizes when it expires.
|
|
25
|
+
*/
|
|
26
|
+
declare function generateSetupTokenParams(): OAuthParams;
|
|
27
|
+
/** Exchange authorization code for tokens. */
|
|
28
|
+
declare function exchangeCodeForTokens$2(request: TokenExchangeRequest, fetchImpl: FetchLike): Promise<{
|
|
29
|
+
accessToken: string;
|
|
30
|
+
refreshToken: string;
|
|
31
|
+
expiresIn: number;
|
|
32
|
+
scopes: string[];
|
|
33
|
+
}>;
|
|
34
|
+
/**
|
|
35
|
+
* Exchange Setup Token authorization code for access token.
|
|
36
|
+
* Note: Setup Token does NOT return refresh_token.
|
|
37
|
+
*/
|
|
38
|
+
declare function exchangeSetupTokenCode(request: TokenExchangeRequest, fetchImpl: FetchLike): Promise<{
|
|
39
|
+
accessToken: string;
|
|
40
|
+
expiresIn: number;
|
|
41
|
+
scopes: string[];
|
|
42
|
+
}>;
|
|
43
|
+
/** Refresh access token using refresh_token. */
|
|
44
|
+
declare function refreshAccessToken$2(refreshToken: string, fetchImpl: FetchLike): Promise<{
|
|
45
|
+
accessToken: string;
|
|
46
|
+
refreshToken: string;
|
|
47
|
+
expiresIn: number;
|
|
48
|
+
}>;
|
|
49
|
+
|
|
50
|
+
declare const claude_exchangeSetupTokenCode: typeof exchangeSetupTokenCode;
|
|
51
|
+
declare const claude_generateSetupTokenParams: typeof generateSetupTokenParams;
|
|
52
|
+
declare namespace claude {
|
|
53
|
+
export { exchangeCodeForTokens$2 as exchangeCodeForTokens, claude_exchangeSetupTokenCode as exchangeSetupTokenCode, generateAuthParams$2 as generateAuthParams, claude_generateSetupTokenParams as generateSetupTokenParams, refreshAccessToken$2 as refreshAccessToken };
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
/**
|
|
57
|
+
* Codex (ChatGPT) OAuth flow — host-clean PKCE logic.
|
|
58
|
+
*
|
|
59
|
+
* PKCE verifier = `randomBytes(64).hex` (NOT base64url like claude/gemini),
|
|
60
|
+
* loopback redirect_uri, scope `openid profile email offline_access`, NO state in
|
|
61
|
+
* the exchange body, refresh carries `scope=openid profile email`, and the refresh
|
|
62
|
+
* defaults `expiresIn` to 3600 + returns an `idToken`. Network goes through the
|
|
63
|
+
* injected `FetchLike`.
|
|
64
|
+
* Reference: claude-relay-service `src/services/openaiAccountService.js`.
|
|
65
|
+
*
|
|
66
|
+
* @module @omnicross/subscriptions/oauth/flows/codex
|
|
67
|
+
*/
|
|
68
|
+
|
|
69
|
+
/** Generate OAuth authorization parameters (PKCE). */
|
|
70
|
+
declare function generateAuthParams$1(): OAuthParams;
|
|
71
|
+
/** Exchange authorization code for tokens (codex carries NO state in the body). */
|
|
72
|
+
declare function exchangeCodeForTokens$1(request: TokenExchangeRequest, fetchImpl: FetchLike): Promise<{
|
|
73
|
+
accessToken: string;
|
|
74
|
+
refreshToken: string;
|
|
75
|
+
idToken: string;
|
|
76
|
+
expiresIn: number;
|
|
77
|
+
}>;
|
|
78
|
+
/** Refresh access token using refresh_token. */
|
|
79
|
+
declare function refreshAccessToken$1(refreshToken: string, fetchImpl: FetchLike): Promise<{
|
|
80
|
+
accessToken: string;
|
|
81
|
+
idToken: string;
|
|
82
|
+
refreshToken: string;
|
|
83
|
+
expiresIn: number;
|
|
84
|
+
}>;
|
|
85
|
+
|
|
86
|
+
declare namespace codex {
|
|
87
|
+
export { exchangeCodeForTokens$1 as exchangeCodeForTokens, generateAuthParams$1 as generateAuthParams, refreshAccessToken$1 as refreshAccessToken };
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
/**
|
|
91
|
+
* Gemini (Google) OAuth flow — host-clean logic.
|
|
92
|
+
*
|
|
93
|
+
* PKCE verifier = `randomBytes(32).base64url`, oob redirect_uri
|
|
94
|
+
* (`urn:ietf:wg:oauth:2.0:oob`), authorize carries `access_type=offline` +
|
|
95
|
+
* `prompt=consent`, the exchange + refresh bodies carry the public installed-app
|
|
96
|
+
* `client_secret`, and the refresh response is NOT expected to return a new
|
|
97
|
+
* refresh_token (the caller reuses the old one — see the store's
|
|
98
|
+
* `refreshGeminiToken`). Network goes through the injected `FetchLike`.
|
|
99
|
+
* NOTE: `exchangeCodeForTokens` keeps a POSITIONAL signature
|
|
100
|
+
* `(authorizationCode, codeVerifier)`.
|
|
101
|
+
* Reference: claude-relay-service `src/services/geminiAccountService.js`.
|
|
102
|
+
*
|
|
103
|
+
* @module @omnicross/subscriptions/oauth/flows/gemini
|
|
104
|
+
*/
|
|
105
|
+
|
|
106
|
+
/** Generate OAuth authorization parameters. */
|
|
107
|
+
declare function generateAuthParams(): OAuthParams;
|
|
108
|
+
/** Exchange authorization code for tokens (positional args, mirrors the helper). */
|
|
109
|
+
declare function exchangeCodeForTokens(authorizationCode: string, codeVerifier: string, fetchImpl: FetchLike): Promise<{
|
|
110
|
+
accessToken: string;
|
|
111
|
+
refreshToken: string;
|
|
112
|
+
expiresIn: number;
|
|
113
|
+
}>;
|
|
114
|
+
/**
|
|
115
|
+
* Refresh access token using refresh_token. The Google token endpoint does NOT
|
|
116
|
+
* return a refresh_token on refresh — the result intentionally omits it (the
|
|
117
|
+
* store reuses the old value).
|
|
118
|
+
*/
|
|
119
|
+
declare function refreshAccessToken(refreshToken: string, fetchImpl: FetchLike): Promise<{
|
|
120
|
+
accessToken: string;
|
|
121
|
+
expiresIn: number;
|
|
122
|
+
}>;
|
|
123
|
+
|
|
124
|
+
declare const gemini_exchangeCodeForTokens: typeof exchangeCodeForTokens;
|
|
125
|
+
declare const gemini_generateAuthParams: typeof generateAuthParams;
|
|
126
|
+
declare const gemini_refreshAccessToken: typeof refreshAccessToken;
|
|
127
|
+
declare namespace gemini {
|
|
128
|
+
export { gemini_exchangeCodeForTokens as exchangeCodeForTokens, gemini_generateAuthParams as generateAuthParams, gemini_refreshAccessToken as refreshAccessToken };
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
export { type FetchLike, claude as claudeOAuth, codex as codexOAuth, gemini as geminiOAuth };
|
package/dist/oauth.d.ts
ADDED
|
@@ -0,0 +1,131 @@
|
|
|
1
|
+
import { TokenExchangeRequest, OAuthParams } from '@omnicross/contracts/account-tokens-types';
|
|
2
|
+
|
|
3
|
+
/** Injectable fetch so tests can mock the network without a live endpoint. */
|
|
4
|
+
type FetchLike = (url: string, init: RequestInit) => Promise<Response>;
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* Claude OAuth flow — host-clean PKCE logic.
|
|
8
|
+
*
|
|
9
|
+
* Pure logic only: authorize-URL construction, PKCE generation, authorization-
|
|
10
|
+
* code exchange, setup-token exchange, and refresh. Every network request goes
|
|
11
|
+
* through an INJECTED `FetchLike` port — NO `electron`, NO `net`, NO host path
|
|
12
|
+
* (a desktop host can inject an electron-net adapter; the daemon injects global
|
|
13
|
+
* `fetch`). Claude `code=true`, `state` carried in exchange, setup-token has no
|
|
14
|
+
* refresh_token. Reference: claude-relay-service `src/utils/oauthHelper.js`.
|
|
15
|
+
*
|
|
16
|
+
* @module @omnicross/subscriptions/oauth/flows/claude
|
|
17
|
+
*/
|
|
18
|
+
|
|
19
|
+
/** Generate OAuth authorization parameters (PKCE). */
|
|
20
|
+
declare function generateAuthParams$2(): OAuthParams;
|
|
21
|
+
/**
|
|
22
|
+
* Generate Setup Token authorization parameters (PKCE). Setup Token has minimal
|
|
23
|
+
* permissions (user:inference only) but longer expiry; no refresh token is
|
|
24
|
+
* returned — the user re-authorizes when it expires.
|
|
25
|
+
*/
|
|
26
|
+
declare function generateSetupTokenParams(): OAuthParams;
|
|
27
|
+
/** Exchange authorization code for tokens. */
|
|
28
|
+
declare function exchangeCodeForTokens$2(request: TokenExchangeRequest, fetchImpl: FetchLike): Promise<{
|
|
29
|
+
accessToken: string;
|
|
30
|
+
refreshToken: string;
|
|
31
|
+
expiresIn: number;
|
|
32
|
+
scopes: string[];
|
|
33
|
+
}>;
|
|
34
|
+
/**
|
|
35
|
+
* Exchange Setup Token authorization code for access token.
|
|
36
|
+
* Note: Setup Token does NOT return refresh_token.
|
|
37
|
+
*/
|
|
38
|
+
declare function exchangeSetupTokenCode(request: TokenExchangeRequest, fetchImpl: FetchLike): Promise<{
|
|
39
|
+
accessToken: string;
|
|
40
|
+
expiresIn: number;
|
|
41
|
+
scopes: string[];
|
|
42
|
+
}>;
|
|
43
|
+
/** Refresh access token using refresh_token. */
|
|
44
|
+
declare function refreshAccessToken$2(refreshToken: string, fetchImpl: FetchLike): Promise<{
|
|
45
|
+
accessToken: string;
|
|
46
|
+
refreshToken: string;
|
|
47
|
+
expiresIn: number;
|
|
48
|
+
}>;
|
|
49
|
+
|
|
50
|
+
declare const claude_exchangeSetupTokenCode: typeof exchangeSetupTokenCode;
|
|
51
|
+
declare const claude_generateSetupTokenParams: typeof generateSetupTokenParams;
|
|
52
|
+
declare namespace claude {
|
|
53
|
+
export { exchangeCodeForTokens$2 as exchangeCodeForTokens, claude_exchangeSetupTokenCode as exchangeSetupTokenCode, generateAuthParams$2 as generateAuthParams, claude_generateSetupTokenParams as generateSetupTokenParams, refreshAccessToken$2 as refreshAccessToken };
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
/**
|
|
57
|
+
* Codex (ChatGPT) OAuth flow — host-clean PKCE logic.
|
|
58
|
+
*
|
|
59
|
+
* PKCE verifier = `randomBytes(64).hex` (NOT base64url like claude/gemini),
|
|
60
|
+
* loopback redirect_uri, scope `openid profile email offline_access`, NO state in
|
|
61
|
+
* the exchange body, refresh carries `scope=openid profile email`, and the refresh
|
|
62
|
+
* defaults `expiresIn` to 3600 + returns an `idToken`. Network goes through the
|
|
63
|
+
* injected `FetchLike`.
|
|
64
|
+
* Reference: claude-relay-service `src/services/openaiAccountService.js`.
|
|
65
|
+
*
|
|
66
|
+
* @module @omnicross/subscriptions/oauth/flows/codex
|
|
67
|
+
*/
|
|
68
|
+
|
|
69
|
+
/** Generate OAuth authorization parameters (PKCE). */
|
|
70
|
+
declare function generateAuthParams$1(): OAuthParams;
|
|
71
|
+
/** Exchange authorization code for tokens (codex carries NO state in the body). */
|
|
72
|
+
declare function exchangeCodeForTokens$1(request: TokenExchangeRequest, fetchImpl: FetchLike): Promise<{
|
|
73
|
+
accessToken: string;
|
|
74
|
+
refreshToken: string;
|
|
75
|
+
idToken: string;
|
|
76
|
+
expiresIn: number;
|
|
77
|
+
}>;
|
|
78
|
+
/** Refresh access token using refresh_token. */
|
|
79
|
+
declare function refreshAccessToken$1(refreshToken: string, fetchImpl: FetchLike): Promise<{
|
|
80
|
+
accessToken: string;
|
|
81
|
+
idToken: string;
|
|
82
|
+
refreshToken: string;
|
|
83
|
+
expiresIn: number;
|
|
84
|
+
}>;
|
|
85
|
+
|
|
86
|
+
declare namespace codex {
|
|
87
|
+
export { exchangeCodeForTokens$1 as exchangeCodeForTokens, generateAuthParams$1 as generateAuthParams, refreshAccessToken$1 as refreshAccessToken };
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
/**
|
|
91
|
+
* Gemini (Google) OAuth flow — host-clean logic.
|
|
92
|
+
*
|
|
93
|
+
* PKCE verifier = `randomBytes(32).base64url`, oob redirect_uri
|
|
94
|
+
* (`urn:ietf:wg:oauth:2.0:oob`), authorize carries `access_type=offline` +
|
|
95
|
+
* `prompt=consent`, the exchange + refresh bodies carry the public installed-app
|
|
96
|
+
* `client_secret`, and the refresh response is NOT expected to return a new
|
|
97
|
+
* refresh_token (the caller reuses the old one — see the store's
|
|
98
|
+
* `refreshGeminiToken`). Network goes through the injected `FetchLike`.
|
|
99
|
+
* NOTE: `exchangeCodeForTokens` keeps a POSITIONAL signature
|
|
100
|
+
* `(authorizationCode, codeVerifier)`.
|
|
101
|
+
* Reference: claude-relay-service `src/services/geminiAccountService.js`.
|
|
102
|
+
*
|
|
103
|
+
* @module @omnicross/subscriptions/oauth/flows/gemini
|
|
104
|
+
*/
|
|
105
|
+
|
|
106
|
+
/** Generate OAuth authorization parameters. */
|
|
107
|
+
declare function generateAuthParams(): OAuthParams;
|
|
108
|
+
/** Exchange authorization code for tokens (positional args, mirrors the helper). */
|
|
109
|
+
declare function exchangeCodeForTokens(authorizationCode: string, codeVerifier: string, fetchImpl: FetchLike): Promise<{
|
|
110
|
+
accessToken: string;
|
|
111
|
+
refreshToken: string;
|
|
112
|
+
expiresIn: number;
|
|
113
|
+
}>;
|
|
114
|
+
/**
|
|
115
|
+
* Refresh access token using refresh_token. The Google token endpoint does NOT
|
|
116
|
+
* return a refresh_token on refresh — the result intentionally omits it (the
|
|
117
|
+
* store reuses the old value).
|
|
118
|
+
*/
|
|
119
|
+
declare function refreshAccessToken(refreshToken: string, fetchImpl: FetchLike): Promise<{
|
|
120
|
+
accessToken: string;
|
|
121
|
+
expiresIn: number;
|
|
122
|
+
}>;
|
|
123
|
+
|
|
124
|
+
declare const gemini_exchangeCodeForTokens: typeof exchangeCodeForTokens;
|
|
125
|
+
declare const gemini_generateAuthParams: typeof generateAuthParams;
|
|
126
|
+
declare const gemini_refreshAccessToken: typeof refreshAccessToken;
|
|
127
|
+
declare namespace gemini {
|
|
128
|
+
export { gemini_exchangeCodeForTokens as exchangeCodeForTokens, gemini_generateAuthParams as generateAuthParams, gemini_refreshAccessToken as refreshAccessToken };
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
export { type FetchLike, claude as claudeOAuth, codex as codexOAuth, gemini as geminiOAuth };
|