Files
publisher-dashboard/apps/cli/src/routes/auth/status.ts
igm 67930d90d5 Simplify apps/cli/ code
- config.ts: Convert arrow functions to function declarations
- api-client.ts: Extract duplicated RPCLink logic into buildClient helper
- format-error.ts: Add centralized ORPCError handling
- complete-login.ts: Remove redundant error handling (now in formatError)
- status.ts: Simplify formatRelativeTime, improve whitespace
- create.ts: Rename validRoles to VALID_ROLES, add as const, early return
- completions.ts: Derive Shell type from SUPPORTED_SHELLS array

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-12 15:42:39 +08:00

116 lines
3.6 KiB
TypeScript

import type { LocalContext } from "../../context.js";
import { buildCommand } from "@stricli/core";
import { createApiClient } from "../../utils/api-client.js";
import { getConfigPath, readConfig } from "../../utils/config.js";
import { formatError } from "../../utils/format-error.js";
import { TOKEN_PREFIX } from "../../utils/token.js";
function formatDate(date: Date): string {
return date.toLocaleString();
}
function formatRelativeTime(date: Date): string {
const now = new Date();
const diffMs = date.getTime() - now.getTime();
const diffDays = Math.floor(diffMs / (1000 * 60 * 60 * 24));
if (diffDays < 0) {
return `${Math.abs(diffDays).toLocaleString()} days ago`;
}
if (diffDays === 0) {
const diffHours = Math.floor(diffMs / (1000 * 60 * 60));
return diffHours <= 0 ? "expired" : `in ${diffHours.toLocaleString()} hours`;
}
if (diffDays === 1) {
return "tomorrow";
}
return `in ${diffDays.toLocaleString()} days`;
}
async function status(this: LocalContext): Promise<void> {
const config = await readConfig();
if (!config) {
console.log("Not logged in");
console.log(`\nConfig file: ${getConfigPath()} (not found)`);
console.log(
"\nRun 'reviq bootstrap' to create a superuser or 'reviq auth login' to authenticate.",
);
return;
}
console.log("Authentication Status");
console.log("=====================\n");
// Show local config info
console.log("Local Configuration:");
console.log(` Config file: ${getConfigPath()}`);
console.log(` API URL: ${config.apiUrl}`);
// Show token format info
const hasNewFormat = config.token.startsWith(TOKEN_PREFIX);
console.log(
` Token format: ${hasNewFormat ? "reviq_<base58>" : "legacy (hex)"}`,
);
// Try to fetch status from API
console.log("\nAPI Status:");
try {
const api = await createApiClient();
const response = await api.me.authStatus();
// User info
console.log("\n User:");
console.log(` Email: ${response.user.email}`);
if (response.user.displayName) {
console.log(` Display name: ${response.user.displayName}`);
}
if (response.user.fullName) {
console.log(` Full name: ${response.user.fullName}`);
}
console.log(
` Email verified: ${response.user.emailVerified ? "yes" : "no"}`,
);
console.log(` Superuser: ${response.user.isSuperuser ? "yes" : "no"}`);
// Auth method info
if (response.auth.method === "api_token") {
console.log("\n API Token:");
console.log(` Name: ${response.auth.tokenName}`);
console.log(` Token ID: ${response.auth.tokenId}`);
console.log(` Created: ${formatDate(response.auth.createdAt)}`);
console.log(
` Expires: ${formatDate(response.auth.expiresAt)} (${formatRelativeTime(response.auth.expiresAt)})`,
);
if (response.auth.lastUsedAt) {
console.log(` Last used: ${formatDate(response.auth.lastUsedAt)}`);
}
} else {
console.log("\n Session:");
console.log(` Session ID: ${response.auth.sessionId}`);
console.log(` Created: ${formatDate(response.auth.createdAt)}`);
console.log(
` Expires: ${formatDate(response.auth.expiresAt)} (${formatRelativeTime(response.auth.expiresAt)})`,
);
}
} catch (error) {
console.log(` Error: ${formatError(error)}`);
console.log(
"\n Unable to connect to API. Local credentials may be invalid.",
);
}
}
export const statusCommand = buildCommand({
func: status,
parameters: {},
docs: {
brief: "Check authentication status",
fullDescription:
"Shows the current authentication status and config file location.",
},
});