d3931f1855
* Readd work from old branch * Improved Login.vue * Replace watch with onResult * Server: Error improvement * FE Middleware * Update style * Delete Sso. Mixpanel events * Updates * Improved loading state * Invites. Register sso page * Middleware improvements. Session error no logout * Changes from deisgns * Swap button to LayoutMenu * Improve middleware * Remove typo * Fix errormessage * Remove edit functionality * New composable file for sso * Improved names for composables. Tidyups * Reactive errors * Reorder Login.vue * Improved Typeguard * Enum * Comments from Mike * Add error toast * Remove FormButton from LoginButtonBase * Use linkComponent prop * Move workspace select to new component * Fragmentation * Fix loading useFetch * use WorkspaceAvatar * Feature flag sso button * Update fragment name * Skip middleware during auth flow * Add rules to Workspace Selector * Reactive useWorkspacePublicSsoCheck * AuthRegisterNewsletter types * v-bind on Select * Fragment WrapperSecurity * Remove useForm from Form.vue * Reactive values in composables * Prevent infinite loading when no invite found * useWorkspaceSsoValidation maybeRef * Added comment to requireSsoEnabled * Bugfix * Update Button.vue * Fix form * Update valid model middleware * Update LoginButtonBase.vue * NewsletterConset ref * use setFieldValue * Update Login.vue * Swap mayberef to ref * Comments from PR * Changes from call with Fabs * Fix session-error bug * Fix circleci * Small fix to index
81 lines
2.3 KiB
TypeScript
81 lines
2.3 KiB
TypeScript
import { ProjectVisibility } from '~/lib/common/generated/gql/graphql'
|
|
import { WorkspaceSsoErrorCodes } from '~/lib/workspaces/helpers/types'
|
|
import { useApolloClientFromNuxt } from '~~/lib/common/composables/graphql'
|
|
import {
|
|
convertThrowIntoFetchResult,
|
|
getFirstErrorMessage
|
|
} from '~~/lib/common/helpers/graphql'
|
|
import { projectAccessCheckQuery } from '~~/lib/projects/graphql/queries'
|
|
|
|
/**
|
|
* Used in project page to validate that project ID refers to a valid project and redirects to 404 if not
|
|
*/
|
|
export default defineNuxtRouteMiddleware(async (to) => {
|
|
const projectId = to.params.id as string
|
|
const client = useApolloClientFromNuxt()
|
|
|
|
const { data, errors } = await client
|
|
.query({
|
|
query: projectAccessCheckQuery,
|
|
variables: { id: projectId },
|
|
context: {
|
|
skipLoggingErrors: true
|
|
},
|
|
fetchPolicy: 'network-only'
|
|
})
|
|
.catch(convertThrowIntoFetchResult)
|
|
|
|
// If project is public or link shareable, allow access regardless of SSO
|
|
if (
|
|
data?.project?.visibility === ProjectVisibility.Public ||
|
|
data?.project?.visibility === ProjectVisibility.Unlisted
|
|
) {
|
|
return
|
|
}
|
|
|
|
// Check for SSO session error
|
|
const ssoSessionError = (errors || []).find(
|
|
(e) => e.extensions?.['code'] === WorkspaceSsoErrorCodes.SESSION_MISSING_OR_EXPIRED
|
|
)
|
|
|
|
// If we have an SSO error, the message contains the workspace slug
|
|
if (ssoSessionError) {
|
|
const workspaceSlug = ssoSessionError.message
|
|
return navigateTo(`/workspaces/${workspaceSlug}/sso/session-error`)
|
|
}
|
|
|
|
// If project successfully resolved and isn't public or link shareable, continue with normal flow
|
|
if (data?.project?.id) {
|
|
return
|
|
}
|
|
|
|
const isForbidden = (errors || []).find((e) => e.extensions?.['code'] === 'FORBIDDEN')
|
|
const isNotFound = (errors || []).find(
|
|
(e) => e.extensions?.['code'] === 'STREAM_NOT_FOUND'
|
|
)
|
|
|
|
if (isNotFound) {
|
|
return abortNavigation(
|
|
createError({ statusCode: 404, message: 'Project not found' })
|
|
)
|
|
}
|
|
|
|
if (isForbidden) {
|
|
return abortNavigation(
|
|
createError({
|
|
statusCode: 403,
|
|
message: 'You do not have access to this project'
|
|
})
|
|
)
|
|
}
|
|
|
|
if (errors?.length) {
|
|
return abortNavigation(
|
|
createError({
|
|
statusCode: 500,
|
|
message: getFirstErrorMessage(errors) || 'An unexpected error occurred'
|
|
})
|
|
)
|
|
}
|
|
})
|