1 <?php namespace BookStack\Auth\Access;
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 BookStack\Facades\Theme;
10 use BookStack\Theming\ThemeEvents;
13 class RegistrationService
17 protected $emailConfirmationService;
20 * RegistrationService constructor.
22 public function __construct(UserRepo $userRepo, EmailConfirmationService $emailConfirmationService)
24 $this->userRepo = $userRepo;
25 $this->emailConfirmationService = $emailConfirmationService;
29 * Check whether or not registrations are allowed in the app settings.
30 * @throws UserRegistrationException
32 public function ensureRegistrationAllowed()
34 if (!$this->registrationAllowed()) {
35 throw new UserRegistrationException(trans('auth.registrations_disabled'), '/login');
40 * Check if standard BookStack User registrations are currently allowed.
41 * Does not prevent external-auth based registration.
43 protected function registrationAllowed(): bool
45 $authMethod = config('auth.method');
46 $authMethodsWithRegistration = ['standard'];
47 return in_array($authMethod, $authMethodsWithRegistration) && setting('registration-enabled');
51 * The registrations flow for all users.
52 * @throws UserRegistrationException
54 public function registerUser(array $userData, ?SocialAccount $socialAccount = null, bool $emailConfirmed = false): User
56 $userEmail = $userData['email'];
59 $this->ensureEmailDomainAllowed($userEmail);
61 // Ensure user does not already exist
62 $alreadyUser = !is_null($this->userRepo->getByEmail($userEmail));
64 throw new UserRegistrationException(trans('errors.error_user_exists_different_creds', ['email' => $userEmail]), '/login');
68 $newUser = $this->userRepo->registerNew($userData, $emailConfirmed);
70 // Assign social account if given
72 $newUser->socialAccounts()->save($socialAccount);
75 Activity::add(ActivityType::AUTH_REGISTER, $socialAccount ?? $newUser);
76 Theme::dispatch(ThemeEvents::AUTH_REGISTER, $socialAccount ? $socialAccount->driver : auth()->getDefaultDriver(), $newUser);
78 // Start email confirmation flow if required
79 if ($this->emailConfirmationService->confirmationRequired() && !$emailConfirmed) {
83 $this->emailConfirmationService->sendConfirmation($newUser);
84 session()->flash('sent-email-confirmation', true);
85 } catch (Exception $e) {
86 $message = trans('auth.email_confirm_send_error');
87 throw new UserRegistrationException($message, '/register/confirm');
95 * Ensure that the given email meets any active email domain registration restrictions.
96 * Throws if restrictions are active and the email does not match an allowed domain.
97 * @throws UserRegistrationException
99 protected function ensureEmailDomainAllowed(string $userEmail): void
101 $registrationRestrict = setting('registration-restrict');
103 if (!$registrationRestrict) {
107 $restrictedEmailDomains = explode(',', str_replace(' ', '', $registrationRestrict));
108 $userEmailDomain = $domain = mb_substr(mb_strrchr($userEmail, "@"), 1);
109 if (!in_array($userEmailDomain, $restrictedEmailDomains)) {
110 $redirect = $this->registrationAllowed() ? '/register' : '/login';
111 throw new UserRegistrationException(trans('auth.registration_email_domain_invalid'), $redirect);