@cat-factory/app 0.103.0 → 0.104.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/app/components/auth/AuthGate.vue +3 -0
- package/app/components/auth/BackendMisconfiguredScreen.vue +55 -0
- package/app/stores/auth.ts +25 -1
- package/i18n/locales/de.json +8 -1
- package/i18n/locales/en.json +8 -1
- package/i18n/locales/es.json +8 -1
- package/i18n/locales/fr.json +8 -1
- package/i18n/locales/he.json +8 -1
- package/i18n/locales/it.json +8 -1
- package/i18n/locales/ja.json +8 -1
- package/i18n/locales/pl.json +8 -1
- package/i18n/locales/tr.json +8 -1
- package/i18n/locales/uk.json +8 -1
- package/package.json +2 -2
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
<script setup lang="ts">
|
|
2
2
|
import { computed } from 'vue'
|
|
3
|
+
import BackendMisconfiguredScreen from '~/components/auth/BackendMisconfiguredScreen.vue'
|
|
3
4
|
import LoginScreen from '~/components/auth/LoginScreen.vue'
|
|
4
5
|
|
|
5
6
|
// Resolves auth state once on mount, then either renders the app (auth off, or
|
|
@@ -25,6 +26,8 @@ onMounted(() => auth.bootstrap())
|
|
|
25
26
|
<span class="text-sm">{{ t('auth.gate.loading') }}</span>
|
|
26
27
|
</div>
|
|
27
28
|
|
|
29
|
+
<BackendMisconfiguredScreen v-else-if="auth.isMisconfigured" />
|
|
30
|
+
|
|
28
31
|
<slot v-else-if="isPublicRoute" />
|
|
29
32
|
|
|
30
33
|
<LoginScreen v-else-if="auth.needsLogin" />
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
<script setup lang="ts">
|
|
2
|
+
import type { ConfigProblem } from '@cat-factory/contracts'
|
|
3
|
+
|
|
4
|
+
// Shown when the backend booted into its misconfiguration fallback: it couldn't start normally
|
|
5
|
+
// because one or more mandatory environment variables / bindings are missing or invalid. We list
|
|
6
|
+
// each one with what it is for and how to fill it, so the developer can fix their env and reload
|
|
7
|
+
// rather than staring at a generic "can't reach the backend" panel. The `problems` never carry a
|
|
8
|
+
// secret value — only the variable name, its meaning, and the remedy.
|
|
9
|
+
const auth = useAuthStore()
|
|
10
|
+
const { t } = useI18n()
|
|
11
|
+
|
|
12
|
+
const problems = computed<ConfigProblem[]>(() => auth.misconfigured?.problems ?? [])
|
|
13
|
+
|
|
14
|
+
function reload() {
|
|
15
|
+
window.location.reload()
|
|
16
|
+
}
|
|
17
|
+
</script>
|
|
18
|
+
|
|
19
|
+
<template>
|
|
20
|
+
<div
|
|
21
|
+
class="flex h-screen w-screen flex-col items-center justify-center bg-slate-950 p-6 text-slate-200"
|
|
22
|
+
>
|
|
23
|
+
<div class="w-full max-w-2xl">
|
|
24
|
+
<div class="mb-6 text-center">
|
|
25
|
+
<UIcon name="i-lucide-server-cog" class="mx-auto mb-3 h-10 w-10 text-amber-400" />
|
|
26
|
+
<h1 class="text-lg font-semibold">{{ t('app.misconfigured.title') }}</h1>
|
|
27
|
+
<p class="mx-auto mt-2 max-w-lg text-sm text-slate-400">
|
|
28
|
+
{{ t('app.misconfigured.intro') }}
|
|
29
|
+
</p>
|
|
30
|
+
</div>
|
|
31
|
+
|
|
32
|
+
<ul class="space-y-3">
|
|
33
|
+
<li
|
|
34
|
+
v-for="problem in problems"
|
|
35
|
+
:key="problem.key"
|
|
36
|
+
class="rounded-lg border border-slate-800 bg-slate-900/60 p-4"
|
|
37
|
+
>
|
|
38
|
+
<code class="text-sm font-semibold text-amber-300">{{ problem.key }}</code>
|
|
39
|
+
<p class="mt-1 text-sm text-slate-300">{{ problem.summary }}</p>
|
|
40
|
+
<p class="mt-2 text-sm text-slate-400">
|
|
41
|
+
<span class="font-medium text-slate-300">{{ t('app.misconfigured.howToFix') }}</span>
|
|
42
|
+
{{ problem.remedy }}
|
|
43
|
+
</p>
|
|
44
|
+
</li>
|
|
45
|
+
</ul>
|
|
46
|
+
|
|
47
|
+
<div class="mt-6 flex items-center justify-center gap-3">
|
|
48
|
+
<UButton color="primary" icon="i-lucide-rotate-ccw" @click="reload">
|
|
49
|
+
{{ t('app.misconfigured.reload') }}
|
|
50
|
+
</UButton>
|
|
51
|
+
</div>
|
|
52
|
+
<p class="mt-4 text-center text-xs text-slate-500">{{ t('app.misconfigured.hint') }}</p>
|
|
53
|
+
</div>
|
|
54
|
+
</div>
|
|
55
|
+
</template>
|
package/app/stores/auth.ts
CHANGED
|
@@ -1,4 +1,8 @@
|
|
|
1
|
-
import type {
|
|
1
|
+
import type {
|
|
2
|
+
BackendMisconfigured,
|
|
3
|
+
InfrastructureCapabilities,
|
|
4
|
+
LocalModeConfig,
|
|
5
|
+
} from '@cat-factory/contracts'
|
|
2
6
|
import { defineStore } from 'pinia'
|
|
3
7
|
import { computed, ref } from 'vue'
|
|
4
8
|
import type { AuthUser } from '~/types/domain'
|
|
@@ -60,6 +64,14 @@ export const useAuthStore = defineStore(
|
|
|
60
64
|
const autoLoginProvider = ref<'github' | 'gitlab' | null>(null)
|
|
61
65
|
/** True once the initial auth handshake has settled. */
|
|
62
66
|
const ready = ref(false)
|
|
67
|
+
/**
|
|
68
|
+
* Set when the backend answered its boot handshake but reported that it is MISCONFIGURED — it
|
|
69
|
+
* failed to start normally because a mandatory env var / binding is missing, and is serving the
|
|
70
|
+
* fallback backend that lists the problems (each carries only a name + meaning + remedy, never a
|
|
71
|
+
* secret). Present ⇒ the SPA renders the dedicated misconfiguration screen instead of the
|
|
72
|
+
* login/board. Null on a normally-booted backend.
|
|
73
|
+
*/
|
|
74
|
+
const misconfigured = ref<BackendMisconfigured | null>(null)
|
|
63
75
|
/**
|
|
64
76
|
* Mothership mode: the last mothership sign-in failure (node unreachable / rejected session),
|
|
65
77
|
* or null. Set when the post-OAuth connect exchange fails, so the login screen can tell the
|
|
@@ -84,6 +96,9 @@ export const useAuthStore = defineStore(
|
|
|
84
96
|
/** May the app render? True when auth is off, or on with a known user. */
|
|
85
97
|
const isAuthenticated = computed(() => !required.value || user.value !== null)
|
|
86
98
|
|
|
99
|
+
/** Whether the backend reported itself misconfigured (drives the dedicated error screen). */
|
|
100
|
+
const isMisconfigured = computed(() => misconfigured.value !== null)
|
|
101
|
+
|
|
87
102
|
/**
|
|
88
103
|
* Whether the SPA must show the login screen before the board.
|
|
89
104
|
*
|
|
@@ -176,7 +191,14 @@ export const useAuthStore = defineStore(
|
|
|
176
191
|
testingNoAuth.value = config.testingNoAuth ?? false
|
|
177
192
|
localMode.value = config.localMode ?? null
|
|
178
193
|
infrastructure.value = config.infrastructure ?? null
|
|
194
|
+
misconfigured.value = config.misconfigured ?? null
|
|
179
195
|
configLoaded.value = true
|
|
196
|
+
// A misconfigured backend serves only the fallback app; there's no session/board to
|
|
197
|
+
// resolve, so settle here and let the SPA render the misconfiguration screen.
|
|
198
|
+
if (misconfigured.value) {
|
|
199
|
+
ready.value = true
|
|
200
|
+
return
|
|
201
|
+
}
|
|
180
202
|
} catch {
|
|
181
203
|
// Backend unreachable — let the board's own error UI handle it (configLoaded stays
|
|
182
204
|
// false, so we never mistake this for an unauthenticated session and gate it).
|
|
@@ -335,8 +357,10 @@ export const useAuthStore = defineStore(
|
|
|
335
357
|
ready,
|
|
336
358
|
mothershipError,
|
|
337
359
|
configLoaded,
|
|
360
|
+
misconfigured,
|
|
338
361
|
isLocalFacade,
|
|
339
362
|
isAuthenticated,
|
|
363
|
+
isMisconfigured,
|
|
340
364
|
needsLogin,
|
|
341
365
|
bootstrap,
|
|
342
366
|
login,
|
package/i18n/locales/de.json
CHANGED
|
@@ -3552,7 +3552,14 @@
|
|
|
3552
3552
|
"loadingBoard": "Board wird geladen…",
|
|
3553
3553
|
"backendUnreachable": "Backend nicht erreichbar",
|
|
3554
3554
|
"reconnecting": "Verbindung wird wiederhergestellt…",
|
|
3555
|
-
"offline": "Keine Live-Updates"
|
|
3555
|
+
"offline": "Keine Live-Updates",
|
|
3556
|
+
"misconfigured": {
|
|
3557
|
+
"title": "Backend nicht konfiguriert",
|
|
3558
|
+
"intro": "Der Server wurde gestartet, kann aber erst laufen, wenn die folgenden Einstellungen vorhanden sind. Ergänze die fehlenden Werte in deiner Umgebung und lade neu.",
|
|
3559
|
+
"howToFix": "So behebst du es:",
|
|
3560
|
+
"reload": "Neu laden",
|
|
3561
|
+
"hint": "Hier werden nur Variablennamen und deren Einrichtung angezeigt, niemals geheime Werte."
|
|
3562
|
+
}
|
|
3556
3563
|
},
|
|
3557
3564
|
"language": {
|
|
3558
3565
|
"switcher": "Sprache",
|
package/i18n/locales/en.json
CHANGED
|
@@ -4,7 +4,14 @@
|
|
|
4
4
|
"loadingBoard": "Loading board…",
|
|
5
5
|
"backendUnreachable": "Can't reach the backend",
|
|
6
6
|
"reconnecting": "Reconnecting…",
|
|
7
|
-
"offline": "Not receiving live updates"
|
|
7
|
+
"offline": "Not receiving live updates",
|
|
8
|
+
"misconfigured": {
|
|
9
|
+
"title": "Backend not configured",
|
|
10
|
+
"intro": "The server started but can't run until the settings below are provided. Add the missing values to your environment, then reload.",
|
|
11
|
+
"howToFix": "How to fix:",
|
|
12
|
+
"reload": "Reload",
|
|
13
|
+
"hint": "Only variable names and how to set them are shown here, never any secret values."
|
|
14
|
+
}
|
|
8
15
|
},
|
|
9
16
|
"language": {
|
|
10
17
|
"switcher": "Language",
|
package/i18n/locales/es.json
CHANGED
|
@@ -4,7 +4,14 @@
|
|
|
4
4
|
"loadingBoard": "Cargando tablero…",
|
|
5
5
|
"backendUnreachable": "No se puede conectar con el backend",
|
|
6
6
|
"reconnecting": "Reconectando…",
|
|
7
|
-
"offline": "No se reciben actualizaciones en vivo"
|
|
7
|
+
"offline": "No se reciben actualizaciones en vivo",
|
|
8
|
+
"misconfigured": {
|
|
9
|
+
"title": "Backend sin configurar",
|
|
10
|
+
"intro": "El servidor se inició pero no puede funcionar hasta que se proporcionen los ajustes siguientes. Añade los valores que faltan a tu entorno y vuelve a cargar.",
|
|
11
|
+
"howToFix": "Cómo solucionarlo:",
|
|
12
|
+
"reload": "Recargar",
|
|
13
|
+
"hint": "Aquí solo se muestran los nombres de las variables y cómo definirlas, nunca valores secretos."
|
|
14
|
+
}
|
|
8
15
|
},
|
|
9
16
|
"language": {
|
|
10
17
|
"switcher": "Idioma",
|
package/i18n/locales/fr.json
CHANGED
|
@@ -4,7 +4,14 @@
|
|
|
4
4
|
"loadingBoard": "Chargement du tableau…",
|
|
5
5
|
"backendUnreachable": "Impossible de joindre le backend",
|
|
6
6
|
"reconnecting": "Reconnexion…",
|
|
7
|
-
"offline": "Mises à jour en direct non reçues"
|
|
7
|
+
"offline": "Mises à jour en direct non reçues",
|
|
8
|
+
"misconfigured": {
|
|
9
|
+
"title": "Backend non configuré",
|
|
10
|
+
"intro": "Le serveur a démarré mais ne peut pas fonctionner tant que les paramètres ci-dessous ne sont pas fournis. Ajoutez les valeurs manquantes à votre environnement, puis rechargez.",
|
|
11
|
+
"howToFix": "Comment corriger :",
|
|
12
|
+
"reload": "Recharger",
|
|
13
|
+
"hint": "Seuls les noms des variables et la façon de les définir sont affichés ici, jamais de valeurs secrètes."
|
|
14
|
+
}
|
|
8
15
|
},
|
|
9
16
|
"language": {
|
|
10
17
|
"switcher": "Langue",
|
package/i18n/locales/he.json
CHANGED
|
@@ -4,7 +4,14 @@
|
|
|
4
4
|
"loadingBoard": "טוען לוח…",
|
|
5
5
|
"backendUnreachable": "לא ניתן להתחבר לבקאנד",
|
|
6
6
|
"reconnecting": "מתחבר מחדש…",
|
|
7
|
-
"offline": "לא מתקבלים עדכונים חיים"
|
|
7
|
+
"offline": "לא מתקבלים עדכונים חיים",
|
|
8
|
+
"misconfigured": {
|
|
9
|
+
"title": "השרת אינו מוגדר",
|
|
10
|
+
"intro": "השרת עלה אך אינו יכול לפעול עד שהערכים הבאים יסופקו. הוסיפו את הערכים החסרים לסביבה שלכם וטענו מחדש.",
|
|
11
|
+
"howToFix": "איך לתקן:",
|
|
12
|
+
"reload": "טעינה מחדש",
|
|
13
|
+
"hint": "כאן מוצגים רק שמות המשתנים וכיצד להגדיר אותם, לעולם לא ערכים סודיים."
|
|
14
|
+
}
|
|
8
15
|
},
|
|
9
16
|
"language": {
|
|
10
17
|
"switcher": "שפה",
|
package/i18n/locales/it.json
CHANGED
|
@@ -3552,7 +3552,14 @@
|
|
|
3552
3552
|
"loadingBoard": "Caricamento della board…",
|
|
3553
3553
|
"backendUnreachable": "Impossibile raggiungere il backend",
|
|
3554
3554
|
"reconnecting": "Riconnessione…",
|
|
3555
|
-
"offline": "Aggiornamenti in tempo reale non ricevuti"
|
|
3555
|
+
"offline": "Aggiornamenti in tempo reale non ricevuti",
|
|
3556
|
+
"misconfigured": {
|
|
3557
|
+
"title": "Backend non configurato",
|
|
3558
|
+
"intro": "Il server è avviato ma non può funzionare finché non vengono forniti i parametri seguenti. Aggiungi i valori mancanti al tuo ambiente e ricarica.",
|
|
3559
|
+
"howToFix": "Come risolvere:",
|
|
3560
|
+
"reload": "Ricarica",
|
|
3561
|
+
"hint": "Qui vengono mostrati solo i nomi delle variabili e come impostarle, mai valori segreti."
|
|
3562
|
+
}
|
|
3556
3563
|
},
|
|
3557
3564
|
"language": {
|
|
3558
3565
|
"switcher": "Lingua",
|
package/i18n/locales/ja.json
CHANGED
|
@@ -4,7 +4,14 @@
|
|
|
4
4
|
"loadingBoard": "ボードを読み込み中…",
|
|
5
5
|
"backendUnreachable": "バックエンドに接続できません",
|
|
6
6
|
"reconnecting": "再接続中…",
|
|
7
|
-
"offline": "ライブ更新を受信していません"
|
|
7
|
+
"offline": "ライブ更新を受信していません",
|
|
8
|
+
"misconfigured": {
|
|
9
|
+
"title": "バックエンドが設定されていません",
|
|
10
|
+
"intro": "サーバーは起動しましたが、以下の設定が指定されるまで動作できません。不足している値を環境に追加してから再読み込みしてください。",
|
|
11
|
+
"howToFix": "対処方法:",
|
|
12
|
+
"reload": "再読み込み",
|
|
13
|
+
"hint": "ここに表示されるのは変数名と設定方法のみで、秘密の値は表示されません。"
|
|
14
|
+
}
|
|
8
15
|
},
|
|
9
16
|
"language": {
|
|
10
17
|
"switcher": "言語",
|
package/i18n/locales/pl.json
CHANGED
|
@@ -4,7 +4,14 @@
|
|
|
4
4
|
"loadingBoard": "Ładowanie tablicy…",
|
|
5
5
|
"backendUnreachable": "Nie można połączyć się z backendem",
|
|
6
6
|
"reconnecting": "Ponowne łączenie…",
|
|
7
|
-
"offline": "Brak aktualizacji na żywo"
|
|
7
|
+
"offline": "Brak aktualizacji na żywo",
|
|
8
|
+
"misconfigured": {
|
|
9
|
+
"title": "Backend nie jest skonfigurowany",
|
|
10
|
+
"intro": "Serwer wystartował, ale nie zadziała, dopóki nie uzupełnisz poniższych ustawień. Dodaj brakujące wartości do swojego środowiska i odśwież.",
|
|
11
|
+
"howToFix": "Jak naprawić:",
|
|
12
|
+
"reload": "Odśwież",
|
|
13
|
+
"hint": "Tutaj pokazujemy tylko nazwy zmiennych i sposób ich ustawienia, nigdy wartości sekretnych."
|
|
14
|
+
}
|
|
8
15
|
},
|
|
9
16
|
"language": {
|
|
10
17
|
"switcher": "Język",
|
package/i18n/locales/tr.json
CHANGED
|
@@ -4,7 +4,14 @@
|
|
|
4
4
|
"loadingBoard": "Pano yükleniyor…",
|
|
5
5
|
"backendUnreachable": "Arka uca ulaşılamıyor",
|
|
6
6
|
"reconnecting": "Yeniden bağlanılıyor…",
|
|
7
|
-
"offline": "Canlı güncellemeler alınmıyor"
|
|
7
|
+
"offline": "Canlı güncellemeler alınmıyor",
|
|
8
|
+
"misconfigured": {
|
|
9
|
+
"title": "Arka uç yapılandırılmadı",
|
|
10
|
+
"intro": "Sunucu başladı ancak aşağıdaki ayarlar sağlanana kadar çalışamaz. Eksik değerleri ortamınıza ekleyip yeniden yükleyin.",
|
|
11
|
+
"howToFix": "Nasıl düzeltilir:",
|
|
12
|
+
"reload": "Yeniden yükle",
|
|
13
|
+
"hint": "Burada yalnızca değişken adları ve nasıl ayarlanacakları gösterilir, asla gizli değerler değil."
|
|
14
|
+
}
|
|
8
15
|
},
|
|
9
16
|
"language": {
|
|
10
17
|
"switcher": "Dil",
|
package/i18n/locales/uk.json
CHANGED
|
@@ -4,7 +4,14 @@
|
|
|
4
4
|
"loadingBoard": "Завантаження дошки…",
|
|
5
5
|
"backendUnreachable": "Не вдається зʼєднатися з бекендом",
|
|
6
6
|
"reconnecting": "Повторне зʼєднання…",
|
|
7
|
-
"offline": "Оновлення в реальному часі не надходять"
|
|
7
|
+
"offline": "Оновлення в реальному часі не надходять",
|
|
8
|
+
"misconfigured": {
|
|
9
|
+
"title": "Бекенд не налаштовано",
|
|
10
|
+
"intro": "Сервер запустився, але не працюватиме, доки не буде задано наведені нижче параметри. Додайте відсутні значення до свого середовища та перезавантажте.",
|
|
11
|
+
"howToFix": "Як виправити:",
|
|
12
|
+
"reload": "Перезавантажити",
|
|
13
|
+
"hint": "Тут показано лише назви змінних і як їх задати, ніколи не секретні значення."
|
|
14
|
+
}
|
|
8
15
|
},
|
|
9
16
|
"language": {
|
|
10
17
|
"switcher": "Мова",
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@cat-factory/app",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.104.0",
|
|
4
4
|
"description": "Reusable Nuxt layer for the Agent Architecture Board SPA (components, stores, composables, pages). Consume it from a thin deployment app via `extends: ['@cat-factory/app']` and point it at your backend with NUXT_PUBLIC_API_BASE. See deploy/frontend for an example.",
|
|
5
5
|
"repository": {
|
|
6
6
|
"type": "git",
|
|
@@ -34,7 +34,7 @@
|
|
|
34
34
|
"valibot": "^1.4.2",
|
|
35
35
|
"vue": "3.5.39",
|
|
36
36
|
"wretch": "^3.0.9",
|
|
37
|
-
"@cat-factory/contracts": "0.
|
|
37
|
+
"@cat-factory/contracts": "0.114.0"
|
|
38
38
|
},
|
|
39
39
|
"devDependencies": {
|
|
40
40
|
"@toad-contracts/testing": "0.3.2",
|