import type { AuthorizationCode, AccessToken, RefreshToken, IDToken, } from '../types'; import type { StorageAdapter } from '../storage'; /** * 令牌管理器 * 处理所有令牌相关的存储业务逻辑 */ export class TokenManager { constructor(private storage: StorageAdapter) { } // 生成存储键 private getTokenKey(type: string, token: string): string { return `${type}:${token}`; } private getUserClientKey(type: string, userId: string, clientId: string): string { return `${type}:user:${userId}:client:${clientId}`; } // 授权码管理 async storeAuthorizationCode(authCode: AuthorizationCode): Promise { const key = this.getTokenKey('auth_code', authCode.code); const ttl = Math.floor((authCode.expires_at.getTime() - Date.now()) / 1000); const data = { ...authCode, expires_at: authCode.expires_at.toISOString(), created_at: authCode.created_at.toISOString(), }; await this.storage.set(key, data, Math.max(ttl, 1)); } async getAuthorizationCode(code: string): Promise { const key = this.getTokenKey('auth_code', code); const data = await this.storage.get(key); if (!data) return null; return { ...data, expires_at: new Date(data.expires_at), created_at: new Date(data.created_at), }; } async deleteAuthorizationCode(code: string): Promise { const key = this.getTokenKey('auth_code', code); await this.storage.delete(key); } // 访问令牌管理 async storeAccessToken(token: AccessToken): Promise { const key = this.getTokenKey('access_token', token.token); const userClientKey = this.getUserClientKey('access_tokens', token.user_id, token.client_id); const ttl = Math.floor((token.expires_at.getTime() - Date.now()) / 1000); const data = { ...token, expires_at: token.expires_at.toISOString(), created_at: token.created_at.toISOString(), }; // 存储令牌数据 await this.storage.set(key, data, Math.max(ttl, 1)); // 存储用户-客户端索引 const existingTokens = await this.storage.get(userClientKey) || []; existingTokens.push(token.token); await this.storage.set(userClientKey, existingTokens, Math.max(ttl, 1)); } async getAccessToken(token: string): Promise { const key = this.getTokenKey('access_token', token); const data = await this.storage.get(key); if (!data) return null; return { ...data, expires_at: new Date(data.expires_at), created_at: new Date(data.created_at), }; } async deleteAccessToken(token: string): Promise { const key = this.getTokenKey('access_token', token); // 获取令牌数据以清理索引 const tokenData = await this.storage.get(key); if (tokenData) { const userClientKey = this.getUserClientKey('access_tokens', tokenData.user_id, tokenData.client_id); const tokens = await this.storage.get(userClientKey) || []; const filteredTokens = tokens.filter(t => t !== token); if (filteredTokens.length > 0) { await this.storage.set(userClientKey, filteredTokens); } else { await this.storage.delete(userClientKey); } } await this.storage.delete(key); } async deleteAccessTokensByUserAndClient(userId: string, clientId: string): Promise { const userClientKey = this.getUserClientKey('access_tokens', userId, clientId); const tokens = await this.storage.get(userClientKey) || []; // 删除所有相关令牌 for (const token of tokens) { await this.storage.delete(this.getTokenKey('access_token', token)); } // 删除索引 await this.storage.delete(userClientKey); } // 刷新令牌管理 async storeRefreshToken(token: RefreshToken): Promise { const key = this.getTokenKey('refresh_token', token.token); const userClientKey = this.getUserClientKey('refresh_tokens', token.user_id, token.client_id); const ttl = Math.floor((token.expires_at.getTime() - Date.now()) / 1000); const data = { ...token, expires_at: token.expires_at.toISOString(), created_at: token.created_at.toISOString(), }; // 存储令牌数据 await this.storage.set(key, data, Math.max(ttl, 1)); // 存储用户-客户端索引 const existingTokens = await this.storage.get(userClientKey) || []; existingTokens.push(token.token); await this.storage.set(userClientKey, existingTokens, Math.max(ttl, 1)); } async getRefreshToken(token: string): Promise { const key = this.getTokenKey('refresh_token', token); const data = await this.storage.get(key); if (!data) return null; return { ...data, expires_at: new Date(data.expires_at), created_at: new Date(data.created_at), }; } async deleteRefreshToken(token: string): Promise { const key = this.getTokenKey('refresh_token', token); // 获取令牌数据以清理索引 const tokenData = await this.storage.get(key); if (tokenData) { const userClientKey = this.getUserClientKey('refresh_tokens', tokenData.user_id, tokenData.client_id); const tokens = await this.storage.get(userClientKey) || []; const filteredTokens = tokens.filter(t => t !== token); if (filteredTokens.length > 0) { await this.storage.set(userClientKey, filteredTokens); } else { await this.storage.delete(userClientKey); } } await this.storage.delete(key); } // ID令牌管理 async storeIDToken(token: IDToken): Promise { const key = this.getTokenKey('id_token', token.token); const ttl = Math.floor((token.expires_at.getTime() - Date.now()) / 1000); const data = { ...token, expires_at: token.expires_at.toISOString(), created_at: token.created_at.toISOString(), }; await this.storage.set(key, data, Math.max(ttl, 1)); } async getIDToken(token: string): Promise { const key = this.getTokenKey('id_token', token); const data = await this.storage.get(key); if (!data) return null; return { ...data, expires_at: new Date(data.expires_at), created_at: new Date(data.created_at), }; } async deleteIDToken(token: string): Promise { const key = this.getTokenKey('id_token', token); await this.storage.delete(key); } }