Add Nuxt MiniMax H3 relay studio for local ComfyUI.

Headless image-to-video UI queues jobs on the desktop ComfyUI instance with live SSE progress and Authentik SSO.
This commit is contained in:
2026-08-25 17:43:29 -05:00
commit 4c5c65db98
31 changed files with 12965 additions and 0 deletions
+85
View File
@@ -0,0 +1,85 @@
import { createHmac, randomBytes, timingSafeEqual } from 'node:crypto'
import type { H3Event } from 'h3'
export interface SessionUser {
sub: string
email?: string
name?: string
}
const COOKIE = 'aigen_session'
const STATE_COOKIE = 'aigen_oauth_state'
function secret() {
const config = useRuntimeConfig()
return config.sessionSecret || 'dev-only-change-me'
}
function sign(value: string) {
return createHmac('sha256', secret()).update(value).digest('base64url')
}
function seal(payload: unknown) {
const data = Buffer.from(JSON.stringify(payload)).toString('base64url')
return `${data}.${sign(data)}`
}
function unseal<T>(token: string | undefined): T | null {
if (!token || !token.includes('.')) return null
const [data, sig] = token.split('.')
const expected = sign(data)
const a = Buffer.from(sig)
const b = Buffer.from(expected)
if (a.length !== b.length || !timingSafeEqual(a, b)) return null
try {
return JSON.parse(Buffer.from(data, 'base64url').toString('utf8')) as T
} catch {
return null
}
}
function cookieOpts(event: H3Event) {
const proto = getRequestHeader(event, 'x-forwarded-proto') || getRequestProtocol(event)
return {
httpOnly: true,
sameSite: 'lax' as const,
path: '/',
secure: proto === 'https',
maxAge: 60 * 60 * 24 * 14
}
}
export function getSessionUser(event: H3Event): SessionUser | null {
return unseal<SessionUser>(getCookie(event, COOKIE))
}
export function setSessionUser(event: H3Event, user: SessionUser) {
setCookie(event, COOKIE, seal(user), cookieOpts(event))
}
export function clearAuthSession(event: H3Event) {
deleteCookie(event, COOKIE, { path: '/' })
}
export function createOauthState(event: H3Event) {
const state = randomBytes(24).toString('hex')
setCookie(event, STATE_COOKIE, state, { ...cookieOpts(event), maxAge: 600 })
return state
}
export function consumeOauthState(event: H3Event, incoming: string | undefined) {
const stored = getCookie(event, STATE_COOKIE)
deleteCookie(event, STATE_COOKIE, { path: '/' })
return Boolean(stored && incoming && stored === incoming)
}
export function authEnabled() {
const config = useRuntimeConfig()
return Boolean(config.public.authEnabled && config.oidcClientId && config.oidcClientSecret)
}
export function publicBaseUrl(event: H3Event) {
const proto = getRequestHeader(event, 'x-forwarded-proto') || getRequestProtocol(event)
const host = getRequestHeader(event, 'x-forwarded-host') || getRequestHost(event)
return `${proto}://${host}`
}