diff --git a/src/modules/atproto/infrastructure/services/FakeAgentService.ts b/src/modules/atproto/infrastructure/services/FakeAgentService.ts new file mode 100644 index 00000000..c74d1c06 --- /dev/null +++ b/src/modules/atproto/infrastructure/services/FakeAgentService.ts @@ -0,0 +1,40 @@ +import { Result, ok, err } from 'src/shared/core/Result'; +import { IAgentService } from '../../application/IAgentService'; +import { DID } from '../../domain/DID'; +import { Agent } from '@atproto/api'; + +export class FakeAgentService implements IAgentService { + getUnauthenticatedAgent(): Result { + try { + // Create a mock agent - in a real implementation this would be a proper Agent instance + const mockAgent = { + getProfile: async ({ actor }: { actor: string }) => { + const mockHandle = process.env.BSKY_HANDLE || 'mock.bsky.social'; + return { + success: true, + data: { + did: actor, + handle: mockHandle, + displayName: `Mock User (${mockHandle})`, + description: 'This is a mock profile for testing purposes', + avatar: 'https://via.placeholder.com/150', + }, + }; + }, + } as Agent; + + return ok(mockAgent); + } catch (error: any) { + return err(error); + } + } + + async getAuthenticatedAgent(did: DID): Promise> { + try { + // Return the same mock agent for authenticated requests + return this.getUnauthenticatedAgent(); + } catch (error: any) { + return err(error); + } + } +} diff --git a/src/modules/atproto/infrastructure/services/FakeAppPasswordSessionService.ts b/src/modules/atproto/infrastructure/services/FakeAppPasswordSessionService.ts new file mode 100644 index 00000000..971aaeba --- /dev/null +++ b/src/modules/atproto/infrastructure/services/FakeAppPasswordSessionService.ts @@ -0,0 +1,51 @@ +import { Result, ok, err } from 'src/shared/core/Result'; +import { IAppPasswordSessionService } from '../../application/IAppPasswordSessionService'; +import { AtpSessionData } from '@atproto/api'; + +export class FakeAppPasswordSessionService implements IAppPasswordSessionService { + async getSession(did: string): Promise> { + try { + // Use mock data from environment variables + const mockDid = process.env.BSKY_DID || 'did:plc:mock123'; + const mockHandle = process.env.BSKY_HANDLE || 'mock.bsky.social'; + const mockAccessToken = process.env.MOCK_ACCESS_TOKEN || 'mock-access-token-123'; + const mockRefreshToken = process.env.MOCK_REFRESH_TOKEN || 'mock-refresh-token-456'; + + const mockSession: AtpSessionData = { + did: mockDid, + handle: mockHandle, + accessJwt: mockAccessToken, + refreshJwt: mockRefreshToken, + }; + + return ok(mockSession); + } catch (error: any) { + return err(error); + } + } + + async createSession( + identifier: string, + appPassword: string, + ): Promise> { + try { + // Use mock data from environment variables + const mockDid = process.env.BSKY_DID || 'did:plc:mock123'; + const mockHandle = process.env.BSKY_HANDLE || 'mock.bsky.social'; + const mockAccessToken = process.env.MOCK_ACCESS_TOKEN || 'mock-access-token-123'; + const mockRefreshToken = process.env.MOCK_REFRESH_TOKEN || 'mock-refresh-token-456'; + + // Simulate successful session creation with any identifier/password + const mockSession: AtpSessionData = { + did: mockDid, + handle: mockHandle, + accessJwt: mockAccessToken, + refreshJwt: mockRefreshToken, + }; + + return ok(mockSession); + } catch (error: any) { + return err(error); + } + } +} diff --git a/src/modules/atproto/infrastructure/services/FakeAtProtoOAuthProcessor.ts b/src/modules/atproto/infrastructure/services/FakeAtProtoOAuthProcessor.ts new file mode 100644 index 00000000..53a5234f --- /dev/null +++ b/src/modules/atproto/infrastructure/services/FakeAtProtoOAuthProcessor.ts @@ -0,0 +1,34 @@ +import { Result, err, ok } from 'src/shared/core/Result'; +import { + IOAuthProcessor, + AuthResult, +} from '../../../user/application/services/IOAuthProcessor'; +import { OAuthCallbackDTO } from '../../../user/application/dtos/OAuthCallbackDTO'; + +export class FakeAtProtoOAuthProcessor implements IOAuthProcessor { + async generateAuthUrl(handle?: string): Promise> { + try { + // Return a mock auth URL + const mockUrl = `https://mock-oauth.example.com/auth?handle=${handle || 'mock'}`; + return ok(mockUrl); + } catch (error: any) { + return err(error); + } + } + + async processCallback(params: OAuthCallbackDTO): Promise> { + try { + // Use mock data from environment variables + const mockDid = process.env.BSKY_DID || 'did:plc:mock123'; + const mockHandle = process.env.BSKY_HANDLE || 'mock.bsky.social'; + + // Simulate successful OAuth callback processing + return ok({ + did: mockDid, + handle: mockHandle, + }); + } catch (error: any) { + return err(error); + } + } +} diff --git a/src/modules/atproto/infrastructure/services/FakeAtpAppPasswordProcessor.ts b/src/modules/atproto/infrastructure/services/FakeAtpAppPasswordProcessor.ts new file mode 100644 index 00000000..a81a8797 --- /dev/null +++ b/src/modules/atproto/infrastructure/services/FakeAtpAppPasswordProcessor.ts @@ -0,0 +1,24 @@ +import { ok, Result, err } from 'src/shared/core/Result'; +import { IAppPasswordProcessor } from '../../application/IAppPasswordProcessor'; +import { AuthResult } from 'src/modules/user/application/services/IOAuthProcessor'; + +export class FakeAtpAppPasswordProcessor implements IAppPasswordProcessor { + async processAppPassword( + identifier: string, + appPassword: string, + ): Promise> { + try { + // Use mock data from environment variables + const mockDid = process.env.BSKY_DID || 'did:plc:mock123'; + const mockHandle = process.env.BSKY_HANDLE || 'mock.bsky.social'; + + // Simulate successful authentication with any identifier/password + return ok({ + did: mockDid, + handle: mockHandle, + }); + } catch (error: any) { + return err(error); + } + } +} diff --git a/src/modules/atproto/infrastructure/services/FakeBlueskyProfileService.ts b/src/modules/atproto/infrastructure/services/FakeBlueskyProfileService.ts new file mode 100644 index 00000000..2a9619bc --- /dev/null +++ b/src/modules/atproto/infrastructure/services/FakeBlueskyProfileService.ts @@ -0,0 +1,32 @@ +import { + IProfileService, + UserProfile, +} from 'src/modules/cards/domain/services/IProfileService'; +import { Result, ok, err } from 'src/shared/core/Result'; + +export class FakeBlueskyProfileService implements IProfileService { + async getProfile(userId: string): Promise> { + try { + // Use mock data from environment variables + const mockHandle = process.env.BSKY_HANDLE || 'mock.bsky.social'; + const mockDid = process.env.BSKY_DID || 'did:plc:mock123'; + + // Return mock profile data + const userProfile: UserProfile = { + id: userId, + name: `Mock User (${mockHandle})`, + handle: mockHandle, + avatarUrl: 'https://via.placeholder.com/150', + bio: 'This is a mock profile for testing purposes', + }; + + return ok(userProfile); + } catch (error) { + return err( + new Error( + `Error fetching mock profile: ${error instanceof Error ? error.message : String(error)}`, + ), + ); + } + } +} diff --git a/src/modules/user/infrastructure/services/FakeJwtTokenService.ts b/src/modules/user/infrastructure/services/FakeJwtTokenService.ts new file mode 100644 index 00000000..0f70e1e6 --- /dev/null +++ b/src/modules/user/infrastructure/services/FakeJwtTokenService.ts @@ -0,0 +1,68 @@ +import { Result, ok, err } from 'src/shared/core/Result'; +import { ITokenService, TokenPair } from '../../application/services/ITokenService'; +import { ITokenRepository } from '../../domain/repositories/ITokenRepository'; + +export class FakeJwtTokenService implements ITokenService { + constructor(private tokenRepository: ITokenRepository) {} + + async generateToken(did: string): Promise> { + try { + // Use mock tokens from environment variables + const mockAccessToken = process.env.MOCK_ACCESS_TOKEN || 'mock-access-token-123'; + const mockRefreshToken = process.env.MOCK_REFRESH_TOKEN || 'mock-refresh-token-456'; + + return ok({ + accessToken: mockAccessToken, + refreshToken: mockRefreshToken, + }); + } catch (error: any) { + return err(error); + } + } + + async validateToken(token: string): Promise> { + try { + // Use mock data from environment variables + const mockAccessToken = process.env.MOCK_ACCESS_TOKEN || 'mock-access-token-123'; + const mockDid = process.env.BSKY_DID || 'did:plc:mock123'; + + // Return mock DID if token matches mock token + if (token === mockAccessToken) { + return ok(mockDid); + } + + return ok(null); + } catch (error: any) { + return err(error); + } + } + + async refreshToken(refreshToken: string): Promise> { + try { + // Use mock tokens from environment variables + const mockRefreshToken = process.env.MOCK_REFRESH_TOKEN || 'mock-refresh-token-456'; + const mockAccessToken = process.env.MOCK_ACCESS_TOKEN || 'mock-access-token-123'; + + // Return new tokens if refresh token matches mock token + if (refreshToken === mockRefreshToken) { + return ok({ + accessToken: mockAccessToken, + refreshToken: mockRefreshToken, + }); + } + + return ok(null); + } catch (error: any) { + return err(error); + } + } + + async revokeToken(refreshToken: string): Promise> { + try { + // Mock token revocation - always succeeds + return ok(undefined); + } catch (error: any) { + return err(error); + } + } +} diff --git a/src/modules/user/infrastructure/services/FakeUserAuthenticationService.ts b/src/modules/user/infrastructure/services/FakeUserAuthenticationService.ts new file mode 100644 index 00000000..2ee6e564 --- /dev/null +++ b/src/modules/user/infrastructure/services/FakeUserAuthenticationService.ts @@ -0,0 +1,66 @@ +import { Result, err, ok } from 'src/shared/core/Result'; +import { IUserRepository } from '../../domain/repositories/IUserRepository'; +import { + IUserAuthenticationService, + AuthenticationResult, +} from '../../domain/services/IUserAuthenticationService'; +import { DID } from '../../domain/value-objects/DID'; +import { Handle } from '../../domain/value-objects/Handle'; +import { User } from '../../domain/User'; + +export class FakeUserAuthenticationService implements IUserAuthenticationService { + constructor(private userRepository: IUserRepository) {} + + async validateUserCredentials( + did: DID, + handle?: Handle, + ): Promise> { + try { + // Use mock data from environment variables + const mockDid = process.env.BSKY_DID || 'did:plc:mock123'; + const mockHandle = process.env.BSKY_HANDLE || 'mock.bsky.social'; + + // Create mock DID and Handle + const mockDIDResult = DID.create(mockDid); + if (mockDIDResult.isErr()) { + return err(mockDIDResult.error); + } + + const mockHandleResult = Handle.create(mockHandle); + if (mockHandleResult.isErr()) { + return err(mockHandleResult.error); + } + + // Try to find existing user + const userResult = await this.userRepository.findByDID(mockDIDResult.value); + + if (userResult.isErr()) { + return err(userResult.error); + } + + const existingUser = userResult.value; + + // If user exists, return it + if (existingUser) { + return ok({ + user: existingUser, + isNewUser: false, + }); + } + + // Create new user with mock data + const newUserResult = User.createNew(mockDIDResult.value, mockHandleResult.value); + + if (newUserResult.isErr()) { + return err(newUserResult.error); + } + + return ok({ + user: newUserResult.value, + isNewUser: true, + }); + } catch (error: any) { + return err(error); + } + } +}