UNPKG

agents

Version:
155 lines (153 loc) 4.66 kB
import { nanoid } from "nanoid"; //#region src/mcp/do-oauth-client-provider.ts const STATE_EXPIRATION_MS = 600 * 1e3; var DurableObjectOAuthClientProvider = class { constructor(storage, clientName, baseRedirectUrl) { this.storage = storage; this.clientName = clientName; this.baseRedirectUrl = baseRedirectUrl; if (!storage) throw new Error("DurableObjectOAuthClientProvider requires a valid DurableObjectStorage instance"); } get clientMetadata() { return { client_name: this.clientName, client_uri: this.clientUri, grant_types: ["authorization_code", "refresh_token"], redirect_uris: [this.redirectUrl], response_types: ["code"], token_endpoint_auth_method: "none" }; } get clientUri() { return new URL(this.redirectUrl).origin; } get redirectUrl() { return this.baseRedirectUrl; } get clientId() { if (!this._clientId_) throw new Error("Trying to access clientId before it was set"); return this._clientId_; } set clientId(clientId_) { this._clientId_ = clientId_; } get serverId() { if (!this._serverId_) throw new Error("Trying to access serverId before it was set"); return this._serverId_; } set serverId(serverId_) { this._serverId_ = serverId_; } keyPrefix(clientId) { return `/${this.clientName}/${this.serverId}/${clientId}`; } clientInfoKey(clientId) { return `${this.keyPrefix(clientId)}/client_info/`; } async clientInformation() { if (!this._clientId_) return; return await this.storage.get(this.clientInfoKey(this.clientId)) ?? void 0; } async saveClientInformation(clientInformation) { await this.storage.put(this.clientInfoKey(clientInformation.client_id), clientInformation); this.clientId = clientInformation.client_id; } tokenKey(clientId) { return `${this.keyPrefix(clientId)}/token`; } async tokens() { if (!this._clientId_) return; return await this.storage.get(this.tokenKey(this.clientId)) ?? void 0; } async saveTokens(tokens) { await this.storage.put(this.tokenKey(this.clientId), tokens); } get authUrl() { return this._authUrl_; } stateKey(nonce) { return `/${this.clientName}/${this.serverId}/state/${nonce}`; } async state() { const nonce = nanoid(); const state = `${nonce}.${this.serverId}`; const storedState = { nonce, serverId: this.serverId, createdAt: Date.now() }; await this.storage.put(this.stateKey(nonce), storedState); return state; } async checkState(state) { const parts = state.split("."); if (parts.length !== 2) return { valid: false, error: "Invalid state format" }; const [nonce, serverId] = parts; const key = this.stateKey(nonce); const storedState = await this.storage.get(key); if (!storedState) return { valid: false, error: "State not found or already used" }; if (storedState.serverId !== serverId) { await this.storage.delete(key); return { valid: false, error: "State serverId mismatch" }; } if (Date.now() - storedState.createdAt > STATE_EXPIRATION_MS) { await this.storage.delete(key); return { valid: false, error: "State expired" }; } return { valid: true, serverId }; } async consumeState(state) { const parts = state.split("."); if (parts.length !== 2) { console.warn(`[OAuth] consumeState called with invalid state format: ${state.substring(0, 20)}...`); return; } const [nonce] = parts; await this.storage.delete(this.stateKey(nonce)); } async redirectToAuthorization(authUrl) { this._authUrl_ = authUrl.toString(); } async invalidateCredentials(scope) { if (!this._clientId_) return; const deleteKeys = []; if (scope === "all" || scope === "client") deleteKeys.push(this.clientInfoKey(this.clientId)); if (scope === "all" || scope === "tokens") deleteKeys.push(this.tokenKey(this.clientId)); if (scope === "all" || scope === "verifier") deleteKeys.push(this.codeVerifierKey(this.clientId)); if (deleteKeys.length > 0) await this.storage.delete(deleteKeys); } codeVerifierKey(clientId) { return `${this.keyPrefix(clientId)}/code_verifier`; } async saveCodeVerifier(verifier) { const key = this.codeVerifierKey(this.clientId); if (await this.storage.get(key)) return; await this.storage.put(key, verifier); } async codeVerifier() { const codeVerifier = await this.storage.get(this.codeVerifierKey(this.clientId)); if (!codeVerifier) throw new Error("No code verifier found"); return codeVerifier; } async deleteCodeVerifier() { await this.storage.delete(this.codeVerifierKey(this.clientId)); } }; //#endregion export { DurableObjectOAuthClientProvider as t }; //# sourceMappingURL=do-oauth-client-provider-DDg8QrEA.js.map