import type { KeyObject } from 'node:crypto'; import type { Client as PlcClient } from '@did-plc/lib'; import type { Keypair } from '@atproto/crypto'; import type { IdResolver } from '@atproto/identity'; import { type AtIdentifierString, type DidString, type HandleString } from '@atproto/lex'; import type { Cid } from '@atproto/lex-data'; import { AuthRequiredError } from '@atproto/xrpc-server'; import type { ActorStore } from '../actor-store/actor-store.js'; import type { ServerConfig } from '../config/config.js'; import type { com } from '../lexicons/index.js'; import type { ServerMailer } from '../mailer/index.js'; import type { Sequencer } from '../sequencer/index.js'; import { type AccountDb, type EmailTokenPurpose } from './db/index.js'; import * as accountHelpers from './helpers/account.js'; import { AccountStatus, type ActorAccount } from './helpers/account.js'; import * as password from './helpers/password.js'; export { AccountStatus, formatAccountStatus } from './helpers/account.js'; /** * Thrown by {@link AccountManager.login} when the identifier resolved to a * known account but the supplied credentials (account password / app * password) did not match. The matched `did` is attached so downstream * callers can distinguish "identifier known, credentials wrong" from * "identifier unknown" (which continues to throw a plain * {@link AuthRequiredError}). * * Callers should take care that remote clients *cannot* distinguish the above, * to prevent enumeration attacks. (Tested for in * packages/pds/tests/auth.test.ts) */ export declare class InvalidPasswordError extends AuthRequiredError { readonly did: DidString; constructor(did: DidString, errorMessage?: string); } export type AccountManagerDbConfig = { accountDbLoc: string; disableWalAutoCheckpoint: boolean; }; export declare class AccountManager { readonly cfg: ServerConfig; readonly actorStore: ActorStore; readonly idResolver: IdResolver; readonly jwtKey: KeyObject; readonly mailer: ServerMailer; readonly sequencer: Sequencer; readonly plcClient: PlcClient; readonly plcRotationKey: Keypair; readonly db: AccountDb; constructor(cfg: ServerConfig, actorStore: ActorStore, idResolver: IdResolver, jwtKey: KeyObject, mailer: ServerMailer, sequencer: Sequencer, plcClient: PlcClient, plcRotationKey: Keypair); get serviceDid(): DidString; get serviceHandleDomains(): string[]; migrateOrThrow(): Promise; close(): void; getAccount(handleOrDid: AtIdentifierString, flags?: accountHelpers.AvailabilityFlags): Promise; getAccounts(dids: DidString[], flags?: accountHelpers.AvailabilityFlags): Promise>; getAccountByEmail(email: string, flags?: accountHelpers.AvailabilityFlags): Promise; isAccountActivated(did: DidString): Promise; getDidForActor(handleOrDid: AtIdentifierString, flags?: accountHelpers.AvailabilityFlags): Promise; getAccountStatus(handleOrDid: AtIdentifierString): Promise<{ status: AccountStatus.Deleted; account: null; } | { status: AccountStatus.Takendown; account: ActorAccount; } | { status: AccountStatus.Deactivated; account: ActorAccount; } | { status: AccountStatus.Active; account: ActorAccount; }>; normalizeAndValidateHandle(handle: string, { did, allowAnyValid, }?: { did?: string; allowAnyValid?: boolean; }): Promise; createAccount({ did, handle, email, password, repoCid, repoRev, inviteCode, deactivated, refreshJwt, }: { did: DidString; handle: HandleString; email?: string; password?: string; repoCid: Cid; repoRev: string; inviteCode?: string; deactivated?: boolean; refreshJwt?: string; }): Promise; createAccountAndSession(opts: { did: DidString; handle: HandleString; email?: string; password?: string; repoCid: Cid; repoRev: string; inviteCode?: string; deactivated?: boolean; }): Promise<{ accessJwt: string; refreshJwt: string; }>; /** * Validates the requested handle, updates the PLC document if needed, persists * the new handle locally, and emits an identity event. * * @throws {InvalidRequestError} when the handle is invalid, taken by another * account, or cannot be resolved for non-service domains. * * @see {@link AccountManager.updateAccountHandle} for behavior when the PLC update fails. */ updateHandle(did: DidString, newHandle: string, options?: { allowAnyValid?: boolean; }): Promise; validateHandleUpdate(did: DidString, newHandle: string, options?: { allowAnyValid?: boolean; }): Promise<{ did: DidString; handle: HandleString; account: ActorAccount; }>; /** * @note Failure to emit the identity event will silently be ignored. Users * can emit the event again by updating their handle to the same value. */ updateAccountHandle(did: DidString, handle: HandleString): Promise; deleteAccount(did: DidString): Promise; takedownAccount(did: DidString, takedown: com.atproto.admin.defs.StatusAttr): Promise; getAccountAdminStatus(did: DidString): Promise<{ takedown: com.atproto.admin.defs.StatusAttr; deactivated: com.atproto.admin.defs.StatusAttr; } | null>; updateRepoRoot(did: DidString, cid: Cid, rev: string): Promise; deactivateAccount(did: DidString, options?: { deleteCredentials?: boolean; deleteAfter?: string | null; }): Promise<{ status: AccountStatus.Takendown; account: ActorAccount; } | { status: AccountStatus.Deactivated; account: ActorAccount; } | { status: AccountStatus.Active; account: ActorAccount; }>; activateAccount(did: DidString): Promise<{ status: AccountStatus.Takendown; account: ActorAccount; } | { status: AccountStatus.Deactivated; account: ActorAccount; } | { status: AccountStatus.Active; account: ActorAccount; }>; sequenceAccountStatus(did: DidString): Promise; createSession(did: DidString, appPassword: password.AppPassDescript | null, isSoftDeleted?: boolean): Promise<{ accessJwt: string; refreshJwt: string; }>; rotateRefreshToken(id: string): any; revokeRefreshToken(id: string): Promise; login({ identifier, password, }: { identifier: string; password: string; }): Promise<{ user: ActorAccount; appPassword: password.AppPassDescript | null; isSoftDeleted: boolean; }>; createAppPassword(did: DidString, name: string, privileged: boolean): Promise; listAppPasswords(did: DidString): Promise<{ name: string; createdAt: import("@atproto/lex").DatetimeString; privileged: boolean; }[]>; verifyAccountPassword(did: DidString, passwordStr: string): Promise; verifyAppPassword(did: DidString, passwordStr: string): Promise; revokeAppPassword(did: DidString, name: string): Promise; ensureInviteIsAvailable(code: string): Promise; createInviteCodes(toCreate: { account: string; codes: string[]; }[], useCount: number): Promise; createAccountInviteCodes(forAccount: string, codes: string[], expectedTotal: number, disabled: 0 | 1): Promise; getAccountInvitesCodes(did: DidString): Promise; getAccountsInvitesCodes(dids: DidString[]): Promise>; getInvitedByForAccounts(dids: DidString[]): Promise>; getInviteCodesUses(codes: string[]): Promise>; setAccountInvitesDisabled(did: DidString, disabled: boolean): Promise; disableInviteCodes(opts: { codes: string[]; accounts: string[]; }): Promise; createEmailToken(did: DidString, purpose: EmailTokenPurpose): Promise; assertValidEmailToken(did: DidString, purpose: EmailTokenPurpose, token: string): Promise; assertValidEmailTokenAndCleanup(did: DidString, purpose: EmailTokenPurpose, token: string): Promise; requestEmailConfirmation(did: DidString, opts?: { locale?: string; }): Promise; confirmEmail(did: DidString, email: string, token: string): Promise; requestEmailUpdate(did: DidString, opts?: { locale?: string; }): Promise<{ tokenRequired: boolean; }>; /** * @throws UserAlreadyExistsError if the new email is already in use by another account */ updateEmail(did: DidString, email: string, token?: string, opts?: { locale?: string; sendConfirmationEmail?: boolean; }): Promise; updateAccountEmail(opts: { did: DidString; email: string; }): Promise; resetPassword(opts: { password: string; token: string; }): Promise<`did:${string}:${string}`>; updateAccountPassword(opts: { did: DidString; password: string; }): Promise; } //# sourceMappingURL=account-manager.d.ts.map