From 4949b8ce8b8212706f1fbcb16fab6f16fde50cf4 Mon Sep 17 00:00:00 2001 From: Steve Date: Thu, 05 Feb 2026 03:49:56 +0000 Subject: [PATCH] chore: cleaned up remaining auth implementations --- packages/cli/src/commands/init.ts | 5 +++-- packages/cli/src/commands/publish.ts | 7 +++++-- packages/cli/src/commands/sync.ts | 7 +++++-- packages/cli/src/commands/update.ts | 65 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++----- packages/cli/src/lib/credential-select.ts | 1 - packages/cli/src/lib/credentials.ts | 3 --- packages/cli/src/lib/types.ts | 2 +- 7 file(s) changed, 74 insertion(s)(+), 16 deletion(s)(-) diff --git a/packages/cli/src/commands/init.ts b/packages/cli/src/commands/init.ts --- a/packages/cli/src/commands/init.ts +++ b/packages/cli/src/commands/init.ts @@ -325,8 +325,9 @@ }; } - // Get PDS URL from credentials (already loaded earlier) - const pdsUrl = credentials?.pdsUrl; + // Get PDS URL from credentials (only available for app-password auth) + const pdsUrl = + credentials?.type === "app-password" ? credentials.pdsUrl : undefined; // Generate config file const configContent = generateConfigTemplate({ diff --git a/packages/cli/src/commands/publish.ts b/packages/cli/src/commands/publish.ts --- a/packages/cli/src/commands/publish.ts +++ b/packages/cli/src/commands/publish.ts @@ -107,7 +107,6 @@ type: "oauth", did: selected, handle: handle || selected, - pdsUrl: "https://bsky.social", }; } } else { @@ -246,7 +245,11 @@ } // Create agent - s.start(`Connecting to ${credentials.pdsUrl}...`); + const connectingTo = + credentials.type === "oauth" + ? credentials.handle + : credentials.pdsUrl; + s.start(`Connecting as ${connectingTo}...`); let agent: Awaited> | undefined; try { agent = await createAgent(credentials); diff --git a/packages/cli/src/commands/sync.ts b/packages/cli/src/commands/sync.ts --- a/packages/cli/src/commands/sync.ts +++ b/packages/cli/src/commands/sync.ts @@ -93,7 +93,6 @@ type: "oauth", did: selected, handle: handle || selected, - pdsUrl: "https://bsky.social", }; } } else { @@ -108,7 +107,11 @@ // Create agent const s = spinner(); - s.start(`Connecting to ${credentials.pdsUrl}...`); + const connectingTo = + credentials.type === "oauth" + ? credentials.handle + : credentials.pdsUrl; + s.start(`Connecting as ${connectingTo}...`); let agent: Awaited> | undefined; try { agent = await createAgent(credentials); diff --git a/packages/cli/src/commands/update.ts b/packages/cli/src/commands/update.ts --- a/packages/cli/src/commands/update.ts +++ b/packages/cli/src/commands/update.ts @@ -11,7 +11,12 @@ log, } from "@clack/prompts"; import { findConfig, loadConfig, generateConfigTemplate } from "../lib/config"; -import { loadCredentials } from "../lib/credentials"; +import { + loadCredentials, + listAllCredentials, + getCredentials, +} from "../lib/credentials"; +import { getOAuthHandle, getOAuthSession } from "../lib/oauth-store"; import { createAgent, getPublication, updatePublication } from "../lib/atproto"; import { exitOnCancel } from "../lib/prompts"; import type { @@ -438,12 +443,62 @@ async function updatePublicationFlow(config: PublisherConfig): Promise { // Load credentials - const credentials = await loadCredentials(config.identity); + let credentials = await loadCredentials(config.identity); + if (!credentials) { - log.error( - "No credentials found. Run 'sequoia auth' or 'sequoia login' first.", + const identities = await listAllCredentials(); + if (identities.length === 0) { + log.error( + "No credentials found. Run 'sequoia login' or 'sequoia auth' first.", + ); + process.exit(1); + } + + // Build labels with handles for OAuth sessions + const options = await Promise.all( + identities.map(async (cred) => { + if (cred.type === "oauth") { + const handle = await getOAuthHandle(cred.id); + return { + value: cred.id, + label: `${handle || cred.id} (OAuth)`, + }; + } + return { + value: cred.id, + label: `${cred.id} (App Password)`, + }; + }), ); - process.exit(1); + + log.info("Multiple identities found. Select one to use:"); + const selected = exitOnCancel( + await select({ + message: "Identity:", + options, + }), + ); + + // Load the selected credentials + const selectedCred = identities.find((c) => c.id === selected); + if (selectedCred?.type === "oauth") { + const session = await getOAuthSession(selected); + if (session) { + const handle = await getOAuthHandle(selected); + credentials = { + type: "oauth", + did: selected, + handle: handle || selected, + }; + } + } else { + credentials = await getCredentials(selected); + } + + if (!credentials) { + log.error("Failed to load selected credentials."); + process.exit(1); + } } const s = spinner(); diff --git a/packages/cli/src/lib/credential-select.ts b/packages/cli/src/lib/credential-select.ts --- a/packages/cli/src/lib/credential-select.ts +++ b/packages/cli/src/lib/credential-select.ts @@ -41,7 +41,6 @@ type: "oauth", did: selected.id, handle: handle || selected.id, - pdsUrl: "https://bsky.social", }; } } else { diff --git a/packages/cli/src/lib/credentials.ts b/packages/cli/src/lib/credentials.ts --- a/packages/cli/src/lib/credentials.ts +++ b/packages/cli/src/lib/credentials.ts @@ -96,7 +96,6 @@ type: "oauth", did: profile, handle: handle || profile, - pdsUrl: "https://bsky.social", // Will be resolved from DID doc }; } } @@ -109,7 +108,6 @@ type: "oauth", did: match.did, handle: match.handle || match.did, - pdsUrl: "https://bsky.social", }; } @@ -186,7 +184,6 @@ type: "oauth", did: oauthDids[0], handle: handle || oauthDids[0], - pdsUrl: "https://bsky.social", }; } } diff --git a/packages/cli/src/lib/types.ts b/packages/cli/src/lib/types.ts --- a/packages/cli/src/lib/types.ts +++ b/packages/cli/src/lib/types.ts @@ -54,11 +54,11 @@ } // OAuth credentials (references stored OAuth session) +// Note: pdsUrl is not needed for OAuth - the OAuth client resolves PDS from the DID export interface OAuthCredentials { type: "oauth"; did: string; handle: string; - pdsUrl: string; } // Union type for all credential types -- tangled.sh