A social knowledge tool for researchers built on ATProto
1import { Result, ok, err } from 'src/shared/core/Result';
2import {
3 ITokenRepository,
4 RefreshToken,
5} from '../../domain/repositories/ITokenRepository';
6
7export class InMemoryTokenRepository implements ITokenRepository {
8 private static instance: InMemoryTokenRepository;
9 private tokens: Map<string, RefreshToken> = new Map();
10
11 private constructor() {}
12
13 public static getInstance(): InMemoryTokenRepository {
14 if (!InMemoryTokenRepository.instance) {
15 InMemoryTokenRepository.instance = new InMemoryTokenRepository();
16 }
17 return InMemoryTokenRepository.instance;
18 }
19
20 async saveRefreshToken(token: RefreshToken): Promise<Result<void>> {
21 try {
22 this.tokens.set(token.refreshToken, token);
23 return ok(undefined);
24 } catch (error: any) {
25 return err(error);
26 }
27 }
28
29 async findRefreshToken(
30 refreshToken: string,
31 ): Promise<Result<RefreshToken | null>> {
32 try {
33 const token = this.tokens.get(refreshToken);
34 if (!token || token.revoked) {
35 return ok(null);
36 }
37 return ok(token);
38 } catch (error: any) {
39 return err(error);
40 }
41 }
42
43 async revokeRefreshToken(refreshToken: string): Promise<Result<void>> {
44 try {
45 const token = this.tokens.get(refreshToken);
46 if (token) {
47 token.revoked = true;
48 this.tokens.set(refreshToken, token);
49 }
50 return ok(undefined);
51 } catch (error: any) {
52 return err(error);
53 }
54 }
55
56 // Helper method for testing
57 clear(): void {
58 this.tokens.clear();
59 }
60}