mirror of
https://github.com/siderolabs/omni.git
synced 2026-05-04 22:26:13 +02:00
fix(frontend): fix eula handling to prevent being stuck on /eula
If initial EULA request fails, we will show AppUnavailable instead of sending to /eula. If you navigate directly /eula and its already accepted, navigate away to the Home page. Signed-off-by: Edward Sammut Alessi <edward.sammutalessi@siderolabs.com>
This commit is contained in:
parent
725f41d4ee
commit
921389a59c
@ -11,6 +11,8 @@ import { createApp } from 'vue'
|
||||
import { handleHotUpdate } from 'vue-router/auto-routes'
|
||||
|
||||
import { Runtime } from '@/api/common/omni.pb'
|
||||
import type { RequestError } from '@/api/fetch.pb'
|
||||
import { Code } from '@/api/google/rpc/code.pb'
|
||||
import type { Resource } from '@/api/grpc'
|
||||
import { initState, ResourceService } from '@/api/grpc'
|
||||
import type { AuthConfigSpec, EulaAcceptanceSpec } from '@/api/omni/specs/auth.pb'
|
||||
@ -65,7 +67,13 @@ const setupApp = async () => {
|
||||
withRuntime(Runtime.Omni),
|
||||
)
|
||||
eulaAccepted.value = true
|
||||
} catch {
|
||||
} catch (e) {
|
||||
if ((e as RequestError)?.code !== Code.NOT_FOUND) {
|
||||
console.error('failed to get eula state', e)
|
||||
createApp(AppUnavailable).mount('#app')
|
||||
return
|
||||
}
|
||||
|
||||
eulaAccepted.value = false
|
||||
}
|
||||
|
||||
|
||||
@ -8,12 +8,19 @@ import { Runtime } from '@/api/common/omni.pb'
|
||||
import type { fetchOption } from '@/api/fetch.pb'
|
||||
import { type Resource, ResourceService } from '@/api/grpc'
|
||||
import type { GetRequest } from '@/api/omni/resources/resources.pb'
|
||||
import { withAbortController, withContext, withRuntime, withSelectors } from '@/api/options'
|
||||
import {
|
||||
withAbortController,
|
||||
withContext,
|
||||
withRuntime,
|
||||
withSelectors,
|
||||
withSkipRequestSignature,
|
||||
} from '@/api/options'
|
||||
import type { WatchContext } from '@/api/watch'
|
||||
|
||||
interface GetOptionsCommon {
|
||||
resource: GetRequest
|
||||
selectors?: string[]
|
||||
skipSignature?: boolean
|
||||
skip?: boolean
|
||||
}
|
||||
|
||||
@ -54,6 +61,10 @@ export function useResourceGet<TSpec = unknown, TStatus = unknown>(
|
||||
|
||||
const fetchOptions: fetchOption[] = []
|
||||
|
||||
if (options.skipSignature) {
|
||||
fetchOptions.push(withSkipRequestSignature())
|
||||
}
|
||||
|
||||
if (options.runtime) {
|
||||
fetchOptions.push(withRuntime(options.runtime))
|
||||
}
|
||||
|
||||
@ -8,12 +8,19 @@ import { Runtime } from '@/api/common/omni.pb'
|
||||
import type { fetchOption } from '@/api/fetch.pb'
|
||||
import { type Resource, ResourceService } from '@/api/grpc'
|
||||
import type { ListRequest } from '@/api/omni/resources/resources.pb'
|
||||
import { withAbortController, withContext, withRuntime, withSelectors } from '@/api/options'
|
||||
import {
|
||||
withAbortController,
|
||||
withContext,
|
||||
withRuntime,
|
||||
withSelectors,
|
||||
withSkipRequestSignature,
|
||||
} from '@/api/options'
|
||||
import type { WatchContext } from '@/api/watch'
|
||||
|
||||
interface ListOptionsCommon {
|
||||
resource: ListRequest
|
||||
selectors?: string[]
|
||||
skipSignature?: boolean
|
||||
skip?: boolean
|
||||
}
|
||||
|
||||
@ -54,6 +61,10 @@ export function useResourceList<TSpec = unknown, TStatus = unknown>(
|
||||
|
||||
const fetchOptions: fetchOption[] = []
|
||||
|
||||
if (options.skipSignature) {
|
||||
fetchOptions.push(withSkipRequestSignature())
|
||||
}
|
||||
|
||||
if (options.runtime) {
|
||||
fetchOptions.push(withRuntime(options.runtime))
|
||||
}
|
||||
|
||||
@ -5,7 +5,8 @@
|
||||
import type { Meta, StoryObj } from '@storybook/vue3-vite'
|
||||
import { delay, http, HttpResponse } from 'msw'
|
||||
|
||||
import type { CreateRequest, CreateResponse } from '@/api/omni/resources/resources.pb'
|
||||
import { Code } from '@/api/google/rpc/code.pb'
|
||||
import type { CreateRequest, CreateResponse, GetRequest } from '@/api/omni/resources/resources.pb'
|
||||
import { DefaultNamespace, EulaAcceptanceID, EulaAcceptanceType } from '@/api/resources'
|
||||
|
||||
import Eula from './eula.vue'
|
||||
@ -21,6 +22,29 @@ export const Default: Story = {
|
||||
parameters: {
|
||||
msw: {
|
||||
handlers: [
|
||||
http.post<never, GetRequest>('/omni.resources.ResourceService/Get', async ({ request }) => {
|
||||
const { id, type, namespace } = await request.clone().json()
|
||||
|
||||
if (
|
||||
id !== EulaAcceptanceID ||
|
||||
type !== EulaAcceptanceType ||
|
||||
namespace !== DefaultNamespace
|
||||
) {
|
||||
return
|
||||
}
|
||||
|
||||
return HttpResponse.json(
|
||||
{
|
||||
body: {
|
||||
code: Code.NOT_FOUND,
|
||||
message:
|
||||
"failed to get: resource EulaAcceptances.omni.sidero.dev(default/eula@undefined) doesn't exist",
|
||||
},
|
||||
},
|
||||
{ status: 404 },
|
||||
)
|
||||
}),
|
||||
|
||||
http.post<never, CreateRequest, CreateResponse>(
|
||||
'/omni.resources.ResourceService/Create',
|
||||
async ({ request }) => {
|
||||
|
||||
@ -5,7 +5,7 @@ Use of this software is governed by the Business Source License
|
||||
included in the LICENSE file.
|
||||
-->
|
||||
<script setup lang="ts">
|
||||
import { computed, ref } from 'vue'
|
||||
import { computed, ref, watchEffect } from 'vue'
|
||||
import { useRouter } from 'vue-router'
|
||||
|
||||
import { Runtime } from '@/api/common/omni.pb'
|
||||
@ -17,6 +17,7 @@ import TCheckbox from '@/components/Checkbox/TCheckbox.vue'
|
||||
import PageContainer from '@/components/PageContainer/PageContainer.vue'
|
||||
import TInput from '@/components/TInput/TInput.vue'
|
||||
import { eulaAccepted } from '@/methods'
|
||||
import { useResourceGet } from '@/methods/useResourceGet'
|
||||
import { showError } from '@/notification'
|
||||
|
||||
import { withRuntime, withSkipRequestSignature } from '../api/options'
|
||||
@ -34,6 +35,20 @@ const accepting = ref(false)
|
||||
|
||||
const invalidForm = computed(() => !accepted.value || !name.value.trim() || !email.value.trim())
|
||||
|
||||
const { data, loading } = useResourceGet<EulaAcceptanceSpec>({
|
||||
runtime: Runtime.Omni,
|
||||
resource: {
|
||||
namespace: DefaultNamespace,
|
||||
type: EulaAcceptanceType,
|
||||
id: EulaAcceptanceID,
|
||||
},
|
||||
skipSignature: true,
|
||||
})
|
||||
|
||||
watchEffect(() => {
|
||||
if (data.value) router.replace({ name: 'Home' })
|
||||
})
|
||||
|
||||
const accept = async () => {
|
||||
if (accepting.value) return
|
||||
|
||||
@ -68,7 +83,7 @@ const accept = async () => {
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<PageContainer class="flex h-full items-center justify-center">
|
||||
<PageContainer v-if="!loading && !data" class="flex h-full items-center justify-center">
|
||||
<form
|
||||
class="flex w-full max-w-2xl flex-col gap-6 rounded-md bg-naturals-n3 px-8 py-8 drop-shadow-md"
|
||||
@submit.prevent="accept"
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user