From 9a6871cd66f799c310ad7488ff7fda0e1014e66d Mon Sep 17 00:00:00 2001 From: Wesley Finck Date: Fri, 4 Jul 2025 11:00:19 -0700 Subject: [PATCH] update app password processor and service to create a session --- .../application/IAppPasswordProcessor.ts | 9 ++++ .../application/IAppPasswordSessionService.ts | 10 +++++ .../services/AppPasswordSessionService.ts | 44 ++++++++++++++++++- .../services/AtpAppPasswordProcessor.ts | 24 ++++++++++ 4 files changed, 86 insertions(+), 1 deletion(-) create mode 100644 src/modules/atproto/application/IAppPasswordProcessor.ts create mode 100644 src/modules/atproto/application/IAppPasswordSessionService.ts create mode 100644 src/modules/atproto/infrastructure/services/AtpAppPasswordProcessor.ts diff --git a/src/modules/atproto/application/IAppPasswordProcessor.ts b/src/modules/atproto/application/IAppPasswordProcessor.ts new file mode 100644 index 00000000..a0635b4a --- /dev/null +++ b/src/modules/atproto/application/IAppPasswordProcessor.ts @@ -0,0 +1,9 @@ +import { AuthResult } from "src/modules/user/application/services/IOAuthProcessor"; +import { Result } from "src/shared/core/Result"; + +export interface IAppPasswordProcessor { + processAppPassword( + identifier: string, + appPassword: string + ): Promise>; +} diff --git a/src/modules/atproto/application/IAppPasswordSessionService.ts b/src/modules/atproto/application/IAppPasswordSessionService.ts new file mode 100644 index 00000000..9f4b474c --- /dev/null +++ b/src/modules/atproto/application/IAppPasswordSessionService.ts @@ -0,0 +1,10 @@ +import { AtpSessionData } from "@atproto/api"; +import { Result } from "src/shared/core/Result"; + +export interface IAppPasswordSessionService { + getSession(did: string): Promise>; + createSession( + identifier: string, + appPassword: string + ): Promise>; +} diff --git a/src/modules/atproto/infrastructure/services/AppPasswordSessionService.ts b/src/modules/atproto/infrastructure/services/AppPasswordSessionService.ts index bb234d28..3c728c11 100644 --- a/src/modules/atproto/infrastructure/services/AppPasswordSessionService.ts +++ b/src/modules/atproto/infrastructure/services/AppPasswordSessionService.ts @@ -1,8 +1,9 @@ import { err, ok, Result } from "src/shared/core/Result"; import { IAppPasswordSessionRepository } from "../repositories/IAppPasswordSessionRepository"; import { AtpAgent, AtpSessionData } from "@atproto/api"; +import { IAppPasswordSessionService } from "../../application/IAppPasswordSessionService"; -export class AppPasswordSessionService { +export class AppPasswordSessionService implements IAppPasswordSessionService { constructor( private readonly appPasswordSessionRepository: IAppPasswordSessionRepository ) {} @@ -65,4 +66,45 @@ export class AppPasswordSessionService { } } } + async createSession( + identifier: string, + appPassword: string + ): Promise> { + const agent = new AtpAgent({ + service: "https://bsky.social", + }); + + try { + await agent.login({ + identifier, + password: appPassword, + }); + const session = agent.session; + if (!session) { + return err( + new Error(`Failed to create session for identifier: ${identifier}`) + ); + } + const saveResult = await this.appPasswordSessionRepository.saveSession( + session.did, + { session, appPassword } + ); + if (saveResult.isErr()) { + return err( + new Error( + `Failed to save session after login for identifier: ${identifier}, error: ${saveResult.error.message}` + ) + ); + } + return ok(session); + } catch (error) { + return err( + new Error( + `Failed to create session for identifier: ${identifier}, error: ${ + error instanceof Error ? error.message : String(error) + }` + ) + ); + } + } } diff --git a/src/modules/atproto/infrastructure/services/AtpAppPasswordProcessor.ts b/src/modules/atproto/infrastructure/services/AtpAppPasswordProcessor.ts new file mode 100644 index 00000000..fd2a443c --- /dev/null +++ b/src/modules/atproto/infrastructure/services/AtpAppPasswordProcessor.ts @@ -0,0 +1,24 @@ +import { ok, Result } from "src/shared/core/Result"; +import { IAppPasswordProcessor } from "../../application/IAppPasswordProcessor"; +import { AuthResult } from "src/modules/user/application/services/IOAuthProcessor"; +import { IAppPasswordSessionService } from "../../application/IAppPasswordSessionService"; + +export class AtpAppPasswordProcessor implements IAppPasswordProcessor { + constructor(private readonly sessionService: IAppPasswordSessionService) {} + async processAppPassword( + identifier: string, + appPassword: string + ): Promise> { + const result = await this.sessionService.createSession( + identifier, + appPassword + ); + if (result.isErr()) { + return result; + } + return ok({ + did: result.value.did, + handle: result.value.handle, + }); + } +} -- 2.51.2