mirror of
https://github.com/toeverything/AFFiNE.git
synced 2026-08-08 20:57:08 +08:00
feat(server): improve team invite (#9092)
This commit is contained in:
@@ -1,3 +1,5 @@
|
|||||||
|
import { pick } from 'lodash-es';
|
||||||
|
|
||||||
import { PrismaTransaction } from '../../fundamentals';
|
import { PrismaTransaction } from '../../fundamentals';
|
||||||
import { formatDate, formatSize, Quota, QuotaSchema } from './types';
|
import { formatDate, formatSize, Quota, QuotaSchema } from './types';
|
||||||
|
|
||||||
@@ -5,7 +7,7 @@ const QuotaCache = new Map<number, QuotaConfig>();
|
|||||||
|
|
||||||
export class QuotaConfig {
|
export class QuotaConfig {
|
||||||
readonly config: Quota;
|
readonly config: Quota;
|
||||||
readonly override?: Quota['configs'];
|
readonly override?: Partial<Quota['configs']>;
|
||||||
|
|
||||||
static async get(tx: PrismaTransaction, featureId: number) {
|
static async get(tx: PrismaTransaction, featureId: number) {
|
||||||
const cachedQuota = QuotaCache.get(featureId);
|
const cachedQuota = QuotaCache.get(featureId);
|
||||||
@@ -49,7 +51,10 @@ export class QuotaConfig {
|
|||||||
configs: Object.assign({}, config.data.configs, override),
|
configs: Object.assign({}, config.data.configs, override),
|
||||||
});
|
});
|
||||||
if (overrideConfig.success) {
|
if (overrideConfig.success) {
|
||||||
this.override = overrideConfig.data.configs;
|
this.override = pick(
|
||||||
|
overrideConfig.data.configs,
|
||||||
|
Object.keys(override)
|
||||||
|
);
|
||||||
} else {
|
} else {
|
||||||
throw new Error(
|
throw new Error(
|
||||||
`Invalid quota override config: ${override.error.message}, ${JSON.stringify(
|
`Invalid quota override config: ${override.error.message}, ${JSON.stringify(
|
||||||
|
|||||||
@@ -280,7 +280,7 @@ export class QuotaService {
|
|||||||
.findFirst({
|
.findFirst({
|
||||||
where: {
|
where: {
|
||||||
workspaceId,
|
workspaceId,
|
||||||
feature: { feature: type, type: FeatureKind.Feature },
|
feature: { feature: type, type: FeatureKind.Quota },
|
||||||
activated: true,
|
activated: true,
|
||||||
},
|
},
|
||||||
select: { configs: true },
|
select: { configs: true },
|
||||||
|
|||||||
@@ -191,7 +191,7 @@ export class QuotaManagementService {
|
|||||||
FeatureType.UnlimitedWorkspace
|
FeatureType.UnlimitedWorkspace
|
||||||
);
|
);
|
||||||
|
|
||||||
const quota = {
|
const quota: QuotaBusinessType = {
|
||||||
name,
|
name,
|
||||||
blobLimit,
|
blobLimit,
|
||||||
businessBlobLimit,
|
businessBlobLimit,
|
||||||
|
|||||||
@@ -16,12 +16,14 @@ import {
|
|||||||
NotInSpace,
|
NotInSpace,
|
||||||
RequestMutex,
|
RequestMutex,
|
||||||
TooManyRequest,
|
TooManyRequest,
|
||||||
|
URLHelper,
|
||||||
} from '../../../fundamentals';
|
} from '../../../fundamentals';
|
||||||
import { CurrentUser } from '../../auth';
|
import { CurrentUser } from '../../auth';
|
||||||
import { Permission, PermissionService } from '../../permission';
|
import { Permission, PermissionService } from '../../permission';
|
||||||
import { QuotaManagementService } from '../../quota';
|
import { QuotaManagementService } from '../../quota';
|
||||||
import { UserService } from '../../user';
|
import { UserService } from '../../user';
|
||||||
import {
|
import {
|
||||||
|
InviteLink,
|
||||||
InviteResult,
|
InviteResult,
|
||||||
WorkspaceInviteLinkExpireTime,
|
WorkspaceInviteLinkExpireTime,
|
||||||
WorkspaceType,
|
WorkspaceType,
|
||||||
@@ -41,6 +43,7 @@ export class TeamWorkspaceResolver {
|
|||||||
private readonly cache: Cache,
|
private readonly cache: Cache,
|
||||||
private readonly event: EventEmitter,
|
private readonly event: EventEmitter,
|
||||||
private readonly mailer: MailService,
|
private readonly mailer: MailService,
|
||||||
|
private readonly url: URLHelper,
|
||||||
private readonly prisma: PrismaClient,
|
private readonly prisma: PrismaClient,
|
||||||
private readonly permissions: PermissionService,
|
private readonly permissions: PermissionService,
|
||||||
private readonly users: UserService,
|
private readonly users: UserService,
|
||||||
@@ -71,6 +74,10 @@ export class TeamWorkspaceResolver {
|
|||||||
Permission.Admin
|
Permission.Admin
|
||||||
);
|
);
|
||||||
|
|
||||||
|
if (emails.length > 512) {
|
||||||
|
return new TooManyRequest();
|
||||||
|
}
|
||||||
|
|
||||||
// lock to prevent concurrent invite
|
// lock to prevent concurrent invite
|
||||||
const lockFlag = `invite:${workspaceId}`;
|
const lockFlag = `invite:${workspaceId}`;
|
||||||
await using lock = await this.mutex.lock(lockFlag);
|
await using lock = await this.mutex.lock(lockFlag);
|
||||||
@@ -150,8 +157,27 @@ export class TeamWorkspaceResolver {
|
|||||||
return results;
|
return results;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ResolveField(() => InviteLink, {
|
||||||
|
description: 'invite link for workspace',
|
||||||
|
nullable: true,
|
||||||
|
})
|
||||||
|
async inviteLink(@Parent() workspace: WorkspaceType) {
|
||||||
|
const cacheId = `workspace:inviteLink:${workspace.id}`;
|
||||||
|
const id = await this.cache.get<{ inviteId: string }>(cacheId);
|
||||||
|
if (id) {
|
||||||
|
const expireTime = await this.cache.ttl(cacheId);
|
||||||
|
if (Number.isSafeInteger(expireTime)) {
|
||||||
|
return {
|
||||||
|
link: this.url.link(`/invite/${id.inviteId}`),
|
||||||
|
expireTime: new Date(Date.now() + expireTime),
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
@Mutation(() => String)
|
@Mutation(() => String)
|
||||||
async inviteLink(
|
async createInviteLink(
|
||||||
@CurrentUser() user: CurrentUser,
|
@CurrentUser() user: CurrentUser,
|
||||||
@Args('workspaceId') workspaceId: string,
|
@Args('workspaceId') workspaceId: string,
|
||||||
@Args('expireTime', { type: () => WorkspaceInviteLinkExpireTime })
|
@Args('expireTime', { type: () => WorkspaceInviteLinkExpireTime })
|
||||||
@@ -171,7 +197,11 @@ export class TeamWorkspaceResolver {
|
|||||||
const inviteId = nanoid();
|
const inviteId = nanoid();
|
||||||
const cacheInviteId = `workspace:inviteLinkId:${inviteId}`;
|
const cacheInviteId = `workspace:inviteLinkId:${inviteId}`;
|
||||||
await this.cache.set(cacheWorkspaceId, { inviteId }, { ttl: expireTime });
|
await this.cache.set(cacheWorkspaceId, { inviteId }, { ttl: expireTime });
|
||||||
await this.cache.set(cacheInviteId, { workspaceId }, { ttl: expireTime });
|
await this.cache.set(
|
||||||
|
cacheInviteId,
|
||||||
|
{ workspaceId, inviteeUserId: user.id },
|
||||||
|
{ ttl: expireTime }
|
||||||
|
);
|
||||||
return inviteId;
|
return inviteId;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -485,12 +485,15 @@ export class WorkspaceResolver {
|
|||||||
})
|
})
|
||||||
async getInviteInfo(@Args('inviteId') inviteId: string) {
|
async getInviteInfo(@Args('inviteId') inviteId: string) {
|
||||||
let workspaceId = null;
|
let workspaceId = null;
|
||||||
|
let invitee = null;
|
||||||
// invite link
|
// invite link
|
||||||
const invite = await this.cache.get<{ workspaceId: string }>(
|
const invite = await this.cache.get<{
|
||||||
`workspace:inviteLinkId:${inviteId}`
|
workspaceId: string;
|
||||||
);
|
inviteeUserId: string;
|
||||||
|
}>(`workspace:inviteLinkId:${inviteId}`);
|
||||||
if (typeof invite?.workspaceId === 'string') {
|
if (typeof invite?.workspaceId === 'string') {
|
||||||
workspaceId = invite.workspaceId;
|
workspaceId = invite.workspaceId;
|
||||||
|
invitee = { user: await this.users.findUserById(invite.inviteeUserId) };
|
||||||
}
|
}
|
||||||
if (!workspaceId) {
|
if (!workspaceId) {
|
||||||
workspaceId = await this.prisma.workspaceUserPermission
|
workspaceId = await this.prisma.workspaceUserPermission
|
||||||
@@ -508,10 +511,13 @@ export class WorkspaceResolver {
|
|||||||
const workspaceContent = await this.doc.getWorkspaceContent(workspaceId);
|
const workspaceContent = await this.doc.getWorkspaceContent(workspaceId);
|
||||||
|
|
||||||
const owner = await this.permissions.getWorkspaceOwner(workspaceId);
|
const owner = await this.permissions.getWorkspaceOwner(workspaceId);
|
||||||
const invitee = await this.permissions.getWorkspaceInvitation(
|
|
||||||
inviteId,
|
if (!invitee) {
|
||||||
workspaceId
|
invitee = await this.permissions.getWorkspaceInvitation(
|
||||||
);
|
inviteId,
|
||||||
|
workspaceId
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
let avatar = '';
|
let avatar = '';
|
||||||
if (workspaceContent?.avatarKey) {
|
if (workspaceContent?.avatarKey) {
|
||||||
|
|||||||
@@ -115,6 +115,15 @@ export class UpdateWorkspaceInput extends PickType(
|
|||||||
id!: string;
|
id!: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ObjectType()
|
||||||
|
export class InviteLink {
|
||||||
|
@Field(() => String, { description: 'Invite link' })
|
||||||
|
link!: string;
|
||||||
|
|
||||||
|
@Field(() => Date, { description: 'Invite link expire time' })
|
||||||
|
expireTime!: Date;
|
||||||
|
}
|
||||||
|
|
||||||
@ObjectType()
|
@ObjectType()
|
||||||
export class InviteResult {
|
export class InviteResult {
|
||||||
@Field(() => String)
|
@Field(() => String)
|
||||||
|
|||||||
@@ -361,6 +361,14 @@ type InvitationWorkspaceType {
|
|||||||
name: String!
|
name: String!
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type InviteLink {
|
||||||
|
"""Invite link expire time"""
|
||||||
|
expireTime: DateTime!
|
||||||
|
|
||||||
|
"""Invite link"""
|
||||||
|
link: String!
|
||||||
|
}
|
||||||
|
|
||||||
type InviteResult {
|
type InviteResult {
|
||||||
email: String!
|
email: String!
|
||||||
|
|
||||||
@@ -496,6 +504,7 @@ type Mutation {
|
|||||||
|
|
||||||
"""Create a stripe customer portal to manage payment methods"""
|
"""Create a stripe customer portal to manage payment methods"""
|
||||||
createCustomerPortal: String!
|
createCustomerPortal: String!
|
||||||
|
createInviteLink(expireTime: WorkspaceInviteLinkExpireTime!, workspaceId: String!): String!
|
||||||
|
|
||||||
"""Create a new user"""
|
"""Create a new user"""
|
||||||
createUser(input: CreateUserInput!): UserType!
|
createUser(input: CreateUserInput!): UserType!
|
||||||
@@ -514,7 +523,6 @@ type Mutation {
|
|||||||
grantMember(permission: Permission!, userId: String!, workspaceId: String!): String!
|
grantMember(permission: Permission!, userId: String!, workspaceId: String!): String!
|
||||||
invite(email: String!, permission: Permission!, sendInviteMail: Boolean, workspaceId: String!): String!
|
invite(email: String!, permission: Permission!, sendInviteMail: Boolean, workspaceId: String!): String!
|
||||||
inviteBatch(emails: [String!]!, sendInviteMail: Boolean, workspaceId: String!): [InviteResult!]!
|
inviteBatch(emails: [String!]!, sendInviteMail: Boolean, workspaceId: String!): [InviteResult!]!
|
||||||
inviteLink(expireTime: WorkspaceInviteLinkExpireTime!, workspaceId: String!): String!
|
|
||||||
leaveWorkspace(sendLeaveMail: Boolean, workspaceId: String!, workspaceName: String!): Boolean!
|
leaveWorkspace(sendLeaveMail: Boolean, workspaceId: String!, workspaceName: String!): Boolean!
|
||||||
publishPage(mode: PublicPageMode = Page, pageId: String!, workspaceId: String!): WorkspacePage!
|
publishPage(mode: PublicPageMode = Page, pageId: String!, workspaceId: String!): WorkspacePage!
|
||||||
recoverDoc(guid: String!, timestamp: DateTime!, workspaceId: String!): DateTime!
|
recoverDoc(guid: String!, timestamp: DateTime!, workspaceId: String!): DateTime!
|
||||||
@@ -996,6 +1004,9 @@ type WorkspaceType {
|
|||||||
"""is current workspace initialized"""
|
"""is current workspace initialized"""
|
||||||
initialized: Boolean!
|
initialized: Boolean!
|
||||||
|
|
||||||
|
"""invite link for workspace"""
|
||||||
|
inviteLink: InviteLink
|
||||||
|
|
||||||
"""Get user invoice count"""
|
"""Get user invoice count"""
|
||||||
invoiceCount: Int!
|
invoiceCount: Int!
|
||||||
invoices(skip: Int, take: Int = 8): [InvoiceType!]!
|
invoices(skip: Int, take: Int = 8): [InvoiceType!]!
|
||||||
|
|||||||
@@ -17,6 +17,7 @@ import {
|
|||||||
acceptInviteById,
|
acceptInviteById,
|
||||||
createTestingApp,
|
createTestingApp,
|
||||||
createWorkspace,
|
createWorkspace,
|
||||||
|
getInviteInfo,
|
||||||
grantMember,
|
grantMember,
|
||||||
inviteLink,
|
inviteLink,
|
||||||
inviteUser,
|
inviteUser,
|
||||||
@@ -95,11 +96,14 @@ const init = async (app: INestApplication, memberLimit = 10) => {
|
|||||||
|
|
||||||
const createInviteLink = async () => {
|
const createInviteLink = async () => {
|
||||||
const inviteId = await inviteLink(app, owner.token.token, ws.id, 'OneDay');
|
const inviteId = await inviteLink(app, owner.token.token, ws.id, 'OneDay');
|
||||||
return async (email: string): Promise<UserAuthedType> => {
|
return [
|
||||||
const member = await signUp(app, email.split('@')[0], email, '123456');
|
inviteId,
|
||||||
await acceptInviteById(app, ws.id, inviteId, false, member.token.token);
|
async (email: string): Promise<UserAuthedType> => {
|
||||||
return member;
|
const member = await signUp(app, email.split('@')[0], email, '123456');
|
||||||
};
|
await acceptInviteById(app, ws.id, inviteId, false, member.token.token);
|
||||||
|
return member;
|
||||||
|
},
|
||||||
|
] as const;
|
||||||
};
|
};
|
||||||
|
|
||||||
const admin = await invite('admin@affine.pro', 'Admin');
|
const admin = await invite('admin@affine.pro', 'Admin');
|
||||||
@@ -237,8 +241,15 @@ test('should be able to leave workspace', async t => {
|
|||||||
|
|
||||||
test('should be able to invite by link', async t => {
|
test('should be able to invite by link', async t => {
|
||||||
const { app, permissions, quotaManager } = t.context;
|
const { app, permissions, quotaManager } = t.context;
|
||||||
const { createInviteLink, ws } = await init(app, 4);
|
const { createInviteLink, owner, ws } = await init(app, 4);
|
||||||
const invite = await createInviteLink();
|
const [inviteId, invite] = await createInviteLink();
|
||||||
|
|
||||||
|
{
|
||||||
|
// check invite link
|
||||||
|
const info = await getInviteInfo(app, owner.token.token, inviteId);
|
||||||
|
t.is(info.workspace.id, ws.id, 'should be able to get invite info');
|
||||||
|
}
|
||||||
|
|
||||||
{
|
{
|
||||||
// invite link
|
// invite link
|
||||||
const members: UserAuthedType[] = [];
|
const members: UserAuthedType[] = [];
|
||||||
|
|||||||
@@ -78,7 +78,7 @@ export async function inviteLink(
|
|||||||
.send({
|
.send({
|
||||||
query: `
|
query: `
|
||||||
mutation {
|
mutation {
|
||||||
inviteLink(workspaceId: "${workspaceId}", expireTime: ${expireTime})
|
createInviteLink(workspaceId: "${workspaceId}", expireTime: ${expireTime})
|
||||||
}
|
}
|
||||||
`,
|
`,
|
||||||
})
|
})
|
||||||
@@ -86,7 +86,7 @@ export async function inviteLink(
|
|||||||
if (res.body.errors) {
|
if (res.body.errors) {
|
||||||
throw new Error(res.body.errors[0].message);
|
throw new Error(res.body.errors[0].message);
|
||||||
}
|
}
|
||||||
return res.body.data.inviteLink;
|
return res.body.data.createInviteLink;
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function acceptInviteById(
|
export async function acceptInviteById(
|
||||||
@@ -187,5 +187,10 @@ export async function getInviteInfo(
|
|||||||
`,
|
`,
|
||||||
})
|
})
|
||||||
.expect(200);
|
.expect(200);
|
||||||
|
if (res.body.errors) {
|
||||||
|
throw new Error(res.body.errors[0].message, {
|
||||||
|
cause: res.body.errors[0].cause,
|
||||||
|
});
|
||||||
|
}
|
||||||
return res.body.data.getInviteInfo;
|
return res.body.data.getInviteInfo;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,11 +2,11 @@ import type { WorkspaceServerService } from '@affine/core/modules/cloud';
|
|||||||
import {
|
import {
|
||||||
acceptInviteByInviteIdMutation,
|
acceptInviteByInviteIdMutation,
|
||||||
approveWorkspaceTeamMemberMutation,
|
approveWorkspaceTeamMemberMutation,
|
||||||
|
createInviteLinkMutation,
|
||||||
getWorkspaceInfoQuery,
|
getWorkspaceInfoQuery,
|
||||||
grantWorkspaceTeamMemberMutation,
|
grantWorkspaceTeamMemberMutation,
|
||||||
inviteByEmailMutation,
|
inviteByEmailMutation,
|
||||||
inviteByEmailsMutation,
|
inviteByEmailsMutation,
|
||||||
inviteLinkMutation,
|
|
||||||
leaveWorkspaceMutation,
|
leaveWorkspaceMutation,
|
||||||
type Permission,
|
type Permission,
|
||||||
revokeInviteLinkMutation,
|
revokeInviteLinkMutation,
|
||||||
@@ -83,13 +83,13 @@ export class WorkspacePermissionStore extends Store {
|
|||||||
throw new Error('No Server');
|
throw new Error('No Server');
|
||||||
}
|
}
|
||||||
const inviteLink = await this.workspaceServerService.server.gql({
|
const inviteLink = await this.workspaceServerService.server.gql({
|
||||||
query: inviteLinkMutation,
|
query: createInviteLinkMutation,
|
||||||
variables: {
|
variables: {
|
||||||
workspaceId,
|
workspaceId,
|
||||||
expireTime,
|
expireTime,
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
return inviteLink.inviteLink;
|
return inviteLink.createInviteLink;
|
||||||
}
|
}
|
||||||
|
|
||||||
async revokeInviteLink(workspaceId: string, signal?: AbortSignal) {
|
async revokeInviteLink(workspaceId: string, signal?: AbortSignal) {
|
||||||
|
|||||||
@@ -1249,6 +1249,10 @@ query getWorkspaceConfig($id: String!) {
|
|||||||
workspace(id: $id) {
|
workspace(id: $id) {
|
||||||
enableAi
|
enableAi
|
||||||
enableUrlPreview
|
enableUrlPreview
|
||||||
|
inviteLink {
|
||||||
|
link
|
||||||
|
expireTime
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}`,
|
}`,
|
||||||
};
|
};
|
||||||
@@ -1431,14 +1435,14 @@ mutation inviteBatch($workspaceId: String!, $emails: [String!]!, $sendInviteMail
|
|||||||
}`,
|
}`,
|
||||||
};
|
};
|
||||||
|
|
||||||
export const inviteLinkMutation = {
|
export const createInviteLinkMutation = {
|
||||||
id: 'inviteLinkMutation' as const,
|
id: 'createInviteLinkMutation' as const,
|
||||||
operationName: 'inviteLink',
|
operationName: 'createInviteLink',
|
||||||
definitionName: 'inviteLink',
|
definitionName: 'createInviteLink',
|
||||||
containsFile: false,
|
containsFile: false,
|
||||||
query: `
|
query: `
|
||||||
mutation inviteLink($workspaceId: String!, $expireTime: WorkspaceInviteLinkExpireTime!) {
|
mutation createInviteLink($workspaceId: String!, $expireTime: WorkspaceInviteLinkExpireTime!) {
|
||||||
inviteLink(workspaceId: $workspaceId, expireTime: $expireTime)
|
createInviteLink(workspaceId: $workspaceId, expireTime: $expireTime)
|
||||||
}`,
|
}`,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -2,5 +2,9 @@ query getWorkspaceConfig($id: String!) {
|
|||||||
workspace(id: $id) {
|
workspace(id: $id) {
|
||||||
enableAi
|
enableAi
|
||||||
enableUrlPreview
|
enableUrlPreview
|
||||||
|
inviteLink {
|
||||||
|
link
|
||||||
|
expireTime
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
mutation inviteLink(
|
mutation createInviteLink(
|
||||||
$workspaceId: String!
|
$workspaceId: String!
|
||||||
$expireTime: WorkspaceInviteLinkExpireTime!
|
$expireTime: WorkspaceInviteLinkExpireTime!
|
||||||
) {
|
) {
|
||||||
inviteLink(workspaceId: $workspaceId, expireTime: $expireTime)
|
createInviteLink(workspaceId: $workspaceId, expireTime: $expireTime)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -438,6 +438,14 @@ export interface InvitationWorkspaceType {
|
|||||||
name: Scalars['String']['output'];
|
name: Scalars['String']['output'];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export interface InviteLink {
|
||||||
|
__typename?: 'InviteLink';
|
||||||
|
/** Invite link expire time */
|
||||||
|
expireTime: Scalars['DateTime']['output'];
|
||||||
|
/** Invite link */
|
||||||
|
link: Scalars['String']['output'];
|
||||||
|
}
|
||||||
|
|
||||||
export interface InviteResult {
|
export interface InviteResult {
|
||||||
__typename?: 'InviteResult';
|
__typename?: 'InviteResult';
|
||||||
email: Scalars['String']['output'];
|
email: Scalars['String']['output'];
|
||||||
@@ -559,6 +567,7 @@ export interface Mutation {
|
|||||||
createCopilotSession: Scalars['String']['output'];
|
createCopilotSession: Scalars['String']['output'];
|
||||||
/** Create a stripe customer portal to manage payment methods */
|
/** Create a stripe customer portal to manage payment methods */
|
||||||
createCustomerPortal: Scalars['String']['output'];
|
createCustomerPortal: Scalars['String']['output'];
|
||||||
|
createInviteLink: Scalars['String']['output'];
|
||||||
/** Create a new user */
|
/** Create a new user */
|
||||||
createUser: UserType;
|
createUser: UserType;
|
||||||
/** Create a new workspace */
|
/** Create a new workspace */
|
||||||
@@ -573,7 +582,6 @@ export interface Mutation {
|
|||||||
grantMember: Scalars['String']['output'];
|
grantMember: Scalars['String']['output'];
|
||||||
invite: Scalars['String']['output'];
|
invite: Scalars['String']['output'];
|
||||||
inviteBatch: Array<InviteResult>;
|
inviteBatch: Array<InviteResult>;
|
||||||
inviteLink: Scalars['String']['output'];
|
|
||||||
leaveWorkspace: Scalars['Boolean']['output'];
|
leaveWorkspace: Scalars['Boolean']['output'];
|
||||||
publishPage: WorkspacePage;
|
publishPage: WorkspacePage;
|
||||||
recoverDoc: Scalars['DateTime']['output'];
|
recoverDoc: Scalars['DateTime']['output'];
|
||||||
@@ -673,6 +681,11 @@ export interface MutationCreateCopilotSessionArgs {
|
|||||||
options: CreateChatSessionInput;
|
options: CreateChatSessionInput;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export interface MutationCreateInviteLinkArgs {
|
||||||
|
expireTime: WorkspaceInviteLinkExpireTime;
|
||||||
|
workspaceId: Scalars['String']['input'];
|
||||||
|
}
|
||||||
|
|
||||||
export interface MutationCreateUserArgs {
|
export interface MutationCreateUserArgs {
|
||||||
input: CreateUserInput;
|
input: CreateUserInput;
|
||||||
}
|
}
|
||||||
@@ -719,11 +732,6 @@ export interface MutationInviteBatchArgs {
|
|||||||
workspaceId: Scalars['String']['input'];
|
workspaceId: Scalars['String']['input'];
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface MutationInviteLinkArgs {
|
|
||||||
expireTime: WorkspaceInviteLinkExpireTime;
|
|
||||||
workspaceId: Scalars['String']['input'];
|
|
||||||
}
|
|
||||||
|
|
||||||
export interface MutationLeaveWorkspaceArgs {
|
export interface MutationLeaveWorkspaceArgs {
|
||||||
sendLeaveMail?: InputMaybe<Scalars['Boolean']['input']>;
|
sendLeaveMail?: InputMaybe<Scalars['Boolean']['input']>;
|
||||||
workspaceId: Scalars['String']['input'];
|
workspaceId: Scalars['String']['input'];
|
||||||
@@ -1342,6 +1350,8 @@ export interface WorkspaceType {
|
|||||||
id: Scalars['ID']['output'];
|
id: Scalars['ID']['output'];
|
||||||
/** is current workspace initialized */
|
/** is current workspace initialized */
|
||||||
initialized: Scalars['Boolean']['output'];
|
initialized: Scalars['Boolean']['output'];
|
||||||
|
/** invite link for workspace */
|
||||||
|
inviteLink: Maybe<InviteLink>;
|
||||||
/** Get user invoice count */
|
/** Get user invoice count */
|
||||||
invoiceCount: Scalars['Int']['output'];
|
invoiceCount: Scalars['Int']['output'];
|
||||||
invoices: Array<InvoiceType>;
|
invoices: Array<InvoiceType>;
|
||||||
@@ -2526,6 +2536,11 @@ export type GetWorkspaceConfigQuery = {
|
|||||||
__typename?: 'WorkspaceType';
|
__typename?: 'WorkspaceType';
|
||||||
enableAi: boolean;
|
enableAi: boolean;
|
||||||
enableUrlPreview: boolean;
|
enableUrlPreview: boolean;
|
||||||
|
inviteLink: {
|
||||||
|
__typename?: 'InviteLink';
|
||||||
|
link: string;
|
||||||
|
expireTime: string;
|
||||||
|
} | null;
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -2670,14 +2685,14 @@ export type InviteBatchMutation = {
|
|||||||
}>;
|
}>;
|
||||||
};
|
};
|
||||||
|
|
||||||
export type InviteLinkMutationVariables = Exact<{
|
export type CreateInviteLinkMutationVariables = Exact<{
|
||||||
workspaceId: Scalars['String']['input'];
|
workspaceId: Scalars['String']['input'];
|
||||||
expireTime: WorkspaceInviteLinkExpireTime;
|
expireTime: WorkspaceInviteLinkExpireTime;
|
||||||
}>;
|
}>;
|
||||||
|
|
||||||
export type InviteLinkMutation = {
|
export type CreateInviteLinkMutation = {
|
||||||
__typename?: 'Mutation';
|
__typename?: 'Mutation';
|
||||||
inviteLink: string;
|
createInviteLink: string;
|
||||||
};
|
};
|
||||||
|
|
||||||
export type RevokeInviteLinkMutationVariables = Exact<{
|
export type RevokeInviteLinkMutationVariables = Exact<{
|
||||||
@@ -3228,9 +3243,9 @@ export type Mutations =
|
|||||||
response: InviteBatchMutation;
|
response: InviteBatchMutation;
|
||||||
}
|
}
|
||||||
| {
|
| {
|
||||||
name: 'inviteLinkMutation';
|
name: 'createInviteLinkMutation';
|
||||||
variables: InviteLinkMutationVariables;
|
variables: CreateInviteLinkMutationVariables;
|
||||||
response: InviteLinkMutation;
|
response: CreateInviteLinkMutation;
|
||||||
}
|
}
|
||||||
| {
|
| {
|
||||||
name: 'revokeInviteLinkMutation';
|
name: 'revokeInviteLinkMutation';
|
||||||
|
|||||||
Reference in New Issue
Block a user