Files
speckle-server/packages/server/modules/serverinvites/services/management.ts
T
Gergő Jedlicska c6cd4c311d feat(serverinvites): create domain module in server invites (#2401)
* chore(serverinvites): repository refactor for multiregion

* chore(serverinvites): remove migrated functions from old repository

* chore(serverinvites): refactor serverInviteForToken resolver for multiregion

* chore(serverinvites): invite processing service refactor for multiregion

* chore(serverinvites): subscription refactor for multiregion

* chore(serverinvites): move buildEmailContents to dedicated file

* chore(serverinvites): deleteAllStreamInvites function multiregion refactor

* chore(serverinvites): refactor deleteServerOnlyInvites multiregion repository

* chore(serverinvites): complete repository refactor for multiregion

* feat(serverinvites): create domain module in server invites

* fix(serverinvites): no relative imports

* feat(serverinvites): extract individual types from repository

* feat(serverinvites): move interfaces to operations

* fix(serverinvites): update imports referencing old interfaces file

* fix(serverinvites): type mismatch for insert invite and delete old

* chore(serverinvites): refactor to single repo function

* test(serverinvites): fix tests

* fix(serverinvites): use domain types in all places

* feat(serverinvites): WIP unity

* feat(serverinvites): move to new facory names and types

* feat(serverinvites): fix tests

* fix(serverinvites): use factory name

---------

Co-authored-by: Alessandro Magionami <alessandro.magionami@gmail.com>
2024-06-25 13:24:37 +02:00

100 lines
3.1 KiB
TypeScript

import { MaybeNullOrUndefined, Roles, ServerRoles, StreamRoles } from '@speckle/shared'
import {
MutationStreamInviteUseArgs,
ProjectInviteCreateInput,
ProjectInviteUseInput,
StreamInviteCreateInput
} from '@/modules/core/graph/generated/graphql'
import { InviteCreateValidationError } from '@/modules/serverinvites/errors'
import {
buildUserTarget,
ResourceTargets
} from '@/modules/serverinvites/helpers/inviteHelper'
import { has } from 'lodash'
import {
ContextResourceAccessRules,
isResourceAllowed
} from '@/modules/core/helpers/token'
import { StreamInvalidAccessError } from '@/modules/core/errors/stream'
import {
CreateAndSendInvite,
FinalizeStreamInvite
} from '@/modules/serverinvites/services/operations'
import { TokenResourceIdentifier } from '@/modules/core/domain/tokens/types'
type FullProjectInviteCreateInput = ProjectInviteCreateInput & { projectId: string }
const isStreamInviteCreateInput = (
i: StreamInviteCreateInput | FullProjectInviteCreateInput
): i is StreamInviteCreateInput => has(i, 'streamId')
export const createStreamInviteAndNotifyFactory =
({ createAndSendInvite }: { createAndSendInvite: CreateAndSendInvite }) =>
async (
input: StreamInviteCreateInput | FullProjectInviteCreateInput,
inviterId: string,
inviterResourceAccessRules: MaybeNullOrUndefined<TokenResourceIdentifier[]>
) => {
const { email, userId, role } = input
if (!email && !userId) {
throw new InviteCreateValidationError('Either email or userId must be specified')
}
const target = (userId ? buildUserTarget(userId) : email)!
await createAndSendInvite(
{
target,
inviterId,
resourceTarget: ResourceTargets.Streams,
resourceId: isStreamInviteCreateInput(input) ? input.streamId : input.projectId,
role: (role as StreamRoles) || Roles.Stream.Contributor,
message: isStreamInviteCreateInput(input)
? input.message || undefined
: undefined,
serverRole: (input.serverRole as ServerRoles) || undefined
},
inviterResourceAccessRules
)
}
const isStreamInviteUseArgs = (
i: MutationStreamInviteUseArgs | ProjectInviteUseInput
): i is MutationStreamInviteUseArgs => has(i, 'streamId')
export const useStreamInviteAndNotify =
({ finalizeStreamInvite }: { finalizeStreamInvite: FinalizeStreamInvite }) =>
async (
input: MutationStreamInviteUseArgs | ProjectInviteUseInput,
userId: string,
userResourceAccessRules: ContextResourceAccessRules
) => {
const { accept, token } = input
if (
!isResourceAllowed({
resourceId: isStreamInviteUseArgs(input) ? input.streamId : input.projectId,
resourceType: 'project',
resourceAccessRules: userResourceAccessRules
})
) {
throw new StreamInvalidAccessError(
'You are not allowed to process an invite for this stream',
{
info: {
userId,
userResourceAccessRules,
input
}
}
)
}
await finalizeStreamInvite(
accept,
isStreamInviteUseArgs(input) ? input.streamId : input.projectId,
token,
userId
)
}