Add possibility to invite members to workspace (#579)
* Add possibility to invite members to workspace * Update endpoints * Wrap up front end * Fix according to review * Fix lint
This commit is contained in:
@ -17,6 +17,9 @@ export class WorkspaceCountAggregateInput {
|
||||
@Field(() => Boolean, {nullable:true})
|
||||
logo?: true;
|
||||
|
||||
@Field(() => Boolean, {nullable:true})
|
||||
inviteHash?: true;
|
||||
|
||||
@HideField()
|
||||
deletedAt?: true;
|
||||
|
||||
|
||||
@ -18,6 +18,9 @@ export class WorkspaceCountAggregate {
|
||||
@Field(() => Int, {nullable:false})
|
||||
logo!: number;
|
||||
|
||||
@Field(() => Int, {nullable:false})
|
||||
inviteHash!: number;
|
||||
|
||||
@HideField()
|
||||
deletedAt!: number;
|
||||
|
||||
|
||||
@ -18,6 +18,9 @@ export class WorkspaceCountOrderByAggregateInput {
|
||||
@Field(() => SortOrder, {nullable:true})
|
||||
logo?: keyof typeof SortOrder;
|
||||
|
||||
@Field(() => SortOrder, {nullable:true})
|
||||
inviteHash?: keyof typeof SortOrder;
|
||||
|
||||
@HideField()
|
||||
deletedAt?: keyof typeof SortOrder;
|
||||
|
||||
|
||||
@ -26,6 +26,11 @@ export class WorkspaceCreateManyInput {
|
||||
@Validator.IsOptional()
|
||||
logo?: string;
|
||||
|
||||
@Field(() => String, {nullable:true})
|
||||
@Validator.IsString()
|
||||
@Validator.IsOptional()
|
||||
inviteHash?: string;
|
||||
|
||||
@HideField()
|
||||
deletedAt?: Date | string;
|
||||
|
||||
|
||||
@ -33,6 +33,11 @@ export class WorkspaceCreateWithoutCommentThreadsInput {
|
||||
@Validator.IsOptional()
|
||||
logo?: string;
|
||||
|
||||
@Field(() => String, {nullable:true})
|
||||
@Validator.IsString()
|
||||
@Validator.IsOptional()
|
||||
inviteHash?: string;
|
||||
|
||||
@HideField()
|
||||
deletedAt?: Date | string;
|
||||
|
||||
|
||||
@ -33,6 +33,11 @@ export class WorkspaceCreateWithoutCommentsInput {
|
||||
@Validator.IsOptional()
|
||||
logo?: string;
|
||||
|
||||
@Field(() => String, {nullable:true})
|
||||
@Validator.IsString()
|
||||
@Validator.IsOptional()
|
||||
inviteHash?: string;
|
||||
|
||||
@HideField()
|
||||
deletedAt?: Date | string;
|
||||
|
||||
|
||||
@ -33,6 +33,11 @@ export class WorkspaceCreateWithoutCompaniesInput {
|
||||
@Validator.IsOptional()
|
||||
logo?: string;
|
||||
|
||||
@Field(() => String, {nullable:true})
|
||||
@Validator.IsString()
|
||||
@Validator.IsOptional()
|
||||
inviteHash?: string;
|
||||
|
||||
@HideField()
|
||||
deletedAt?: Date | string;
|
||||
|
||||
|
||||
@ -33,6 +33,11 @@ export class WorkspaceCreateWithoutPeopleInput {
|
||||
@Validator.IsOptional()
|
||||
logo?: string;
|
||||
|
||||
@Field(() => String, {nullable:true})
|
||||
@Validator.IsString()
|
||||
@Validator.IsOptional()
|
||||
inviteHash?: string;
|
||||
|
||||
@HideField()
|
||||
deletedAt?: Date | string;
|
||||
|
||||
|
||||
@ -33,6 +33,11 @@ export class WorkspaceCreateWithoutPipelineProgressesInput {
|
||||
@Validator.IsOptional()
|
||||
logo?: string;
|
||||
|
||||
@Field(() => String, {nullable:true})
|
||||
@Validator.IsString()
|
||||
@Validator.IsOptional()
|
||||
inviteHash?: string;
|
||||
|
||||
@HideField()
|
||||
deletedAt?: Date | string;
|
||||
|
||||
|
||||
@ -33,6 +33,11 @@ export class WorkspaceCreateWithoutPipelineStagesInput {
|
||||
@Validator.IsOptional()
|
||||
logo?: string;
|
||||
|
||||
@Field(() => String, {nullable:true})
|
||||
@Validator.IsString()
|
||||
@Validator.IsOptional()
|
||||
inviteHash?: string;
|
||||
|
||||
@HideField()
|
||||
deletedAt?: Date | string;
|
||||
|
||||
|
||||
@ -33,6 +33,11 @@ export class WorkspaceCreateWithoutPipelinesInput {
|
||||
@Validator.IsOptional()
|
||||
logo?: string;
|
||||
|
||||
@Field(() => String, {nullable:true})
|
||||
@Validator.IsString()
|
||||
@Validator.IsOptional()
|
||||
inviteHash?: string;
|
||||
|
||||
@HideField()
|
||||
deletedAt?: Date | string;
|
||||
|
||||
|
||||
@ -33,6 +33,11 @@ export class WorkspaceCreateWithoutWorkspaceMemberInput {
|
||||
@Validator.IsOptional()
|
||||
logo?: string;
|
||||
|
||||
@Field(() => String, {nullable:true})
|
||||
@Validator.IsString()
|
||||
@Validator.IsOptional()
|
||||
inviteHash?: string;
|
||||
|
||||
@HideField()
|
||||
deletedAt?: Date | string;
|
||||
|
||||
|
||||
@ -34,6 +34,11 @@ export class WorkspaceCreateInput {
|
||||
@Validator.IsOptional()
|
||||
logo?: string;
|
||||
|
||||
@Field(() => String, {nullable:true})
|
||||
@Validator.IsString()
|
||||
@Validator.IsOptional()
|
||||
inviteHash?: string;
|
||||
|
||||
@HideField()
|
||||
deletedAt?: Date | string;
|
||||
|
||||
|
||||
@ -29,6 +29,11 @@ export class WorkspaceGroupBy {
|
||||
@Validator.IsOptional()
|
||||
logo?: string;
|
||||
|
||||
@Field(() => String, {nullable:true})
|
||||
@Validator.IsString()
|
||||
@Validator.IsOptional()
|
||||
inviteHash?: string;
|
||||
|
||||
@HideField()
|
||||
deletedAt?: Date | string;
|
||||
|
||||
|
||||
@ -17,6 +17,9 @@ export class WorkspaceMaxAggregateInput {
|
||||
@Field(() => Boolean, {nullable:true})
|
||||
logo?: true;
|
||||
|
||||
@Field(() => Boolean, {nullable:true})
|
||||
inviteHash?: true;
|
||||
|
||||
@HideField()
|
||||
deletedAt?: true;
|
||||
|
||||
|
||||
@ -26,6 +26,11 @@ export class WorkspaceMaxAggregate {
|
||||
@Validator.IsOptional()
|
||||
logo?: string;
|
||||
|
||||
@Field(() => String, {nullable:true})
|
||||
@Validator.IsString()
|
||||
@Validator.IsOptional()
|
||||
inviteHash?: string;
|
||||
|
||||
@HideField()
|
||||
deletedAt?: Date | string;
|
||||
|
||||
|
||||
@ -18,6 +18,9 @@ export class WorkspaceMaxOrderByAggregateInput {
|
||||
@Field(() => SortOrder, {nullable:true})
|
||||
logo?: keyof typeof SortOrder;
|
||||
|
||||
@Field(() => SortOrder, {nullable:true})
|
||||
inviteHash?: keyof typeof SortOrder;
|
||||
|
||||
@HideField()
|
||||
deletedAt?: keyof typeof SortOrder;
|
||||
|
||||
|
||||
@ -17,6 +17,9 @@ export class WorkspaceMinAggregateInput {
|
||||
@Field(() => Boolean, {nullable:true})
|
||||
logo?: true;
|
||||
|
||||
@Field(() => Boolean, {nullable:true})
|
||||
inviteHash?: true;
|
||||
|
||||
@HideField()
|
||||
deletedAt?: true;
|
||||
|
||||
|
||||
@ -26,6 +26,11 @@ export class WorkspaceMinAggregate {
|
||||
@Validator.IsOptional()
|
||||
logo?: string;
|
||||
|
||||
@Field(() => String, {nullable:true})
|
||||
@Validator.IsString()
|
||||
@Validator.IsOptional()
|
||||
inviteHash?: string;
|
||||
|
||||
@HideField()
|
||||
deletedAt?: Date | string;
|
||||
|
||||
|
||||
@ -18,6 +18,9 @@ export class WorkspaceMinOrderByAggregateInput {
|
||||
@Field(() => SortOrder, {nullable:true})
|
||||
logo?: keyof typeof SortOrder;
|
||||
|
||||
@Field(() => SortOrder, {nullable:true})
|
||||
inviteHash?: keyof typeof SortOrder;
|
||||
|
||||
@HideField()
|
||||
deletedAt?: keyof typeof SortOrder;
|
||||
|
||||
|
||||
@ -21,6 +21,9 @@ export class WorkspaceOrderByWithAggregationInput {
|
||||
@Field(() => SortOrder, {nullable:true})
|
||||
logo?: keyof typeof SortOrder;
|
||||
|
||||
@Field(() => SortOrder, {nullable:true})
|
||||
inviteHash?: keyof typeof SortOrder;
|
||||
|
||||
@HideField()
|
||||
deletedAt?: keyof typeof SortOrder;
|
||||
|
||||
|
||||
@ -26,6 +26,9 @@ export class WorkspaceOrderByWithRelationInput {
|
||||
@Field(() => SortOrder, {nullable:true})
|
||||
logo?: keyof typeof SortOrder;
|
||||
|
||||
@Field(() => SortOrder, {nullable:true})
|
||||
inviteHash?: keyof typeof SortOrder;
|
||||
|
||||
@HideField()
|
||||
deletedAt?: keyof typeof SortOrder;
|
||||
|
||||
|
||||
@ -5,6 +5,7 @@ export enum WorkspaceScalarFieldEnum {
|
||||
domainName = "domainName",
|
||||
displayName = "displayName",
|
||||
logo = "logo",
|
||||
inviteHash = "inviteHash",
|
||||
deletedAt = "deletedAt",
|
||||
createdAt = "createdAt",
|
||||
updatedAt = "updatedAt"
|
||||
|
||||
@ -30,6 +30,9 @@ export class WorkspaceScalarWhereWithAggregatesInput {
|
||||
@Field(() => StringNullableWithAggregatesFilter, {nullable:true})
|
||||
logo?: StringNullableWithAggregatesFilter;
|
||||
|
||||
@Field(() => StringNullableWithAggregatesFilter, {nullable:true})
|
||||
inviteHash?: StringNullableWithAggregatesFilter;
|
||||
|
||||
@HideField()
|
||||
deletedAt?: DateTimeNullableWithAggregatesFilter;
|
||||
|
||||
|
||||
@ -33,6 +33,11 @@ export class WorkspaceUncheckedCreateWithoutCommentThreadsInput {
|
||||
@Validator.IsOptional()
|
||||
logo?: string;
|
||||
|
||||
@Field(() => String, {nullable:true})
|
||||
@Validator.IsString()
|
||||
@Validator.IsOptional()
|
||||
inviteHash?: string;
|
||||
|
||||
@HideField()
|
||||
deletedAt?: Date | string;
|
||||
|
||||
|
||||
@ -33,6 +33,11 @@ export class WorkspaceUncheckedCreateWithoutCommentsInput {
|
||||
@Validator.IsOptional()
|
||||
logo?: string;
|
||||
|
||||
@Field(() => String, {nullable:true})
|
||||
@Validator.IsString()
|
||||
@Validator.IsOptional()
|
||||
inviteHash?: string;
|
||||
|
||||
@HideField()
|
||||
deletedAt?: Date | string;
|
||||
|
||||
|
||||
@ -33,6 +33,11 @@ export class WorkspaceUncheckedCreateWithoutCompaniesInput {
|
||||
@Validator.IsOptional()
|
||||
logo?: string;
|
||||
|
||||
@Field(() => String, {nullable:true})
|
||||
@Validator.IsString()
|
||||
@Validator.IsOptional()
|
||||
inviteHash?: string;
|
||||
|
||||
@HideField()
|
||||
deletedAt?: Date | string;
|
||||
|
||||
|
||||
@ -33,6 +33,11 @@ export class WorkspaceUncheckedCreateWithoutPeopleInput {
|
||||
@Validator.IsOptional()
|
||||
logo?: string;
|
||||
|
||||
@Field(() => String, {nullable:true})
|
||||
@Validator.IsString()
|
||||
@Validator.IsOptional()
|
||||
inviteHash?: string;
|
||||
|
||||
@HideField()
|
||||
deletedAt?: Date | string;
|
||||
|
||||
|
||||
@ -33,6 +33,11 @@ export class WorkspaceUncheckedCreateWithoutPipelineProgressesInput {
|
||||
@Validator.IsOptional()
|
||||
logo?: string;
|
||||
|
||||
@Field(() => String, {nullable:true})
|
||||
@Validator.IsString()
|
||||
@Validator.IsOptional()
|
||||
inviteHash?: string;
|
||||
|
||||
@HideField()
|
||||
deletedAt?: Date | string;
|
||||
|
||||
|
||||
@ -33,6 +33,11 @@ export class WorkspaceUncheckedCreateWithoutPipelineStagesInput {
|
||||
@Validator.IsOptional()
|
||||
logo?: string;
|
||||
|
||||
@Field(() => String, {nullable:true})
|
||||
@Validator.IsString()
|
||||
@Validator.IsOptional()
|
||||
inviteHash?: string;
|
||||
|
||||
@HideField()
|
||||
deletedAt?: Date | string;
|
||||
|
||||
|
||||
@ -33,6 +33,11 @@ export class WorkspaceUncheckedCreateWithoutPipelinesInput {
|
||||
@Validator.IsOptional()
|
||||
logo?: string;
|
||||
|
||||
@Field(() => String, {nullable:true})
|
||||
@Validator.IsString()
|
||||
@Validator.IsOptional()
|
||||
inviteHash?: string;
|
||||
|
||||
@HideField()
|
||||
deletedAt?: Date | string;
|
||||
|
||||
|
||||
@ -33,6 +33,11 @@ export class WorkspaceUncheckedCreateWithoutWorkspaceMemberInput {
|
||||
@Validator.IsOptional()
|
||||
logo?: string;
|
||||
|
||||
@Field(() => String, {nullable:true})
|
||||
@Validator.IsString()
|
||||
@Validator.IsOptional()
|
||||
inviteHash?: string;
|
||||
|
||||
@HideField()
|
||||
deletedAt?: Date | string;
|
||||
|
||||
|
||||
@ -34,6 +34,11 @@ export class WorkspaceUncheckedCreateInput {
|
||||
@Validator.IsOptional()
|
||||
logo?: string;
|
||||
|
||||
@Field(() => String, {nullable:true})
|
||||
@Validator.IsString()
|
||||
@Validator.IsOptional()
|
||||
inviteHash?: string;
|
||||
|
||||
@HideField()
|
||||
deletedAt?: Date | string;
|
||||
|
||||
|
||||
@ -21,6 +21,9 @@ export class WorkspaceUncheckedUpdateManyInput {
|
||||
@Field(() => NullableStringFieldUpdateOperationsInput, {nullable:true})
|
||||
logo?: NullableStringFieldUpdateOperationsInput;
|
||||
|
||||
@Field(() => NullableStringFieldUpdateOperationsInput, {nullable:true})
|
||||
inviteHash?: NullableStringFieldUpdateOperationsInput;
|
||||
|
||||
@HideField()
|
||||
deletedAt?: NullableDateTimeFieldUpdateOperationsInput;
|
||||
|
||||
|
||||
@ -28,6 +28,9 @@ export class WorkspaceUncheckedUpdateWithoutCommentThreadsInput {
|
||||
@Field(() => NullableStringFieldUpdateOperationsInput, {nullable:true})
|
||||
logo?: NullableStringFieldUpdateOperationsInput;
|
||||
|
||||
@Field(() => NullableStringFieldUpdateOperationsInput, {nullable:true})
|
||||
inviteHash?: NullableStringFieldUpdateOperationsInput;
|
||||
|
||||
@HideField()
|
||||
deletedAt?: NullableDateTimeFieldUpdateOperationsInput;
|
||||
|
||||
|
||||
@ -28,6 +28,9 @@ export class WorkspaceUncheckedUpdateWithoutCommentsInput {
|
||||
@Field(() => NullableStringFieldUpdateOperationsInput, {nullable:true})
|
||||
logo?: NullableStringFieldUpdateOperationsInput;
|
||||
|
||||
@Field(() => NullableStringFieldUpdateOperationsInput, {nullable:true})
|
||||
inviteHash?: NullableStringFieldUpdateOperationsInput;
|
||||
|
||||
@HideField()
|
||||
deletedAt?: NullableDateTimeFieldUpdateOperationsInput;
|
||||
|
||||
|
||||
@ -28,6 +28,9 @@ export class WorkspaceUncheckedUpdateWithoutCompaniesInput {
|
||||
@Field(() => NullableStringFieldUpdateOperationsInput, {nullable:true})
|
||||
logo?: NullableStringFieldUpdateOperationsInput;
|
||||
|
||||
@Field(() => NullableStringFieldUpdateOperationsInput, {nullable:true})
|
||||
inviteHash?: NullableStringFieldUpdateOperationsInput;
|
||||
|
||||
@HideField()
|
||||
deletedAt?: NullableDateTimeFieldUpdateOperationsInput;
|
||||
|
||||
|
||||
@ -28,6 +28,9 @@ export class WorkspaceUncheckedUpdateWithoutPeopleInput {
|
||||
@Field(() => NullableStringFieldUpdateOperationsInput, {nullable:true})
|
||||
logo?: NullableStringFieldUpdateOperationsInput;
|
||||
|
||||
@Field(() => NullableStringFieldUpdateOperationsInput, {nullable:true})
|
||||
inviteHash?: NullableStringFieldUpdateOperationsInput;
|
||||
|
||||
@HideField()
|
||||
deletedAt?: NullableDateTimeFieldUpdateOperationsInput;
|
||||
|
||||
|
||||
@ -28,6 +28,9 @@ export class WorkspaceUncheckedUpdateWithoutPipelineProgressesInput {
|
||||
@Field(() => NullableStringFieldUpdateOperationsInput, {nullable:true})
|
||||
logo?: NullableStringFieldUpdateOperationsInput;
|
||||
|
||||
@Field(() => NullableStringFieldUpdateOperationsInput, {nullable:true})
|
||||
inviteHash?: NullableStringFieldUpdateOperationsInput;
|
||||
|
||||
@HideField()
|
||||
deletedAt?: NullableDateTimeFieldUpdateOperationsInput;
|
||||
|
||||
|
||||
@ -28,6 +28,9 @@ export class WorkspaceUncheckedUpdateWithoutPipelineStagesInput {
|
||||
@Field(() => NullableStringFieldUpdateOperationsInput, {nullable:true})
|
||||
logo?: NullableStringFieldUpdateOperationsInput;
|
||||
|
||||
@Field(() => NullableStringFieldUpdateOperationsInput, {nullable:true})
|
||||
inviteHash?: NullableStringFieldUpdateOperationsInput;
|
||||
|
||||
@HideField()
|
||||
deletedAt?: NullableDateTimeFieldUpdateOperationsInput;
|
||||
|
||||
|
||||
@ -28,6 +28,9 @@ export class WorkspaceUncheckedUpdateWithoutPipelinesInput {
|
||||
@Field(() => NullableStringFieldUpdateOperationsInput, {nullable:true})
|
||||
logo?: NullableStringFieldUpdateOperationsInput;
|
||||
|
||||
@Field(() => NullableStringFieldUpdateOperationsInput, {nullable:true})
|
||||
inviteHash?: NullableStringFieldUpdateOperationsInput;
|
||||
|
||||
@HideField()
|
||||
deletedAt?: NullableDateTimeFieldUpdateOperationsInput;
|
||||
|
||||
|
||||
@ -28,6 +28,9 @@ export class WorkspaceUncheckedUpdateWithoutWorkspaceMemberInput {
|
||||
@Field(() => NullableStringFieldUpdateOperationsInput, {nullable:true})
|
||||
logo?: NullableStringFieldUpdateOperationsInput;
|
||||
|
||||
@Field(() => NullableStringFieldUpdateOperationsInput, {nullable:true})
|
||||
inviteHash?: NullableStringFieldUpdateOperationsInput;
|
||||
|
||||
@HideField()
|
||||
deletedAt?: NullableDateTimeFieldUpdateOperationsInput;
|
||||
|
||||
|
||||
@ -29,6 +29,9 @@ export class WorkspaceUncheckedUpdateInput {
|
||||
@Field(() => NullableStringFieldUpdateOperationsInput, {nullable:true})
|
||||
logo?: NullableStringFieldUpdateOperationsInput;
|
||||
|
||||
@Field(() => NullableStringFieldUpdateOperationsInput, {nullable:true})
|
||||
inviteHash?: NullableStringFieldUpdateOperationsInput;
|
||||
|
||||
@HideField()
|
||||
deletedAt?: NullableDateTimeFieldUpdateOperationsInput;
|
||||
|
||||
|
||||
@ -21,6 +21,9 @@ export class WorkspaceUpdateManyMutationInput {
|
||||
@Field(() => NullableStringFieldUpdateOperationsInput, {nullable:true})
|
||||
logo?: NullableStringFieldUpdateOperationsInput;
|
||||
|
||||
@Field(() => NullableStringFieldUpdateOperationsInput, {nullable:true})
|
||||
inviteHash?: NullableStringFieldUpdateOperationsInput;
|
||||
|
||||
@HideField()
|
||||
deletedAt?: NullableDateTimeFieldUpdateOperationsInput;
|
||||
|
||||
|
||||
@ -28,6 +28,9 @@ export class WorkspaceUpdateWithoutCommentThreadsInput {
|
||||
@Field(() => NullableStringFieldUpdateOperationsInput, {nullable:true})
|
||||
logo?: NullableStringFieldUpdateOperationsInput;
|
||||
|
||||
@Field(() => NullableStringFieldUpdateOperationsInput, {nullable:true})
|
||||
inviteHash?: NullableStringFieldUpdateOperationsInput;
|
||||
|
||||
@HideField()
|
||||
deletedAt?: NullableDateTimeFieldUpdateOperationsInput;
|
||||
|
||||
|
||||
@ -28,6 +28,9 @@ export class WorkspaceUpdateWithoutCommentsInput {
|
||||
@Field(() => NullableStringFieldUpdateOperationsInput, {nullable:true})
|
||||
logo?: NullableStringFieldUpdateOperationsInput;
|
||||
|
||||
@Field(() => NullableStringFieldUpdateOperationsInput, {nullable:true})
|
||||
inviteHash?: NullableStringFieldUpdateOperationsInput;
|
||||
|
||||
@HideField()
|
||||
deletedAt?: NullableDateTimeFieldUpdateOperationsInput;
|
||||
|
||||
|
||||
@ -28,6 +28,9 @@ export class WorkspaceUpdateWithoutCompaniesInput {
|
||||
@Field(() => NullableStringFieldUpdateOperationsInput, {nullable:true})
|
||||
logo?: NullableStringFieldUpdateOperationsInput;
|
||||
|
||||
@Field(() => NullableStringFieldUpdateOperationsInput, {nullable:true})
|
||||
inviteHash?: NullableStringFieldUpdateOperationsInput;
|
||||
|
||||
@HideField()
|
||||
deletedAt?: NullableDateTimeFieldUpdateOperationsInput;
|
||||
|
||||
|
||||
@ -28,6 +28,9 @@ export class WorkspaceUpdateWithoutPeopleInput {
|
||||
@Field(() => NullableStringFieldUpdateOperationsInput, {nullable:true})
|
||||
logo?: NullableStringFieldUpdateOperationsInput;
|
||||
|
||||
@Field(() => NullableStringFieldUpdateOperationsInput, {nullable:true})
|
||||
inviteHash?: NullableStringFieldUpdateOperationsInput;
|
||||
|
||||
@HideField()
|
||||
deletedAt?: NullableDateTimeFieldUpdateOperationsInput;
|
||||
|
||||
|
||||
@ -28,6 +28,9 @@ export class WorkspaceUpdateWithoutPipelineProgressesInput {
|
||||
@Field(() => NullableStringFieldUpdateOperationsInput, {nullable:true})
|
||||
logo?: NullableStringFieldUpdateOperationsInput;
|
||||
|
||||
@Field(() => NullableStringFieldUpdateOperationsInput, {nullable:true})
|
||||
inviteHash?: NullableStringFieldUpdateOperationsInput;
|
||||
|
||||
@HideField()
|
||||
deletedAt?: NullableDateTimeFieldUpdateOperationsInput;
|
||||
|
||||
|
||||
@ -28,6 +28,9 @@ export class WorkspaceUpdateWithoutPipelineStagesInput {
|
||||
@Field(() => NullableStringFieldUpdateOperationsInput, {nullable:true})
|
||||
logo?: NullableStringFieldUpdateOperationsInput;
|
||||
|
||||
@Field(() => NullableStringFieldUpdateOperationsInput, {nullable:true})
|
||||
inviteHash?: NullableStringFieldUpdateOperationsInput;
|
||||
|
||||
@HideField()
|
||||
deletedAt?: NullableDateTimeFieldUpdateOperationsInput;
|
||||
|
||||
|
||||
@ -28,6 +28,9 @@ export class WorkspaceUpdateWithoutPipelinesInput {
|
||||
@Field(() => NullableStringFieldUpdateOperationsInput, {nullable:true})
|
||||
logo?: NullableStringFieldUpdateOperationsInput;
|
||||
|
||||
@Field(() => NullableStringFieldUpdateOperationsInput, {nullable:true})
|
||||
inviteHash?: NullableStringFieldUpdateOperationsInput;
|
||||
|
||||
@HideField()
|
||||
deletedAt?: NullableDateTimeFieldUpdateOperationsInput;
|
||||
|
||||
|
||||
@ -28,6 +28,9 @@ export class WorkspaceUpdateWithoutWorkspaceMemberInput {
|
||||
@Field(() => NullableStringFieldUpdateOperationsInput, {nullable:true})
|
||||
logo?: NullableStringFieldUpdateOperationsInput;
|
||||
|
||||
@Field(() => NullableStringFieldUpdateOperationsInput, {nullable:true})
|
||||
inviteHash?: NullableStringFieldUpdateOperationsInput;
|
||||
|
||||
@HideField()
|
||||
deletedAt?: NullableDateTimeFieldUpdateOperationsInput;
|
||||
|
||||
|
||||
@ -29,6 +29,9 @@ export class WorkspaceUpdateInput {
|
||||
@Field(() => NullableStringFieldUpdateOperationsInput, {nullable:true})
|
||||
logo?: NullableStringFieldUpdateOperationsInput;
|
||||
|
||||
@Field(() => NullableStringFieldUpdateOperationsInput, {nullable:true})
|
||||
inviteHash?: NullableStringFieldUpdateOperationsInput;
|
||||
|
||||
@HideField()
|
||||
deletedAt?: NullableDateTimeFieldUpdateOperationsInput;
|
||||
|
||||
|
||||
@ -38,6 +38,9 @@ export class WorkspaceWhereInput {
|
||||
@Field(() => StringNullableFilter, {nullable:true})
|
||||
logo?: StringNullableFilter;
|
||||
|
||||
@Field(() => StringNullableFilter, {nullable:true})
|
||||
inviteHash?: StringNullableFilter;
|
||||
|
||||
@HideField()
|
||||
deletedAt?: DateTimeNullableFilter;
|
||||
|
||||
|
||||
@ -27,6 +27,9 @@ export class Workspace {
|
||||
@Field(() => String, {nullable:true})
|
||||
logo!: string | null;
|
||||
|
||||
@Field(() => String, {nullable:true})
|
||||
inviteHash!: string | null;
|
||||
|
||||
@HideField()
|
||||
deletedAt!: Date | null;
|
||||
|
||||
|
||||
@ -9,6 +9,7 @@ import { VerifyAuthController } from './controllers/verify-auth.controller';
|
||||
import { TokenService } from './services/token.service';
|
||||
import { AuthResolver } from './auth.resolver';
|
||||
import { EnvironmentService } from 'src/integrations/environment/environment.service';
|
||||
import { WorkspaceModule } from '../workspace/workspace.module';
|
||||
|
||||
const jwtModule = JwtModule.registerAsync({
|
||||
useFactory: async (environmentService: EnvironmentService) => {
|
||||
@ -23,7 +24,7 @@ const jwtModule = JwtModule.registerAsync({
|
||||
});
|
||||
|
||||
@Module({
|
||||
imports: [jwtModule, UserModule],
|
||||
imports: [jwtModule, UserModule, WorkspaceModule],
|
||||
controllers: [GoogleAuthController, VerifyAuthController],
|
||||
providers: [
|
||||
AuthService,
|
||||
|
||||
@ -15,6 +15,9 @@ import {
|
||||
import { Prisma } from '@prisma/client';
|
||||
import { UserExists } from './dto/user-exists.entity';
|
||||
import { CheckUserExistsInput } from './dto/user-exists.input';
|
||||
import { WorkspaceInviteHashValid } from './dto/workspace-invite-hash-valid.entity';
|
||||
import { WorkspaceInviteHashValidInput } from './dto/workspace-invite-hash.input';
|
||||
import { SignUpInput } from './dto/sign-up.input';
|
||||
|
||||
@Resolver()
|
||||
export class AuthResolver {
|
||||
@ -33,6 +36,15 @@ export class AuthResolver {
|
||||
return { exists };
|
||||
}
|
||||
|
||||
@Query(() => WorkspaceInviteHashValid)
|
||||
async checkWorkspaceInviteHashIsValid(
|
||||
@Args() workspaceInviteHashValidInput: WorkspaceInviteHashValidInput,
|
||||
): Promise<WorkspaceInviteHashValid> {
|
||||
return await this.authService.checkWorkspaceInviteHashIsValid(
|
||||
workspaceInviteHashValidInput.inviteHash,
|
||||
);
|
||||
}
|
||||
|
||||
@Mutation(() => LoginToken)
|
||||
async challenge(@Args() challengeInput: ChallengeInput): Promise<LoginToken> {
|
||||
const user = await this.authService.challenge(challengeInput);
|
||||
@ -41,6 +53,14 @@ export class AuthResolver {
|
||||
return { loginToken };
|
||||
}
|
||||
|
||||
@Mutation(() => LoginToken)
|
||||
async signUp(@Args() signUpInput: SignUpInput): Promise<LoginToken> {
|
||||
const user = await this.authService.signUp(signUpInput);
|
||||
const loginToken = await this.tokenService.generateLoginToken(user.email);
|
||||
|
||||
return { loginToken };
|
||||
}
|
||||
|
||||
@Mutation(() => Verify)
|
||||
async verify(
|
||||
@Args() verifyInput: VerifyInput,
|
||||
|
||||
20
server/src/core/auth/dto/sign-up.input.ts
Normal file
20
server/src/core/auth/dto/sign-up.input.ts
Normal file
@ -0,0 +1,20 @@
|
||||
import { ArgsType, Field } from '@nestjs/graphql';
|
||||
import { IsEmail, IsNotEmpty, IsOptional, IsString } from 'class-validator';
|
||||
|
||||
@ArgsType()
|
||||
export class SignUpInput {
|
||||
@Field(() => String)
|
||||
@IsNotEmpty()
|
||||
@IsEmail()
|
||||
email: string;
|
||||
|
||||
@Field(() => String)
|
||||
@IsNotEmpty()
|
||||
@IsString()
|
||||
password: string;
|
||||
|
||||
@Field(() => String, { nullable: true })
|
||||
@IsString()
|
||||
@IsOptional()
|
||||
workspaceInviteHash?: string;
|
||||
}
|
||||
@ -0,0 +1,7 @@
|
||||
import { Field, ObjectType } from '@nestjs/graphql';
|
||||
|
||||
@ObjectType()
|
||||
export class WorkspaceInviteHashValid {
|
||||
@Field(() => Boolean)
|
||||
isValid: boolean;
|
||||
}
|
||||
11
server/src/core/auth/dto/workspace-invite-hash.input.ts
Normal file
11
server/src/core/auth/dto/workspace-invite-hash.input.ts
Normal file
@ -0,0 +1,11 @@
|
||||
import { ArgsType, Field } from '@nestjs/graphql';
|
||||
import { IsNotEmpty, IsString, MinLength } from 'class-validator';
|
||||
|
||||
@ArgsType()
|
||||
export class WorkspaceInviteHashValidInput {
|
||||
@Field(() => String)
|
||||
@IsString()
|
||||
@IsNotEmpty()
|
||||
@MinLength(10)
|
||||
inviteHash: string;
|
||||
}
|
||||
@ -2,6 +2,7 @@ import { Test, TestingModule } from '@nestjs/testing';
|
||||
import { AuthService } from './auth.service';
|
||||
import { TokenService } from './token.service';
|
||||
import { UserService } from 'src/core/user/user.service';
|
||||
import { WorkspaceService } from 'src/core/workspace/services/workspace.service';
|
||||
|
||||
describe('AuthService', () => {
|
||||
let service: AuthService;
|
||||
@ -18,6 +19,10 @@ describe('AuthService', () => {
|
||||
provide: UserService,
|
||||
useValue: {},
|
||||
},
|
||||
{
|
||||
provide: WorkspaceService,
|
||||
useValue: {},
|
||||
},
|
||||
],
|
||||
}).compile();
|
||||
|
||||
|
||||
@ -12,6 +12,9 @@ import { Verify } from '../dto/verify.entity';
|
||||
import { TokenService } from './token.service';
|
||||
import { Prisma } from '@prisma/client';
|
||||
import { UserExists } from '../dto/user-exists.entity';
|
||||
import { WorkspaceService } from 'src/core/workspace/services/workspace.service';
|
||||
import { WorkspaceInviteHashValid } from '../dto/workspace-invite-hash-valid.entity';
|
||||
import { SignUpInput } from '../dto/sign-up.input';
|
||||
|
||||
export type UserPayload = {
|
||||
firstName: string;
|
||||
@ -24,31 +27,16 @@ export class AuthService {
|
||||
constructor(
|
||||
private readonly tokenService: TokenService,
|
||||
private readonly userService: UserService,
|
||||
private readonly workspaceService: WorkspaceService,
|
||||
) {}
|
||||
|
||||
async challenge(challengeInput: ChallengeInput) {
|
||||
let user = await this.userService.findUnique({
|
||||
const user = await this.userService.findUnique({
|
||||
where: {
|
||||
email: challengeInput.email,
|
||||
},
|
||||
});
|
||||
|
||||
const isPasswordValid = PASSWORD_REGEX.test(challengeInput.password);
|
||||
|
||||
assert(!!user || isPasswordValid, 'Password too weak', BadRequestException);
|
||||
|
||||
if (!user) {
|
||||
const passwordHash = await hashPassword(challengeInput.password);
|
||||
|
||||
user = await this.userService.createUser({
|
||||
data: {
|
||||
email: challengeInput.email,
|
||||
passwordHash,
|
||||
locale: 'en',
|
||||
},
|
||||
} as Prisma.UserCreateArgs);
|
||||
}
|
||||
|
||||
assert(user, "This user doesn't exist", NotFoundException);
|
||||
assert(user.passwordHash, 'Incorrect login method', ForbiddenException);
|
||||
|
||||
@ -62,6 +50,53 @@ export class AuthService {
|
||||
return user;
|
||||
}
|
||||
|
||||
async signUp(signUpInput: SignUpInput) {
|
||||
const existingUser = await this.userService.findUnique({
|
||||
where: {
|
||||
email: signUpInput.email,
|
||||
},
|
||||
});
|
||||
assert(!existingUser, 'This user already exists', ForbiddenException);
|
||||
|
||||
const isPasswordValid = PASSWORD_REGEX.test(signUpInput.password);
|
||||
assert(isPasswordValid, 'Password too weak', BadRequestException);
|
||||
|
||||
const passwordHash = await hashPassword(signUpInput.password);
|
||||
|
||||
if (signUpInput.workspaceInviteHash) {
|
||||
const workspace = await this.workspaceService.findFirst({
|
||||
where: {
|
||||
inviteHash: signUpInput.workspaceInviteHash,
|
||||
},
|
||||
});
|
||||
|
||||
assert(
|
||||
workspace,
|
||||
'This workspace inviteHash is invalid',
|
||||
ForbiddenException,
|
||||
);
|
||||
|
||||
return await this.userService.createUser(
|
||||
{
|
||||
data: {
|
||||
email: signUpInput.email,
|
||||
passwordHash,
|
||||
locale: 'en',
|
||||
},
|
||||
} as Prisma.UserCreateArgs,
|
||||
workspace.id,
|
||||
);
|
||||
}
|
||||
|
||||
return await this.userService.createUser({
|
||||
data: {
|
||||
email: signUpInput.email,
|
||||
passwordHash,
|
||||
locale: 'en',
|
||||
},
|
||||
} as Prisma.UserCreateArgs);
|
||||
}
|
||||
|
||||
async verify(
|
||||
email: string,
|
||||
select: Prisma.UserSelect & {
|
||||
@ -101,4 +136,16 @@ export class AuthService {
|
||||
|
||||
return { exists: !!user };
|
||||
}
|
||||
|
||||
async checkWorkspaceInviteHashIsValid(
|
||||
inviteHash: string,
|
||||
): Promise<WorkspaceInviteHashValid> {
|
||||
const workspace = await this.workspaceService.findFirst({
|
||||
where: {
|
||||
inviteHash,
|
||||
},
|
||||
});
|
||||
|
||||
return { isValid: !!workspace };
|
||||
}
|
||||
}
|
||||
|
||||
@ -46,6 +46,7 @@ export class UserService {
|
||||
// Customs
|
||||
async createUser<T extends Prisma.UserCreateArgs>(
|
||||
args: Prisma.SelectSubset<T, Prisma.UserCreateArgs>,
|
||||
workspaceId?: string,
|
||||
): Promise<Prisma.UserGetPayload<T>> {
|
||||
assert(args.data.email, 'email is missing', BadRequestException);
|
||||
|
||||
@ -55,14 +56,23 @@ export class UserService {
|
||||
},
|
||||
create: {
|
||||
...(args.data as Prisma.UserCreateInput),
|
||||
// Assign the user to a new workspace by default
|
||||
workspaceMember: {
|
||||
create: {
|
||||
workspace: {
|
||||
create: {},
|
||||
|
||||
workspaceMember: workspaceId
|
||||
? {
|
||||
create: {
|
||||
workspace: {
|
||||
connect: { id: workspaceId },
|
||||
},
|
||||
},
|
||||
}
|
||||
: // Assign the user to a new workspace by default
|
||||
{
|
||||
create: {
|
||||
workspace: {
|
||||
create: {},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
locale: 'en',
|
||||
},
|
||||
update: {},
|
||||
|
||||
@ -0,0 +1,2 @@
|
||||
-- AlterTable
|
||||
ALTER TABLE "workspaces" ADD COLUMN "inviteHash" TEXT;
|
||||
@ -196,6 +196,9 @@ model Workspace {
|
||||
/// @Validator.IsString()
|
||||
/// @Validator.IsOptional()
|
||||
logo String?
|
||||
/// @Validator.IsString()
|
||||
/// @Validator.IsOptional()
|
||||
inviteHash String?
|
||||
|
||||
workspaceMember WorkspaceMember[]
|
||||
companies Company[]
|
||||
|
||||
File diff suppressed because one or more lines are too long
Reference in New Issue
Block a user