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:
+48
-48
@@ -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>
|
||||
|
||||
@@ -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 }}
|
||||
|
||||
@@ -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 }
|
||||
|
||||
Reference in New Issue
Block a user