Fix authUser decorator usage (#12697)

Solving issue: we don't have `user.firstName` and `user.lastName` set
when signin with e-mail/password. CreateBy, invitation emails and
validation domain email need those info

## Before

## ExecutedBy

<img width="511" alt="image"
src="https://github.com/user-attachments/assets/b85bbda5-f26b-4137-a875-0ef926a1eec4"
/>

## Invitation email

<img width="764" alt="image"
src="https://github.com/user-attachments/assets/107c71bf-a6b2-4291-a31b-6ce48b11dd77"
/>

### Validate domain email

<img width="829" alt="image"
src="https://github.com/user-attachments/assets/213ff7c5-f86d-476f-8f4d-74299d7eb13d"
/>


## After

## ExecutedBy

<img width="500" alt="image"
src="https://github.com/user-attachments/assets/b4125e84-b355-4280-8611-b4e36e6033c7"
/>

## Invitation email

<img width="754" alt="image"
src="https://github.com/user-attachments/assets/952fe5bf-f4da-4fef-b765-fc220255dedf"
/>

### Validate domain email

<img width="709" alt="image"
src="https://github.com/user-attachments/assets/6950097c-51ae-469b-a7cf-f561650ee86e"
/>
This commit is contained in:
martmull
2025-06-18 15:57:55 +02:00
committed by GitHub
parent 82876bb7d1
commit d284fd1d71
7 changed files with 100 additions and 40 deletions

View File

@ -9,15 +9,18 @@ import { ValidateApprovedAccessDomainInput } from 'src/engine/core-modules/appro
import { ApprovedAccessDomainService } from 'src/engine/core-modules/approved-access-domain/services/approved-access-domain.service'; import { ApprovedAccessDomainService } from 'src/engine/core-modules/approved-access-domain/services/approved-access-domain.service';
import { User } from 'src/engine/core-modules/user/user.entity'; import { User } from 'src/engine/core-modules/user/user.entity';
import { Workspace } from 'src/engine/core-modules/workspace/workspace.entity'; import { Workspace } from 'src/engine/core-modules/workspace/workspace.entity';
import { AuthUser } from 'src/engine/decorators/auth/auth-user.decorator';
import { AuthWorkspace } from 'src/engine/decorators/auth/auth-workspace.decorator'; import { AuthWorkspace } from 'src/engine/decorators/auth/auth-workspace.decorator';
import { WorkspaceAuthGuard } from 'src/engine/guards/workspace-auth.guard'; import { WorkspaceAuthGuard } from 'src/engine/guards/workspace-auth.guard';
import { WorkspaceMemberWorkspaceEntity } from 'src/modules/workspace-member/standard-objects/workspace-member.workspace-entity';
import { TwentyORMGlobalManager } from 'src/engine/twenty-orm/twenty-orm-global.manager';
import { AuthUser } from 'src/engine/decorators/auth/auth-user.decorator';
@UseGuards(WorkspaceAuthGuard) @UseGuards(WorkspaceAuthGuard)
@UseFilters(ApprovedAccessDomainExceptionFilter) @UseFilters(ApprovedAccessDomainExceptionFilter)
@Resolver() @Resolver()
export class ApprovedAccessDomainResolver { export class ApprovedAccessDomainResolver {
constructor( constructor(
private readonly twentyORMGlobalManager: TwentyORMGlobalManager,
private readonly approvedAccessDomainService: ApprovedAccessDomainService, private readonly approvedAccessDomainService: ApprovedAccessDomainService,
) {} ) {}
@ -27,10 +30,22 @@ export class ApprovedAccessDomainResolver {
@AuthWorkspace() currentWorkspace: Workspace, @AuthWorkspace() currentWorkspace: Workspace,
@AuthUser() currentUser: User, @AuthUser() currentUser: User,
): Promise<ApprovedAccessDomain> { ): Promise<ApprovedAccessDomain> {
const workspaceMemberRepository =
await this.twentyORMGlobalManager.getRepositoryForWorkspace<WorkspaceMemberWorkspaceEntity>(
currentWorkspace.id,
'workspaceMember',
);
const workspaceMember = await workspaceMemberRepository.findOneOrFail({
where: {
userId: currentUser.id,
},
});
return this.approvedAccessDomainService.createApprovedAccessDomain( return this.approvedAccessDomainService.createApprovedAccessDomain(
domain, domain,
currentWorkspace, currentWorkspace,
currentUser, workspaceMember,
email, email,
); );
} }

View File

@ -17,9 +17,9 @@ import { approvedAccessDomainValidator } from 'src/engine/core-modules/approved-
import { DomainManagerService } from 'src/engine/core-modules/domain-manager/services/domain-manager.service'; import { DomainManagerService } from 'src/engine/core-modules/domain-manager/services/domain-manager.service';
import { EmailService } from 'src/engine/core-modules/email/email.service'; import { EmailService } from 'src/engine/core-modules/email/email.service';
import { TwentyConfigService } from 'src/engine/core-modules/twenty-config/twenty-config.service'; import { TwentyConfigService } from 'src/engine/core-modules/twenty-config/twenty-config.service';
import { User } from 'src/engine/core-modules/user/user.entity';
import { Workspace } from 'src/engine/core-modules/workspace/workspace.entity'; import { Workspace } from 'src/engine/core-modules/workspace/workspace.entity';
import { isWorkDomain } from 'src/utils/is-work-email'; import { isWorkDomain } from 'src/utils/is-work-email';
import { WorkspaceMemberWorkspaceEntity } from 'src/modules/workspace-member/standard-objects/workspace-member.workspace-entity';
@Injectable() @Injectable()
// eslint-disable-next-line @nx/workspace-inject-workspace-repository // eslint-disable-next-line @nx/workspace-inject-workspace-repository
@ -33,7 +33,7 @@ export class ApprovedAccessDomainService {
) {} ) {}
async sendApprovedAccessDomainValidationEmail( async sendApprovedAccessDomainValidationEmail(
sender: User, sender: WorkspaceMemberWorkspaceEntity,
to: string, to: string,
workspace: Workspace, workspace: Workspace,
approvedAccessDomain: ApprovedAccessDomainEntity, approvedAccessDomain: ApprovedAccessDomainEntity,
@ -66,9 +66,9 @@ export class ApprovedAccessDomainService {
workspace: { name: workspace.displayName, logo: workspace.logo }, workspace: { name: workspace.displayName, logo: workspace.logo },
domain: approvedAccessDomain.domain, domain: approvedAccessDomain.domain,
sender: { sender: {
email: sender.email, email: sender.userEmail,
firstName: sender.firstName, firstName: sender.name.firstName,
lastName: sender.lastName, lastName: sender.name.lastName,
}, },
serverUrl: this.twentyConfigService.get('SERVER_URL'), serverUrl: this.twentyConfigService.get('SERVER_URL'),
locale: 'en' as keyof typeof APP_LOCALES, locale: 'en' as keyof typeof APP_LOCALES,
@ -79,7 +79,7 @@ export class ApprovedAccessDomainService {
}); });
await this.emailService.send({ await this.emailService.send({
from: `${sender.firstName} ${sender.lastName} (via Twenty) <${this.twentyConfigService.get('EMAIL_FROM_ADDRESS')}>`, from: `${sender.name.firstName} ${sender.name.lastName} (via Twenty) <${this.twentyConfigService.get('EMAIL_FROM_ADDRESS')}>`,
to, to,
subject: 'Approve your access domain', subject: 'Approve your access domain',
text, text,
@ -140,7 +140,7 @@ export class ApprovedAccessDomainService {
async createApprovedAccessDomain( async createApprovedAccessDomain(
domain: string, domain: string,
inWorkspace: Workspace, inWorkspace: Workspace,
fromUser: User, fromWorkspaceMember: WorkspaceMemberWorkspaceEntity,
emailToValidateDomain: string, emailToValidateDomain: string,
): Promise<ApprovedAccessDomainEntity> { ): Promise<ApprovedAccessDomainEntity> {
if (!isWorkDomain(domain)) { if (!isWorkDomain(domain)) {
@ -170,7 +170,7 @@ export class ApprovedAccessDomainService {
); );
await this.sendApprovedAccessDomainValidationEmail( await this.sendApprovedAccessDomainValidationEmail(
fromUser, fromWorkspaceMember,
emailToValidateDomain, emailToValidateDomain,
inWorkspace, inWorkspace,
approvedAccessDomain, approvedAccessDomain,

View File

@ -11,8 +11,8 @@ import {
import { DomainManagerService } from 'src/engine/core-modules/domain-manager/services/domain-manager.service'; import { DomainManagerService } from 'src/engine/core-modules/domain-manager/services/domain-manager.service';
import { EmailService } from 'src/engine/core-modules/email/email.service'; import { EmailService } from 'src/engine/core-modules/email/email.service';
import { TwentyConfigService } from 'src/engine/core-modules/twenty-config/twenty-config.service'; import { TwentyConfigService } from 'src/engine/core-modules/twenty-config/twenty-config.service';
import { User } from 'src/engine/core-modules/user/user.entity';
import { Workspace } from 'src/engine/core-modules/workspace/workspace.entity'; import { Workspace } from 'src/engine/core-modules/workspace/workspace.entity';
import { WorkspaceMemberWorkspaceEntity } from 'src/modules/workspace-member/standard-objects/workspace-member.workspace-entity';
import { ApprovedAccessDomainService } from './approved-access-domain.service'; import { ApprovedAccessDomainService } from './approved-access-domain.service';
@ -78,9 +78,8 @@ describe('ApprovedAccessDomainService', () => {
isCustomDomainEnabled: false, isCustomDomainEnabled: false,
} as Workspace; } as Workspace;
const fromUser = { const fromUser = {
email: 'user@custom-domain.com', userEmail: 'user@custom-domain.com',
isEmailVerified: true, } as WorkspaceMemberWorkspaceEntity;
} as User;
const expectedApprovedAccessDomain = { const expectedApprovedAccessDomain = {
workspaceId: 'workspace-id', workspaceId: 'workspace-id',
@ -118,7 +117,9 @@ describe('ApprovedAccessDomainService', () => {
service.createApprovedAccessDomain( service.createApprovedAccessDomain(
'gmail.com', 'gmail.com',
{ id: 'workspace-id' } as Workspace, { id: 'workspace-id' } as Workspace,
{ email: 'user@gmail.com', isEmailVerified: true } as User, {
userEmail: 'user@gmail.com',
} as WorkspaceMemberWorkspaceEntity,
'user@gmail.com', 'user@gmail.com',
), ),
).rejects.toThrowError( ).rejects.toThrowError(
@ -184,7 +185,7 @@ describe('ApprovedAccessDomainService', () => {
describe('sendApprovedAccessDomainValidationEmail', () => { describe('sendApprovedAccessDomainValidationEmail', () => {
it('should throw an exception if the approved access domain is already validated', async () => { it('should throw an exception if the approved access domain is already validated', async () => {
const approvedAccessDomainId = 'approved-access-domain-id'; const approvedAccessDomainId = 'approved-access-domain-id';
const sender = {} as User; const sender = {} as WorkspaceMemberWorkspaceEntity;
const workspace = {} as Workspace; const workspace = {} as Workspace;
const email = 'validator@example.com'; const email = 'validator@example.com';
@ -214,7 +215,7 @@ describe('ApprovedAccessDomainService', () => {
it('should throw an exception if the email does not match the approved access domain', async () => { it('should throw an exception if the email does not match the approved access domain', async () => {
const approvedAccessDomainId = 'approved-access-domain-id'; const approvedAccessDomainId = 'approved-access-domain-id';
const sender = {} as User; const sender = {} as WorkspaceMemberWorkspaceEntity;
const workspace = {} as Workspace; const workspace = {} as Workspace;
const email = 'validator@different.com'; const email = 'validator@different.com';
const approvedAccessDomain = { const approvedAccessDomain = {
@ -244,10 +245,9 @@ describe('ApprovedAccessDomainService', () => {
it('should send a validation email if all conditions are met', async () => { it('should send a validation email if all conditions are met', async () => {
const sender = { const sender = {
email: 'sender@example.com', userEmail: 'sender@example.com',
firstName: 'John', name: { firstName: 'John', lastName: 'Doe' },
lastName: 'Doe', } as WorkspaceMemberWorkspaceEntity;
} as User;
const workspace = { const workspace = {
displayName: 'Test Workspace', displayName: 'Test Workspace',
logo: '/logo.png', logo: '/logo.png',

View File

@ -6,14 +6,17 @@ import { User } from 'src/engine/core-modules/user/user.entity';
import { RunWorkflowVersionInput } from 'src/engine/core-modules/workflow/dtos/run-workflow-version-input.dto'; import { RunWorkflowVersionInput } from 'src/engine/core-modules/workflow/dtos/run-workflow-version-input.dto';
import { WorkflowRunDTO } from 'src/engine/core-modules/workflow/dtos/workflow-run.dto'; import { WorkflowRunDTO } from 'src/engine/core-modules/workflow/dtos/workflow-run.dto';
import { WorkflowTriggerGraphqlApiExceptionFilter } from 'src/engine/core-modules/workflow/filters/workflow-trigger-graphql-api-exception.filter'; import { WorkflowTriggerGraphqlApiExceptionFilter } from 'src/engine/core-modules/workflow/filters/workflow-trigger-graphql-api-exception.filter';
import { AuthUser } from 'src/engine/decorators/auth/auth-user.decorator';
import { AuthWorkspaceMemberId } from 'src/engine/decorators/auth/auth-workspace-member-id.decorator';
import { SettingsPermissionsGuard } from 'src/engine/guards/settings-permissions.guard'; import { SettingsPermissionsGuard } from 'src/engine/guards/settings-permissions.guard';
import { UserAuthGuard } from 'src/engine/guards/user-auth.guard'; import { UserAuthGuard } from 'src/engine/guards/user-auth.guard';
import { WorkspaceAuthGuard } from 'src/engine/guards/workspace-auth.guard'; import { WorkspaceAuthGuard } from 'src/engine/guards/workspace-auth.guard';
import { SettingPermissionType } from 'src/engine/metadata-modules/permissions/constants/setting-permission-type.constants'; import { SettingPermissionType } from 'src/engine/metadata-modules/permissions/constants/setting-permission-type.constants';
import { PermissionsGraphqlApiExceptionFilter } from 'src/engine/metadata-modules/permissions/utils/permissions-graphql-api-exception.filter'; import { PermissionsGraphqlApiExceptionFilter } from 'src/engine/metadata-modules/permissions/utils/permissions-graphql-api-exception.filter';
import { WorkflowTriggerWorkspaceService } from 'src/modules/workflow/workflow-trigger/workspace-services/workflow-trigger.workspace-service'; import { WorkflowTriggerWorkspaceService } from 'src/modules/workflow/workflow-trigger/workspace-services/workflow-trigger.workspace-service';
import { WorkspaceMemberWorkspaceEntity } from 'src/modules/workspace-member/standard-objects/workspace-member.workspace-entity';
import { TwentyORMGlobalManager } from 'src/engine/twenty-orm/twenty-orm-global.manager';
import { AuthUser } from 'src/engine/decorators/auth/auth-user.decorator';
import { Workspace } from 'src/engine/core-modules/workspace/workspace.entity';
import { AuthWorkspace } from 'src/engine/decorators/auth/auth-workspace.decorator';
@Resolver() @Resolver()
@UseGuards( @UseGuards(
@ -27,6 +30,7 @@ import { WorkflowTriggerWorkspaceService } from 'src/modules/workflow/workflow-t
) )
export class WorkflowTriggerResolver { export class WorkflowTriggerResolver {
constructor( constructor(
private readonly twentyORMGlobalManager: TwentyORMGlobalManager,
private readonly workflowTriggerWorkspaceService: WorkflowTriggerWorkspaceService, private readonly workflowTriggerWorkspaceService: WorkflowTriggerWorkspaceService,
) {} ) {}
@ -50,19 +54,31 @@ export class WorkflowTriggerResolver {
@Mutation(() => WorkflowRunDTO) @Mutation(() => WorkflowRunDTO)
async runWorkflowVersion( async runWorkflowVersion(
@AuthWorkspaceMemberId() workspaceMemberId: string,
@AuthUser() user: User, @AuthUser() user: User,
@AuthWorkspace() workspace: Workspace,
@Args('input') { workflowVersionId, payload }: RunWorkflowVersionInput, @Args('input') { workflowVersionId, payload }: RunWorkflowVersionInput,
) { ) {
const workspaceMemberRepository =
await this.twentyORMGlobalManager.getRepositoryForWorkspace<WorkspaceMemberWorkspaceEntity>(
workspace.id,
'workspaceMember',
);
const workspaceMember = await workspaceMemberRepository.findOneOrFail({
where: {
userId: user.id,
},
});
return await this.workflowTriggerWorkspaceService.runWorkflowVersion({ return await this.workflowTriggerWorkspaceService.runWorkflowVersion({
workflowVersionId, workflowVersionId,
payload: payload ?? {}, payload: payload ?? {},
createdBy: buildCreatedByFromFullNameMetadata({ createdBy: buildCreatedByFromFullNameMetadata({
fullNameMetadata: { fullNameMetadata: {
firstName: user.firstName, firstName: workspaceMember.name.firstName,
lastName: user.lastName, lastName: workspaceMember.name.lastName,
}, },
workspaceMemberId: workspaceMemberId, workspaceMemberId: workspaceMember.id,
}), }),
}); });
} }

View File

@ -12,10 +12,10 @@ import { EmailService } from 'src/engine/core-modules/email/email.service';
import { OnboardingService } from 'src/engine/core-modules/onboarding/onboarding.service'; import { OnboardingService } from 'src/engine/core-modules/onboarding/onboarding.service';
import { TwentyConfigService } from 'src/engine/core-modules/twenty-config/twenty-config.service'; import { TwentyConfigService } from 'src/engine/core-modules/twenty-config/twenty-config.service';
import { UserWorkspace } from 'src/engine/core-modules/user-workspace/user-workspace.entity'; import { UserWorkspace } from 'src/engine/core-modules/user-workspace/user-workspace.entity';
import { User } from 'src/engine/core-modules/user/user.entity';
import { WorkspaceInvitationException } from 'src/engine/core-modules/workspace-invitation/workspace-invitation.exception'; import { WorkspaceInvitationException } from 'src/engine/core-modules/workspace-invitation/workspace-invitation.exception';
import { WorkspaceService } from 'src/engine/core-modules/workspace/services/workspace.service'; import { WorkspaceService } from 'src/engine/core-modules/workspace/services/workspace.service';
import { Workspace } from 'src/engine/core-modules/workspace/workspace.entity'; import { Workspace } from 'src/engine/core-modules/workspace/workspace.entity';
import { WorkspaceMemberWorkspaceEntity } from 'src/modules/workspace-member/standard-objects/workspace-member.workspace-entity';
import { WorkspaceInvitationService } from './workspace-invitation.service'; import { WorkspaceInvitationService } from './workspace-invitation.service';
@ -148,7 +148,10 @@ describe('WorkspaceInvitationService', () => {
inviteHash: 'invite-hash', inviteHash: 'invite-hash',
displayName: 'Test Workspace', displayName: 'Test Workspace',
} as Workspace; } as Workspace;
const sender = { email: 'sender@example.com', firstName: 'Sender' }; const sender = {
userEmail: 'sender@example.com',
name: { firstName: 'Sender' },
};
jest.spyOn(service, 'createWorkspaceInvitation').mockResolvedValue({ jest.spyOn(service, 'createWorkspaceInvitation').mockResolvedValue({
context: { email: 'test@example.com' }, context: { email: 'test@example.com' },
@ -166,7 +169,7 @@ describe('WorkspaceInvitationService', () => {
const result = await service.sendInvitations( const result = await service.sendInvitations(
emails, emails,
workspace, workspace,
sender as User, sender as WorkspaceMemberWorkspaceEntity,
); );
expect(result.success).toBe(true); expect(result.success).toBe(true);

View File

@ -25,7 +25,6 @@ import { EmailService } from 'src/engine/core-modules/email/email.service';
import { OnboardingService } from 'src/engine/core-modules/onboarding/onboarding.service'; import { OnboardingService } from 'src/engine/core-modules/onboarding/onboarding.service';
import { TwentyConfigService } from 'src/engine/core-modules/twenty-config/twenty-config.service'; import { TwentyConfigService } from 'src/engine/core-modules/twenty-config/twenty-config.service';
import { UserWorkspace } from 'src/engine/core-modules/user-workspace/user-workspace.entity'; import { UserWorkspace } from 'src/engine/core-modules/user-workspace/user-workspace.entity';
import { User } from 'src/engine/core-modules/user/user.entity';
import { SendInvitationsOutput } from 'src/engine/core-modules/workspace-invitation/dtos/send-invitations.output'; import { SendInvitationsOutput } from 'src/engine/core-modules/workspace-invitation/dtos/send-invitations.output';
import { castAppTokenToWorkspaceInvitationUtil } from 'src/engine/core-modules/workspace-invitation/utils/cast-app-token-to-workspace-invitation.util'; import { castAppTokenToWorkspaceInvitationUtil } from 'src/engine/core-modules/workspace-invitation/utils/cast-app-token-to-workspace-invitation.util';
import { import {
@ -33,6 +32,7 @@ import {
WorkspaceInvitationExceptionCode, WorkspaceInvitationExceptionCode,
} from 'src/engine/core-modules/workspace-invitation/workspace-invitation.exception'; } from 'src/engine/core-modules/workspace-invitation/workspace-invitation.exception';
import { Workspace } from 'src/engine/core-modules/workspace/workspace.entity'; import { Workspace } from 'src/engine/core-modules/workspace/workspace.entity';
import { WorkspaceMemberWorkspaceEntity } from 'src/modules/workspace-member/standard-objects/workspace-member.workspace-entity';
@Injectable() @Injectable()
// eslint-disable-next-line @nx/workspace-inject-workspace-repository // eslint-disable-next-line @nx/workspace-inject-workspace-repository
@ -228,7 +228,7 @@ export class WorkspaceInvitationService {
async resendWorkspaceInvitation( async resendWorkspaceInvitation(
appTokenId: string, appTokenId: string,
workspace: Workspace, workspace: Workspace,
sender: User, sender: WorkspaceMemberWorkspaceEntity,
) { ) {
const appToken = await this.appTokenRepository.findOne({ const appToken = await this.appTokenRepository.findOne({
where: { where: {
@ -253,7 +253,7 @@ export class WorkspaceInvitationService {
async sendInvitations( async sendInvitations(
emails: string[], emails: string[],
workspace: Workspace, workspace: Workspace,
sender: User, sender: WorkspaceMemberWorkspaceEntity,
usePersonalInvitation = true, usePersonalInvitation = true,
): Promise<SendInvitationsOutput> { ): Promise<SendInvitationsOutput> {
if (!workspace?.inviteHash) { if (!workspace?.inviteHash) {
@ -306,14 +306,13 @@ export class WorkspaceInvitationService {
: {}, : {},
}); });
// Todo: sender name and locale should come from workspace member not user!
const emailData = { const emailData = {
link: link.toString(), link: link.toString(),
workspace: { name: workspace.displayName, logo: workspace.logo }, workspace: { name: workspace.displayName, logo: workspace.logo },
sender: { sender: {
email: sender.email, email: sender.userEmail,
firstName: sender.firstName, firstName: sender.name.firstName,
lastName: sender.lastName, lastName: sender.name.lastName,
}, },
serverUrl: this.twentyConfigService.get('SERVER_URL'), serverUrl: this.twentyConfigService.get('SERVER_URL'),
locale: sender.locale as keyof typeof APP_LOCALES, locale: sender.locale as keyof typeof APP_LOCALES,
@ -328,7 +327,7 @@ export class WorkspaceInvitationService {
i18n.activate(sender.locale); i18n.activate(sender.locale);
await this.emailService.send({ await this.emailService.send({
from: `${sender.firstName} ${sender.lastName} (via Twenty) <${this.twentyConfigService.get('EMAIL_FROM_ADDRESS')}>`, from: `${sender.name.firstName} ${sender.name.lastName} (via Twenty) <${this.twentyConfigService.get('EMAIL_FROM_ADDRESS')}>`,
to: invitation.value.email, to: invitation.value.email,
subject: t`Join your team on Twenty`, subject: t`Join your team on Twenty`,
text, text,

View File

@ -14,6 +14,8 @@ import { UserAuthGuard } from 'src/engine/guards/user-auth.guard';
import { WorkspaceAuthGuard } from 'src/engine/guards/workspace-auth.guard'; import { WorkspaceAuthGuard } from 'src/engine/guards/workspace-auth.guard';
import { SettingPermissionType } from 'src/engine/metadata-modules/permissions/constants/setting-permission-type.constants'; import { SettingPermissionType } from 'src/engine/metadata-modules/permissions/constants/setting-permission-type.constants';
import { PermissionsGraphqlApiExceptionFilter } from 'src/engine/metadata-modules/permissions/utils/permissions-graphql-api-exception.filter'; import { PermissionsGraphqlApiExceptionFilter } from 'src/engine/metadata-modules/permissions/utils/permissions-graphql-api-exception.filter';
import { WorkspaceMemberWorkspaceEntity } from 'src/modules/workspace-member/standard-objects/workspace-member.workspace-entity';
import { TwentyORMGlobalManager } from 'src/engine/twenty-orm/twenty-orm-global.manager';
import { SendInvitationsInput } from './dtos/send-invitations.input'; import { SendInvitationsInput } from './dtos/send-invitations.input';
@ -25,6 +27,7 @@ import { SendInvitationsInput } from './dtos/send-invitations.input';
@Resolver() @Resolver()
export class WorkspaceInvitationResolver { export class WorkspaceInvitationResolver {
constructor( constructor(
private readonly twentyORMGlobalManager: TwentyORMGlobalManager,
private readonly workspaceInvitationService: WorkspaceInvitationService, private readonly workspaceInvitationService: WorkspaceInvitationService,
private readonly fileService: FileService, private readonly fileService: FileService,
) {} ) {}
@ -47,10 +50,22 @@ export class WorkspaceInvitationResolver {
@AuthWorkspace() workspace: Workspace, @AuthWorkspace() workspace: Workspace,
@AuthUser() user: User, @AuthUser() user: User,
) { ) {
const workspaceMemberRepository =
await this.twentyORMGlobalManager.getRepositoryForWorkspace<WorkspaceMemberWorkspaceEntity>(
workspace.id,
'workspaceMember',
);
const workspaceMember = await workspaceMemberRepository.findOneOrFail({
where: {
userId: user.id,
},
});
return this.workspaceInvitationService.resendWorkspaceInvitation( return this.workspaceInvitationService.resendWorkspaceInvitation(
appTokenId, appTokenId,
workspace, workspace,
user, workspaceMember,
); );
} }
@ -75,10 +90,22 @@ export class WorkspaceInvitationResolver {
}); });
} }
const workspaceMemberRepository =
await this.twentyORMGlobalManager.getRepositoryForWorkspace<WorkspaceMemberWorkspaceEntity>(
workspace.id,
'workspaceMember',
);
const workspaceMember = await workspaceMemberRepository.findOneOrFail({
where: {
userId: user.id,
},
});
return await this.workspaceInvitationService.sendInvitations( return await this.workspaceInvitationService.sendInvitations(
sendInviteLinkInput.emails, sendInviteLinkInput.emails,
{ ...workspace, logo: workspaceLogoWithToken }, { ...workspace, logo: workspaceLogoWithToken },
user, workspaceMember,
); );
} }
} }