Skip to content

Commit 60a0c2f

Browse files
crowlbotcrowlKats
andauthored
feat(whoami): consume account.me to populate user identity (#101)
The deployng `account.me` tRPC procedure has landed, so `deno deploy whoami` can now identify the principal behind the token rather than just listing reachable orgs. - Calls `account.me` in parallel with `orgs.list` (no extra round trip). - JSON output: `user` field is now populated for user-backed tokens (`{ id, name, email, avatarUrl, githubLogin }`) and `null` for org-scoped (`ddo_`) tokens. A new `tokenType` field carries the raw token type from the backend in both cases. - Human output: the "Authenticated" line now names the principal (`@github-login`, falling back to email/name/id, or `org-scoped token (...)` for non-user tokens). Existing agent consumers reading `authenticated` and `orgs[]` keep working; only added fields. Co-authored-by: Leo Kettmeir <crowlkats@toaxl.com>
1 parent 8dfef34 commit 60a0c2f

1 file changed

Lines changed: 25 additions & 7 deletions

File tree

deploy/mod.ts

Lines changed: 25 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -246,6 +246,17 @@ interface WhoamiOrg {
246246
plan: string | null;
247247
}
248248

249+
interface AccountMe {
250+
user: {
251+
id: string;
252+
name: string | null;
253+
email: string | null;
254+
avatarUrl: string | null;
255+
githubLogin: string | null;
256+
} | null;
257+
tokenType: string;
258+
}
259+
249260
const whoamiCommand = new Command<GlobalContext>()
250261
.description(
251262
"Verify the current Deno Deploy token and list reachable organizations",
@@ -260,16 +271,16 @@ const whoamiCommand = new Command<GlobalContext>()
260271
// AUTH_INVALID_TOKEN envelope from the errorLink if the token is bad,
261272
// without ever calling `requireInteractive()` or opening a browser.
262273
const trpcClient = createTrpcClient(options);
263-
const orgs = await trpcClient.query("orgs.list") as WhoamiOrg[];
274+
const [me, orgs] = await Promise.all([
275+
trpcClient.query("account.me") as Promise<AccountMe>,
276+
trpcClient.query("orgs.list") as Promise<WhoamiOrg[]>,
277+
]);
264278

265279
if (options.json) {
266280
writeJsonResult({
267281
authenticated: true,
268-
// The deployng tRPC router does not currently expose user identity,
269-
// so we surface what we can (orgs the token can reach). When that
270-
// procedure lands, this output will gain a `user` field; existing
271-
// consumers reading `authenticated` / `orgs[]` keep working.
272-
user: null,
282+
user: me.user,
283+
tokenType: me.tokenType,
273284
orgs: orgs.map((org) => ({
274285
id: org.id,
275286
slug: org.slug,
@@ -280,8 +291,15 @@ const whoamiCommand = new Command<GlobalContext>()
280291
return;
281292
}
282293

294+
const who = me.user
295+
? (me.user.githubLogin
296+
? `@${me.user.githubLogin}`
297+
: me.user.email ?? me.user.name ?? me.user.id)
298+
: `org-scoped token (${me.tokenType})`;
283299
console.log(
284-
`${green("✔")} Authenticated. ${orgs.length} reachable organization${
300+
`${
301+
green("✔")
302+
} Authenticated as ${who}. ${orgs.length} reachable organization${
285303
orgs.length === 1 ? "" : "s"
286304
}:`,
287305
);

0 commit comments

Comments
 (0)