Fix workspace invite onboarding loop (#16444)

- The issue is that the listener is not triggered if they are no change
to the workspaceMember (which happens when name is already filled
through GoogleSSO)

Fixes https://github.com/twentyhq/twenty/issues/16440
This commit is contained in:
Charles Bochet
2025-12-09 19:18:17 +01:00
committed by GitHub
parent 3e9820fa8d
commit 83fc434c5d
6 changed files with 49 additions and 84 deletions
@@ -1,9 +1,10 @@
import { Injectable } from '@nestjs/common';
import { isDefined } from 'twenty-shared/utils';
import { PermissionFlagType } from 'twenty-shared/constants';
import { isDefined } from 'twenty-shared/utils';
import { type ApiKeyEntity } from 'src/engine/core-modules/api-key/api-key.entity';
import { OnboardingService } from 'src/engine/core-modules/onboarding/onboarding.service';
import {
PermissionsException,
PermissionsExceptionCode,
@@ -13,7 +14,10 @@ import { PermissionsService } from 'src/engine/metadata-modules/permissions/perm
@Injectable()
export class WorkspaceMemberPreQueryHookService {
constructor(private readonly permissionsService: PermissionsService) {}
constructor(
private readonly permissionsService: PermissionsService,
private readonly onboardingService: OnboardingService,
) {}
async validateWorkspaceMemberUpdatePermissionOrThrow({
userWorkspaceId,
@@ -62,4 +66,34 @@ export class WorkspaceMemberPreQueryHookService {
PermissionsExceptionCode.PERMISSION_DENIED,
);
}
async completeOnboardingProfileStepIfNameProvided({
userId,
workspaceId,
firstName,
lastName,
}: {
userId?: string;
workspaceId: string;
firstName?: string;
lastName?: string;
}) {
if (!userId) {
return;
}
if (firstName === '' && lastName === '') {
return;
}
if (!isDefined(firstName) && !isDefined(lastName)) {
return;
}
await this.onboardingService.setOnboardingCreateProfilePending({
userId,
workspaceId,
value: false,
});
}
}
@@ -2,6 +2,7 @@ import { Module } from '@nestjs/common';
import { TypeOrmModule } from '@nestjs/typeorm';
import { FeatureFlagModule } from 'src/engine/core-modules/feature-flag/feature-flag.module';
import { OnboardingModule } from 'src/engine/core-modules/onboarding/onboarding.module';
import { UserWorkspaceEntity } from 'src/engine/core-modules/user-workspace/user-workspace.entity';
import { UserWorkspaceModule } from 'src/engine/core-modules/user-workspace/user-workspace.module';
import { UserModule } from 'src/engine/core-modules/user/user.module';
@@ -36,6 +37,7 @@ import { WorkspaceMemberUpdateOnePreQueryHook } from 'src/modules/workspace-memb
],
imports: [
FeatureFlagModule,
OnboardingModule,
PermissionsModule,
UserWorkspaceModule,
TypeOrmModule.forFeature([UserWorkspaceEntity]),
@@ -1,8 +1,8 @@
import { InjectRepository } from '@nestjs/typeorm';
import { isDefined } from 'class-validator';
import { Repository } from 'typeorm';
import { assertIsDefinedOrThrow } from 'twenty-shared/utils';
import { Repository } from 'typeorm';
import { type WorkspacePreQueryHookInstance } from 'src/engine/api/graphql/workspace-query-runner/workspace-query-hook/interfaces/workspace-query-hook.interface';
import { type UpdateOneResolverArgs } from 'src/engine/api/graphql/workspace-resolver-builder/interfaces/workspace-resolvers-builder.interface';
@@ -14,8 +14,8 @@ import {
} from 'src/engine/core-modules/auth/auth.exception';
import { type AuthContext } from 'src/engine/core-modules/auth/types/auth-context.type';
import { UserWorkspaceEntity } from 'src/engine/core-modules/user-workspace/user-workspace.entity';
import { WorkspaceMemberPreQueryHookService } from 'src/modules/workspace-member/query-hooks/workspace-member-pre-query-hook.service';
import { WorkspaceNotFoundDefaultError } from 'src/engine/core-modules/workspace/workspace.exception';
import { WorkspaceMemberPreQueryHookService } from 'src/modules/workspace-member/query-hooks/workspace-member-pre-query-hook.service';
@WorkspaceQueryHook(`workspaceMember.updateOne`)
export class WorkspaceMemberUpdateOnePreQueryHook
@@ -67,6 +67,15 @@ export class WorkspaceMemberUpdateOnePreQueryHook
});
}
await this.workspaceMemberPreQueryHookService.completeOnboardingProfileStepIfNameProvided(
{
userId: authContext.user?.id,
workspaceId: workspace.id,
firstName: payload.data.name?.firstName,
lastName: payload.data.name?.lastName,
},
);
return payload;
}
}