/** * Configuration for OAuth client credentials flow */ export interface OAuthConfig { /** The URL to request the OAuth token from */ authUrl: string; /** The client ID for OAuth authentication */ clientId: string; /** The client secret for OAuth authentication */ clientSecret: string; /** The scope for the OAuth token. Use empty string if no scope is needed. */ scope: string; } /** * Standard OAuth 2.0 token response format as defined in RFC 6749 */ export interface OAuthTokenResponse { /** The access token issued by the authorization server */ access_token: string; /** The type of token issued (typically "Bearer") */ token_type: string; /** The lifetime in seconds of the access token */ expires_in: number; /** The refresh token, which can be used to obtain new access tokens (optional) */ refresh_token?: string; /** The scope of the access token (optional) */ scope?: string; } /** * A utility class for handling OAuth client credentials flow. * This is specifically for the client credentials grant type, * which is used for server-to-server authentication. */ export class OAuthClient { constructor(private config: OAuthConfig) {} /** * Requests an OAuth token using the client credentials flow. * The request is sent as application/x-www-form-urlencoded. * @returns A promise that resolves to the token response containing access_token and expires_in * @throws Error if the token request fails */ async getToken(): Promise { const formData = new URLSearchParams({ grant_type: "client_credentials", client_id: this.config.clientId, client_secret: this.config.clientSecret, scope: this.config.scope, }); const response = await fetch(this.config.authUrl, { method: "POST", headers: { "Content-Type": "application/x-www-form-urlencoded", }, body: formData, }); if (!response.ok) { throw new Error(`OAuth token request failed: ${response.statusText}`); } const data = (await response.json()) as OAuthTokenResponse; if (data.token_type !== "Bearer") { throw new Error(`Unexpected token type: ${data.token_type}`); } return data; } }