Add device-grant dev sign-in (CRD-driven) for local/agent development
Build and Publish / Metadata (push) Successful in 2s
Build and Publish / BuildAndDeployAmd64 (push) Successful in 58s

AuthClient dev-console + AuthServer deviceFlow via k8s/auth-dev.yaml; otel
server accepts its own URL as an extra audience (OTEL_OIDC_AUDIENCE). Vite
dev-only device-flow sign-in, scripts/dev-auth.mjs helper, AGENTS.md notes.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
matsandClaude Sonnet 5 committed 2026-09-19 09:08:46 +00:00
1 parent 0fde8a0f92
commit bd17837663
10 files changed
+305 -3

No files matched your search

+19 -2
View File
@@ -74,8 +74,25 @@ export async function ensureTokens(): Promise<Tokens | null> {
return refreshing;
}
// Dev-only hook (see src/dev/device-auth.ts): tokens obtained through the
// device grant must be refreshed through the device refresh endpoint.
type RefreshOverride = (refreshToken: string) => Promise<TokenResponse | null>;
let refreshOverride: RefreshOverride | null = null;
export function setRefreshOverride(fn: RefreshOverride | null) {
refreshOverride = fn;
}
async function doRefresh(t: Tokens): Promise<Tokens | null> {
try {
if (refreshOverride) {
const body = await refreshOverride(t.refreshToken!);
if (!body) {
localStorage.removeItem(TOKEN_KEY);
return null;
}
saveTokens(body, t.refreshToken);
return readTokens();
}
const res = await fetch("/api/auth/token", {
method: "POST",
headers: { "Content-Type": "application/x-www-form-urlencoded" },
@@ -97,14 +114,14 @@ async function doRefresh(t: Tokens): Promise<Tokens | null> {
}
}
interface TokenResponse {
export interface TokenResponse {
access_token: string;
id_token: string;
refresh_token?: string;
expires_in: number;
}
function saveTokens(body: TokenResponse, fallbackRefresh?: string) {
export function saveTokens(body: TokenResponse, fallbackRefresh?: string) {
if (typeof window === "undefined") return;
localStorage.setItem(
TOKEN_KEY,