Merge branch 'enhance-authentication-error-handling' into 'main'

feat: enhance authentication error handling and schema fetching

See merge request unboundsoftware/schemas-app!12
This commit was merged in pull request #13.
This commit is contained in:
2025-11-23 14:09:18 +01:00
3 changed files with 67 additions and 51 deletions
+48 -48
View File
@@ -124,14 +124,60 @@
</template>
<script setup lang="ts">
import { useAuth0 } from '@auth0/auth0-vue'
import { useLatestSchemaQuery } from '~/graphql/generated'
const auth0 = useAuth0()
const route = useRoute()
const _config = useRuntimeConfig()
const schema = ref<any>(null)
const loading = ref(true)
// Parse the ID which should contain both ref and service info
// The ID format from backend is typically: orgId_ref_service or similar
const schemaId = route.params.id as string
const snackbar = ref(false)
const snackbarText = ref('')
// We need to fetch all schemas and find the matching one
// Since we don't have a direct query for a single subgraph by ID,
// we'll need to get it from the URL or store it in a better format
// For now, let's extract ref from the route query or use a default
const schemaRef = computed(() => {
return (route.query.ref as string) || 'production'
})
// Fetch latest schema for the ref
const latestSchemaQuery = useLatestSchemaQuery(() => ({
ref: schemaRef.value,
}), () => ({
skip: !auth0.isAuthenticated.value,
}))
// Find the specific subgraph matching our ID
const schema = computed(() => {
if (!latestSchemaQuery.result.value?.latestSchema?.subGraphs) return null
const subgraph = latestSchemaQuery.result.value.latestSchema.subGraphs.find(
s => s.id === schemaId,
)
if (!subgraph) return null
return {
id: subgraph.id,
service: subgraph.service,
ref: schemaRef.value,
url: subgraph.url || 'N/A',
wsUrl: subgraph.wsUrl,
updatedAt: new Date(subgraph.changedAt).toLocaleString(),
updatedBy: subgraph.changedBy,
sdl: subgraph.sdl,
}
})
const loading = computed(() => latestSchemaQuery.loading.value)
const downloadSchema = () => {
if (!schema.value) return
@@ -164,52 +210,6 @@ const viewFederationGraph = () => {
if (!schema.value?.ref) return
navigateTo(`/graph/${schema.value.ref}`)
}
// TODO: Fetch actual data from the GraphQL API
onMounted(() => {
// Mock data for now
setTimeout(() => {
schema.value = {
id: route.params.id,
service: 'users-service',
ref: 'production',
url: 'http://users.example.com/graphql',
wsUrl: 'ws://users.example.com/graphql',
updatedAt: '2024-11-21 19:30:00',
updatedBy: 'john.doe@example.com',
sdl: `type User @key(fields: "id") {
id: ID!
username: String!
email: String!
createdAt: DateTime!
}
type Query {
user(id: ID!): User
users(limit: Int, offset: Int): [User!]!
}
type Mutation {
createUser(input: CreateUserInput!): User!
updateUser(id: ID!, input: UpdateUserInput!): User!
deleteUser(id: ID!): Boolean!
}
input CreateUserInput {
username: String!
email: String!
}
input UpdateUserInput {
username: String
email: String
}
scalar DateTime`,
}
loading.value = false
}, 500)
})
</script>
<style scoped>
+1 -1
View File
@@ -59,7 +59,7 @@
md="6"
lg="4"
>
<v-card hover @click="navigateTo(`/schemas/${schema.id}`)">
<v-card hover @click="navigateTo(`/schemas/${schema.id}?ref=${schema.ref}`)">
<v-card-title>
<v-icon icon="mdi-graphql" class="mr-2" />
{{ schema.service }}
+18 -2
View File
@@ -51,8 +51,24 @@ export default defineNuxtPlugin((nuxtApp) => {
}
}
}
} catch (error) {
console.error('[Apollo] Failed to get Auth0 token:', error)
} catch (error: any) {
// Handle consent required error
if (error?.error === 'consent_required') {
console.warn('[Apollo] Consent required, redirecting to login...')
const auth0Instance = (nuxtApp.vueApp.config.globalProperties as any).$auth0
// Trigger login with consent
await auth0Instance.loginWithRedirect({
authorizationParams: {
prompt: 'consent',
},
})
} else if (error?.error === 'login_required') {
console.warn('[Apollo] Login required, redirecting...')
const auth0Instance = (nuxtApp.vueApp.config.globalProperties as any).$auth0
await auth0Instance.loginWithRedirect()
} else {
console.error('[Apollo] Failed to get Auth0 token:', error)
}
}
return { headers }