feat: invitation link (#3979)
* feat: invitation link schema and apis * feat: add invitation link * feat: member status: active, leave, forbidden * fix: expires show hours and minutes * feat: invalid invitation link hint * fix: typo * chore: fix typo & i18n * fix * pref: fe * feat: add ttl index for 30-day-clean-up
This commit is contained in:
@@ -0,0 +1 @@
|
||||
export const MaxInvitationLinksAmount = 10;
|
||||
@@ -0,0 +1,3 @@
|
||||
export function isForbidden({ expires, forbidden }: { expires: Date; forbidden?: boolean }) {
|
||||
return forbidden || new Date(expires) < new Date();
|
||||
}
|
||||
54
packages/service/support/user/team/invitationLink/schema.ts
Normal file
54
packages/service/support/user/team/invitationLink/schema.ts
Normal file
@@ -0,0 +1,54 @@
|
||||
import {
|
||||
TeamCollectionName,
|
||||
TeamMemberCollectionName
|
||||
} from '@fastgpt/global/support/user/team/constant';
|
||||
import { connectionMongo, getMongoModel } from '../../../../common/mongo';
|
||||
import { InvitationSchemaType } from './type';
|
||||
import addDays from 'date-fns/esm/fp/addDays/index.js';
|
||||
const { Schema } = connectionMongo;
|
||||
|
||||
export const InvitationCollectionName = 'team_invitation_links';
|
||||
|
||||
const InvitationSchema = new Schema({
|
||||
teamId: {
|
||||
type: Schema.Types.ObjectId,
|
||||
ref: TeamCollectionName,
|
||||
required: true
|
||||
},
|
||||
usedTimesLimit: {
|
||||
type: Number
|
||||
},
|
||||
forbidden: {
|
||||
type: Boolean
|
||||
},
|
||||
expires: {
|
||||
type: Date
|
||||
},
|
||||
description: {
|
||||
type: String
|
||||
},
|
||||
members: {
|
||||
type: [String],
|
||||
default: []
|
||||
}
|
||||
});
|
||||
|
||||
InvitationSchema.virtual('team', {
|
||||
ref: TeamCollectionName,
|
||||
localField: 'teamId',
|
||||
foreignField: '_id',
|
||||
justOne: true
|
||||
});
|
||||
|
||||
InvitationSchema.index({ expires: 1 }, { expireAfterSeconds: 30 * 24 * 60 * 60 });
|
||||
|
||||
try {
|
||||
InvitationSchema.index({ teamId: 1 }, { background: true });
|
||||
} catch (error) {
|
||||
console.log(error);
|
||||
}
|
||||
|
||||
export const MongoInvitationLink = getMongoModel<InvitationSchemaType>(
|
||||
InvitationCollectionName,
|
||||
InvitationSchema
|
||||
);
|
||||
37
packages/service/support/user/team/invitationLink/type.ts
Normal file
37
packages/service/support/user/team/invitationLink/type.ts
Normal file
@@ -0,0 +1,37 @@
|
||||
import { TeamMemberSchema } from '@fastgpt/global/support/user/team/type';
|
||||
|
||||
export type InvitationSchemaType = {
|
||||
_id: string;
|
||||
teamId: string;
|
||||
usedTimesLimit?: number;
|
||||
forbidden?: boolean;
|
||||
expires: Date;
|
||||
description: string;
|
||||
members: string[];
|
||||
};
|
||||
|
||||
export type InvitationType = Omit<InvitationSchemaType, 'members'> & {
|
||||
members: {
|
||||
tmbId: string;
|
||||
avatar: string;
|
||||
name: string;
|
||||
}[];
|
||||
};
|
||||
|
||||
export type InvitationLinkExpiresType = '30m' | '7d' | '1y';
|
||||
|
||||
export type InvitationLinkCreateType = {
|
||||
description: string;
|
||||
expires: InvitationLinkExpiresType;
|
||||
usedTimesLimit: number;
|
||||
};
|
||||
export type InvitationLinkUpdateType = Partial<
|
||||
Omit<InvitationSchemaType, 'members' | 'teamId' | '_id'>
|
||||
> & {
|
||||
linkId: string;
|
||||
};
|
||||
|
||||
export type InvitationInfoType = InvitationSchemaType & {
|
||||
teamAvatar: string;
|
||||
teamName: string;
|
||||
};
|
||||
Reference in New Issue
Block a user