Files
speckle-server/packages/server/modules/workspaces/tests/helpers/creation.ts
T
Gergő Jedlicska 08e941f8af Poor man's SSO (#2641)
* Implemented workspace general page

* Added notifications to user input

* Allowed non-admins to view but not edit

* Added redirect to homeroute

* Fixed validation

* Squashed commit of the following:

commit 7bf14ab8af0f76b4c9d0aa87fc08085af7c34959
Author: Chuck Driesler <chuck@speckle.systems>
Date:   Tue Aug 6 19:40:50 2024 +0200

    mob next [ci-skip] [ci skip] [skip ci]

    lastFile:packages/server/modules/workspacesCore/migrations/20240806160740_workspace_domains.ts

commit 8aa3fb0cb052c10eeeb83bf9874ae0d1c065e480
Author: Alessandro Magionami <alessandro.magionami@gmail.com>
Date:   Tue Aug 6 18:54:15 2024 +0200

    mob next [ci-skip] [ci skip] [skip ci]

    lastFile:packages/server/modules/core/domain/userEmails/operations.ts

commit 66dfd0cf6c15a789c8f96a65a3168323e83a7b9e
Author: Chuck Driesler <chuck@speckle.systems>
Date:   Tue Aug 6 18:30:22 2024 +0200

    mob next [ci-skip] [ci skip] [skip ci]

    lastFile:packages/server/modules/workspacesCore/domain/types.ts

Co-authored-by: Alessandro Magionami <alessandro.magionami@gmail.com>

* Move General to workspaces folder

* feat(workspaces): inputs on security section

* feat(workspaces): add domain to workspace mutation

* chore(workspaces): add blocked domains list

* fix(workspaces): modals with buttons

* feat(workspaceDomains): delete domain

* fix(workspaces): use  mutation

* fix(workspaces): present user verified domains as options

* Moved sidebar menu to a composable

* Added coming soon tag back

* feat(workspaces): create domains resolver for workspace

* chore(workspaces): fix tests

* chore(workspaces): fix types

* chore(workspaces): fix linter

* fix(workspaces): do some delete I think

* chore(workspaces): add domainBasedMembershipProtectionEnabled field to workspace

* chore(workspaces): improve validation for email domain

* fix(workspace): query and do the thing

* chore(workspaces): add graphql schema for domainBasedMembershipProtection

* chore(workspaces): lint and test failures

* fix(workspaces): test issues w new field

* feat(workspaces): add discoverability flag

* chore(workspaces): they made me do it

* feat(workspaces): enable toggling domain protection

* feat(workspaces): add discoverability toggle to workspace settings

* feat(workspace): auto enable discoverability on first domain registration

* feat(workspace): discoverability toggle fixes

* fix(eventBus): fix tests

* feat(workspaces): user discoverable workspaces (#2620)

* feat(workspaces): it works just trust me

* fix(workspaces): don't worry about it

* fix(workspaces); happy path success

* fix(workspaces): almost there

* fix(workspaces): successful tests!

* fix(workspaces): we have DISCOVERED (#2621)

* Fixed linting issue

* Updated query

* Updated validation rules

* Updated validation rules

* Fix unsaved file with type export

* Addressed PR comments

* Updated cache

* Updated item classes, add fragment back

* Gergo/web 1574 join workspaces via discovery (#2623)

* chore(useremails): add find verified emails by user function

* chore(workspace): table helper for workspace domains

* chore(workspace): get workspace with domains function

* chore(workspace): test get workspace with domains function

* feat(workspace): restrict workspace membership when updating workspace role

* chore(workspaces): fix types

* feat(workspaces): WIP join

* feat(workspaces): join button makes u join

* chore(useremails): fix type for find verified emails function

* feat(workspaces): join

* feat(workspace): prevent inviting user without email matching domain

* chore(workspaces): fix linter

* fix(workspaces): invoke join (gergo wrote this)

* fuck

* fix(workspaces): properly get discoverable workspaces

* fix(workspaces): test

---------

Co-authored-by: Gergő Jedlicska <gergo@jedlicska.com>
Co-authored-by: Chuck Driesler <chuck@speckle.systems>

* fix(workspaces): some query stuff

* fix(workspaces): mutate cache instead of refetch

* fix(workspaces): more adjustments to gql query and fragment structure

* fix(workspaces): queries, style, structure

* fix(workspaces): match discoverability with current styles

* chore(workspaces): lint lint lint

* fix(workspaces): got it twisted

* chore(workspaces): fix test

* fix(workspaces): route to joined workspace on join

---------

Co-authored-by: Mike Tasset <mike.tasset@gmail.com>
Co-authored-by: Chuck Driesler <chuck@speckle.systems>
Co-authored-by: Alessandro Magionami <alessandro.magionami@gmail.com>
2024-08-26 13:33:16 +02:00

196 lines
5.8 KiB
TypeScript

import { db } from '@/db/knex'
import {
getStream,
grantStreamPermissions,
revokeStreamPermissions
} from '@/modules/core/repositories/streams'
import { findVerifiedEmailsByUserIdFactory } from '@/modules/core/repositories/userEmails'
import { getStreams } from '@/modules/core/services/streams'
import {
findUserByTargetFactory,
insertInviteAndDeleteOldFactory
} from '@/modules/serverinvites/repositories/serverInvites'
import { createAndSendInviteFactory } from '@/modules/serverinvites/services/creation'
import { getEventBus } from '@/modules/shared/services/eventBus'
import {
getWorkspaceRolesFactory,
upsertWorkspaceFactory,
upsertWorkspaceRoleFactory,
deleteWorkspaceRoleFactory as dbDeleteWorkspaceRoleFactory,
getWorkspaceFactory,
getWorkspaceWithDomainsFactory,
getWorkspaceDomainsFactory
} from '@/modules/workspaces/repositories/workspaces'
import {
buildWorkspaceInviteEmailContentsFactory,
collectAndValidateWorkspaceTargetsFactory,
createWorkspaceInviteFactory
} from '@/modules/workspaces/services/invites'
import {
createWorkspaceFactory,
updateWorkspaceRoleFactory,
deleteWorkspaceRoleFactory,
updateWorkspaceFactory
} from '@/modules/workspaces/services/management'
import { BasicTestUser } from '@/test/authHelper'
import { CreateWorkspaceInviteMutationVariables } from '@/test/graphql/generated/graphql'
import { MaybeNullOrUndefined, Roles, WorkspaceRoles } from '@speckle/shared'
export type BasicTestWorkspace = {
/**
* Leave empty, will be filled on creation
*/
id: string
/**
* Leave empty, will be filled on creation
*/
ownerId: string
name: string
description?: string
logo?: string
discoverabilityEnabled?: boolean
domainBasedMembershipProtectionEnabled?: boolean
}
export const createTestWorkspace = async (
workspace: BasicTestWorkspace,
owner: BasicTestUser
) => {
const createWorkspace = createWorkspaceFactory({
upsertWorkspace: upsertWorkspaceFactory({ db }),
upsertWorkspaceRole: upsertWorkspaceRoleFactory({ db }),
emitWorkspaceEvent: (...args) => getEventBus().emit(...args)
})
const newWorkspace = await createWorkspace({
userId: owner.id,
workspaceInput: {
name: workspace.name,
description: workspace.description || null,
logo: workspace.logo || null,
defaultLogoIndex: 0
},
userResourceAccessLimits: null
})
workspace.id = newWorkspace.id
if (workspace.discoverabilityEnabled) {
const updateWorkspace = updateWorkspaceFactory({
getWorkspace: getWorkspaceFactory({ db }),
upsertWorkspace: upsertWorkspaceFactory({ db }),
emitWorkspaceEvent: (...args) => getEventBus().emit(...args)
})
await updateWorkspace({
workspaceId: newWorkspace.id,
workspaceInput: {
discoverabilityEnabled: true
}
})
}
await updateWorkspaceFactory({
getWorkspace: getWorkspaceFactory({ db }),
upsertWorkspace: upsertWorkspaceFactory({ db }),
emitWorkspaceEvent: getEventBus().emit
})({
workspaceId: newWorkspace.id,
workspaceInput: { domainBasedMembershipProtectionEnabled: true }
})
workspace.ownerId = owner.id
}
export const assignToWorkspace = async (
workspace: BasicTestWorkspace,
user: BasicTestUser,
role?: WorkspaceRoles
) => {
const updateWorkspaceRole = updateWorkspaceRoleFactory({
getWorkspaceWithDomains: getWorkspaceWithDomainsFactory({ db }),
findVerifiedEmailsByUserId: findVerifiedEmailsByUserIdFactory({ db }),
getWorkspaceRoles: getWorkspaceRolesFactory({ db }),
upsertWorkspaceRole: upsertWorkspaceRoleFactory({ db }),
emitWorkspaceEvent: (...args) => getEventBus().emit(...args),
getStreams,
grantStreamPermissions
})
await updateWorkspaceRole({
userId: user.id,
workspaceId: workspace.id,
role: role || Roles.Workspace.Member
})
}
export const unassignFromWorkspace = async (
workspace: BasicTestWorkspace,
user: BasicTestUser
) => {
const deleteWorkspaceRole = deleteWorkspaceRoleFactory({
getWorkspaceRoles: getWorkspaceRolesFactory({ db }),
deleteWorkspaceRole: dbDeleteWorkspaceRoleFactory({ db }),
emitWorkspaceEvent: (...args) => getEventBus().emit(...args),
getStreams,
revokeStreamPermissions
})
await deleteWorkspaceRole({
userId: user.id,
workspaceId: workspace.id
})
}
export const unassignFromWorkspaces = async (
pairs: [BasicTestWorkspace, BasicTestUser][]
) => {
await Promise.all(pairs.map((p) => unassignFromWorkspace(p[0], p[1])))
}
export const assignToWorkspaces = async (
pairs: [BasicTestWorkspace, BasicTestUser, MaybeNullOrUndefined<WorkspaceRoles>][]
) => {
await Promise.all(pairs.map((p) => assignToWorkspace(p[0], p[1], p[2] || undefined)))
}
export const createTestWorkspaces = async (
pairs: [BasicTestWorkspace, BasicTestUser][]
) => {
await Promise.all(pairs.map((p) => createTestWorkspace(p[0], p[1])))
}
export const createWorkspaceInviteDirectly = async (
args: CreateWorkspaceInviteMutationVariables,
inviterId: string
) => {
const createAndSendInvite = createAndSendInviteFactory({
findUserByTarget: findUserByTargetFactory(),
insertInviteAndDeleteOld: insertInviteAndDeleteOldFactory({ db }),
collectAndValidateResourceTargets: collectAndValidateWorkspaceTargetsFactory({
getStream,
getWorkspace: getWorkspaceFactory({ db }),
getWorkspaceDomains: getWorkspaceDomainsFactory({ db }),
findVerifiedEmailsByUserId: findVerifiedEmailsByUserIdFactory({ db })
}),
buildInviteEmailContents: buildWorkspaceInviteEmailContentsFactory({
getStream,
getWorkspace: getWorkspaceFactory({ db })
}),
emitEvent: ({ eventName, payload }) =>
getEventBus().emit({
eventName,
payload
})
})
const createInvite = createWorkspaceInviteFactory({
createAndSendInvite
})
return await createInvite({
...args,
inviterId,
inviterResourceAccessRules: null
})
}