Files
twenty/packages/twenty-server/src/engine/guards/admin-panel-or-impersonate.guard.ts
T
Paul Rastoin e7e99247e8 Centralize and standardize impersonation validation rules (#21717)
# Introduction
Followup https://github.com/twentyhq/twenty/pull/21707

## Behavioral change worth calling out
Server-level impersonation now requires verified 2FA outside development
at every checkpoint (generation, exchange, and per-request). In main the
2FA gate only existed in ImpersonationService. This is the right
tightening, but it means existing server-admin impersonation sessions in
production for admins without verified 2FA will now be rejected on the
next request, not just at token creation.

cc @s0yd4RK

<!-- This is an auto-generated description by cubic. -->
<a
href="https://cubic.dev/pr/twentyhq/twenty/pull/21717?utm_source=github"
target="_blank" rel="noopener noreferrer"
data-no-image-dialog="true"><picture><source
media="(prefers-color-scheme: dark)"
srcset="https://www.cubic.dev/buttons/review-in-cubic-dark.svg"><source
media="(prefers-color-scheme: light)"
srcset="https://www.cubic.dev/buttons/review-in-cubic-light.svg"><img
alt="Review in cubic"
src="https://www.cubic.dev/buttons/review-in-cubic-dark.svg"></picture></a>
<!-- End of auto-generated description by cubic. -->

---------

Co-authored-by: s0yd4RK <285671363+s0yd4RK@users.noreply.github.com>
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-06-18 13:13:50 +02:00

17 lines
753 B
TypeScript

import { type CanActivate, type ExecutionContext } from '@nestjs/common';
import { GqlExecutionContext } from '@nestjs/graphql';
import { userHasAdminPrivileges } from 'src/engine/core-modules/impersonation/utils/user-has-admin-privileges.util';
// Read-only admin-panel lookups (user/recent-users search) are available to
// full admins as well as impersonators: managing server-admin access requires
// finding users, and a full admin is the higher privilege.
export class AdminPanelOrImpersonateGuard implements CanActivate {
canActivate(context: ExecutionContext): boolean | Promise<boolean> {
const ctx = GqlExecutionContext.create(context);
const request = ctx.getContext().req;
return userHasAdminPrivileges(request.user);
}
}