Skip to main content
Glama
state-manager.ts2.04 kB
// State Manager for OAuth CSRF protection // Generates random opaque state tokens and tracks associated payload with TTL export interface OAuthStatePayload { provider?: string serverId?: string clientToken?: string returnTo?: string issuedAt: number } export interface StateRecord { payload: OAuthStatePayload expiresAt: number } export interface StateManagerOptions { ttlMs?: number } function getCrypto(): any { const g: any = globalThis as any if (g.crypto && g.crypto.subtle && g.crypto.getRandomValues) return g.crypto as any try { // eslint-disable-next-line @typescript-eslint/no-var-requires const nodeCrypto = require('node:crypto') return nodeCrypto.webcrypto as any } catch { throw new Error('Secure crypto not available in this environment') } } function randomId(bytes = 32): string { const crypto = getCrypto() const arr = new Uint8Array(bytes) crypto.getRandomValues(arr) let str = '' for (let i = 0; i < arr.length; i++) str += arr[i].toString(16).padStart(2, '0') return str } export class StateManager { private readonly store = new Map<string, StateRecord>() private readonly ttl: number constructor(options?: StateManagerOptions) { this.ttl = options?.ttlMs ?? 10 * 60_000 } create(payload: Omit<OAuthStatePayload, 'issuedAt'>): string { const state = randomId(32) const now = Date.now() this.store.set(state, { payload: { ...payload, issuedAt: now }, expiresAt: now + this.ttl }) return state } consume(state: string): OAuthStatePayload | null { const rec = this.store.get(state) if (!rec) return null this.store.delete(state) if (rec.expiresAt <= Date.now()) return null return rec.payload } peek(state: string): OAuthStatePayload | null { const rec = this.store.get(state) if (!rec || rec.expiresAt <= Date.now()) return null return rec.payload } cleanup(): void { const now = Date.now() for (const [k, v] of this.store) if (v.expiresAt <= now) this.store.delete(k) } }

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/Jakedismo/master-mcp-server'

If you have feedback or need assistance with the MCP directory API, please join our Discord server