import type { MCPOAuthStorage, OAuthClient, OAuthUser, AuthorizationCode, AccessToken, RefreshToken } from '../types.js' export class MemoryStorage implements MCPOAuthStorage { private clients = new Map() private users = new Map() private authorizationCodes = new Map() private accessTokens = new Map() private refreshTokens = new Map() // ===== CLIENT MANAGEMENT ===== async createClient(client: OAuthClient): Promise { this.clients.set(client.id, client) } async getClient(clientId: string): Promise { return this.clients.get(clientId) || null } async listClients(): Promise { return Array.from(this.clients.values()) } async updateClient(clientId: string, updates: Partial): Promise { const client = this.clients.get(clientId) if (client) { this.clients.set(clientId, { ...client, ...updates, updatedAt: new Date() }) } } async deleteClient(clientId: string): Promise { this.clients.delete(clientId) } // ===== USER MANAGEMENT ===== async createUser(user: OAuthUser): Promise { this.users.set(user.id, user) } async getUser(userId: string): Promise { return this.users.get(userId) || null } async getUserByUsername(username: string): Promise { for (const user of this.users.values()) { if (user.username === username) { return user } } return null } async listUsers(): Promise { return Array.from(this.users.values()) } async updateUser(userId: string, updates: Partial): Promise { const user = this.users.get(userId) if (user) { this.users.set(userId, { ...user, ...updates, updatedAt: new Date() }) } } async deleteUser(userId: string): Promise { this.users.delete(userId) } // ===== AUTHORIZATION CODES ===== async createAuthorizationCode(code: AuthorizationCode): Promise { this.authorizationCodes.set(code.code, code) } async getAuthorizationCode(code: string): Promise { return this.authorizationCodes.get(code) || null } async deleteAuthorizationCode(code: string): Promise { this.authorizationCodes.delete(code) } async cleanupExpiredCodes(): Promise { const now = new Date() for (const [code, authCode] of this.authorizationCodes.entries()) { if (authCode.expiresAt < now) { this.authorizationCodes.delete(code) } } } // ===== ACCESS TOKENS ===== async createAccessToken(token: AccessToken): Promise { this.accessTokens.set(token.token, token) } async getAccessToken(token: string): Promise { return this.accessTokens.get(token) || null } async deleteAccessToken(token: string): Promise { this.accessTokens.delete(token) } async cleanupExpiredTokens(): Promise { const now = new Date() for (const [token, accessToken] of this.accessTokens.entries()) { if (accessToken.expiresAt < now) { this.accessTokens.delete(token) } } } // ===== REFRESH TOKENS ===== async createRefreshToken(token: RefreshToken): Promise { this.refreshTokens.set(token.token, token) } async getRefreshToken(token: string): Promise { return this.refreshTokens.get(token) || null } async deleteRefreshToken(token: string): Promise { this.refreshTokens.delete(token) } async deleteRefreshTokensByAccessToken(accessTokenId: string): Promise { for (const [token, refreshToken] of this.refreshTokens.entries()) { if (refreshToken.accessTokenId === accessTokenId) { this.refreshTokens.delete(token) } } } async cleanupExpiredRefreshTokens(): Promise { const now = new Date() for (const [token, refreshToken] of this.refreshTokens.entries()) { if (refreshToken.expiresAt < now) { this.refreshTokens.delete(token) } } } // ===== UTILITY METHODS ===== getStats() { return { clients: this.clients.size, users: this.users.size, authorizationCodes: this.authorizationCodes.size, accessTokens: this.accessTokens.size, refreshTokens: this.refreshTokens.size } } }