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
@@ -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 { User } from 'src/engine/core-modules/user/user.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 { 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)
@UseFilters(ApprovedAccessDomainExceptionFilter)
@Resolver()
export class ApprovedAccessDomainResolver {
constructor(
private readonly twentyORMGlobalManager: TwentyORMGlobalManager,
private readonly approvedAccessDomainService: ApprovedAccessDomainService,
) {}
@@ -27,10 +30,22 @@ export class ApprovedAccessDomainResolver {
@AuthWorkspace() currentWorkspace: Workspace,
@AuthUser() currentUser: User,
): 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(
domain,
currentWorkspace,
currentUser,
workspaceMember,
email,
);
}
@@ -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 { EmailService } from 'src/engine/core-modules/email/email.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 { isWorkDomain } from 'src/utils/is-work-email';
import { WorkspaceMemberWorkspaceEntity } from 'src/modules/workspace-member/standard-objects/workspace-member.workspace-entity';
@Injectable()
// eslint-disable-next-line @nx/workspace-inject-workspace-repository
@@ -33,7 +33,7 @@ export class ApprovedAccessDomainService {
) {}
async sendApprovedAccessDomainValidationEmail(
sender: User,
sender: WorkspaceMemberWorkspaceEntity,
to: string,
workspace: Workspace,
approvedAccessDomain: ApprovedAccessDomainEntity,
@@ -66,9 +66,9 @@ export class ApprovedAccessDomainService {
workspace: { name: workspace.displayName, logo: workspace.logo },
domain: approvedAccessDomain.domain,
sender: {
email: sender.email,
firstName: sender.firstName,
lastName: sender.lastName,
email: sender.userEmail,
firstName: sender.name.firstName,
lastName: sender.name.lastName,
},
serverUrl: this.twentyConfigService.get('SERVER_URL'),
locale: 'en' as keyof typeof APP_LOCALES,
@@ -79,7 +79,7 @@ export class ApprovedAccessDomainService {
});
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,
subject: 'Approve your access domain',
text,
@@ -140,7 +140,7 @@ export class ApprovedAccessDomainService {
async createApprovedAccessDomain(
domain: string,
inWorkspace: Workspace,
fromUser: User,
fromWorkspaceMember: WorkspaceMemberWorkspaceEntity,
emailToValidateDomain: string,
): Promise<ApprovedAccessDomainEntity> {
if (!isWorkDomain(domain)) {
@@ -170,7 +170,7 @@ export class ApprovedAccessDomainService {
);
await this.sendApprovedAccessDomainValidationEmail(
fromUser,
fromWorkspaceMember,
emailToValidateDomain,
inWorkspace,
approvedAccessDomain,
@@ -11,8 +11,8 @@ import {
import { DomainManagerService } from 'src/engine/core-modules/domain-manager/services/domain-manager.service';
import { EmailService } from 'src/engine/core-modules/email/email.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 { WorkspaceMemberWorkspaceEntity } from 'src/modules/workspace-member/standard-objects/workspace-member.workspace-entity';
import { ApprovedAccessDomainService } from './approved-access-domain.service';
@@ -78,9 +78,8 @@ describe('ApprovedAccessDomainService', () => {
isCustomDomainEnabled: false,
} as Workspace;
const fromUser = {
email: 'user@custom-domain.com',
isEmailVerified: true,
} as User;
userEmail: 'user@custom-domain.com',
} as WorkspaceMemberWorkspaceEntity;
const expectedApprovedAccessDomain = {
workspaceId: 'workspace-id',
@@ -118,7 +117,9 @@ describe('ApprovedAccessDomainService', () => {
service.createApprovedAccessDomain(
'gmail.com',
{ id: 'workspace-id' } as Workspace,
{ email: 'user@gmail.com', isEmailVerified: true } as User,
{
userEmail: 'user@gmail.com',
} as WorkspaceMemberWorkspaceEntity,
'user@gmail.com',
),
).rejects.toThrowError(
@@ -184,7 +185,7 @@ describe('ApprovedAccessDomainService', () => {
describe('sendApprovedAccessDomainValidationEmail', () => {
it('should throw an exception if the approved access domain is already validated', async () => {
const approvedAccessDomainId = 'approved-access-domain-id';
const sender = {} as User;
const sender = {} as WorkspaceMemberWorkspaceEntity;
const workspace = {} as Workspace;
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 () => {
const approvedAccessDomainId = 'approved-access-domain-id';
const sender = {} as User;
const sender = {} as WorkspaceMemberWorkspaceEntity;
const workspace = {} as Workspace;
const email = 'validator@different.com';
const approvedAccessDomain = {
@@ -244,10 +245,9 @@ describe('ApprovedAccessDomainService', () => {
it('should send a validation email if all conditions are met', async () => {
const sender = {
email: 'sender@example.com',
firstName: 'John',
lastName: 'Doe',
} as User;
userEmail: 'sender@example.com',
name: { firstName: 'John', lastName: 'Doe' },
} as WorkspaceMemberWorkspaceEntity;
const workspace = {
displayName: 'Test Workspace',
logo: '/logo.png',