Skip to content

Conversation

harshit078
Copy link
Contributor

Description

  • This PR solves the a sub-issue from Impersonation 2.0 core-team-issues#1421
  • impersonation tokens bypasses 2FA as intended
  • Added Audit trails to cover all impersonation events
  • Added Proper testing coverage

Copy link
Contributor

@greptile-apps greptile-apps bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Greptile Summary

This PR enhances the server-level impersonation functionality to properly bypass 2FA when enabled and adds comprehensive audit trails for all impersonation events. The changes modify the admin panel's impersonation flow by:

  1. Adding audit trail capabilities: The AuditModule is now imported into the AdminPanelModule to enable tracking of impersonation events

  2. Capturing impersonator identity: The GraphQL resolver now uses the @AuthUser decorator to extract the admin user performing the impersonation and passes this ID to the service layer

  3. Implementing comprehensive security measures: The service method signature has been updated to accept an impersonatorUserId parameter, with UUID validation using Zod for all inputs, extensive logging with correlation IDs, and proper error handling

  4. Enabling 2FA bypass for impersonation tokens: The LoginTokenService.generateLoginToken call now includes impersonation-specific metadata ({ isImpersonation: true, impersonatorUserId }) as a fourth parameter, which allows the authentication system to properly bypass 2FA validation for legitimate admin impersonation attempts

The changes follow the existing service patterns while adding necessary security enhancements for administrative operations. The audit trail implementation ensures compliance requirements are met by tracking both impersonation attempts and successful token generation events.

Confidence score: 4/5

  • This PR addresses a critical security requirement but introduces breaking changes that need coordination
  • The comprehensive audit logging and 2FA bypass mechanism appear well-implemented following security best practices
  • Pay close attention to the AdminPanelService method signature change and ensure all calling code is updated accordingly

3 files reviewed, 1 comment

Edit Code Review Bot Settings | Greptile

Copy link
Contributor

github-actions bot commented Sep 6, 2025

🚀 Preview Environment Ready!

Your preview environment is available at: http://bore.pub:50655

This environment will automatically shut down when the PR is closed or after 5 hours.

workspaceId: string,
impersonatorUserId: string,
) {
try {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This doesn't seem like the standard pattern for input validation in the codebase, usually it's validated at the graphql layer (ImpersonateInput). For impersonatorUserId why not but I don't think it should ever be corrupted unless it's a malicious attempt

const loginToken = await this.loginTokenService.generateLoginToken(
user.email,
user.userWorkspaces[0].workspace.id,
undefined,
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't really like this undefined option it feels like a codesmell. Maybe we should introduce Impersonation as an auth provider type?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

agreed, I felt the need to improve the undefined and was thinking for a better approach than this. Thanks for the advice, I'll add impersonation as an auth provider and import it here.

`Impersonation token exchange attempt for ${email} by ${impersonatorUserId}`,
'AuthResolver.getAuthTokensFromLoginToken',
);
if (workspace.allowImpersonation !== true) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We try to avoid nested if structures, and also avoid else {} statements, when possible (because they are hard to follow). Usually it's more elegant to use ifs with an early return / exception thrown

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Got it, I'll remove nested if and else and introduce a more flat approach.

@FelixMalfait FelixMalfait self-assigned this Sep 7, 2025
@FelixMalfait FelixMalfait merged commit b78d139 into twentyhq:main Sep 7, 2025
51 checks passed
Copy link
Contributor

github-actions bot commented Sep 7, 2025

Thanks @harshit078 for your contribution!
This marks your 44th PR on the repo. You're top 1% of all our contributors 🎉
See contributor page - Share on LinkedIn - Share on Twitter

Contributions

AnishSarkar22 pushed a commit to AnishSarkar22/twenty that referenced this pull request Sep 8, 2025
…tyhq#14340)

## Description

- This PR solves the a sub-issue from
twentyhq/core-team-issues#1421
- impersonation tokens bypasses 2FA as intended 
- Added Audit trails to cover all impersonation events
- Added Proper testing coverage

---------

Co-authored-by: Félix Malfait <[email protected]>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants