]> BookStack Code Mirror - bookstack/blob - app/Auth/Access/RegistrationService.php
Apply fixes from StyleCI
[bookstack] / app / Auth / Access / RegistrationService.php
1 <?php
2
3 namespace BookStack\Auth\Access;
4
5 use BookStack\Actions\ActivityType;
6 use BookStack\Auth\SocialAccount;
7 use BookStack\Auth\User;
8 use BookStack\Auth\UserRepo;
9 use BookStack\Exceptions\UserRegistrationException;
10 use BookStack\Facades\Activity;
11 use BookStack\Facades\Theme;
12 use BookStack\Theming\ThemeEvents;
13 use Exception;
14
15 class RegistrationService
16 {
17     protected $userRepo;
18     protected $emailConfirmationService;
19
20     /**
21      * RegistrationService constructor.
22      */
23     public function __construct(UserRepo $userRepo, EmailConfirmationService $emailConfirmationService)
24     {
25         $this->userRepo = $userRepo;
26         $this->emailConfirmationService = $emailConfirmationService;
27     }
28
29     /**
30      * Check whether or not registrations are allowed in the app settings.
31      *
32      * @throws UserRegistrationException
33      */
34     public function ensureRegistrationAllowed()
35     {
36         if (!$this->registrationAllowed()) {
37             throw new UserRegistrationException(trans('auth.registrations_disabled'), '/login');
38         }
39     }
40
41     /**
42      * Check if standard BookStack User registrations are currently allowed.
43      * Does not prevent external-auth based registration.
44      */
45     protected function registrationAllowed(): bool
46     {
47         $authMethod = config('auth.method');
48         $authMethodsWithRegistration = ['standard'];
49
50         return in_array($authMethod, $authMethodsWithRegistration) && setting('registration-enabled');
51     }
52
53     /**
54      * The registrations flow for all users.
55      *
56      * @throws UserRegistrationException
57      */
58     public function registerUser(array $userData, ?SocialAccount $socialAccount = null, bool $emailConfirmed = false): User
59     {
60         $userEmail = $userData['email'];
61
62         // Email restriction
63         $this->ensureEmailDomainAllowed($userEmail);
64
65         // Ensure user does not already exist
66         $alreadyUser = !is_null($this->userRepo->getByEmail($userEmail));
67         if ($alreadyUser) {
68             throw new UserRegistrationException(trans('errors.error_user_exists_different_creds', ['email' => $userEmail]), '/login');
69         }
70
71         // Create the user
72         $newUser = $this->userRepo->registerNew($userData, $emailConfirmed);
73
74         // Assign social account if given
75         if ($socialAccount) {
76             $newUser->socialAccounts()->save($socialAccount);
77         }
78
79         Activity::add(ActivityType::AUTH_REGISTER, $socialAccount ?? $newUser);
80         Theme::dispatch(ThemeEvents::AUTH_REGISTER, $socialAccount ? $socialAccount->driver : auth()->getDefaultDriver(), $newUser);
81
82         // Start email confirmation flow if required
83         if ($this->emailConfirmationService->confirmationRequired() && !$emailConfirmed) {
84             $newUser->save();
85
86             try {
87                 $this->emailConfirmationService->sendConfirmation($newUser);
88                 session()->flash('sent-email-confirmation', true);
89             } catch (Exception $e) {
90                 $message = trans('auth.email_confirm_send_error');
91
92                 throw new UserRegistrationException($message, '/register/confirm');
93             }
94         }
95
96         return $newUser;
97     }
98
99     /**
100      * Ensure that the given email meets any active email domain registration restrictions.
101      * Throws if restrictions are active and the email does not match an allowed domain.
102      *
103      * @throws UserRegistrationException
104      */
105     protected function ensureEmailDomainAllowed(string $userEmail): void
106     {
107         $registrationRestrict = setting('registration-restrict');
108
109         if (!$registrationRestrict) {
110             return;
111         }
112
113         $restrictedEmailDomains = explode(',', str_replace(' ', '', $registrationRestrict));
114         $userEmailDomain = $domain = mb_substr(mb_strrchr($userEmail, '@'), 1);
115         if (!in_array($userEmailDomain, $restrictedEmailDomains)) {
116             $redirect = $this->registrationAllowed() ? '/register' : '/login';
117
118             throw new UserRegistrationException(trans('auth.registration_email_domain_invalid'), $redirect);
119         }
120     }
121 }