fix(automate): redirect github auth flow to workspace if possible (#3632)
* fix(automate): redirect to workspace after auth if possible * fix(automate): include session in github auth flow * chore(automate): update props after merge * fix(automate): pick => fragment * fix(automate): use fragments correctly
This commit is contained in:
@@ -61,8 +61,12 @@ import {
|
||||
useUpdateAutomateFunction
|
||||
} from '~/lib/automate/composables/management'
|
||||
import { useMutationLoading } from '@vue/apollo-composable'
|
||||
import type { AutomateFunctionCreateDialogDoneStep_AutomateFunctionFragment } from '~~/lib/common/generated/gql/graphql'
|
||||
import type {
|
||||
AutomateFunctionCreateDialogDoneStep_AutomateFunctionFragment,
|
||||
AutomateFunctionCreateDialog_WorkspaceFragment
|
||||
} from '~~/lib/common/generated/gql/graphql'
|
||||
import { useMixpanel } from '~/lib/core/composables/mp'
|
||||
import { graphql } from '~/lib/common/generated/gql'
|
||||
|
||||
enum FunctionCreateSteps {
|
||||
Authorize,
|
||||
@@ -73,11 +77,19 @@ enum FunctionCreateSteps {
|
||||
|
||||
type DetailsFormValues = FunctionDetailsFormValues
|
||||
|
||||
graphql(`
|
||||
fragment AutomateFunctionCreateDialog_Workspace on Workspace {
|
||||
id
|
||||
name
|
||||
slug
|
||||
}
|
||||
`)
|
||||
|
||||
const props = defineProps<{
|
||||
isAuthorized: boolean
|
||||
templates: CreatableFunctionTemplate[]
|
||||
githubOrgs: string[]
|
||||
workspaceId?: string
|
||||
workspace?: AutomateFunctionCreateDialog_WorkspaceFragment
|
||||
}>()
|
||||
const open = defineModel<boolean>('open', { required: true })
|
||||
|
||||
@@ -114,19 +126,19 @@ const onDetailsSubmit = handleDetailsSubmit(async (values) => {
|
||||
templateId: selectedTemplate.value.id,
|
||||
name: values.name,
|
||||
/* eslint-disable-next-line camelcase */
|
||||
workspace_id: props.workspaceId
|
||||
workspace_id: props.workspace?.id
|
||||
})
|
||||
createdFunction.value = res
|
||||
step.value++
|
||||
|
||||
if (!props.workspaceId) {
|
||||
if (!props.workspace?.id) {
|
||||
return
|
||||
}
|
||||
|
||||
await updateFunction({
|
||||
input: {
|
||||
id: res.id,
|
||||
workspaceIds: [props.workspaceId]
|
||||
workspaceIds: [props.workspace.id]
|
||||
}
|
||||
})
|
||||
})
|
||||
@@ -184,7 +196,10 @@ const title = computed(() => {
|
||||
})
|
||||
|
||||
const authorizeGithubUrl = computed(() => {
|
||||
const redirectUrl = new URL(automateGithubAppAuthorizationRoute, apiBaseUrl)
|
||||
const redirectUrl = new URL(
|
||||
automateGithubAppAuthorizationRoute(props.workspace?.slug),
|
||||
apiBaseUrl
|
||||
)
|
||||
return redirectUrl.toString()
|
||||
})
|
||||
|
||||
|
||||
@@ -18,12 +18,20 @@ import { difference, differenceBy } from 'lodash-es'
|
||||
import { useForm } from 'vee-validate'
|
||||
import { useUpdateAutomateFunction } from '~/lib/automate/composables/management'
|
||||
import type { FunctionDetailsFormValues } from '~/lib/automate/helpers/functions'
|
||||
import type { Workspace } from '~/lib/common/generated/gql/graphql'
|
||||
import { graphql } from '~/lib/common/generated/gql'
|
||||
import type { AutomateFunctionEditDialog_WorkspaceFragment } from '~/lib/common/generated/gql/graphql'
|
||||
|
||||
graphql(`
|
||||
fragment AutomateFunctionEditDialog_Workspace on Workspace {
|
||||
id
|
||||
name
|
||||
}
|
||||
`)
|
||||
|
||||
const props = defineProps<{
|
||||
model: FunctionDetailsFormValues
|
||||
fnId: string
|
||||
workspaces?: Pick<Workspace, 'id' | 'name'>[]
|
||||
workspaces?: AutomateFunctionEditDialog_WorkspaceFragment[]
|
||||
}>()
|
||||
const open = defineModel<boolean>('open', { required: true })
|
||||
const { handleSubmit, setValues } = useForm<FunctionDetailsFormValues>()
|
||||
|
||||
@@ -109,19 +109,11 @@
|
||||
<script setup lang="ts">
|
||||
import { ValidationHelpers } from '@speckle/ui-components'
|
||||
import { isArray } from 'lodash-es'
|
||||
import { graphql } from '~/lib/common/generated/gql'
|
||||
import type { Workspace } from '~/lib/common/generated/gql/graphql'
|
||||
|
||||
graphql(`
|
||||
fragment AutomateFunctionCreateDialog_Workspace on Workspace {
|
||||
id
|
||||
name
|
||||
}
|
||||
`)
|
||||
import type { AutomateFunctionCreateDialog_WorkspaceFragment } from '~/lib/common/generated/gql/graphql'
|
||||
|
||||
defineProps<{
|
||||
githubOrgs?: string[]
|
||||
workspaces?: Pick<Workspace, 'id' | 'name'>[]
|
||||
workspaces?: AutomateFunctionCreateDialog_WorkspaceFragment[]
|
||||
}>()
|
||||
|
||||
const avatarEditMode = ref(false)
|
||||
|
||||
@@ -35,7 +35,7 @@
|
||||
:is-authorized="!!activeUser?.automateInfo.hasAutomateGithubApp"
|
||||
:github-orgs="activeUser?.automateInfo.availableGithubOrgs || []"
|
||||
:templates="availableTemplates"
|
||||
:workspace-id="workspace?.id"
|
||||
:workspace="workspace"
|
||||
/>
|
||||
</div>
|
||||
</template>
|
||||
@@ -45,8 +45,8 @@ import { Roles, type Nullable, type Optional } from '@speckle/shared'
|
||||
import { useDebouncedTextInput } from '@speckle/ui-components'
|
||||
import { graphql } from '~/lib/common/generated/gql'
|
||||
import type {
|
||||
AutomateFunctionsPageHeader_QueryFragment,
|
||||
Workspace
|
||||
AutomateFunctionCreateDialog_WorkspaceFragment,
|
||||
AutomateFunctionsPageHeader_QueryFragment
|
||||
} from '~/lib/common/generated/gql/graphql'
|
||||
import { workspaceFunctionsRoute, workspaceRoute } from '~/lib/common/helpers/route'
|
||||
import { useMixpanel } from '~/lib/core/composables/mp'
|
||||
@@ -74,7 +74,7 @@ graphql(`
|
||||
const props = defineProps<{
|
||||
activeUser: Optional<AutomateFunctionsPageHeader_QueryFragment['activeUser']>
|
||||
serverInfo: Optional<AutomateFunctionsPageHeader_QueryFragment['serverInfo']>
|
||||
workspace?: Pick<Workspace, 'id' | 'slug' | 'name'>
|
||||
workspace?: AutomateFunctionCreateDialog_WorkspaceFragment
|
||||
}>()
|
||||
const search = defineModel<string>('search')
|
||||
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
<div class="flex flex-col gap-y-4 md:gap-y-6">
|
||||
<ProjectPageAutomationsHeader
|
||||
v-model:search="search"
|
||||
:workspace-slug="workspaceSlug"
|
||||
:workspace-slug="workspace?.slug"
|
||||
:show-empty-state="shouldShowEmptyState"
|
||||
:creation-disabled-message="disableCreateAutomationMessage"
|
||||
@new-automation="onNewAutomation"
|
||||
@@ -13,7 +13,7 @@
|
||||
<template v-else>
|
||||
<ProjectPageAutomationsEmptyState
|
||||
v-if="shouldShowEmptyState"
|
||||
:workspace-slug="workspaceSlug"
|
||||
:workspace-slug="workspace?.slug"
|
||||
:hidden-actions="hiddenActions"
|
||||
:disabled-actions="disabledActions"
|
||||
@new-automation="onNewAutomation"
|
||||
@@ -37,15 +37,15 @@
|
||||
</template>
|
||||
</template>
|
||||
<AutomateAutomationCreateDialog
|
||||
v-if="workspaceId"
|
||||
v-if="workspace?.id"
|
||||
v-model:open="showNewAutomationDialog"
|
||||
:workspace-id="workspaceId"
|
||||
:workspace-id="workspace?.id"
|
||||
:preselected-project="project"
|
||||
:preselected-function="newAutomationTargetFn"
|
||||
/>
|
||||
<AutomateFunctionCreateDialog
|
||||
v-model:open="showNewFunctionDialog"
|
||||
:workspace-id="workspaceId"
|
||||
:workspace="workspace"
|
||||
:is-authorized="isGithubAppConfigured"
|
||||
:github-orgs="githubOrgs"
|
||||
:templates="availableFunctionTemplates"
|
||||
@@ -83,8 +83,7 @@ const { result, loading } = useQuery(
|
||||
})
|
||||
)
|
||||
|
||||
const workspaceId = computed(() => result.value?.project?.workspace?.id)
|
||||
const workspaceSlug = computed(() => result.value?.project?.workspace?.slug)
|
||||
const workspace = computed(() => result.value?.project?.workspace ?? undefined)
|
||||
|
||||
const workspaceFunctionCount = computed(
|
||||
() => result.value?.project.workspace?.automateFunctions.totalCount ?? 0
|
||||
|
||||
@@ -27,7 +27,8 @@ const documents = {
|
||||
"\n fragment AutomateAutomationCreateDialogFunctionParametersStep_AutomateFunction on AutomateFunction {\n id\n releases(limit: 1) {\n items {\n id\n inputSchema\n }\n }\n }\n": types.AutomateAutomationCreateDialogFunctionParametersStep_AutomateFunctionFragmentDoc,
|
||||
"\n query AutomationCreateDialogFunctionsSearch(\n $workspaceId: String!\n $search: String\n $cursor: String = null\n ) {\n workspace(id: $workspaceId) {\n automateFunctions(limit: 20, filter: { search: $search }, cursor: $cursor) {\n cursor\n totalCount\n items {\n id\n ...AutomateAutomationCreateDialog_AutomateFunction\n }\n }\n }\n }\n": types.AutomationCreateDialogFunctionsSearchDocument,
|
||||
"\n fragment AutomationsFunctionsCard_AutomateFunction on AutomateFunction {\n id\n name\n isFeatured\n description\n logo\n repo {\n id\n url\n owner\n name\n }\n }\n": types.AutomationsFunctionsCard_AutomateFunctionFragmentDoc,
|
||||
"\n fragment AutomateFunctionCreateDialog_Workspace on Workspace {\n id\n name\n }\n": types.AutomateFunctionCreateDialog_WorkspaceFragmentDoc,
|
||||
"\n fragment AutomateFunctionCreateDialog_Workspace on Workspace {\n id\n name\n slug\n }\n": types.AutomateFunctionCreateDialog_WorkspaceFragmentDoc,
|
||||
"\n fragment AutomateFunctionEditDialog_Workspace on Workspace {\n id\n name\n }\n": types.AutomateFunctionEditDialog_WorkspaceFragmentDoc,
|
||||
"\n fragment AutomateFunctionCreateDialogDoneStep_AutomateFunction on AutomateFunction {\n id\n repo {\n id\n url\n owner\n name\n }\n ...AutomationsFunctionsCard_AutomateFunction\n }\n": types.AutomateFunctionCreateDialogDoneStep_AutomateFunctionFragmentDoc,
|
||||
"\n fragment AutomateFunctionCreateDialogTemplateStep_AutomateFunctionTemplate on AutomateFunctionTemplate {\n id\n title\n logo\n url\n }\n": types.AutomateFunctionCreateDialogTemplateStep_AutomateFunctionTemplateFragmentDoc,
|
||||
"\n fragment AutomateFunctionPageHeader_Function on AutomateFunction {\n id\n name\n logo\n repo {\n id\n url\n owner\n name\n }\n releases(limit: 1) {\n totalCount\n }\n workspaceIds\n }\n": types.AutomateFunctionPageHeader_FunctionFragmentDoc,
|
||||
@@ -258,7 +259,7 @@ const documents = {
|
||||
"\n query ProjectModelVersions(\n $projectId: String!\n $modelId: String!\n $versionsCursor: String\n ) {\n project(id: $projectId) {\n id\n ...ProjectModelPageVersionsPagination\n }\n }\n": types.ProjectModelVersionsDocument,
|
||||
"\n query ProjectModelsPage($projectId: String!) {\n project(id: $projectId) {\n id\n ...ProjectModelsPageHeader_Project\n ...ProjectModelsPageResults_Project\n }\n }\n": types.ProjectModelsPageDocument,
|
||||
"\n query ProjectDiscussionsPage($projectId: String!) {\n project(id: $projectId) {\n id\n ...ProjectDiscussionsPageHeader_Project\n ...ProjectDiscussionsPageResults_Project\n }\n }\n": types.ProjectDiscussionsPageDocument,
|
||||
"\n query ProjectAutomationsTab($projectId: String!) {\n project(id: $projectId) {\n id\n role\n models(limit: 1) {\n items {\n id\n }\n }\n automations(filter: null, cursor: null, limit: 5) {\n totalCount\n items {\n id\n ...ProjectPageAutomationsRow_Automation\n }\n cursor\n }\n workspace {\n id\n slug\n automateFunctions(limit: 0) {\n totalCount\n }\n }\n ...FormSelectProjects_Project\n }\n ...AutomateFunctionsPageHeader_Query\n }\n": types.ProjectAutomationsTabDocument,
|
||||
"\n query ProjectAutomationsTab($projectId: String!) {\n project(id: $projectId) {\n id\n role\n models(limit: 1) {\n items {\n id\n }\n }\n automations(filter: null, cursor: null, limit: 5) {\n totalCount\n items {\n id\n ...ProjectPageAutomationsRow_Automation\n }\n cursor\n }\n workspace {\n id\n automateFunctions(limit: 0) {\n totalCount\n }\n ...AutomateFunctionCreateDialog_Workspace\n }\n ...FormSelectProjects_Project\n }\n ...AutomateFunctionsPageHeader_Query\n }\n": types.ProjectAutomationsTabDocument,
|
||||
"\n query ProjectAutomationsTabAutomationsPagination(\n $projectId: String!\n $search: String = null\n $cursor: String = null\n ) {\n project(id: $projectId) {\n id\n automations(filter: $search, cursor: $cursor, limit: 5) {\n totalCount\n cursor\n items {\n id\n ...ProjectPageAutomationsRow_Automation\n }\n }\n }\n }\n": types.ProjectAutomationsTabAutomationsPaginationDocument,
|
||||
"\n query ProjectAutomationPage($projectId: String!, $automationId: String!) {\n project(id: $projectId) {\n id\n ...ProjectPageAutomationPage_Project\n automation(id: $automationId) {\n id\n ...ProjectPageAutomationPage_Automation\n }\n }\n }\n": types.ProjectAutomationPageDocument,
|
||||
"\n query ProjectAutomationPagePaginatedRuns(\n $projectId: String!\n $automationId: String!\n $cursor: String = null\n ) {\n project(id: $projectId) {\n id\n automation(id: $automationId) {\n id\n runs(cursor: $cursor, limit: 10) {\n totalCount\n cursor\n items {\n id\n ...AutomationRunDetails\n }\n }\n }\n }\n }\n": types.ProjectAutomationPagePaginatedRunsDocument,
|
||||
@@ -372,7 +373,7 @@ const documents = {
|
||||
"\n query AutoAcceptableWorkspaceInvite(\n $token: String!\n $workspaceId: String!\n $options: WorkspaceInviteLookupOptions\n ) {\n workspaceInvite(token: $token, workspaceId: $workspaceId, options: $options) {\n id\n ...UseWorkspaceInviteManager_PendingWorkspaceCollaborator\n }\n }\n": types.AutoAcceptableWorkspaceInviteDocument,
|
||||
"\n query ResolveCommentLink($commentId: String!, $projectId: String!) {\n project(id: $projectId) {\n comment(id: $commentId) {\n id\n ...LinkableComment\n }\n }\n }\n": types.ResolveCommentLinkDocument,
|
||||
"\n fragment AutomateFunctionPage_AutomateFunction on AutomateFunction {\n id\n name\n description\n logo\n supportedSourceApps\n tags\n ...AutomateFunctionPageHeader_Function\n ...AutomateFunctionPageInfo_AutomateFunction\n ...AutomateAutomationCreateDialog_AutomateFunction\n creator {\n id\n }\n }\n": types.AutomateFunctionPage_AutomateFunctionFragmentDoc,
|
||||
"\n query AutomateFunctionPage($functionId: ID!) {\n automateFunction(id: $functionId) {\n ...AutomateFunctionPage_AutomateFunction\n }\n activeUser {\n workspaces {\n items {\n ...AutomateFunctionCreateDialog_Workspace\n }\n }\n }\n }\n": types.AutomateFunctionPageDocument,
|
||||
"\n query AutomateFunctionPage($functionId: ID!) {\n automateFunction(id: $functionId) {\n ...AutomateFunctionPage_AutomateFunction\n }\n activeUser {\n workspaces {\n items {\n ...AutomateFunctionCreateDialog_Workspace\n ...AutomateFunctionEditDialog_Workspace\n }\n }\n }\n }\n": types.AutomateFunctionPageDocument,
|
||||
"\n query AutomateFunctionsPage($search: String, $cursor: String = null) {\n ...AutomateFunctionsPageItems_Query\n ...AutomateFunctionsPageHeader_Query\n }\n": types.AutomateFunctionsPageDocument,
|
||||
"\n fragment ProjectPageProject on Project {\n id\n createdAt\n modelCount: models(limit: 0) {\n totalCount\n }\n commentThreadCount: commentThreads(limit: 0) {\n totalCount\n }\n workspace {\n id\n }\n ...ProjectPageTeamInternals_Project\n ...ProjectPageProjectHeader\n ...ProjectPageTeamDialog\n ...ProjectsMoveToWorkspaceDialog_Project\n }\n": types.ProjectPageProjectFragmentDoc,
|
||||
"\n fragment ProjectPageAutomationPage_Automation on Automation {\n id\n ...ProjectPageAutomationHeader_Automation\n ...ProjectPageAutomationFunctions_Automation\n ...ProjectPageAutomationRuns_Automation\n }\n": types.ProjectPageAutomationPage_AutomationFragmentDoc,
|
||||
@@ -449,7 +450,11 @@ export function graphql(source: "\n fragment AutomationsFunctionsCard_AutomateF
|
||||
/**
|
||||
* The graphql function is used to parse GraphQL queries into a document that can be used by GraphQL clients.
|
||||
*/
|
||||
export function graphql(source: "\n fragment AutomateFunctionCreateDialog_Workspace on Workspace {\n id\n name\n }\n"): (typeof documents)["\n fragment AutomateFunctionCreateDialog_Workspace on Workspace {\n id\n name\n }\n"];
|
||||
export function graphql(source: "\n fragment AutomateFunctionCreateDialog_Workspace on Workspace {\n id\n name\n slug\n }\n"): (typeof documents)["\n fragment AutomateFunctionCreateDialog_Workspace on Workspace {\n id\n name\n slug\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 fragment AutomateFunctionEditDialog_Workspace on Workspace {\n id\n name\n }\n"): (typeof documents)["\n fragment AutomateFunctionEditDialog_Workspace on Workspace {\n id\n name\n }\n"];
|
||||
/**
|
||||
* The graphql function is used to parse GraphQL queries into a document that can be used by GraphQL clients.
|
||||
*/
|
||||
@@ -1373,7 +1378,7 @@ export function graphql(source: "\n query ProjectDiscussionsPage($projectId: St
|
||||
/**
|
||||
* 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 ProjectAutomationsTab($projectId: String!) {\n project(id: $projectId) {\n id\n role\n models(limit: 1) {\n items {\n id\n }\n }\n automations(filter: null, cursor: null, limit: 5) {\n totalCount\n items {\n id\n ...ProjectPageAutomationsRow_Automation\n }\n cursor\n }\n workspace {\n id\n slug\n automateFunctions(limit: 0) {\n totalCount\n }\n }\n ...FormSelectProjects_Project\n }\n ...AutomateFunctionsPageHeader_Query\n }\n"): (typeof documents)["\n query ProjectAutomationsTab($projectId: String!) {\n project(id: $projectId) {\n id\n role\n models(limit: 1) {\n items {\n id\n }\n }\n automations(filter: null, cursor: null, limit: 5) {\n totalCount\n items {\n id\n ...ProjectPageAutomationsRow_Automation\n }\n cursor\n }\n workspace {\n id\n slug\n automateFunctions(limit: 0) {\n totalCount\n }\n }\n ...FormSelectProjects_Project\n }\n ...AutomateFunctionsPageHeader_Query\n }\n"];
|
||||
export function graphql(source: "\n query ProjectAutomationsTab($projectId: String!) {\n project(id: $projectId) {\n id\n role\n models(limit: 1) {\n items {\n id\n }\n }\n automations(filter: null, cursor: null, limit: 5) {\n totalCount\n items {\n id\n ...ProjectPageAutomationsRow_Automation\n }\n cursor\n }\n workspace {\n id\n automateFunctions(limit: 0) {\n totalCount\n }\n ...AutomateFunctionCreateDialog_Workspace\n }\n ...FormSelectProjects_Project\n }\n ...AutomateFunctionsPageHeader_Query\n }\n"): (typeof documents)["\n query ProjectAutomationsTab($projectId: String!) {\n project(id: $projectId) {\n id\n role\n models(limit: 1) {\n items {\n id\n }\n }\n automations(filter: null, cursor: null, limit: 5) {\n totalCount\n items {\n id\n ...ProjectPageAutomationsRow_Automation\n }\n cursor\n }\n workspace {\n id\n automateFunctions(limit: 0) {\n totalCount\n }\n ...AutomateFunctionCreateDialog_Workspace\n }\n ...FormSelectProjects_Project\n }\n ...AutomateFunctionsPageHeader_Query\n }\n"];
|
||||
/**
|
||||
* The graphql function is used to parse GraphQL queries into a document that can be used by GraphQL clients.
|
||||
*/
|
||||
@@ -1829,7 +1834,7 @@ export function graphql(source: "\n fragment AutomateFunctionPage_AutomateFunct
|
||||
/**
|
||||
* 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 AutomateFunctionPage($functionId: ID!) {\n automateFunction(id: $functionId) {\n ...AutomateFunctionPage_AutomateFunction\n }\n activeUser {\n workspaces {\n items {\n ...AutomateFunctionCreateDialog_Workspace\n }\n }\n }\n }\n"): (typeof documents)["\n query AutomateFunctionPage($functionId: ID!) {\n automateFunction(id: $functionId) {\n ...AutomateFunctionPage_AutomateFunction\n }\n activeUser {\n workspaces {\n items {\n ...AutomateFunctionCreateDialog_Workspace\n }\n }\n }\n }\n"];
|
||||
export function graphql(source: "\n query AutomateFunctionPage($functionId: ID!) {\n automateFunction(id: $functionId) {\n ...AutomateFunctionPage_AutomateFunction\n }\n activeUser {\n workspaces {\n items {\n ...AutomateFunctionCreateDialog_Workspace\n ...AutomateFunctionEditDialog_Workspace\n }\n }\n }\n }\n"): (typeof documents)["\n query AutomateFunctionPage($functionId: ID!) {\n automateFunction(id: $functionId) {\n ...AutomateFunctionPage_AutomateFunction\n }\n activeUser {\n workspaces {\n items {\n ...AutomateFunctionCreateDialog_Workspace\n ...AutomateFunctionEditDialog_Workspace\n }\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
@@ -62,7 +62,11 @@ export const projectWebhooksRoute = (projectId: string) =>
|
||||
export const threadRedirectRoute = (projectId: string, threadId: string) =>
|
||||
`/projects/${projectId}/threads/${threadId}`
|
||||
|
||||
export const automateGithubAppAuthorizationRoute = '/api/automate/auth/githubapp'
|
||||
export const automateGithubAppAuthorizationRoute = (workspaceSlug?: string) => {
|
||||
return `/api/automate/auth/githubapp${
|
||||
workspaceSlug ? `?workspaceSlug=${workspaceSlug}` : ''
|
||||
}`
|
||||
}
|
||||
|
||||
export const automationFunctionsRoute = '/functions'
|
||||
|
||||
|
||||
@@ -253,10 +253,10 @@ export const projectAutomationsTabQuery = graphql(`
|
||||
}
|
||||
workspace {
|
||||
id
|
||||
slug
|
||||
automateFunctions(limit: 0) {
|
||||
totalCount
|
||||
}
|
||||
...AutomateFunctionCreateDialog_Workspace
|
||||
}
|
||||
...FormSelectProjects_Project
|
||||
}
|
||||
|
||||
@@ -62,6 +62,7 @@ const pageQuery = graphql(`
|
||||
workspaces {
|
||||
items {
|
||||
...AutomateFunctionCreateDialog_Workspace
|
||||
...AutomateFunctionEditDialog_Workspace
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -11,10 +11,14 @@ import { authMiddlewareCreator } from '@/modules/shared/middleware'
|
||||
import { getRolesFactory } from '@/modules/shared/repositories/roles'
|
||||
import { Roles, Scopes } from '@speckle/shared'
|
||||
import { Application } from 'express'
|
||||
import { validateRequest } from 'zod-express'
|
||||
import { z } from 'zod'
|
||||
import { sessionMiddlewareFactory } from '@/modules/auth/middleware'
|
||||
|
||||
export default (app: Application) => {
|
||||
app.get(
|
||||
'/api/automate/auth/githubapp',
|
||||
sessionMiddlewareFactory(),
|
||||
corsMiddleware(),
|
||||
authMiddlewareCreator([
|
||||
validateServerRoleBuilderFactory({
|
||||
@@ -22,7 +26,14 @@ export default (app: Application) => {
|
||||
})({ requiredRole: Roles.Server.Guest }),
|
||||
validateScope({ requiredScope: Scopes.AutomateFunctions.Write })
|
||||
]),
|
||||
validateRequest({
|
||||
query: z.object({
|
||||
workspaceSlug: z.string().optional()
|
||||
})
|
||||
}),
|
||||
async (req, res) => {
|
||||
req.session.workspaceSlug = req.query.workspaceSlug
|
||||
|
||||
const startAuth = startAutomateFunctionCreatorAuthFactory({
|
||||
createStoredAuthCode: createStoredAuthCodeFactory({
|
||||
redis: getGenericRedis()
|
||||
@@ -34,6 +45,7 @@ export default (app: Application) => {
|
||||
|
||||
app.get(
|
||||
'/api/automate/ghAuthComplete',
|
||||
sessionMiddlewareFactory(),
|
||||
corsMiddleware(),
|
||||
authMiddlewareCreator([
|
||||
validateServerRoleBuilderFactory({
|
||||
|
||||
@@ -46,6 +46,7 @@ import { getFunctionsMarketplaceUrl } from '@/modules/core/helpers/routeHelper'
|
||||
import { automateLogger } from '@/logging/logging'
|
||||
import { CreateStoredAuthCode } from '@/modules/automate/domain/operations'
|
||||
import { GetUser } from '@/modules/core/domain/users/operations'
|
||||
import { noop } from 'lodash'
|
||||
|
||||
const mapGqlTemplateIdToExecEngineTemplateId = (
|
||||
id: AutomateFunctionTemplateLanguage
|
||||
@@ -272,9 +273,11 @@ export const handleAutomateFunctionCreatorAuthCallbackFactory =
|
||||
} = req.query as Record<string, string>
|
||||
|
||||
const isSuccess = ghAuth === 'success'
|
||||
const redirectUrl = getFunctionsMarketplaceUrl()
|
||||
const redirectUrl = getFunctionsMarketplaceUrl(req.session.workspaceSlug)
|
||||
redirectUrl.searchParams.set('ghAuth', isSuccess ? 'success' : ghAuth)
|
||||
redirectUrl.searchParams.set('ghAuthDesc', isSuccess ? '' : ghAuthDesc)
|
||||
|
||||
req.session?.destroy?.(noop)
|
||||
|
||||
return res.redirect(redirectUrl.toString())
|
||||
}
|
||||
|
||||
@@ -60,6 +60,7 @@ export function buildAbsoluteFrontendUrlFromPath(route: string): string {
|
||||
return new URL(route, getFrontendOrigin()).toString()
|
||||
}
|
||||
|
||||
export function getFunctionsMarketplaceUrl() {
|
||||
return new URL('/functions', getFrontendOrigin())
|
||||
export function getFunctionsMarketplaceUrl(workspaceSlug?: string) {
|
||||
const path = workspaceSlug ? `/workspaces/${workspaceSlug}/functions` : '/functions'
|
||||
return new URL(path, getFrontendOrigin())
|
||||
}
|
||||
|
||||
@@ -15,6 +15,7 @@ import { omit } from 'lodash'
|
||||
declare module 'express-session' {
|
||||
interface SessionData {
|
||||
workspaceId?: string
|
||||
workspaceSlug?: string
|
||||
ssoNonce?: string
|
||||
ssoState?: SsoSessionState
|
||||
oidcProvider?: OidcProvider
|
||||
|
||||
Reference in New Issue
Block a user