src/Entity/User.php line 20

Open in your IDE?
  1. <?php
  2. namespace App\Entity;
  3. use App\Repository\UserRepository;
  4. use Doctrine\ORM\Mapping as ORM;
  5. use Scheb\TwoFactorBundle\Model\Email\TwoFactorInterface as EmailTwoFactorInterface;
  6. use Scheb\TwoFactorBundle\Model\Totp\TotpConfiguration;
  7. use Scheb\TwoFactorBundle\Model\Totp\TotpConfigurationInterface;
  8. use Scheb\TwoFactorBundle\Model\Totp\TwoFactorInterface as TotpTwoFactorInterface;
  9. use Scheb\TwoFactorBundle\Model\TrustedDeviceInterface;
  10. use Symfony\Bridge\Doctrine\Validator\Constraints\UniqueEntity;
  11. use Symfony\Component\Security\Core\User\PasswordAuthenticatedUserInterface;
  12. use Symfony\Component\Security\Core\User\UserInterface;
  13. use Symfony\Component\Validator\Constraints as Assert;
  14. #[ORM\Entity(repositoryClassUserRepository::class)]
  15. #[UniqueEntity(['email'])]
  16. #[UniqueEntity(['username'])]
  17. class User implements UserInterface,
  18.     PasswordAuthenticatedUserInterface,
  19.     EmailTwoFactorInterface,
  20.     TotpTwoFactorInterface,
  21.     TrustedDeviceInterface
  22. {
  23.     final const USER_SUPER_ADMIN_ID 1;
  24.     final const USER_DEFAULT_ID 2;
  25.     #[ORM\Id]
  26.     #[ORM\GeneratedValue]
  27.     #[ORM\Column(type'integer')]
  28.     private ?int $id;
  29.     #[ORM\Column(type'string'length180uniquetrue)]
  30.     #[Assert\Email]
  31.     #[Assert\NotNull]
  32.     private ?string $email;
  33.     #[ORM\Column(length255)]
  34. //    #[Assert\Length(
  35. //        min: 3,
  36. //        max: 4096,
  37. //        minMessage: " the username must have minimum {{ limit }} characters")]
  38. //    #[Assert\NotNull]
  39.     private ?string $username null;
  40.     #[ORM\Column(type'json')]
  41.     private array $roles = [];
  42.     #[ORM\Column(type'string')]
  43.     #[Assert\Length(min6minMessage'Your password should be at least {{ limit }} characters')]
  44.     private ?string $password=  null;
  45.     #[ORM\OneToOne(inversedBy'user'targetEntityPersonal::class, cascade: ['persist''remove'])]
  46.     private ?Personal $personal;
  47.     #[ORM\Column(type'boolean')]
  48.     private bool $isVerified false;
  49.     #[ORM\Column(nullablefalse)]
  50.     private ?bool $active null;
  51.     #[ORM\ManyToOne(cascade: ['persist'])]
  52.     private ?Customer $customer null;
  53.     #[ORM\Column(length255,nullabletrue)]
  54.     private ?string $google_id null;
  55.     // =============================================
  56.     // Two-Factor Authentication Fields
  57.     // =============================================
  58.     /**
  59.      * Temporary 6-digit code sent via email for 2FA
  60.      */
  61.     #[ORM\Column(type'string'length6nullabletrue)]
  62.     private ?string $emailAuthCode null;
  63.     /**
  64.      * Base32 encoded TOTP secret for authenticator apps
  65.      */
  66.     #[ORM\Column(type'string'length255nullabletrue)]
  67.     private ?string $totpSecret null;
  68.     /**
  69.      * Selected 2FA method: 'email', 'totp', or null (disabled)
  70.      */
  71.     #[ORM\Column(type'string'length10nullabletrue)]
  72.     private ?string $twoFactorMethod null;
  73.     /**
  74.      * Transient (non-persisted) field set from session during login flow.
  75.      */
  76.     private ?string $sessionTwoFactorMethod null;
  77.     /**
  78.      * Version counter for trusted device invalidation
  79.      * Increment this to invalidate all trusted devices for this user
  80.      */
  81.     #[ORM\Column(type'integer'options: ['default' => 0])]
  82.     private int $trustedTokenVersion 0;
  83.     public function __construct()
  84.     {
  85.     }
  86.     public function getId(): ?int
  87.     {
  88.         return $this->id;
  89.     }
  90.     public function getEmail(): ?string
  91.     {
  92.         return $this->email;
  93.     }
  94.     public function setEmail(?string $email): self
  95.     {
  96.         $this->email $email;
  97.         return $this;
  98.     }
  99.     /**
  100.      * A visual identifier that represents this user.
  101.      *
  102.      * @see UserInterface
  103.      */
  104.     public function getUserIdentifier(): string
  105.     {
  106.         return (string)$this->email;
  107.     }
  108.     /**
  109.      * @see UserInterface
  110.      */
  111.     public function getRoles(): array
  112.     {
  113.         $roles $this->roles;
  114.         // guarantee every user at least has ROLE_USER
  115.         $roles[] = 'ROLE_USER';
  116.         return array_unique($roles);
  117.     }
  118.     public function getRole(): string
  119.     {
  120.         if ($this->roles && count($this->roles) > 0) {
  121.             return $this->roles[0];
  122.         }
  123.         return '';
  124.     }
  125.     public function setRoles(array $roles): self
  126.     {
  127.         $this->roles $roles;
  128.         return $this;
  129.     }
  130.     /**
  131.      * @see PasswordAuthenticatedUserInterface
  132.      */
  133.     public function getPassword(): ?string
  134.     {
  135.         return $this->password;
  136.     }
  137.     public function setPassword(?string $password): self
  138.     {
  139.         $this->password $password;
  140.         return $this;
  141.     }
  142.     /**
  143.      * @see UserInterface
  144.      */
  145.     public function eraseCredentials()
  146.     {
  147.         // If you store any temporary, sensitive data on the user, clear it here
  148.         // $this->plainPassword = null;
  149.     }
  150.     public function getPersonal(): ?Personal
  151.     {
  152.         return $this->personal;
  153.     }
  154.     public function setPersonal(?Personal $personal): self
  155.     {
  156.         $this->personal $personal;
  157.         return $this;
  158.     }
  159.     public function isVerified(): bool
  160.     {
  161.         return $this->isVerified;
  162.     }
  163.     public function setIsVerified(bool $isVerified): self
  164.     {
  165.         $this->isVerified $isVerified;
  166.         return $this;
  167.     }
  168.     public function getUsername(): ?string
  169.     {
  170.         return $this->username;
  171.     }
  172.     public function setUsername(string $username): self
  173.     {
  174.         $this->username $username;
  175.         return $this;
  176.     }
  177.     public function isActive(): ?bool
  178.     {
  179.         return $this->active;
  180.     }
  181.     public function setActive(?bool $active): self
  182.     {
  183.         $this->active $active;
  184.         return $this;
  185.     }
  186.     public function getCustomer(): ?Customer
  187.     {
  188.         return $this->customer;
  189.     }
  190.     public function setCustomer(?Customer $customer): self
  191.     {
  192.         $this->customer $customer;
  193.         return $this;
  194.     }
  195.     public function __toString(): string
  196.     {
  197.         return $this->username;
  198.     }
  199.     public function getGoogleId(): ?string
  200.     {
  201.         return $this->google_id;
  202.     }
  203.     public function setGoogleId(string $google_id): static
  204.     {
  205.         $this->google_id $google_id;
  206.         return $this;
  207.     }
  208.     // =============================================
  209.     // Email Two-Factor Authentication Methods
  210.     // =============================================
  211.     /**
  212.      * Return the email address to which the authentication code is sent
  213.      */
  214.     public function getEmailAuthRecipient(): string
  215.     {
  216.         return $this->email;
  217.     }
  218.     /**
  219.      * Return the authentication code
  220.      */
  221.     public function getEmailAuthCode(): ?string
  222.     {
  223.         return $this->emailAuthCode;
  224.     }
  225.     /**
  226.      * Set the authentication code
  227.      */
  228.     public function setEmailAuthCode(?string $authCode): void
  229.     {
  230.         $this->emailAuthCode $authCode;
  231.     }
  232.     /**
  233.      * Check if the user has email 2FA enabled.
  234.      * Session method takes priority over DB method.
  235.      */
  236.     public function isEmailAuthEnabled(): bool
  237.     {
  238.         return $this->sessionTwoFactorMethod === 'email' || $this->twoFactorMethod === 'email';
  239.     }
  240.     // =============================================
  241.     // TOTP Two-Factor Authentication Methods
  242.     // =============================================
  243.     /**
  244.      * Check if the user has TOTP 2FA enabled.
  245.      * Session method takes priority over DB method.
  246.      */
  247.     public function isTotpAuthenticationEnabled(): bool
  248.     {
  249.         return ($this->sessionTwoFactorMethod === 'totp' || $this->twoFactorMethod === 'totp')
  250.             && $this->totpSecret !== null;
  251.     }
  252.     /**
  253.      * Return the username shown in authenticator apps
  254.      */
  255.     public function getTotpAuthenticationUsername(): string
  256.     {
  257.         return $this->email;
  258.     }
  259.     /**
  260.      * Get TOTP configuration for the user
  261.      */
  262.     public function getTotpAuthenticationConfiguration(): ?TotpConfigurationInterface
  263.     {
  264.         if (!$this->totpSecret) {
  265.             return null;
  266.         }
  267.         return new TotpConfiguration(
  268.             $this->totpSecret,
  269.             TotpConfiguration::ALGORITHM_SHA1,
  270.             30,
  271.             6
  272.         );
  273.     }
  274.     /**
  275.      * Get the TOTP secret
  276.      */
  277.     public function getTotpSecret(): ?string
  278.     {
  279.         return $this->totpSecret;
  280.     }
  281.     /**
  282.      * Set the TOTP secret
  283.      */
  284.     public function setTotpSecret(?string $totpSecret): self
  285.     {
  286.         $this->totpSecret $totpSecret;
  287.         return $this;
  288.     }
  289.     // =============================================
  290.     // Two-Factor Method Management
  291.     // =============================================
  292.     /**
  293.      * Get the currently active 2FA method
  294.      */
  295.     public function getTwoFactorMethod(): ?string
  296.     {
  297.         return $this->twoFactorMethod;
  298.     }
  299.     /**
  300.      * Set the 2FA method ('email', 'totp', or null to disable)
  301.      */
  302.     public function setTwoFactorMethod(?string $method): self
  303.     {
  304.         $this->twoFactorMethod $method;
  305.         return $this;
  306.     }
  307.     /**
  308.      * Check if user has any 2FA method enabled.
  309.      * Session method takes priority over DB method.
  310.      */
  311.     public function isTwoFactorEnabled(): bool
  312.     {
  313.         return $this->sessionTwoFactorMethod !== null || $this->twoFactorMethod !== null;
  314.     }
  315.     // =============================================
  316.     // Session Two-Factor Method (transient)
  317.     // =============================================
  318.     public function getSessionTwoFactorMethod(): ?string
  319.     {
  320.         return $this->sessionTwoFactorMethod;
  321.     }
  322.     public function setSessionTwoFactorMethod(?string $method): self
  323.     {
  324.         $this->sessionTwoFactorMethod $method;
  325.         return $this;
  326.     }
  327.     // =============================================
  328.     // Trusted Device Methods
  329.     // =============================================
  330.     /**
  331.      * Get trusted device token version
  332.      * Used by scheb/2fa-trusted-device to validate trusted cookies
  333.      */
  334.     public function getTrustedTokenVersion(): int
  335.     {
  336.         return $this->trustedTokenVersion;
  337.     }
  338.     /**
  339.      * Increment token version to invalidate all trusted devices
  340.      */
  341.     public function invalidateTrustedDevices(): self
  342.     {
  343.         $this->trustedTokenVersion++;
  344.         return $this;
  345.     }
  346.     /**
  347.      * Set trusted token version (mainly for persistence)
  348.      */
  349.     public function setTrustedTokenVersion(int $version): self
  350.     {
  351.         $this->trustedTokenVersion $version;
  352.         return $this;
  353.     }
  354. }