Small refactors and better handling of multiple identities in functions that require auth
+3
-2
packages/cli/src/commands/init.ts
+3
-2
packages/cli/src/commands/init.ts
···
325
325
};
326
326
}
327
327
328
-
// Get PDS URL from credentials (already loaded earlier)
329
-
const pdsUrl = credentials?.pdsUrl;
328
+
// Get PDS URL from credentials (only available for app-password auth)
329
+
const pdsUrl =
330
+
credentials?.type === "app-password" ? credentials.pdsUrl : undefined;
330
331
331
332
// Generate config file
332
333
const configContent = generateConfigTemplate({
+3
-2
packages/cli/src/commands/publish.ts
+3
-2
packages/cli/src/commands/publish.ts
···
107
107
type: "oauth",
108
108
did: selected,
109
109
handle: handle || selected,
110
-
pdsUrl: "https://bsky.social",
111
110
};
112
111
}
113
112
} else {
···
246
245
}
247
246
248
247
// Create agent
249
-
s.start(`Connecting to ${credentials.pdsUrl}...`);
248
+
const connectingTo =
249
+
credentials.type === "oauth" ? credentials.handle : credentials.pdsUrl;
250
+
s.start(`Connecting as ${connectingTo}...`);
250
251
let agent: Awaited<ReturnType<typeof createAgent>> | undefined;
251
252
try {
252
253
agent = await createAgent(credentials);
+3
-2
packages/cli/src/commands/sync.ts
+3
-2
packages/cli/src/commands/sync.ts
···
93
93
type: "oauth",
94
94
did: selected,
95
95
handle: handle || selected,
96
-
pdsUrl: "https://bsky.social",
97
96
};
98
97
}
99
98
} else {
···
108
107
109
108
// Create agent
110
109
const s = spinner();
111
-
s.start(`Connecting to ${credentials.pdsUrl}...`);
110
+
const connectingTo =
111
+
credentials.type === "oauth" ? credentials.handle : credentials.pdsUrl;
112
+
s.start(`Connecting as ${connectingTo}...`);
112
113
let agent: Awaited<ReturnType<typeof createAgent>> | undefined;
113
114
try {
114
115
agent = await createAgent(credentials);
+60
-5
packages/cli/src/commands/update.ts
+60
-5
packages/cli/src/commands/update.ts
···
11
11
log,
12
12
} from "@clack/prompts";
13
13
import { findConfig, loadConfig, generateConfigTemplate } from "../lib/config";
14
-
import { loadCredentials } from "../lib/credentials";
14
+
import {
15
+
loadCredentials,
16
+
listAllCredentials,
17
+
getCredentials,
18
+
} from "../lib/credentials";
19
+
import { getOAuthHandle, getOAuthSession } from "../lib/oauth-store";
15
20
import { createAgent, getPublication, updatePublication } from "../lib/atproto";
16
21
import { exitOnCancel } from "../lib/prompts";
17
22
import type {
···
438
443
439
444
async function updatePublicationFlow(config: PublisherConfig): Promise<void> {
440
445
// Load credentials
441
-
const credentials = await loadCredentials(config.identity);
446
+
let credentials = await loadCredentials(config.identity);
447
+
442
448
if (!credentials) {
443
-
log.error(
444
-
"No credentials found. Run 'sequoia auth' or 'sequoia login' first.",
449
+
const identities = await listAllCredentials();
450
+
if (identities.length === 0) {
451
+
log.error(
452
+
"No credentials found. Run 'sequoia login' or 'sequoia auth' first.",
453
+
);
454
+
process.exit(1);
455
+
}
456
+
457
+
// Build labels with handles for OAuth sessions
458
+
const options = await Promise.all(
459
+
identities.map(async (cred) => {
460
+
if (cred.type === "oauth") {
461
+
const handle = await getOAuthHandle(cred.id);
462
+
return {
463
+
value: cred.id,
464
+
label: `${handle || cred.id} (OAuth)`,
465
+
};
466
+
}
467
+
return {
468
+
value: cred.id,
469
+
label: `${cred.id} (App Password)`,
470
+
};
471
+
}),
445
472
);
446
-
process.exit(1);
473
+
474
+
log.info("Multiple identities found. Select one to use:");
475
+
const selected = exitOnCancel(
476
+
await select({
477
+
message: "Identity:",
478
+
options,
479
+
}),
480
+
);
481
+
482
+
// Load the selected credentials
483
+
const selectedCred = identities.find((c) => c.id === selected);
484
+
if (selectedCred?.type === "oauth") {
485
+
const session = await getOAuthSession(selected);
486
+
if (session) {
487
+
const handle = await getOAuthHandle(selected);
488
+
credentials = {
489
+
type: "oauth",
490
+
did: selected,
491
+
handle: handle || selected,
492
+
};
493
+
}
494
+
} else {
495
+
credentials = await getCredentials(selected);
496
+
}
497
+
498
+
if (!credentials) {
499
+
log.error("Failed to load selected credentials.");
500
+
process.exit(1);
501
+
}
447
502
}
448
503
449
504
const s = spinner();
-1
packages/cli/src/lib/credential-select.ts
-1
packages/cli/src/lib/credential-select.ts
-3
packages/cli/src/lib/credentials.ts
-3
packages/cli/src/lib/credentials.ts
···
96
96
type: "oauth",
97
97
did: profile,
98
98
handle: handle || profile,
99
-
pdsUrl: "https://bsky.social", // Will be resolved from DID doc
100
99
};
101
100
}
102
101
}
···
109
108
type: "oauth",
110
109
did: match.did,
111
110
handle: match.handle || match.did,
112
-
pdsUrl: "https://bsky.social",
113
111
};
114
112
}
115
113
···
186
184
type: "oauth",
187
185
did: oauthDids[0],
188
186
handle: handle || oauthDids[0],
189
-
pdsUrl: "https://bsky.social",
190
187
};
191
188
}
192
189
}
+1
-1
packages/cli/src/lib/types.ts
+1
-1
packages/cli/src/lib/types.ts
···
54
54
}
55
55
56
56
// OAuth credentials (references stored OAuth session)
57
+
// Note: pdsUrl is not needed for OAuth - the OAuth client resolves PDS from the DID
57
58
export interface OAuthCredentials {
58
59
type: "oauth";
59
60
did: string;
60
61
handle: string;
61
-
pdsUrl: string;
62
62
}
63
63
64
64
// Union type for all credential types
History
2 rounds
0 comments
stevedylan.dev
submitted
#1
expand 0 comments
pull request successfully merged
stevedylan.dev
submitted
#0
1 commit
expand
collapse
chore: cleaned up remaining auth implementations