Skip to main content
Glama
AuthManager.ts5.34 kB
/** * Authentication Manager * Handles all authentication methods for WordPress REST API */ import type { WordPressClient } from "@/client/api.js"; import type { AuthConfig, AuthMethod } from "@/types/client.js"; import { AuthenticationError } from "@/types/client.js"; import { LoggerFactory } from "@/utils/logger.js"; export interface JWTToken { token: string; user_email: string; user_nicename: string; user_display_name: string; expiresAt: number; } export class AuthManager { private logger = LoggerFactory.api(); private jwtToken?: JWTToken; constructor( private client: WordPressClient, private authConfig: AuthConfig, ) {} /** * Authenticate using the configured method */ async authenticate(): Promise<boolean> { this.logger.info("Authenticating with method", { method: this.authConfig.method }); try { switch (this.authConfig.method) { case "app-password": return this.authenticateWithAppPassword(); case "jwt": return this.authenticateWithJWT(); case "basic": return this.authenticateWithBasic(); case "cookie": return this.authenticateWithCookie(); case "api-key": return this.authenticateWithAPIKey(); default: throw new AuthenticationError( `Unsupported authentication method: ${this.authConfig.method}`, this.authConfig.method, ); } } catch (error) { this.logger.error("Authentication failed", { method: this.authConfig.method, error: error instanceof Error ? error.message : String(error), }); throw error; } } /** * Get current authentication headers */ getAuthHeaders(): Record<string, string> { const headers: Record<string, string> = {}; switch (this.authConfig.method) { case "app-password": case "basic": if (this.authConfig.username && this.authConfig.appPassword) { const credentials = Buffer.from(`${this.authConfig.username}:${this.authConfig.appPassword}`).toString( "base64", ); headers.Authorization = `Basic ${credentials}`; } break; case "jwt": if (this.jwtToken && !this.isTokenExpired()) { headers.Authorization = `Bearer ${this.jwtToken.token}`; } break; case "api-key": if (this.authConfig.apiKey) { headers["X-API-Key"] = this.authConfig.apiKey; } break; case "cookie": // Cookie authentication is handled by the browser/client // Headers are set automatically after successful login break; } return headers; } /** * JWT authentication */ private async authenticateWithJWT(): Promise<boolean> { if (!this.authConfig.username || !this.authConfig.password) { throw new AuthenticationError( "Username and password are required for JWT authentication", this.authConfig.method, ); } try { const response = await this.client.post<{ token: string; user_email: string; user_nicename: string; user_display_name: string; }>("jwt-auth/v1/token", { username: this.authConfig.username, password: this.authConfig.password, }); if (!response.token) { throw new AuthenticationError("JWT token not received", this.authConfig.method); } // Calculate expiration time (typically 24 hours for JWT) const expiresAt = Date.now() + 24 * 60 * 60 * 1000; // 24 hours this.jwtToken = { token: response.token, user_email: response.user_email, user_nicename: response.user_nicename, user_display_name: response.user_display_name, expiresAt, }; this.logger.info("JWT authentication successful", { user: response.user_nicename, expiresAt: new Date(expiresAt).toISOString(), }); return true; } catch (error) { if (error instanceof Error) { throw new AuthenticationError(`JWT authentication failed: ${error.message}`, this.authConfig.method); } throw new AuthenticationError("JWT authentication failed", this.authConfig.method); } } private authenticateWithAppPassword(): boolean { if (!this.authConfig.username || !this.authConfig.appPassword) { throw new AuthenticationError("Username and app password are required", this.authConfig.method); } return true; } private authenticateWithBasic(): boolean { if (!this.authConfig.username || !this.authConfig.password) { throw new AuthenticationError("Username and password are required", this.authConfig.method); } return true; } private async authenticateWithCookie(): Promise<boolean> { throw new AuthenticationError("Cookie authentication not implemented", this.authConfig.method); } private authenticateWithAPIKey(): boolean { if (!this.authConfig.apiKey) { throw new AuthenticationError("API key is required", this.authConfig.method); } return true; } private isTokenExpired(): boolean { if (!this.jwtToken) return true; return Date.now() > this.jwtToken.expiresAt; } getAuthMethod(): AuthMethod { return this.authConfig.method; } }

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/docdyhr/mcp-wordpress'

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