Feat: Add required valid presentation middleware (#5567)
This commit is contained in:
@@ -296,6 +296,7 @@ type Documents = {
|
||||
"\n query NavigationProjectInvites {\n activeUser {\n id\n projectInvites {\n ...HeaderNavNotificationsProjectInvite_PendingStreamCollaborator\n }\n }\n }\n": typeof types.NavigationProjectInvitesDocument,
|
||||
"\n query NavigationWorkspaceInvites {\n activeUser {\n id\n workspaceInvites {\n ...HeaderNavNotificationsWorkspaceInvite_PendingWorkspaceCollaborator\n }\n }\n }\n": typeof types.NavigationWorkspaceInvitesDocument,
|
||||
"\n mutation UpdatePresentationSlide($input: UpdateSavedViewInput!) {\n projectMutations {\n savedViewMutations {\n updateView(input: $input) {\n id\n name\n description\n }\n }\n }\n }\n": typeof types.UpdatePresentationSlideDocument,
|
||||
"\n query PresentationAccessCheck($savedViewGroupId: ID!, $projectId: String!) {\n project(id: $projectId) {\n id\n savedViewGroup(id: $savedViewGroupId) {\n id\n }\n }\n }\n": typeof types.PresentationAccessCheckDocument,
|
||||
"\n query ProjectPresentationPage(\n $input: SavedViewGroupViewsInput!\n $savedViewGroupId: ID!\n $projectId: String!\n ) {\n project(id: $projectId) {\n id\n limitedWorkspace {\n id\n ...PresentationLeftSidebar_LimitedWorkspace\n }\n savedViewGroup(id: $savedViewGroupId) {\n id\n title\n ...PresentationViewerPageWrapper_SavedViewGroup\n ...PresentationHeader_SavedViewGroup\n ...PresentationSlideList_SavedViewGroup\n ...PresentationPageWrapper_SavedViewGroup\n views(input: $input) {\n totalCount\n items {\n id\n name\n description\n screenshot\n projectId\n visibility\n ...PresentationInfoSidebar_SavedView\n group {\n id\n }\n }\n }\n }\n }\n }\n": typeof types.ProjectPresentationPageDocument,
|
||||
"\n fragment UseCopyModelLink_Model on Model {\n id\n projectId\n ...GetModelItemRoute_Model\n }\n": typeof types.UseCopyModelLink_ModelFragmentDoc,
|
||||
"\n fragment UseCanCreatePersonalProject_User on User {\n permissions {\n canCreatePersonalProject {\n ...FullPermissionCheckResult\n }\n }\n }\n": typeof types.UseCanCreatePersonalProject_UserFragmentDoc,
|
||||
@@ -831,6 +832,7 @@ const documents: Documents = {
|
||||
"\n query NavigationProjectInvites {\n activeUser {\n id\n projectInvites {\n ...HeaderNavNotificationsProjectInvite_PendingStreamCollaborator\n }\n }\n }\n": types.NavigationProjectInvitesDocument,
|
||||
"\n query NavigationWorkspaceInvites {\n activeUser {\n id\n workspaceInvites {\n ...HeaderNavNotificationsWorkspaceInvite_PendingWorkspaceCollaborator\n }\n }\n }\n": types.NavigationWorkspaceInvitesDocument,
|
||||
"\n mutation UpdatePresentationSlide($input: UpdateSavedViewInput!) {\n projectMutations {\n savedViewMutations {\n updateView(input: $input) {\n id\n name\n description\n }\n }\n }\n }\n": types.UpdatePresentationSlideDocument,
|
||||
"\n query PresentationAccessCheck($savedViewGroupId: ID!, $projectId: String!) {\n project(id: $projectId) {\n id\n savedViewGroup(id: $savedViewGroupId) {\n id\n }\n }\n }\n": types.PresentationAccessCheckDocument,
|
||||
"\n query ProjectPresentationPage(\n $input: SavedViewGroupViewsInput!\n $savedViewGroupId: ID!\n $projectId: String!\n ) {\n project(id: $projectId) {\n id\n limitedWorkspace {\n id\n ...PresentationLeftSidebar_LimitedWorkspace\n }\n savedViewGroup(id: $savedViewGroupId) {\n id\n title\n ...PresentationViewerPageWrapper_SavedViewGroup\n ...PresentationHeader_SavedViewGroup\n ...PresentationSlideList_SavedViewGroup\n ...PresentationPageWrapper_SavedViewGroup\n views(input: $input) {\n totalCount\n items {\n id\n name\n description\n screenshot\n projectId\n visibility\n ...PresentationInfoSidebar_SavedView\n group {\n id\n }\n }\n }\n }\n }\n }\n": types.ProjectPresentationPageDocument,
|
||||
"\n fragment UseCopyModelLink_Model on Model {\n id\n projectId\n ...GetModelItemRoute_Model\n }\n": types.UseCopyModelLink_ModelFragmentDoc,
|
||||
"\n fragment UseCanCreatePersonalProject_User on User {\n permissions {\n canCreatePersonalProject {\n ...FullPermissionCheckResult\n }\n }\n }\n": types.UseCanCreatePersonalProject_UserFragmentDoc,
|
||||
@@ -2226,6 +2228,10 @@ export function graphql(source: "\n query NavigationWorkspaceInvites {\n act
|
||||
* The graphql function is used to parse GraphQL queries into a document that can be used by GraphQL clients.
|
||||
*/
|
||||
export function graphql(source: "\n mutation UpdatePresentationSlide($input: UpdateSavedViewInput!) {\n projectMutations {\n savedViewMutations {\n updateView(input: $input) {\n id\n name\n description\n }\n }\n }\n }\n"): (typeof documents)["\n mutation UpdatePresentationSlide($input: UpdateSavedViewInput!) {\n projectMutations {\n savedViewMutations {\n updateView(input: $input) {\n id\n name\n description\n }\n }\n }\n }\n"];
|
||||
/**
|
||||
* The graphql function is used to parse GraphQL queries into a document that can be used by GraphQL clients.
|
||||
*/
|
||||
export function graphql(source: "\n query PresentationAccessCheck($savedViewGroupId: ID!, $projectId: String!) {\n project(id: $projectId) {\n id\n savedViewGroup(id: $savedViewGroupId) {\n id\n }\n }\n }\n"): (typeof documents)["\n query PresentationAccessCheck($savedViewGroupId: ID!, $projectId: String!) {\n project(id: $projectId) {\n id\n savedViewGroup(id: $savedViewGroupId) {\n id\n }\n }\n }\n"];
|
||||
/**
|
||||
* The graphql function is used to parse GraphQL queries into a document that can be used by GraphQL clients.
|
||||
*/
|
||||
|
||||
File diff suppressed because one or more lines are too long
@@ -1,5 +1,16 @@
|
||||
import { graphql } from '~/lib/common/generated/gql/gql'
|
||||
|
||||
export const presentationAccessCheckQuery = graphql(`
|
||||
query PresentationAccessCheck($savedViewGroupId: ID!, $projectId: String!) {
|
||||
project(id: $projectId) {
|
||||
id
|
||||
savedViewGroup(id: $savedViewGroupId) {
|
||||
id
|
||||
}
|
||||
}
|
||||
}
|
||||
`)
|
||||
|
||||
export const projectPresentationPageQuery = graphql(`
|
||||
query ProjectPresentationPage(
|
||||
$input: SavedViewGroupViewsInput!
|
||||
|
||||
@@ -0,0 +1,57 @@
|
||||
// import type { Optional } from '@speckle/shared'
|
||||
import { useApolloClientFromNuxt } from '~/lib/common/composables/graphql'
|
||||
import {
|
||||
convertThrowIntoFetchResult,
|
||||
errorsToAuthResult
|
||||
} from '~/lib/common/helpers/graphql'
|
||||
import { presentationAccessCheckQuery } from '~/lib/presentations/graphql/queries'
|
||||
|
||||
/**
|
||||
* Used in presentation page to validate that presentation ID refers to a valid presentation and redirects to 404 if not
|
||||
*/
|
||||
export default defineParallelizedNuxtRouteMiddleware(async (to, _from) => {
|
||||
const savedViewGroupId = to.params.presentationId as string
|
||||
const projectId = to.params.id as string
|
||||
|
||||
// Check if token is present in URL
|
||||
// const token = to.query.presentationToken as Optional<string>
|
||||
|
||||
// Skip middleware validation for tokens - let the auth system handle them
|
||||
// if (token) {
|
||||
// return
|
||||
// }
|
||||
|
||||
const client = useApolloClientFromNuxt()
|
||||
|
||||
const { data, errors } = await client
|
||||
.query({
|
||||
query: presentationAccessCheckQuery,
|
||||
variables: { savedViewGroupId, projectId },
|
||||
context: {
|
||||
skipLoggingErrors: true
|
||||
}
|
||||
})
|
||||
.catch(convertThrowIntoFetchResult)
|
||||
|
||||
if (!data?.project?.savedViewGroup) {
|
||||
const authResult = errorsToAuthResult({ errors })
|
||||
|
||||
switch (authResult.code) {
|
||||
case 'FORBIDDEN':
|
||||
return abortNavigation(
|
||||
createError({
|
||||
statusCode: 403,
|
||||
message: authResult.message
|
||||
})
|
||||
)
|
||||
|
||||
default:
|
||||
return abortNavigation(
|
||||
createError({
|
||||
statusCode: 500,
|
||||
message: authResult.message
|
||||
})
|
||||
)
|
||||
}
|
||||
}
|
||||
})
|
||||
@@ -6,7 +6,8 @@
|
||||
|
||||
<script setup lang="ts">
|
||||
definePageMeta({
|
||||
layout: 'empty'
|
||||
layout: 'empty',
|
||||
middleware: ['require-valid-presentation']
|
||||
})
|
||||
|
||||
useHead({
|
||||
|
||||
Reference in New Issue
Block a user