feat: enhance authentication error handling and schema fetching
Handle authentication errors related to consent and login in the Apollo client by redirecting users to the Auth0 login page as necessary. Update the schema-fetching logic to support dynamic references from the URL, removing mock data and improving overall data integrity in the application. Ensure proper loading states during the fetching process.
This commit is contained in:
+48
-48
@@ -124,14 +124,60 @@
|
|||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
|
import { useAuth0 } from '@auth0/auth0-vue'
|
||||||
|
|
||||||
|
import { useLatestSchemaQuery } from '~/graphql/generated'
|
||||||
|
|
||||||
|
const auth0 = useAuth0()
|
||||||
const route = useRoute()
|
const route = useRoute()
|
||||||
const _config = useRuntimeConfig()
|
const _config = useRuntimeConfig()
|
||||||
|
|
||||||
const schema = ref<any>(null)
|
// Parse the ID which should contain both ref and service info
|
||||||
const loading = ref(true)
|
// The ID format from backend is typically: orgId_ref_service or similar
|
||||||
|
const schemaId = route.params.id as string
|
||||||
|
|
||||||
const snackbar = ref(false)
|
const snackbar = ref(false)
|
||||||
const snackbarText = ref('')
|
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 = () => {
|
const downloadSchema = () => {
|
||||||
if (!schema.value) return
|
if (!schema.value) return
|
||||||
|
|
||||||
@@ -164,52 +210,6 @@ const viewFederationGraph = () => {
|
|||||||
if (!schema.value?.ref) return
|
if (!schema.value?.ref) return
|
||||||
navigateTo(`/graph/${schema.value.ref}`)
|
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>
|
</script>
|
||||||
|
|
||||||
<style scoped>
|
<style scoped>
|
||||||
|
|||||||
@@ -59,7 +59,7 @@
|
|||||||
md="6"
|
md="6"
|
||||||
lg="4"
|
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-card-title>
|
||||||
<v-icon icon="mdi-graphql" class="mr-2" />
|
<v-icon icon="mdi-graphql" class="mr-2" />
|
||||||
{{ schema.service }}
|
{{ schema.service }}
|
||||||
|
|||||||
@@ -51,8 +51,24 @@ export default defineNuxtPlugin((nuxtApp) => {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} catch (error) {
|
} catch (error: any) {
|
||||||
console.error('[Apollo] Failed to get Auth0 token:', error)
|
// 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 }
|
return { headers }
|
||||||
|
|||||||
Reference in New Issue
Block a user