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