Skip to main content
Glama

Industrial MCP Server

by intecrel
token-blacklist.ts3.59 kB
/** * Token Blacklist Management with Redis/Upstash * Handles revoked token checking for JWT validation */ import { Redis } from '@upstash/redis'; // Redis client for token blacklist let redis: Redis | null = null; const useRedis = process.env.ENABLE_REDIS_STORAGE === 'true' && process.env.UPSTASH_REDIS_REST_URL && process.env.UPSTASH_REDIS_REST_TOKEN; // In-memory fallback for development const memoryBlacklist = new Set<string>(); // Environment-based key prefix const getKeyPrefix = (): string => { if (process.env.VERCEL_ENV === 'production') return 'prod:'; if (process.env.VERCEL_ENV === 'preview') return 'preview:'; return 'local:'; }; /** * Initialize Redis client if enabled */ function getRedisClient(): Redis | null { if (!useRedis) return null; if (!redis) { redis = new Redis({ url: process.env.UPSTASH_REDIS_REST_URL!, token: process.env.UPSTASH_REDIS_REST_TOKEN!, }); } return redis; } /** * Add token to blacklist */ export async function addToBlacklist(token: string): Promise<void> { const client = getRedisClient(); if (client) { try { const key = `${getKeyPrefix()}oauth:blacklist:${token}`; // Set with 24 hour expiration (longer than max token lifetime) await client.setex(key, 86400, 'revoked'); } catch (error) { console.warn('Redis blacklist add failed, using memory fallback:', error); memoryBlacklist.add(token); } } else { memoryBlacklist.add(token); } } /** * Check if token is in blacklist */ export async function isTokenRevoked(token: string): Promise<boolean> { const client = getRedisClient(); if (client) { try { const key = `${getKeyPrefix()}oauth:blacklist:${token}`; const result = await client.get(key); return result === 'revoked'; } catch (error) { console.warn('Redis blacklist check failed, using memory fallback:', error); return memoryBlacklist.has(token); } } else { return memoryBlacklist.has(token); } } /** * Remove token from blacklist (for cleanup) */ export async function removeFromBlacklist(token: string): Promise<void> { const client = getRedisClient(); if (client) { try { const key = `${getKeyPrefix()}oauth:blacklist:${token}`; await client.del(key); } catch (error) { console.warn('Redis blacklist remove failed, using memory fallback:', error); memoryBlacklist.delete(token); } } else { memoryBlacklist.delete(token); } } /** * Get blacklist size (for monitoring) */ export async function getBlacklistSize(): Promise<number> { const client = getRedisClient(); if (client) { try { const pattern = `${getKeyPrefix()}oauth:blacklist:*`; const keys = await client.keys(pattern); return keys.length; } catch (error) { console.warn('Redis blacklist size check failed, using memory fallback:', error); return memoryBlacklist.size; } } else { return memoryBlacklist.size; } } /** * Clear blacklist (for testing/maintenance) */ export async function clearBlacklist(): Promise<void> { const client = getRedisClient(); if (client) { try { const pattern = `${getKeyPrefix()}oauth:blacklist:*`; const keys = await client.keys(pattern); if (keys.length > 0) { await client.del(...keys); } } catch (error) { console.warn('Redis blacklist clear failed, using memory fallback:', error); memoryBlacklist.clear(); } } else { memoryBlacklist.clear(); } }

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/intecrel/industrial-mcp'

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