@vymalo/opencode-oauth2 0.2.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.
Files changed (57) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +213 -0
  3. package/dist/cache.d.ts +9 -0
  4. package/dist/cache.js +91 -0
  5. package/dist/cache.js.map +1 -0
  6. package/dist/config.d.ts +97 -0
  7. package/dist/config.js +179 -0
  8. package/dist/config.js.map +1 -0
  9. package/dist/index.d.ts +9 -0
  10. package/dist/index.js +8 -0
  11. package/dist/index.js.map +1 -0
  12. package/dist/logging.d.ts +11 -0
  13. package/dist/logging.js +59 -0
  14. package/dist/logging.js.map +1 -0
  15. package/dist/model-discovery.d.ts +9 -0
  16. package/dist/model-discovery.js +74 -0
  17. package/dist/model-discovery.js.map +1 -0
  18. package/dist/model-normalization.d.ts +4 -0
  19. package/dist/model-normalization.js +86 -0
  20. package/dist/model-normalization.js.map +1 -0
  21. package/dist/oauth/browser.d.ts +1 -0
  22. package/dist/oauth/browser.js +29 -0
  23. package/dist/oauth/browser.js.map +1 -0
  24. package/dist/oauth/client.d.ts +56 -0
  25. package/dist/oauth/client.js +436 -0
  26. package/dist/oauth/client.js.map +1 -0
  27. package/dist/oauth/device-code.d.ts +22 -0
  28. package/dist/oauth/device-code.js +240 -0
  29. package/dist/oauth/device-code.js.map +1 -0
  30. package/dist/oauth/discovery.d.ts +8 -0
  31. package/dist/oauth/discovery.js +38 -0
  32. package/dist/oauth/discovery.js.map +1 -0
  33. package/dist/oauth/http-utils.d.ts +33 -0
  34. package/dist/oauth/http-utils.js +129 -0
  35. package/dist/oauth/http-utils.js.map +1 -0
  36. package/dist/oauth/local-callback.d.ts +10 -0
  37. package/dist/oauth/local-callback.js +82 -0
  38. package/dist/oauth/local-callback.js.map +1 -0
  39. package/dist/oauth/pkce.d.ts +5 -0
  40. package/dist/oauth/pkce.js +13 -0
  41. package/dist/oauth/pkce.js.map +1 -0
  42. package/dist/oauth/subject-token.d.ts +20 -0
  43. package/dist/oauth/subject-token.js +86 -0
  44. package/dist/oauth/subject-token.js.map +1 -0
  45. package/dist/opencode.d.ts +11 -0
  46. package/dist/opencode.js +347 -0
  47. package/dist/opencode.js.map +1 -0
  48. package/dist/plugin.d.ts +47 -0
  49. package/dist/plugin.js +220 -0
  50. package/dist/plugin.js.map +1 -0
  51. package/dist/scheduler.d.ts +11 -0
  52. package/dist/scheduler.js +44 -0
  53. package/dist/scheduler.js.map +1 -0
  54. package/dist/types.d.ts +37 -0
  55. package/dist/types.js +2 -0
  56. package/dist/types.js.map +1 -0
  57. package/package.json +53 -0
@@ -0,0 +1,436 @@
1
+ import { DEFAULT_TOKEN_EXPIRY_SKEW_MS } from "../config.js";
2
+ import { openExternalUrl } from "./browser.js";
3
+ import { acquireTokenViaDeviceCode } from "./device-code.js";
4
+ import { discoverOidcMetadata } from "./discovery.js";
5
+ import { readResponseBodyPreview, redactUrl, scrubSecrets } from "./http-utils.js";
6
+ import { startLocalCallbackServer } from "./local-callback.js";
7
+ import { generatePkcePair, generateStateToken } from "./pkce.js";
8
+ import { resolveSubjectToken } from "./subject-token.js";
9
+ export function toTokenSet(payload, options) {
10
+ const accessToken = payload.access_token;
11
+ if (typeof accessToken !== "string" || accessToken.length === 0) {
12
+ throw new Error("OAuth token response is missing access_token");
13
+ }
14
+ const tokenType = typeof payload.token_type === "string" && payload.token_type.length > 0
15
+ ? payload.token_type
16
+ : "Bearer";
17
+ const expiresIn = typeof payload.expires_in === "number" && Number.isFinite(payload.expires_in)
18
+ ? payload.expires_in
19
+ : undefined;
20
+ const refreshToken = typeof payload.refresh_token === "string" && payload.refresh_token.length > 0
21
+ ? payload.refresh_token
22
+ : options?.fallbackRefreshToken;
23
+ if (options?.requireRefreshToken !== false && !refreshToken) {
24
+ throw new Error("OAuth token response is missing refresh_token");
25
+ }
26
+ return {
27
+ accessToken,
28
+ tokenType,
29
+ refreshToken: refreshToken,
30
+ scope: typeof payload.scope === "string" ? payload.scope : undefined,
31
+ expiresAt: expiresIn ? Date.now() + expiresIn * 1000 : undefined
32
+ };
33
+ }
34
+ export class OAuthClient {
35
+ server;
36
+ fetchImpl;
37
+ logger;
38
+ timeoutMs;
39
+ onAuthorizationUrl;
40
+ tokenExpirySkewMs;
41
+ constructor(server, options) {
42
+ this.server = server;
43
+ this.fetchImpl = options.fetchImpl ?? fetch;
44
+ this.logger = options.logger;
45
+ this.timeoutMs = options.timeoutMs;
46
+ this.onAuthorizationUrl = options.onAuthorizationUrl;
47
+ this.tokenExpirySkewMs =
48
+ typeof options.tokenExpirySkewMs === "number" &&
49
+ Number.isFinite(options.tokenExpirySkewMs) &&
50
+ options.tokenExpirySkewMs > 0
51
+ ? options.tokenExpirySkewMs
52
+ : DEFAULT_TOKEN_EXPIRY_SKEW_MS;
53
+ }
54
+ isTokenValid(token) {
55
+ if (!token?.accessToken) {
56
+ return false;
57
+ }
58
+ if (!token.expiresAt) {
59
+ // For machine-to-machine flows (client_credentials, jwt_bearer,
60
+ // token_exchange), re-authentication is cheap (one POST + maybe a
61
+ // subject-token fetch) and the spec allows but does not require
62
+ // `expires_in`. Without a declared lifetime we cannot tell if the
63
+ // server-side token has been revoked, so we re-acquire each time to
64
+ // avoid persistent 401s after the server's idea of the token has
65
+ // expired. User-interactive flows (authorization_code, device_code)
66
+ // keep the old behavior — assume non-expiring when expires_in is
67
+ // missing — because the cost of forcing an unnecessary browser dance
68
+ // is high.
69
+ const machineFlows = [
70
+ "client_credentials",
71
+ "jwt_bearer",
72
+ "token_exchange"
73
+ ];
74
+ return !machineFlows.includes(this.server.authFlow);
75
+ }
76
+ return Date.now() + this.tokenExpirySkewMs < token.expiresAt;
77
+ }
78
+ /**
79
+ * POST to a token endpoint with an AbortController-backed timeout. Without
80
+ * this, a stalled IdP would block the warmup path indefinitely (the plugin
81
+ * runs token requests at config-hook time for cached/client_credentials
82
+ * paths).
83
+ */
84
+ async postWithTimeout(url, body) {
85
+ const controller = new AbortController();
86
+ const timer = setTimeout(() => controller.abort(), this.timeoutMs);
87
+ try {
88
+ return await this.fetchImpl(url, {
89
+ method: "POST",
90
+ headers: {
91
+ "Content-Type": "application/x-www-form-urlencoded",
92
+ Accept: "application/json"
93
+ },
94
+ body,
95
+ signal: controller.signal
96
+ });
97
+ }
98
+ finally {
99
+ clearTimeout(timer);
100
+ }
101
+ }
102
+ async ensureToken(current, options = {}) {
103
+ if (this.isTokenValid(current)) {
104
+ return current;
105
+ }
106
+ // Machine-to-machine flows never need a refresh token (they re-acquire
107
+ // by re-presenting the platform identity / client secret) and are safe
108
+ // to run during non-interactive warmup. Dispatch before the refresh
109
+ // branch so we don't try to use a stale refresh token that the IdP may
110
+ // not even have issued.
111
+ if (this.server.authFlow === "client_credentials") {
112
+ return this.loginClientCredentials();
113
+ }
114
+ if (this.server.authFlow === "jwt_bearer") {
115
+ return this.loginJwtBearer();
116
+ }
117
+ if (this.server.authFlow === "token_exchange") {
118
+ return this.loginTokenExchange();
119
+ }
120
+ if (current?.refreshToken) {
121
+ try {
122
+ const refreshed = await this.refreshToken(current.refreshToken);
123
+ this.logger.info("oauth_refresh_success", { serverId: this.server.id });
124
+ return refreshed;
125
+ }
126
+ catch (error) {
127
+ this.logger.warn("oauth_refresh_failed", {
128
+ serverId: this.server.id,
129
+ error: error instanceof Error ? error.message : String(error)
130
+ });
131
+ }
132
+ }
133
+ // When called non-interactively (e.g. plugin warmup at config-hook time),
134
+ // refuse to open a browser or block on device-code polling. Callers like
135
+ // syncServer catch this and preserve cached state; the provider's models
136
+ // stay empty in OpenCode until the user actually attempts a chat (which
137
+ // calls ensureToken with the default interactive=true).
138
+ if (options.interactive === false) {
139
+ throw new Error(`interactive authentication required for server "${this.server.id}" (authFlow=${this.server.authFlow}) but called non-interactively`);
140
+ }
141
+ if (this.server.authFlow === "device_code") {
142
+ return this.loginDeviceCode();
143
+ }
144
+ return this.loginInteractive();
145
+ }
146
+ async loginClientCredentials() {
147
+ if (!this.server.clientSecret) {
148
+ throw new Error("client_credentials flow requires clientSecret");
149
+ }
150
+ const endpoints = await this.resolveEndpoints();
151
+ const body = new URLSearchParams({
152
+ grant_type: "client_credentials",
153
+ client_id: this.server.clientId,
154
+ client_secret: this.server.clientSecret
155
+ });
156
+ if (this.server.scopes.length > 0) {
157
+ body.set("scope", this.server.scopes.join(" "));
158
+ }
159
+ this.logger.info("oauth_client_credentials_started", {
160
+ serverId: this.server.id,
161
+ // tokenEndpoint comes from user-supplied config (or OIDC discovery off
162
+ // a user-supplied issuer); strip userinfo + query before logging so
163
+ // configs like `https://user:pass@.../token` don't leak credentials.
164
+ tokenEndpoint: redactUrl(endpoints.tokenEndpoint)
165
+ });
166
+ const response = await this.postWithTimeout(endpoints.tokenEndpoint, body);
167
+ if (!response.ok) {
168
+ const bodyPreview = await readResponseBodyPreview(response, 500);
169
+ // Log the body separately so the logger's redaction can scrub matching
170
+ // keys, and run it through scrubSecrets to also mask token-shaped
171
+ // substrings that IdPs sometimes echo back inside arbitrary error text
172
+ // (where field-name-based redaction wouldn't help). Never embed the
173
+ // body in throw new Error(...) — callers log error.message verbatim.
174
+ this.logger.error("oauth_client_credentials_failed", {
175
+ serverId: this.server.id,
176
+ status: response.status,
177
+ bodyPreview: bodyPreview ? scrubSecrets(bodyPreview) : undefined
178
+ });
179
+ throw new Error(`client_credentials token request failed (${response.status})`);
180
+ }
181
+ const payload = (await response.json());
182
+ const token = toTokenSet(payload, { requireRefreshToken: false });
183
+ this.logger.info("oauth_client_credentials_success", {
184
+ serverId: this.server.id,
185
+ hasExpiry: token.expiresAt !== undefined
186
+ });
187
+ return token;
188
+ }
189
+ async loginJwtBearer() {
190
+ if (!this.server.subjectTokenSource) {
191
+ throw new Error("jwt_bearer flow requires subjectTokenSource");
192
+ }
193
+ return this.postFederatedGrant({
194
+ grantType: "urn:ietf:params:oauth:grant-type:jwt-bearer",
195
+ extraFields: (assertion) => ({ assertion }),
196
+ eventPrefix: "oauth_jwt_bearer"
197
+ });
198
+ }
199
+ async loginTokenExchange() {
200
+ if (!this.server.subjectTokenSource) {
201
+ throw new Error("token_exchange flow requires subjectTokenSource");
202
+ }
203
+ return this.postFederatedGrant({
204
+ grantType: "urn:ietf:params:oauth:grant-type:token-exchange",
205
+ extraFields: (subjectToken) => {
206
+ const fields = {
207
+ subject_token: subjectToken,
208
+ subject_token_type: "urn:ietf:params:oauth:token-type:jwt"
209
+ };
210
+ if (this.server.tokenExchangeAudience) {
211
+ fields.audience = this.server.tokenExchangeAudience;
212
+ }
213
+ return fields;
214
+ },
215
+ eventPrefix: "oauth_token_exchange"
216
+ });
217
+ }
218
+ /**
219
+ * Shared driver for jwt_bearer and token_exchange. Both grants:
220
+ * - resolve a platform-supplied JWT from `subjectTokenSource`
221
+ * - POST it to the token endpoint with grant-specific form fields
222
+ * - get back an access token (refresh token is NOT expected for either)
223
+ */
224
+ async postFederatedGrant(spec) {
225
+ const subjectTokenSource = this.server.subjectTokenSource;
226
+ if (!subjectTokenSource) {
227
+ // Caller already guards this; belt-and-braces for the type narrowing.
228
+ throw new Error("federated flow requires subjectTokenSource");
229
+ }
230
+ const subjectToken = await resolveSubjectToken(subjectTokenSource, {
231
+ fetchImpl: this.fetchImpl,
232
+ timeoutMs: this.timeoutMs
233
+ });
234
+ const endpoints = await this.resolveEndpoints();
235
+ const body = new URLSearchParams({
236
+ grant_type: spec.grantType,
237
+ client_id: this.server.clientId,
238
+ ...spec.extraFields(subjectToken)
239
+ });
240
+ if (this.server.scopes.length > 0) {
241
+ body.set("scope", this.server.scopes.join(" "));
242
+ }
243
+ if (this.server.clientSecret) {
244
+ // Confidential federated clients are permitted by Keycloak and many
245
+ // others; some IdPs require both the assertion AND the client secret.
246
+ body.set("client_secret", this.server.clientSecret);
247
+ }
248
+ this.logger.info(`${spec.eventPrefix}_started`, {
249
+ serverId: this.server.id,
250
+ tokenEndpoint: redactUrl(endpoints.tokenEndpoint),
251
+ subjectTokenSource: subjectTokenSource.type
252
+ });
253
+ const response = await this.postWithTimeout(endpoints.tokenEndpoint, body);
254
+ if (!response.ok) {
255
+ const preview = await readResponseBodyPreview(response, 500);
256
+ this.logger.error(`${spec.eventPrefix}_failed`, {
257
+ serverId: this.server.id,
258
+ status: response.status,
259
+ bodyPreview: preview ? scrubSecrets(preview) : undefined
260
+ });
261
+ throw new Error(`${spec.grantType} request failed (${response.status})`);
262
+ }
263
+ const payload = (await response.json());
264
+ const token = toTokenSet(payload, { requireRefreshToken: false });
265
+ this.logger.info(`${spec.eventPrefix}_success`, {
266
+ serverId: this.server.id,
267
+ hasExpiry: token.expiresAt !== undefined
268
+ });
269
+ return token;
270
+ }
271
+ /**
272
+ * Resolve endpoints for the configured flow. Skips OIDC discovery entirely
273
+ * when the explicit endpoints needed for the flow are all present in config
274
+ * — discovery is unavailable on RFC 8414-only servers and on Keycloak
275
+ * realms where the well-known doc is locked down.
276
+ */
277
+ async resolveEndpoints() {
278
+ const haveAllExplicit = this.hasExplicitEndpointsForFlow();
279
+ if (haveAllExplicit) {
280
+ return {
281
+ authorizationEndpoint: this.server.authorizationEndpoint,
282
+ tokenEndpoint: this.server.tokenEndpoint,
283
+ deviceAuthorizationEndpoint: this.server.deviceAuthorizationEndpoint
284
+ };
285
+ }
286
+ const metadata = await discoverOidcMetadata(this.server.issuer, this.fetchImpl, this.timeoutMs);
287
+ const tokenEndpoint = this.server.tokenEndpoint ?? metadata.token_endpoint;
288
+ const authorizationEndpoint = this.server.authorizationEndpoint ?? metadata.authorization_endpoint;
289
+ const deviceAuthorizationEndpoint = this.server.deviceAuthorizationEndpoint ?? metadata.device_authorization_endpoint;
290
+ if (this.server.authFlow === "authorization_code" && !authorizationEndpoint) {
291
+ throw new Error("authorization_code flow requires an authorization_endpoint (either configured or discovered)");
292
+ }
293
+ if (this.server.authFlow === "device_code" && !deviceAuthorizationEndpoint) {
294
+ throw new Error("device_code flow requires a device_authorization_endpoint (either configured or discovered)");
295
+ }
296
+ return {
297
+ authorizationEndpoint,
298
+ tokenEndpoint,
299
+ deviceAuthorizationEndpoint
300
+ };
301
+ }
302
+ hasExplicitEndpointsForFlow() {
303
+ if (!this.server.tokenEndpoint) {
304
+ return false;
305
+ }
306
+ switch (this.server.authFlow) {
307
+ case "client_credentials":
308
+ case "jwt_bearer":
309
+ case "token_exchange":
310
+ return true;
311
+ case "device_code":
312
+ return Boolean(this.server.deviceAuthorizationEndpoint);
313
+ default:
314
+ return Boolean(this.server.authorizationEndpoint);
315
+ }
316
+ }
317
+ async refreshToken(refreshToken) {
318
+ const endpoints = await this.resolveEndpoints();
319
+ const body = new URLSearchParams({
320
+ grant_type: "refresh_token",
321
+ refresh_token: refreshToken,
322
+ client_id: this.server.clientId
323
+ });
324
+ if (this.server.clientSecret) {
325
+ body.set("client_secret", this.server.clientSecret);
326
+ }
327
+ const response = await this.postWithTimeout(endpoints.tokenEndpoint, body);
328
+ if (!response.ok) {
329
+ throw new Error(`refresh token exchange failed (${response.status})`);
330
+ }
331
+ const payload = (await response.json());
332
+ const nextToken = toTokenSet(payload, {
333
+ fallbackRefreshToken: refreshToken,
334
+ requireRefreshToken: true
335
+ });
336
+ return nextToken;
337
+ }
338
+ async loginDeviceCode() {
339
+ const endpoints = await this.resolveEndpoints();
340
+ if (!endpoints.deviceAuthorizationEndpoint) {
341
+ throw new Error("device_code flow requires a device_authorization_endpoint (either configured or discovered)");
342
+ }
343
+ return acquireTokenViaDeviceCode({
344
+ deviceAuthorizationEndpoint: endpoints.deviceAuthorizationEndpoint,
345
+ tokenEndpoint: endpoints.tokenEndpoint,
346
+ clientId: this.server.clientId,
347
+ clientSecret: this.server.clientSecret,
348
+ scopes: this.server.scopes,
349
+ serverId: this.server.id,
350
+ logger: this.logger,
351
+ fetchImpl: this.fetchImpl,
352
+ timeoutMs: this.timeoutMs
353
+ });
354
+ }
355
+ async loginInteractive() {
356
+ const endpoints = await this.resolveEndpoints();
357
+ if (!endpoints.authorizationEndpoint) {
358
+ // resolveEndpoints already guards this for authorization_code, but TS
359
+ // sees the type as optional. Belt-and-braces.
360
+ throw new Error("authorization_code flow requires an authorization_endpoint (either configured or discovered)");
361
+ }
362
+ const callbackServer = await startLocalCallbackServer("/oauth2/callback", this.server.redirectPort);
363
+ try {
364
+ const { verifier, challenge } = generatePkcePair();
365
+ const state = generateStateToken();
366
+ const authorizeUrl = new URL(endpoints.authorizationEndpoint);
367
+ authorizeUrl.searchParams.set("response_type", "code");
368
+ authorizeUrl.searchParams.set("client_id", this.server.clientId);
369
+ authorizeUrl.searchParams.set("redirect_uri", callbackServer.redirectUri);
370
+ authorizeUrl.searchParams.set("scope", this.server.scopes.join(" "));
371
+ authorizeUrl.searchParams.set("code_challenge", challenge);
372
+ authorizeUrl.searchParams.set("code_challenge_method", "S256");
373
+ authorizeUrl.searchParams.set("state", state);
374
+ this.logger.info("oauth_login_started", {
375
+ serverId: this.server.id,
376
+ issuer: this.server.issuer,
377
+ authorizationEndpoint: `${authorizeUrl.origin}${authorizeUrl.pathname}`
378
+ });
379
+ if (this.onAuthorizationUrl) {
380
+ await this.onAuthorizationUrl(authorizeUrl.toString());
381
+ }
382
+ else {
383
+ try {
384
+ await openExternalUrl(authorizeUrl.toString());
385
+ }
386
+ catch (error) {
387
+ this.logger.warn("oauth_open_browser_failed", {
388
+ serverId: this.server.id,
389
+ error: error instanceof Error ? error.message : String(error)
390
+ });
391
+ // Write the URL to stderr directly so the terminal user can copy-paste
392
+ // it. Bypasses the structured logger to avoid leaking the `state`
393
+ // nonce (and other query params) into centralized log aggregation,
394
+ // which would enable login-CSRF via a forged localhost callback.
395
+ process.stderr.write(`\n[opencode-oauth2] open this URL to authenticate (${this.server.id}):\n${authorizeUrl.toString()}\n\n`);
396
+ }
397
+ }
398
+ const callback = await callbackServer.waitForCode();
399
+ if (callback.state !== state) {
400
+ throw new Error("OAuth callback state mismatch");
401
+ }
402
+ const tokenBody = new URLSearchParams({
403
+ grant_type: "authorization_code",
404
+ code: callback.code,
405
+ client_id: this.server.clientId,
406
+ redirect_uri: callbackServer.redirectUri,
407
+ code_verifier: verifier
408
+ });
409
+ if (this.server.clientSecret) {
410
+ tokenBody.set("client_secret", this.server.clientSecret);
411
+ }
412
+ const tokenResponse = await this.postWithTimeout(endpoints.tokenEndpoint, tokenBody);
413
+ if (!tokenResponse.ok) {
414
+ throw new Error(`authorization code exchange failed (${tokenResponse.status})`);
415
+ }
416
+ const payload = (await tokenResponse.json());
417
+ const token = toTokenSet(payload, { requireRefreshToken: true });
418
+ this.logger.info("oauth_login_success", {
419
+ serverId: this.server.id,
420
+ hasRefreshToken: true
421
+ });
422
+ return token;
423
+ }
424
+ catch (error) {
425
+ this.logger.error("oauth_login_failed", {
426
+ serverId: this.server.id,
427
+ error: error instanceof Error ? error.message : String(error)
428
+ });
429
+ throw error;
430
+ }
431
+ finally {
432
+ await callbackServer.close();
433
+ }
434
+ }
435
+ }
436
+ //# sourceMappingURL=client.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"client.js","sourceRoot":"","sources":["../../src/oauth/client.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,22 @@
1
+ import type { Logger } from "../logging.js";
2
+ import type { TokenSet } from "../types.js";
3
+ export interface AcquireTokenViaDeviceCodeOptions {
4
+ deviceAuthorizationEndpoint: string;
5
+ tokenEndpoint: string;
6
+ clientId: string;
7
+ clientSecret?: string;
8
+ scopes: string[];
9
+ serverId: string;
10
+ logger: Logger;
11
+ fetchImpl?: typeof fetch;
12
+ timeoutMs: number;
13
+ /**
14
+ * Sleep function used between polls. Overridable for tests.
15
+ */
16
+ sleep?: (ms: number) => Promise<void>;
17
+ /**
18
+ * Clock used to measure elapsed time. Overridable for tests.
19
+ */
20
+ now?: () => number;
21
+ }
22
+ export declare function acquireTokenViaDeviceCode(options: AcquireTokenViaDeviceCodeOptions): Promise<TokenSet>;