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:
@@ -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}`
|
||||
}
|
||||
Reference in New Issue
Block a user