Add admin CLI command and auth guard, use oRPC client

CLI changes:
- Use official oRPC client instead of manual HTTP requests
- Add admin complete-login command for dev workflow
- Remove type assertions, use proper ContractRouterClient typing
- Add @orpc/client and @orpc/contract dependencies

API changes:
- Use oRPC cookie helpers from @orpc/server/helpers
- Improve admin complete-login error messages (expired, already completed)

Dashboard changes:
- Add AuthGuard component to redirect unauthenticated users to /auth/login
- Update confirm page with correct CLI command and copy button
- Remove duplicate auth redirect from dashboard layout

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
RevIQ
2026-01-09 19:12:19 +08:00
parent 60bcbeffb3
commit d66894e8dc
19 changed files with 220 additions and 188 deletions

View File

@@ -0,0 +1,51 @@
import type { LocalContext } from "../../context.js";
import { ORPCError } from "@orpc/client";
import { buildCommand } from "@stricli/core";
import { createApiClient } from "../../utils/api-client.js";
interface CompleteLoginFlags {
email: string;
}
async function completeLogin(
this: LocalContext,
flags: CompleteLoginFlags,
): Promise<void> {
try {
const api = await createApiClient();
await api.admin.auth.completeLogin({
email: flags.email,
});
console.log(`Completed login request for: ${flags.email}`);
} catch (error) {
if (error instanceof ORPCError) {
console.error(`Error [${error.code}]:`, error.message);
} else {
console.error(
"Error:",
error instanceof Error ? error.message : String(error),
);
}
this.process.exit(1);
}
}
export const completeLoginCommand = buildCommand({
func: completeLogin,
parameters: {
flags: {
email: {
kind: "parsed",
parse: String,
brief: "Email address of user with pending login request",
},
},
},
docs: {
brief: "Complete pending login request",
fullDescription:
"Completes the most recent pending login request for a user. This is useful for development when email sending is not configured or to bypass email confirmation.",
},
});