Add a password-gated private instance mode for xaigen.
Keep Authentik on aigen, isolate library data per instance, and purge Comfy outputs from the desktop after they are saved on the server. Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
+54
-2
@@ -2,9 +2,32 @@
|
||||
<main class="min-h-screen flex items-center justify-center px-6">
|
||||
<section class="glass w-full max-w-md rounded-3xl p-10 text-center">
|
||||
<p class="text-amber-300/80 text-xs tracking-[0.3em] uppercase">Carr Garage</p>
|
||||
<h1 class="font-display text-4xl font-extrabold mt-3">AIGen</h1>
|
||||
<p class="mt-3 text-zinc-400">Headless MiniMax H3 image-to-video studio. Sign in with Authentik to reach the ComfyUI relay.</p>
|
||||
<h1 class="font-display text-4xl font-extrabold mt-3">{{ instanceName }}</h1>
|
||||
<p class="mt-3 text-zinc-400">
|
||||
{{ authMode === 'password'
|
||||
? 'Private MiniMax H3 studio. Sign in with the username and password for this instance.'
|
||||
: 'Headless MiniMax H3 image-to-video studio. Sign in with Authentik to reach the ComfyUI relay.' }}
|
||||
</p>
|
||||
<form v-if="authMode === 'password'" class="mt-8 space-y-3 text-left" @submit.prevent="submit">
|
||||
<label class="block text-sm">
|
||||
<span class="mb-1 block text-zinc-400">Username</span>
|
||||
<input v-model="username" class="w-full rounded-xl border border-white/10 bg-zinc-950 px-3 py-2 text-sm" autocomplete="username" required>
|
||||
</label>
|
||||
<label class="block text-sm">
|
||||
<span class="mb-1 block text-zinc-400">Password</span>
|
||||
<input v-model="password" type="password" class="w-full rounded-xl border border-white/10 bg-zinc-950 px-3 py-2 text-sm" autocomplete="current-password" required>
|
||||
</label>
|
||||
<p v-if="error" class="text-sm text-red-300">{{ error }}</p>
|
||||
<button
|
||||
type="submit"
|
||||
class="inline-flex w-full items-center justify-center rounded-2xl bg-amber-400 px-5 py-3 font-semibold text-zinc-950 hover:bg-amber-300 transition disabled:opacity-50"
|
||||
:disabled="busy"
|
||||
>
|
||||
{{ busy ? 'Signing in…' : 'Sign in' }}
|
||||
</button>
|
||||
</form>
|
||||
<a
|
||||
v-else
|
||||
href="/api/auth/login"
|
||||
class="mt-8 inline-flex w-full items-center justify-center rounded-2xl bg-amber-400 px-5 py-3 font-semibold text-zinc-950 hover:bg-amber-300 transition"
|
||||
>
|
||||
@@ -13,3 +36,32 @@
|
||||
</section>
|
||||
</main>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
const config = useRuntimeConfig()
|
||||
const instanceName = ref(String(config.public.instanceName || 'AIGen'))
|
||||
const authMode = ref(String(config.public.authMode || ''))
|
||||
const username = ref('')
|
||||
const password = ref('')
|
||||
const error = ref('')
|
||||
const busy = ref(false)
|
||||
|
||||
onMounted(async () => {
|
||||
const me = await $fetch<{ authMode?: string; instanceName?: string }>('/api/auth/me').catch(() => ({}))
|
||||
if (me.authMode) authMode.value = me.authMode
|
||||
if (me.instanceName) instanceName.value = me.instanceName
|
||||
})
|
||||
|
||||
async function submit() {
|
||||
busy.value = true
|
||||
error.value = ''
|
||||
try {
|
||||
await $fetch('/api/auth/login', { method: 'POST', body: { username: username.value, password: password.value } })
|
||||
await navigateTo('/')
|
||||
} catch (err: any) {
|
||||
error.value = err?.data?.statusMessage || err?.statusMessage || 'Sign in failed'
|
||||
} finally {
|
||||
busy.value = false
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
Reference in New Issue
Block a user