fix(server): some serverinvites regressions (#2538)

* project invite retrieval

* fix for invalid invite target when inviting registered user by email

* improved error msg w/ broken streamId
This commit is contained in:
Kristaps Fabians Geikins 2024-07-29 19:15:26 +03:00 коммит произвёл GitHub
Родитель abd89a37b8
Коммит 281f77ac11
Не найден ключ, соответствующий данной подписи
Идентификатор ключа GPG: B5690EEEBB952194
7 изменённых файлов: 273 добавлений и 116 удалений

Просмотреть файл

@ -154,12 +154,6 @@ export = {
},
async streamInviteCreate(_parent, args, context) {
await authorizeResolver(
context.userId,
args.input.streamId,
Roles.Stream.Owner,
context.resourceAccessRules
)
const createProjectInvite = createProjectInviteFactory({
createAndSendInvite: buildCreateAndSendServerOrProjectInvite()
})
@ -320,17 +314,18 @@ export = {
},
ProjectInviteMutations: {
async create(_parent, args, ctx) {
await authorizeResolver(
ctx.userId,
args.projectId,
Roles.Stream.Owner,
ctx.resourceAccessRules
)
const createProjectInvite = createProjectInviteFactory({
createAndSendInvite: buildCreateAndSendServerOrProjectInvite()
})
await createProjectInvite(args, ctx.userId!, ctx.resourceAccessRules)
await createProjectInvite(
{
projectId: args.projectId,
...args.input
},
ctx.userId!,
ctx.resourceAccessRules
)
return ctx.loaders.streams.getStream.load(args.projectId)
},
async batchCreate(_parent, args, ctx) {

Просмотреть файл

@ -57,7 +57,7 @@ export async function down(knex: Knex): Promise<void> {
table.string('serverRole')
table.index(OLD_IDX_2)
table.index(OLD_UNIQUE_IDX_COLS)
table.unique(OLD_UNIQUE_IDX_COLS)
})
// Move back from resource to old fields

Просмотреть файл

@ -95,7 +95,8 @@ export const createAndSendInviteFactory =
}): CreateAndSendInvite =>
async (params, inviterResourceAccessLimits?) => {
const sendInviteEmail = sendInviteEmailFactory({ buildInviteEmailContents })
const { inviterId, target } = params
const { inviterId } = params
let { target } = params
let { message } = params
const [inviter, targetUser, serverInfo] = await Promise.all([
@ -111,6 +112,10 @@ export const createAndSendInviteFactory =
throw new InviteCreateValidationError('Attempting to invite an invalid user')
}
if (targetData.userId) {
target = buildUserTarget(targetData.userId)!
}
if (message && message.length >= 1024) {
throw new InviteCreateValidationError('Personal message too long')
}

Просмотреть файл

@ -57,6 +57,13 @@ export const createProjectInviteFactory =
throw new InviteCreateValidationError('Either email or userId must be specified')
}
const resourceId = isStreamInviteCreateInput(input)
? input.streamId
: input.projectId
if (!resourceId?.length) {
throw new InviteCreateValidationError('Invalid project ID specified')
}
const target = (userId ? buildUserTarget(userId) : email)!
await deps.createAndSendInvite(
{
@ -67,9 +74,7 @@ export const createProjectInviteFactory =
: undefined,
primaryResourceTarget: {
resourceType: ProjectInviteResourceType,
resourceId: isStreamInviteCreateInput(input)
? input.streamId
: input.projectId,
resourceId,
role: role || Roles.Stream.Contributor,
primary: true
}

Просмотреть файл

@ -26,9 +26,12 @@ import {
BatchCreateServerInviteDocument,
BatchCreateStreamInviteDocument,
CancelStreamInviteDocument,
CreateProjectInviteDocument,
CreateProjectInviteMutationVariables,
CreateServerInviteDocument,
CreateStreamInviteDocument,
DeleteInviteDocument,
GetOwnProjectInvitesDocument,
GetStreamInviteDocument,
GetStreamInvitesDocument,
GetStreamPendingCollaboratorsDocument,
@ -195,6 +198,9 @@ describe('[Stream & Server Invites]', () => {
const createInvite = (input: StreamInviteCreateInput) =>
apollo.execute(CreateStreamInviteDocument, { input })
const createProjectInvite = (args: CreateProjectInviteMutationVariables) =>
apollo.execute(CreateProjectInviteDocument, args)
before(async () => {
// Create a stream and make sure otherGuy is already a contributor there
await createTestStream(otherGuyAlreadyInvitedStream, me)
@ -241,112 +247,203 @@ describe('[Stream & Server Invites]', () => {
)
})
const userTypesDataSet = [
{
display: 'registered user',
user: otherGuy,
stream: myPrivateStream,
email: null
},
{
display: 'registered user (with custom role)',
user: otherGuy,
stream: myPrivateStream,
email: null,
role: Roles.Stream.Owner
},
{
display: 'unregistered user',
user: null,
stream: myPrivateStream,
email: 'randomer22@lool.com'
},
{
display: 'unregistered user (with custom role)',
user: null,
stream: myPrivateStream,
email: 'randomer22@lool.com',
Role: Roles.Stream.Reviewer
}
]
const createInviteTypes = [{ projectInvite: false }, { projectInvite: true }]
userTypesDataSet.forEach(({ display, user, stream, email, role }) => {
it(`can invite a ${display}`, async () => {
const messagePart1 = '1234hiiiiduuuuude'
const messagePart2 = 'yepppppp'
const unsanitaryMessage = `<a href="https://google.com">${messagePart1}</a> <script>${messagePart2}</script>`
const targetEmail = email || user?.email
createInviteTypes.forEach(({ projectInvite }) => {
const userTypesDataSet = [
{
display: 'registered user',
user: otherGuy,
stream: myPrivateStream,
email: null
},
{
display: 'registered user (with custom role)',
user: otherGuy,
stream: myPrivateStream,
email: null,
role: Roles.Stream.Owner
},
{
display: 'unregistered user',
user: null,
stream: myPrivateStream,
email: 'randomer22@lool.com'
},
{
display: 'unregistered user (with custom role)',
user: null,
stream: myPrivateStream,
email: 'randomer22@lool.com',
Role: Roles.Stream.Reviewer
}
]
const sendEmailInvocations = mailerMock.hijackFunction(
'sendEmail',
async () => true
)
userTypesDataSet.forEach(({ display, user, stream, email, role }) => {
it(`can ${
projectInvite ? 'project' : 'stream'
} invite a ${display}`, async () => {
const messagePart1 = '1234hiiiiduuuuude'
const messagePart2 = 'yepppppp'
const unsanitaryMessage = `<a href="https://google.com">${messagePart1}</a> <script>${messagePart2}</script>`
const targetEmail = email || user?.email
const result = await createInvite({
email,
message: unsanitaryMessage,
userId: user?.id || null,
streamId: stream.id,
role: role || null
const sendEmailInvocations = mailerMock.hijackFunction(
'sendEmail',
async () => true
)
if (projectInvite) {
const result = await createProjectInvite({
projectId: stream.id,
input: {
email,
userId: user?.id || null,
role: role || null
}
})
// Check that operation was successful
expect(result.data?.projectMutations.invites.create).to.be.ok
expect(result.errors).to.be.not.ok
} else {
const result = await createInvite({
email,
message: unsanitaryMessage,
userId: user?.id || null,
streamId: stream.id,
role: role || null
})
// Check that operation was successful
expect(result.data?.streamInviteCreate).to.be.ok
expect(result.errors).to.be.not.ok
}
// Check that email was sent out
const emailParams = sendEmailInvocations.args[0][0]
expect(emailParams).to.be.ok
expect(emailParams.to).to.eq(targetEmail)
expect(emailParams.subject).to.be.ok
// Check that message was sanitized
if (!projectInvite) {
expect(emailParams.text).to.contain(messagePart1)
expect(emailParams.text).to.not.contain(messagePart2)
expect(emailParams.html).to.contain(messagePart1)
expect(emailParams.html).to.not.contain(messagePart2)
}
// Validate that invite exists
const invite = await validateInviteExistanceFromEmail(emailParams)
expect(invite).to.be.ok
expect(invite?.resource.role).to.eq(role || Roles.Stream.Contributor)
})
// Check that operation was successful
expect(result.data?.streamInviteCreate).to.be.ok
expect(result.errors).to.be.not.ok
// Check that email was sent out
const emailParams = sendEmailInvocations.args[0][0]
expect(emailParams).to.be.ok
expect(emailParams.to).to.eq(targetEmail)
expect(emailParams.subject).to.be.ok
// Check that message was sanitized
expect(emailParams.text).to.contain(messagePart1)
expect(emailParams.text).to.not.contain(messagePart2)
expect(emailParams.html).to.contain(messagePart1)
expect(emailParams.html).to.not.contain(messagePart2)
// Validate that invite exists
const invite = await validateInviteExistanceFromEmail(emailParams)
expect(invite).to.be.ok
expect(invite?.resource.role).to.eq(role || Roles.Stream.Contributor)
})
})
it("can't invite user to a nonexistant stream", async () => {
const result = await createInvite({
email: 'whocares@really.com',
streamId: 'ayoooooooo'
})
expect(result.data).to.not.be.ok
expect((result.errors || []).map((e) => e.message).join('|')).to.contain(
'not found'
)
})
it(`can't ${
projectInvite ? 'project' : 'stream'
} invite user to a nonexistant stream`, async () => {
const params = {
email: 'whocares@really.com',
streamId: 'ayoooooooo'
}
it("can't invite user to a stream, if not its owner", async () => {
const result = await createInvite({
email: 'whocares@really.com',
streamId: otherGuysStream.id
const result = projectInvite
? await createProjectInvite({
projectId: params.streamId,
input: {
email: params.email
}
})
: await createInvite({
email: params.email,
streamId: params.streamId
})
expect(result.data).to.not.be.ok
expect((result.errors || []).map((e) => e.message).join('|')).to.contain(
'not found'
)
})
expect(result.data).to.not.be.ok
expect((result.errors || []).map((e) => e.message).join('|')).to.contain(
'You are not authorized to access this resource'
)
})
it(`can't ${
projectInvite ? 'project' : 'stream'
} invite user w/ broken stream identifier`, async () => {
const params = {
email: 'whocares@really.com',
streamId: ''
}
it("can't invite a nonexistant user ID to a stream", async () => {
const result = await createInvite({
userId: 'bababooey',
streamId: myPrivateStream.id
const result = projectInvite
? await createProjectInvite({
projectId: params.streamId,
input: {
email: params.email
}
})
: await createInvite({
email: params.email,
streamId: params.streamId
})
expect(result.data).to.not.be.ok
expect((result.errors || []).map((e) => e.message).join('|')).to.contain(
'Invalid project ID'
)
})
expect(result.data).to.not.be.ok
expect((result.errors || []).map((e) => e.message).join('|')).to.contain(
'Attempting to invite an invalid user'
)
it(`can't ${
projectInvite ? 'project' : 'stream'
} invite user to a stream, if not its owner`, async () => {
const params = {
email: 'whocares@really.com',
streamId: otherGuysStream.id
}
const result = projectInvite
? await createProjectInvite({
projectId: params.streamId,
input: {
email: params.email
}
})
: await createInvite({
email: params.email,
streamId: params.streamId
})
expect(result.data).to.not.be.ok
expect((result.errors || []).map((e) => e.message).join('|')).to.contain(
'You are not authorized to access this resource'
)
})
it(`can't ${
projectInvite ? 'project' : 'stream'
} invite a nonexistant user ID to a stream`, async () => {
const params = {
userId: 'bababooey',
streamId: myPrivateStream.id
}
const result = projectInvite
? await createProjectInvite({
projectId: params.streamId,
input: {
userId: params.userId
}
})
: await createInvite({
userId: params.userId,
streamId: params.streamId
})
expect(result.data).to.not.be.ok
expect((result.errors || []).map((e) => e.message).join('|')).to.contain(
'Attempting to invite an invalid user'
)
})
})
})
@ -769,14 +866,16 @@ describe('[Stream & Server Invites]', () => {
await Promise.all([
createInviteDirectly(
{
user: ownInvitesGuy,
stream: myPrivateStream
stream: myPrivateStream,
// SPecifically w/ email
email: ownInvitesGuy.email
},
me.id
),
createInviteDirectly(
{
user: ownInvitesGuy,
// Specifically w/ id
userId: ownInvitesGuy.id,
stream: otherGuysStream
},
otherGuy.id
@ -787,7 +886,7 @@ describe('[Stream & Server Invites]', () => {
apollo = await testApolloServer({ authUserId: ownInvitesGuy.id })
})
it('all invites can be retrieved successfully', async () => {
it('all stream invites can be retrieved successfully', async () => {
const { data, errors } = await apollo.execute(GetStreamInvitesDocument, {})
expect(errors).to.be.not.ok
@ -800,6 +899,20 @@ describe('[Stream & Server Invites]', () => {
expect(expectedStreamIds.includes(firstInvite.streamId)).to.be.ok
expect(expectedStreamIds.includes(secondInvite.streamId)).to.be.ok
})
it('all project invites can be retrieved successfully', async () => {
const { data, errors } = await apollo.execute(GetOwnProjectInvitesDocument, {})
expect(errors).to.be.not.ok
expect(data?.activeUser?.projectInvites).to.be.ok
expect(data!.activeUser!.projectInvites.length).to.eq(2)
const expectedStreamIds = [myPrivateStream.id, otherGuysStream.id]
const firstInvite = data!.activeUser!.projectInvites[0]
const secondInvite = data!.activeUser!.projectInvites[1]
expect(expectedStreamIds.includes(firstInvite.streamId)).to.be.ok
expect(expectedStreamIds.includes(secondInvite.streamId)).to.be.ok
})
})
})
})

Просмотреть файл

@ -4257,6 +4257,11 @@ export type GetStreamInvitesQueryVariables = Exact<{ [key: string]: never; }>;
export type GetStreamInvitesQuery = { __typename?: 'Query', streamInvites: Array<{ __typename?: 'PendingStreamCollaborator', id: string, inviteId: string, streamId: string, title: string, role: string, token?: string | null, invitedBy: { __typename?: 'LimitedUser', id: string, name: string, bio?: string | null, company?: string | null, avatar?: string | null, verified?: boolean | null }, user?: { __typename?: 'LimitedUser', id: string, name: string, bio?: string | null, company?: string | null, avatar?: string | null, verified?: boolean | null } | null }> };
export type GetOwnProjectInvitesQueryVariables = Exact<{ [key: string]: never; }>;
export type GetOwnProjectInvitesQuery = { __typename?: 'Query', activeUser?: { __typename?: 'User', projectInvites: Array<{ __typename?: 'PendingStreamCollaborator', id: string, inviteId: string, streamId: string, title: string, role: string, token?: string | null, invitedBy: { __typename?: 'LimitedUser', id: string, name: string, bio?: string | null, company?: string | null, avatar?: string | null, verified?: boolean | null }, user?: { __typename?: 'LimitedUser', id: string, name: string, bio?: string | null, company?: string | null, avatar?: string | null, verified?: boolean | null } | null }> } | null };
export type UseStreamInviteMutationVariables = Exact<{
accept: Scalars['Boolean']['input'];
streamId: Scalars['String']['input'];
@ -4281,6 +4286,14 @@ export type GetStreamPendingCollaboratorsQueryVariables = Exact<{
export type GetStreamPendingCollaboratorsQuery = { __typename?: 'Query', stream?: { __typename?: 'Stream', id: string, pendingCollaborators?: Array<{ __typename?: 'PendingStreamCollaborator', inviteId: string, title: string, token?: string | null, user?: { __typename?: 'LimitedUser', id: string, name: string } | null }> | null } | null };
export type CreateProjectInviteMutationVariables = Exact<{
projectId: Scalars['ID']['input'];
input: ProjectInviteCreateInput;
}>;
export type CreateProjectInviteMutation = { __typename?: 'Mutation', projectMutations: { __typename?: 'ProjectMutations', invites: { __typename?: 'ProjectInviteMutations', create: { __typename?: 'Project', id: string } } } };
export type BasicStreamFieldsFragment = { __typename?: 'Stream', id: string, name: string, description?: string | null, isPublic: boolean, isDiscoverable: boolean, allowPublicComments: boolean, role?: string | null, createdAt: string, updatedAt: string };
export type LeaveStreamMutationVariables = Exact<{
@ -4485,9 +4498,11 @@ export const BatchCreateStreamInviteDocument = {"kind":"Document","definitions":
export const DeleteInviteDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"mutation","name":{"kind":"Name","value":"DeleteInvite"},"variableDefinitions":[{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"inviteId"}},"type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"String"}}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"inviteDelete"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"inviteId"},"value":{"kind":"Variable","name":{"kind":"Name","value":"inviteId"}}}]}]}}]} as unknown as DocumentNode<DeleteInviteMutation, DeleteInviteMutationVariables>;
export const GetStreamInviteDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"query","name":{"kind":"Name","value":"GetStreamInvite"},"variableDefinitions":[{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"streamId"}},"type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"String"}}}},{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"token"}},"type":{"kind":"NamedType","name":{"kind":"Name","value":"String"}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"streamInvite"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"streamId"},"value":{"kind":"Variable","name":{"kind":"Name","value":"streamId"}}},{"kind":"Argument","name":{"kind":"Name","value":"token"},"value":{"kind":"Variable","name":{"kind":"Name","value":"token"}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"FragmentSpread","name":{"kind":"Name","value":"StreamInviteData"}}]}}]}},{"kind":"FragmentDefinition","name":{"kind":"Name","value":"StreamInviteData"},"typeCondition":{"kind":"NamedType","name":{"kind":"Name","value":"PendingStreamCollaborator"}},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"inviteId"}},{"kind":"Field","name":{"kind":"Name","value":"streamId"}},{"kind":"Field","name":{"kind":"Name","value":"title"}},{"kind":"Field","name":{"kind":"Name","value":"role"}},{"kind":"Field","name":{"kind":"Name","value":"token"}},{"kind":"Field","name":{"kind":"Name","value":"invitedBy"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"name"}},{"kind":"Field","name":{"kind":"Name","value":"bio"}},{"kind":"Field","name":{"kind":"Name","value":"company"}},{"kind":"Field","name":{"kind":"Name","value":"avatar"}},{"kind":"Field","name":{"kind":"Name","value":"verified"}}]}},{"kind":"Field","name":{"kind":"Name","value":"user"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"name"}},{"kind":"Field","name":{"kind":"Name","value":"bio"}},{"kind":"Field","name":{"kind":"Name","value":"company"}},{"kind":"Field","name":{"kind":"Name","value":"avatar"}},{"kind":"Field","name":{"kind":"Name","value":"verified"}}]}}]}}]} as unknown as DocumentNode<GetStreamInviteQuery, GetStreamInviteQueryVariables>;
export const GetStreamInvitesDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"query","name":{"kind":"Name","value":"GetStreamInvites"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"streamInvites"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"FragmentSpread","name":{"kind":"Name","value":"StreamInviteData"}}]}}]}},{"kind":"FragmentDefinition","name":{"kind":"Name","value":"StreamInviteData"},"typeCondition":{"kind":"NamedType","name":{"kind":"Name","value":"PendingStreamCollaborator"}},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"inviteId"}},{"kind":"Field","name":{"kind":"Name","value":"streamId"}},{"kind":"Field","name":{"kind":"Name","value":"title"}},{"kind":"Field","name":{"kind":"Name","value":"role"}},{"kind":"Field","name":{"kind":"Name","value":"token"}},{"kind":"Field","name":{"kind":"Name","value":"invitedBy"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"name"}},{"kind":"Field","name":{"kind":"Name","value":"bio"}},{"kind":"Field","name":{"kind":"Name","value":"company"}},{"kind":"Field","name":{"kind":"Name","value":"avatar"}},{"kind":"Field","name":{"kind":"Name","value":"verified"}}]}},{"kind":"Field","name":{"kind":"Name","value":"user"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"name"}},{"kind":"Field","name":{"kind":"Name","value":"bio"}},{"kind":"Field","name":{"kind":"Name","value":"company"}},{"kind":"Field","name":{"kind":"Name","value":"avatar"}},{"kind":"Field","name":{"kind":"Name","value":"verified"}}]}}]}}]} as unknown as DocumentNode<GetStreamInvitesQuery, GetStreamInvitesQueryVariables>;
export const GetOwnProjectInvitesDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"query","name":{"kind":"Name","value":"GetOwnProjectInvites"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"activeUser"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"projectInvites"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"FragmentSpread","name":{"kind":"Name","value":"StreamInviteData"}}]}}]}}]}},{"kind":"FragmentDefinition","name":{"kind":"Name","value":"StreamInviteData"},"typeCondition":{"kind":"NamedType","name":{"kind":"Name","value":"PendingStreamCollaborator"}},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"inviteId"}},{"kind":"Field","name":{"kind":"Name","value":"streamId"}},{"kind":"Field","name":{"kind":"Name","value":"title"}},{"kind":"Field","name":{"kind":"Name","value":"role"}},{"kind":"Field","name":{"kind":"Name","value":"token"}},{"kind":"Field","name":{"kind":"Name","value":"invitedBy"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"name"}},{"kind":"Field","name":{"kind":"Name","value":"bio"}},{"kind":"Field","name":{"kind":"Name","value":"company"}},{"kind":"Field","name":{"kind":"Name","value":"avatar"}},{"kind":"Field","name":{"kind":"Name","value":"verified"}}]}},{"kind":"Field","name":{"kind":"Name","value":"user"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"name"}},{"kind":"Field","name":{"kind":"Name","value":"bio"}},{"kind":"Field","name":{"kind":"Name","value":"company"}},{"kind":"Field","name":{"kind":"Name","value":"avatar"}},{"kind":"Field","name":{"kind":"Name","value":"verified"}}]}}]}}]} as unknown as DocumentNode<GetOwnProjectInvitesQuery, GetOwnProjectInvitesQueryVariables>;
export const UseStreamInviteDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"mutation","name":{"kind":"Name","value":"UseStreamInvite"},"variableDefinitions":[{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"accept"}},"type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"Boolean"}}}},{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"streamId"}},"type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"String"}}}},{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"token"}},"type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"String"}}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"streamInviteUse"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"accept"},"value":{"kind":"Variable","name":{"kind":"Name","value":"accept"}}},{"kind":"Argument","name":{"kind":"Name","value":"streamId"},"value":{"kind":"Variable","name":{"kind":"Name","value":"streamId"}}},{"kind":"Argument","name":{"kind":"Name","value":"token"},"value":{"kind":"Variable","name":{"kind":"Name","value":"token"}}}]}]}}]} as unknown as DocumentNode<UseStreamInviteMutation, UseStreamInviteMutationVariables>;
export const CancelStreamInviteDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"mutation","name":{"kind":"Name","value":"CancelStreamInvite"},"variableDefinitions":[{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"streamId"}},"type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"String"}}}},{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"inviteId"}},"type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"String"}}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"streamInviteCancel"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"streamId"},"value":{"kind":"Variable","name":{"kind":"Name","value":"streamId"}}},{"kind":"Argument","name":{"kind":"Name","value":"inviteId"},"value":{"kind":"Variable","name":{"kind":"Name","value":"inviteId"}}}]}]}}]} as unknown as DocumentNode<CancelStreamInviteMutation, CancelStreamInviteMutationVariables>;
export const GetStreamPendingCollaboratorsDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"query","name":{"kind":"Name","value":"GetStreamPendingCollaborators"},"variableDefinitions":[{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"streamId"}},"type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"String"}}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"stream"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"id"},"value":{"kind":"Variable","name":{"kind":"Name","value":"streamId"}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"pendingCollaborators"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"inviteId"}},{"kind":"Field","name":{"kind":"Name","value":"title"}},{"kind":"Field","name":{"kind":"Name","value":"token"}},{"kind":"Field","name":{"kind":"Name","value":"user"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"name"}}]}}]}}]}}]}}]} as unknown as DocumentNode<GetStreamPendingCollaboratorsQuery, GetStreamPendingCollaboratorsQueryVariables>;
export const CreateProjectInviteDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"mutation","name":{"kind":"Name","value":"CreateProjectInvite"},"variableDefinitions":[{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"projectId"}},"type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"ID"}}}},{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"input"}},"type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"ProjectInviteCreateInput"}}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"projectMutations"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"invites"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"create"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"projectId"},"value":{"kind":"Variable","name":{"kind":"Name","value":"projectId"}}},{"kind":"Argument","name":{"kind":"Name","value":"input"},"value":{"kind":"Variable","name":{"kind":"Name","value":"input"}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}}]}}]}}]}}]}}]} as unknown as DocumentNode<CreateProjectInviteMutation, CreateProjectInviteMutationVariables>;
export const LeaveStreamDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"mutation","name":{"kind":"Name","value":"LeaveStream"},"variableDefinitions":[{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"streamId"}},"type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"String"}}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"streamLeave"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"streamId"},"value":{"kind":"Variable","name":{"kind":"Name","value":"streamId"}}}]}]}}]} as unknown as DocumentNode<LeaveStreamMutation, LeaveStreamMutationVariables>;
export const CreateStreamDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"mutation","name":{"kind":"Name","value":"CreateStream"},"variableDefinitions":[{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"stream"}},"type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"StreamCreateInput"}}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"streamCreate"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"stream"},"value":{"kind":"Variable","name":{"kind":"Name","value":"stream"}}}]}]}}]} as unknown as DocumentNode<CreateStreamMutation, CreateStreamMutationVariables>;
export const UpdateStreamDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"mutation","name":{"kind":"Name","value":"UpdateStream"},"variableDefinitions":[{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"stream"}},"type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"StreamUpdateInput"}}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"streamUpdate"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"stream"},"value":{"kind":"Variable","name":{"kind":"Name","value":"stream"}}}]}]}}]} as unknown as DocumentNode<UpdateStreamMutation, UpdateStreamMutationVariables>;

Просмотреть файл

@ -83,6 +83,18 @@ export const streamInvitesQuery = gql`
${streamInviteFragment}
`
export const getOwnProjectInvitesQuery = gql`
query GetOwnProjectInvites {
activeUser {
projectInvites {
...StreamInviteData
}
}
}
${streamInviteFragment}
`
export const useStreamInviteMutation = gql`
mutation UseStreamInvite($accept: Boolean!, $streamId: String!, $token: String!) {
streamInviteUse(accept: $accept, streamId: $streamId, token: $token)
@ -111,3 +123,15 @@ export const streamPendingCollaboratorsQuery = gql`
}
}
`
export const createProjectInviteMutation = gql`
mutation CreateProjectInvite($projectId: ID!, $input: ProjectInviteCreateInput!) {
projectMutations {
invites {
create(projectId: $projectId, input: $input) {
id
}
}
}
}
`