Merge branch 'development' into release
This commit is contained in:
		
						commit
						becc630acf
					
				| 
						 | 
				
			
			@ -37,8 +37,10 @@ MAIL_FROM=bookstack@example.com
 | 
			
		|||
# SMTP mail options
 | 
			
		||||
# These settings can be checked using the "Send a Test Email"
 | 
			
		||||
# feature found in the "Settings > Maintenance" area of the system.
 | 
			
		||||
# For more detailed documentation on mail options, refer to:
 | 
			
		||||
# https://www.bookstackapp.com/docs/admin/email-webhooks/#email-configuration
 | 
			
		||||
MAIL_HOST=localhost
 | 
			
		||||
MAIL_PORT=1025
 | 
			
		||||
MAIL_PORT=587
 | 
			
		||||
MAIL_USERNAME=null
 | 
			
		||||
MAIL_PASSWORD=null
 | 
			
		||||
MAIL_ENCRYPTION=null
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -69,23 +69,19 @@ DB_PASSWORD=database_user_password
 | 
			
		|||
# certificate itself (Common Name or Subject Alternative Name).
 | 
			
		||||
MYSQL_ATTR_SSL_CA="/path/to/ca.pem"
 | 
			
		||||
 | 
			
		||||
# Mail system to use
 | 
			
		||||
# Can be 'smtp' or 'sendmail'
 | 
			
		||||
# Mail configuration
 | 
			
		||||
# Refer to https://www.bookstackapp.com/docs/admin/email-webhooks/#email-configuration
 | 
			
		||||
MAIL_DRIVER=smtp
 | 
			
		||||
 | 
			
		||||
# Mail sending options
 | 
			
		||||
MAIL_FROM=mail@bookstackapp.com
 | 
			
		||||
MAIL_FROM_NAME=BookStack
 | 
			
		||||
 | 
			
		||||
# SMTP mail options
 | 
			
		||||
MAIL_HOST=localhost
 | 
			
		||||
MAIL_PORT=1025
 | 
			
		||||
MAIL_PORT=587
 | 
			
		||||
MAIL_USERNAME=null
 | 
			
		||||
MAIL_PASSWORD=null
 | 
			
		||||
MAIL_ENCRYPTION=null
 | 
			
		||||
MAIL_VERIFY_SSL=true
 | 
			
		||||
 | 
			
		||||
# Command to use when email is sent via sendmail
 | 
			
		||||
MAIL_SENDMAIL_COMMAND="/usr/sbin/sendmail -bs"
 | 
			
		||||
 | 
			
		||||
# Cache & Session driver to use
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -333,3 +333,11 @@ Patrick Dantas (pa-tiq) :: Portuguese, Brazilian
 | 
			
		|||
Michal (michalgurcik) :: Slovak
 | 
			
		||||
Nepomacs :: German
 | 
			
		||||
Rubens (rubenix) :: Catalan
 | 
			
		||||
m4z :: German; German Informal
 | 
			
		||||
TheRazvy :: Romanian
 | 
			
		||||
Yossi Zilber (lortens) :: Hebrew; Uzbek
 | 
			
		||||
desdinova :: French
 | 
			
		||||
Ingus Rūķis (ingus.rukis) :: Latvian
 | 
			
		||||
Eugene Pershin (SilentEugene) :: Russian
 | 
			
		||||
周盛道 (zhoushengdao) :: Chinese Simplified
 | 
			
		||||
hamidreza amini (hamidrezaamini2022) :: Persian
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1,14 +1,14 @@
 | 
			
		|||
<?php
 | 
			
		||||
 | 
			
		||||
namespace BookStack\Http\Controllers\Auth;
 | 
			
		||||
namespace BookStack\Access\Controllers;
 | 
			
		||||
 | 
			
		||||
use BookStack\Auth\Access\EmailConfirmationService;
 | 
			
		||||
use BookStack\Auth\Access\LoginService;
 | 
			
		||||
use BookStack\Auth\UserRepo;
 | 
			
		||||
use BookStack\Access\EmailConfirmationService;
 | 
			
		||||
use BookStack\Access\LoginService;
 | 
			
		||||
use BookStack\Exceptions\ConfirmationEmailException;
 | 
			
		||||
use BookStack\Exceptions\UserTokenExpiredException;
 | 
			
		||||
use BookStack\Exceptions\UserTokenNotFoundException;
 | 
			
		||||
use BookStack\Http\Controllers\Controller;
 | 
			
		||||
use BookStack\Http\Controller;
 | 
			
		||||
use BookStack\Users\UserRepo;
 | 
			
		||||
use Exception;
 | 
			
		||||
use Illuminate\Http\Request;
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -1,9 +1,9 @@
 | 
			
		|||
<?php
 | 
			
		||||
 | 
			
		||||
namespace BookStack\Http\Controllers\Auth;
 | 
			
		||||
namespace BookStack\Access\Controllers;
 | 
			
		||||
 | 
			
		||||
use BookStack\Actions\ActivityType;
 | 
			
		||||
use BookStack\Http\Controllers\Controller;
 | 
			
		||||
use BookStack\Activity\ActivityType;
 | 
			
		||||
use BookStack\Http\Controller;
 | 
			
		||||
use Illuminate\Http\Request;
 | 
			
		||||
use Illuminate\Support\Facades\Password;
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -1,10 +1,10 @@
 | 
			
		|||
<?php
 | 
			
		||||
 | 
			
		||||
namespace BookStack\Http\Controllers\Auth;
 | 
			
		||||
namespace BookStack\Access\Controllers;
 | 
			
		||||
 | 
			
		||||
use BookStack\Auth\Access\LoginService;
 | 
			
		||||
use BookStack\Auth\User;
 | 
			
		||||
use BookStack\Access\LoginService;
 | 
			
		||||
use BookStack\Exceptions\NotFoundException;
 | 
			
		||||
use BookStack\Users\Models\User;
 | 
			
		||||
 | 
			
		||||
trait HandlesPartialLogins
 | 
			
		||||
{
 | 
			
		||||
| 
						 | 
				
			
			@ -1,13 +1,13 @@
 | 
			
		|||
<?php
 | 
			
		||||
 | 
			
		||||
namespace BookStack\Http\Controllers\Auth;
 | 
			
		||||
namespace BookStack\Access\Controllers;
 | 
			
		||||
 | 
			
		||||
use BookStack\Auth\Access\LoginService;
 | 
			
		||||
use BookStack\Auth\Access\SocialAuthService;
 | 
			
		||||
use BookStack\Access\LoginService;
 | 
			
		||||
use BookStack\Access\SocialAuthService;
 | 
			
		||||
use BookStack\Exceptions\LoginAttemptEmailNeededException;
 | 
			
		||||
use BookStack\Exceptions\LoginAttemptException;
 | 
			
		||||
use BookStack\Facades\Activity;
 | 
			
		||||
use BookStack\Http\Controllers\Controller;
 | 
			
		||||
use BookStack\Http\Controller;
 | 
			
		||||
use Illuminate\Http\RedirectResponse;
 | 
			
		||||
use Illuminate\Http\Request;
 | 
			
		||||
use Illuminate\Support\Facades\Auth;
 | 
			
		||||
| 
						 | 
				
			
			@ -1,14 +1,14 @@
 | 
			
		|||
<?php
 | 
			
		||||
 | 
			
		||||
namespace BookStack\Http\Controllers\Auth;
 | 
			
		||||
namespace BookStack\Access\Controllers;
 | 
			
		||||
 | 
			
		||||
use BookStack\Actions\ActivityType;
 | 
			
		||||
use BookStack\Auth\Access\LoginService;
 | 
			
		||||
use BookStack\Auth\Access\Mfa\BackupCodeService;
 | 
			
		||||
use BookStack\Auth\Access\Mfa\MfaSession;
 | 
			
		||||
use BookStack\Auth\Access\Mfa\MfaValue;
 | 
			
		||||
use BookStack\Access\LoginService;
 | 
			
		||||
use BookStack\Access\Mfa\BackupCodeService;
 | 
			
		||||
use BookStack\Access\Mfa\MfaSession;
 | 
			
		||||
use BookStack\Access\Mfa\MfaValue;
 | 
			
		||||
use BookStack\Activity\ActivityType;
 | 
			
		||||
use BookStack\Exceptions\NotFoundException;
 | 
			
		||||
use BookStack\Http\Controllers\Controller;
 | 
			
		||||
use BookStack\Http\Controller;
 | 
			
		||||
use Exception;
 | 
			
		||||
use Illuminate\Http\Request;
 | 
			
		||||
use Illuminate\Validation\ValidationException;
 | 
			
		||||
| 
						 | 
				
			
			@ -1,10 +1,10 @@
 | 
			
		|||
<?php
 | 
			
		||||
 | 
			
		||||
namespace BookStack\Http\Controllers\Auth;
 | 
			
		||||
namespace BookStack\Access\Controllers;
 | 
			
		||||
 | 
			
		||||
use BookStack\Actions\ActivityType;
 | 
			
		||||
use BookStack\Auth\Access\Mfa\MfaValue;
 | 
			
		||||
use BookStack\Http\Controllers\Controller;
 | 
			
		||||
use BookStack\Access\Mfa\MfaValue;
 | 
			
		||||
use BookStack\Activity\ActivityType;
 | 
			
		||||
use BookStack\Http\Controller;
 | 
			
		||||
use Illuminate\Http\Request;
 | 
			
		||||
 | 
			
		||||
class MfaController extends Controller
 | 
			
		||||
| 
						 | 
				
			
			@ -1,15 +1,15 @@
 | 
			
		|||
<?php
 | 
			
		||||
 | 
			
		||||
namespace BookStack\Http\Controllers\Auth;
 | 
			
		||||
namespace BookStack\Access\Controllers;
 | 
			
		||||
 | 
			
		||||
use BookStack\Actions\ActivityType;
 | 
			
		||||
use BookStack\Auth\Access\LoginService;
 | 
			
		||||
use BookStack\Auth\Access\Mfa\MfaSession;
 | 
			
		||||
use BookStack\Auth\Access\Mfa\MfaValue;
 | 
			
		||||
use BookStack\Auth\Access\Mfa\TotpService;
 | 
			
		||||
use BookStack\Auth\Access\Mfa\TotpValidationRule;
 | 
			
		||||
use BookStack\Access\LoginService;
 | 
			
		||||
use BookStack\Access\Mfa\MfaSession;
 | 
			
		||||
use BookStack\Access\Mfa\MfaValue;
 | 
			
		||||
use BookStack\Access\Mfa\TotpService;
 | 
			
		||||
use BookStack\Access\Mfa\TotpValidationRule;
 | 
			
		||||
use BookStack\Activity\ActivityType;
 | 
			
		||||
use BookStack\Exceptions\NotFoundException;
 | 
			
		||||
use BookStack\Http\Controllers\Controller;
 | 
			
		||||
use BookStack\Http\Controller;
 | 
			
		||||
use Illuminate\Http\Request;
 | 
			
		||||
use Illuminate\Validation\ValidationException;
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -1,10 +1,10 @@
 | 
			
		|||
<?php
 | 
			
		||||
 | 
			
		||||
namespace BookStack\Http\Controllers\Auth;
 | 
			
		||||
namespace BookStack\Access\Controllers;
 | 
			
		||||
 | 
			
		||||
use BookStack\Auth\Access\Oidc\OidcException;
 | 
			
		||||
use BookStack\Auth\Access\Oidc\OidcService;
 | 
			
		||||
use BookStack\Http\Controllers\Controller;
 | 
			
		||||
use BookStack\Access\Oidc\OidcException;
 | 
			
		||||
use BookStack\Access\Oidc\OidcService;
 | 
			
		||||
use BookStack\Http\Controller;
 | 
			
		||||
use Illuminate\Http\Request;
 | 
			
		||||
 | 
			
		||||
class OidcController extends Controller
 | 
			
		||||
| 
						 | 
				
			
			@ -1,13 +1,13 @@
 | 
			
		|||
<?php
 | 
			
		||||
 | 
			
		||||
namespace BookStack\Http\Controllers\Auth;
 | 
			
		||||
namespace BookStack\Access\Controllers;
 | 
			
		||||
 | 
			
		||||
use BookStack\Auth\Access\LoginService;
 | 
			
		||||
use BookStack\Auth\Access\RegistrationService;
 | 
			
		||||
use BookStack\Auth\Access\SocialAuthService;
 | 
			
		||||
use BookStack\Access\LoginService;
 | 
			
		||||
use BookStack\Access\RegistrationService;
 | 
			
		||||
use BookStack\Access\SocialAuthService;
 | 
			
		||||
use BookStack\Exceptions\StoppedAuthenticationException;
 | 
			
		||||
use BookStack\Exceptions\UserRegistrationException;
 | 
			
		||||
use BookStack\Http\Controllers\Controller;
 | 
			
		||||
use BookStack\Http\Controller;
 | 
			
		||||
use Illuminate\Contracts\Validation\Validator as ValidatorContract;
 | 
			
		||||
use Illuminate\Http\Request;
 | 
			
		||||
use Illuminate\Support\Facades\Validator;
 | 
			
		||||
| 
						 | 
				
			
			@ -1,11 +1,11 @@
 | 
			
		|||
<?php
 | 
			
		||||
 | 
			
		||||
namespace BookStack\Http\Controllers\Auth;
 | 
			
		||||
namespace BookStack\Access\Controllers;
 | 
			
		||||
 | 
			
		||||
use BookStack\Actions\ActivityType;
 | 
			
		||||
use BookStack\Auth\Access\LoginService;
 | 
			
		||||
use BookStack\Auth\User;
 | 
			
		||||
use BookStack\Http\Controllers\Controller;
 | 
			
		||||
use BookStack\Access\LoginService;
 | 
			
		||||
use BookStack\Activity\ActivityType;
 | 
			
		||||
use BookStack\Http\Controller;
 | 
			
		||||
use BookStack\Users\Models\User;
 | 
			
		||||
use Illuminate\Http\RedirectResponse;
 | 
			
		||||
use Illuminate\Http\Request;
 | 
			
		||||
use Illuminate\Support\Facades\Hash;
 | 
			
		||||
| 
						 | 
				
			
			@ -1,9 +1,9 @@
 | 
			
		|||
<?php
 | 
			
		||||
 | 
			
		||||
namespace BookStack\Http\Controllers\Auth;
 | 
			
		||||
namespace BookStack\Access\Controllers;
 | 
			
		||||
 | 
			
		||||
use BookStack\Auth\Access\Saml2Service;
 | 
			
		||||
use BookStack\Http\Controllers\Controller;
 | 
			
		||||
use BookStack\Access\Saml2Service;
 | 
			
		||||
use BookStack\Http\Controller;
 | 
			
		||||
use Illuminate\Http\Request;
 | 
			
		||||
use Illuminate\Support\Str;
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -1,15 +1,15 @@
 | 
			
		|||
<?php
 | 
			
		||||
 | 
			
		||||
namespace BookStack\Http\Controllers\Auth;
 | 
			
		||||
namespace BookStack\Access\Controllers;
 | 
			
		||||
 | 
			
		||||
use BookStack\Auth\Access\LoginService;
 | 
			
		||||
use BookStack\Auth\Access\RegistrationService;
 | 
			
		||||
use BookStack\Auth\Access\SocialAuthService;
 | 
			
		||||
use BookStack\Access\LoginService;
 | 
			
		||||
use BookStack\Access\RegistrationService;
 | 
			
		||||
use BookStack\Access\SocialAuthService;
 | 
			
		||||
use BookStack\Exceptions\SocialDriverNotConfigured;
 | 
			
		||||
use BookStack\Exceptions\SocialSignInAccountNotUsed;
 | 
			
		||||
use BookStack\Exceptions\SocialSignInException;
 | 
			
		||||
use BookStack\Exceptions\UserRegistrationException;
 | 
			
		||||
use BookStack\Http\Controllers\Controller;
 | 
			
		||||
use BookStack\Http\Controller;
 | 
			
		||||
use Illuminate\Http\Request;
 | 
			
		||||
use Illuminate\Support\Str;
 | 
			
		||||
use Laravel\Socialite\Contracts\User as SocialUser;
 | 
			
		||||
| 
						 | 
				
			
			@ -1,6 +1,6 @@
 | 
			
		|||
<?php
 | 
			
		||||
 | 
			
		||||
namespace BookStack\Http\Controllers\Auth;
 | 
			
		||||
namespace BookStack\Access\Controllers;
 | 
			
		||||
 | 
			
		||||
use Illuminate\Cache\RateLimiter;
 | 
			
		||||
use Illuminate\Http\Request;
 | 
			
		||||
| 
						 | 
				
			
			@ -1,12 +1,12 @@
 | 
			
		|||
<?php
 | 
			
		||||
 | 
			
		||||
namespace BookStack\Http\Controllers\Auth;
 | 
			
		||||
namespace BookStack\Access\Controllers;
 | 
			
		||||
 | 
			
		||||
use BookStack\Auth\Access\UserInviteService;
 | 
			
		||||
use BookStack\Auth\UserRepo;
 | 
			
		||||
use BookStack\Access\UserInviteService;
 | 
			
		||||
use BookStack\Exceptions\UserTokenExpiredException;
 | 
			
		||||
use BookStack\Exceptions\UserTokenNotFoundException;
 | 
			
		||||
use BookStack\Http\Controllers\Controller;
 | 
			
		||||
use BookStack\Http\Controller;
 | 
			
		||||
use BookStack\Users\UserRepo;
 | 
			
		||||
use Exception;
 | 
			
		||||
use Illuminate\Http\RedirectResponse;
 | 
			
		||||
use Illuminate\Http\Request;
 | 
			
		||||
| 
						 | 
				
			
			@ -1,10 +1,10 @@
 | 
			
		|||
<?php
 | 
			
		||||
 | 
			
		||||
namespace BookStack\Auth\Access;
 | 
			
		||||
namespace BookStack\Access;
 | 
			
		||||
 | 
			
		||||
use BookStack\Auth\User;
 | 
			
		||||
use BookStack\Exceptions\ConfirmationEmailException;
 | 
			
		||||
use BookStack\Notifications\ConfirmEmail;
 | 
			
		||||
use BookStack\Users\Models\User;
 | 
			
		||||
 | 
			
		||||
class EmailConfirmationService extends UserTokenService
 | 
			
		||||
{
 | 
			
		||||
| 
						 | 
				
			
			@ -1,6 +1,6 @@
 | 
			
		|||
<?php
 | 
			
		||||
 | 
			
		||||
namespace BookStack\Auth\Access;
 | 
			
		||||
namespace BookStack\Access;
 | 
			
		||||
 | 
			
		||||
use Illuminate\Contracts\Auth\Authenticatable;
 | 
			
		||||
use Illuminate\Contracts\Auth\UserProvider;
 | 
			
		||||
| 
						 | 
				
			
			@ -1,9 +1,9 @@
 | 
			
		|||
<?php
 | 
			
		||||
 | 
			
		||||
namespace BookStack\Auth\Access;
 | 
			
		||||
namespace BookStack\Access;
 | 
			
		||||
 | 
			
		||||
use BookStack\Auth\Role;
 | 
			
		||||
use BookStack\Auth\User;
 | 
			
		||||
use BookStack\Users\Models\Role;
 | 
			
		||||
use BookStack\Users\Models\User;
 | 
			
		||||
use Illuminate\Support\Collection;
 | 
			
		||||
 | 
			
		||||
class GroupSyncService
 | 
			
		||||
| 
						 | 
				
			
			@ -1,6 +1,6 @@
 | 
			
		|||
<?php
 | 
			
		||||
 | 
			
		||||
namespace BookStack\Auth\Access\Guards;
 | 
			
		||||
namespace BookStack\Access\Guards;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Saml2 Session Guard.
 | 
			
		||||
| 
						 | 
				
			
			@ -1,8 +1,8 @@
 | 
			
		|||
<?php
 | 
			
		||||
 | 
			
		||||
namespace BookStack\Auth\Access\Guards;
 | 
			
		||||
namespace BookStack\Access\Guards;
 | 
			
		||||
 | 
			
		||||
use BookStack\Auth\Access\RegistrationService;
 | 
			
		||||
use BookStack\Access\RegistrationService;
 | 
			
		||||
use Illuminate\Auth\GuardHelpers;
 | 
			
		||||
use Illuminate\Contracts\Auth\Authenticatable as AuthenticatableContract;
 | 
			
		||||
use Illuminate\Contracts\Auth\StatefulGuard;
 | 
			
		||||
| 
						 | 
				
			
			@ -1,15 +1,15 @@
 | 
			
		|||
<?php
 | 
			
		||||
 | 
			
		||||
namespace BookStack\Auth\Access\Guards;
 | 
			
		||||
namespace BookStack\Access\Guards;
 | 
			
		||||
 | 
			
		||||
use BookStack\Auth\Access\LdapService;
 | 
			
		||||
use BookStack\Auth\Access\RegistrationService;
 | 
			
		||||
use BookStack\Auth\User;
 | 
			
		||||
use BookStack\Access\LdapService;
 | 
			
		||||
use BookStack\Access\RegistrationService;
 | 
			
		||||
use BookStack\Exceptions\JsonDebugException;
 | 
			
		||||
use BookStack\Exceptions\LdapException;
 | 
			
		||||
use BookStack\Exceptions\LoginAttemptEmailNeededException;
 | 
			
		||||
use BookStack\Exceptions\LoginAttemptException;
 | 
			
		||||
use BookStack\Exceptions\UserRegistrationException;
 | 
			
		||||
use BookStack\Users\Models\User;
 | 
			
		||||
use Illuminate\Contracts\Auth\UserProvider;
 | 
			
		||||
use Illuminate\Contracts\Session\Session;
 | 
			
		||||
use Illuminate\Support\Str;
 | 
			
		||||
| 
						 | 
				
			
			@ -0,0 +1,110 @@
 | 
			
		|||
<?php
 | 
			
		||||
 | 
			
		||||
namespace BookStack\Access;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Class Ldap
 | 
			
		||||
 * An object-orientated thin abstraction wrapper for common PHP LDAP functions.
 | 
			
		||||
 * Allows the standard LDAP functions to be mocked for testing.
 | 
			
		||||
 */
 | 
			
		||||
class Ldap
 | 
			
		||||
{
 | 
			
		||||
    /**
 | 
			
		||||
     * Connect to an LDAP server.
 | 
			
		||||
     *
 | 
			
		||||
     * @return resource|\LDAP\Connection|false
 | 
			
		||||
     */
 | 
			
		||||
    public function connect(string $hostName)
 | 
			
		||||
    {
 | 
			
		||||
        return ldap_connect($hostName);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Set the value of an LDAP option for the given connection.
 | 
			
		||||
     *
 | 
			
		||||
     * @param resource|\LDAP\Connection|null $ldapConnection
 | 
			
		||||
     */
 | 
			
		||||
    public function setOption($ldapConnection, int $option, mixed $value): bool
 | 
			
		||||
    {
 | 
			
		||||
        return ldap_set_option($ldapConnection, $option, $value);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Start TLS on the given LDAP connection.
 | 
			
		||||
     */
 | 
			
		||||
    public function startTls($ldapConnection): bool
 | 
			
		||||
    {
 | 
			
		||||
        return ldap_start_tls($ldapConnection);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Set the version number for the given LDAP connection.
 | 
			
		||||
     *
 | 
			
		||||
     * @param resource|\LDAP\Connection $ldapConnection
 | 
			
		||||
     */
 | 
			
		||||
    public function setVersion($ldapConnection, int $version): bool
 | 
			
		||||
    {
 | 
			
		||||
        return $this->setOption($ldapConnection, LDAP_OPT_PROTOCOL_VERSION, $version);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Search LDAP tree using the provided filter.
 | 
			
		||||
     *
 | 
			
		||||
     * @param resource|\LDAP\Connection   $ldapConnection
 | 
			
		||||
     *
 | 
			
		||||
     * @return resource|\LDAP\Result
 | 
			
		||||
     */
 | 
			
		||||
    public function search($ldapConnection, string $baseDn, string $filter, array $attributes = null)
 | 
			
		||||
    {
 | 
			
		||||
        return ldap_search($ldapConnection, $baseDn, $filter, $attributes);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Get entries from an LDAP search result.
 | 
			
		||||
     *
 | 
			
		||||
     * @param resource|\LDAP\Connection $ldapConnection
 | 
			
		||||
     * @param resource|\LDAP\Result $ldapSearchResult
 | 
			
		||||
     */
 | 
			
		||||
    public function getEntries($ldapConnection, $ldapSearchResult): array|false
 | 
			
		||||
    {
 | 
			
		||||
        return ldap_get_entries($ldapConnection, $ldapSearchResult);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Search and get entries immediately.
 | 
			
		||||
     *
 | 
			
		||||
     * @param resource|\LDAP\Connection   $ldapConnection
 | 
			
		||||
     */
 | 
			
		||||
    public function searchAndGetEntries($ldapConnection, string $baseDn, string $filter, array $attributes = null): array|false
 | 
			
		||||
    {
 | 
			
		||||
        $search = $this->search($ldapConnection, $baseDn, $filter, $attributes);
 | 
			
		||||
 | 
			
		||||
        return $this->getEntries($ldapConnection, $search);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Bind to LDAP directory.
 | 
			
		||||
     *
 | 
			
		||||
     * @param resource|\LDAP\Connection $ldapConnection
 | 
			
		||||
     */
 | 
			
		||||
    public function bind($ldapConnection, string $bindRdn = null, string $bindPassword = null): bool
 | 
			
		||||
    {
 | 
			
		||||
        return ldap_bind($ldapConnection, $bindRdn, $bindPassword);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Explode an LDAP dn string into an array of components.
 | 
			
		||||
     */
 | 
			
		||||
    public function explodeDn(string $dn, int $withAttrib): array|false
 | 
			
		||||
    {
 | 
			
		||||
        return ldap_explode_dn($dn, $withAttrib);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Escape a string for use in an LDAP filter.
 | 
			
		||||
     */
 | 
			
		||||
    public function escape(string $value, string $ignore = '', int $flags = 0): string
 | 
			
		||||
    {
 | 
			
		||||
        return ldap_escape($value, $ignore, $flags);
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -1,11 +1,11 @@
 | 
			
		|||
<?php
 | 
			
		||||
 | 
			
		||||
namespace BookStack\Auth\Access;
 | 
			
		||||
namespace BookStack\Access;
 | 
			
		||||
 | 
			
		||||
use BookStack\Auth\User;
 | 
			
		||||
use BookStack\Exceptions\JsonDebugException;
 | 
			
		||||
use BookStack\Exceptions\LdapException;
 | 
			
		||||
use BookStack\Uploads\UserAvatars;
 | 
			
		||||
use BookStack\Users\Models\User;
 | 
			
		||||
use ErrorException;
 | 
			
		||||
use Illuminate\Support\Facades\Log;
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -15,26 +15,19 @@ use Illuminate\Support\Facades\Log;
 | 
			
		|||
 */
 | 
			
		||||
class LdapService
 | 
			
		||||
{
 | 
			
		||||
    protected Ldap $ldap;
 | 
			
		||||
    protected GroupSyncService $groupSyncService;
 | 
			
		||||
    protected UserAvatars $userAvatars;
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * @var resource
 | 
			
		||||
     * @var resource|\LDAP\Connection
 | 
			
		||||
     */
 | 
			
		||||
    protected $ldapConnection;
 | 
			
		||||
 | 
			
		||||
    protected array $config;
 | 
			
		||||
    protected bool $enabled;
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * LdapService constructor.
 | 
			
		||||
     */
 | 
			
		||||
    public function __construct(Ldap $ldap, UserAvatars $userAvatars, GroupSyncService $groupSyncService)
 | 
			
		||||
    {
 | 
			
		||||
        $this->ldap = $ldap;
 | 
			
		||||
        $this->userAvatars = $userAvatars;
 | 
			
		||||
        $this->groupSyncService = $groupSyncService;
 | 
			
		||||
    public function __construct(
 | 
			
		||||
        protected Ldap $ldap,
 | 
			
		||||
        protected UserAvatars $userAvatars,
 | 
			
		||||
        protected GroupSyncService $groupSyncService
 | 
			
		||||
    ) {
 | 
			
		||||
        $this->config = config('services.ldap');
 | 
			
		||||
        $this->enabled = config('auth.method') === 'ldap';
 | 
			
		||||
    }
 | 
			
		||||
| 
						 | 
				
			
			@ -59,7 +52,7 @@ class LdapService
 | 
			
		|||
 | 
			
		||||
        // Clean attributes
 | 
			
		||||
        foreach ($attributes as $index => $attribute) {
 | 
			
		||||
            if (strpos($attribute, 'BIN;') === 0) {
 | 
			
		||||
            if (str_starts_with($attribute, 'BIN;')) {
 | 
			
		||||
                $attributes[$index] = substr($attribute, strlen('BIN;'));
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
| 
						 | 
				
			
			@ -82,7 +75,7 @@ class LdapService
 | 
			
		|||
     * Get the details of a user from LDAP using the given username.
 | 
			
		||||
     * User found via configurable user filter.
 | 
			
		||||
     *
 | 
			
		||||
     * @throws LdapException
 | 
			
		||||
     * @throws LdapException|JsonDebugException
 | 
			
		||||
     */
 | 
			
		||||
    public function getUserDetails(string $userName): ?array
 | 
			
		||||
    {
 | 
			
		||||
| 
						 | 
				
			
			@ -126,7 +119,7 @@ class LdapService
 | 
			
		|||
     */
 | 
			
		||||
    protected function getUserResponseProperty(array $userDetails, string $propertyKey, $defaultValue)
 | 
			
		||||
    {
 | 
			
		||||
        $isBinary = strpos($propertyKey, 'BIN;') === 0;
 | 
			
		||||
        $isBinary = str_starts_with($propertyKey, 'BIN;');
 | 
			
		||||
        $propertyKey = strtolower($propertyKey);
 | 
			
		||||
        $value = $defaultValue;
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -170,11 +163,11 @@ class LdapService
 | 
			
		|||
     * Bind the system user to the LDAP connection using the given credentials
 | 
			
		||||
     * otherwise anonymous access is attempted.
 | 
			
		||||
     *
 | 
			
		||||
     * @param resource $connection
 | 
			
		||||
     * @param resource|\LDAP\Connection $connection
 | 
			
		||||
     *
 | 
			
		||||
     * @throws LdapException
 | 
			
		||||
     */
 | 
			
		||||
    protected function bindSystemUser($connection)
 | 
			
		||||
    protected function bindSystemUser($connection): void
 | 
			
		||||
    {
 | 
			
		||||
        $ldapDn = $this->config['dn'];
 | 
			
		||||
        $ldapPass = $this->config['pass'];
 | 
			
		||||
| 
						 | 
				
			
			@ -197,7 +190,7 @@ class LdapService
 | 
			
		|||
     *
 | 
			
		||||
     * @throws LdapException
 | 
			
		||||
     *
 | 
			
		||||
     * @return resource
 | 
			
		||||
     * @return resource|\LDAP\Connection
 | 
			
		||||
     */
 | 
			
		||||
    protected function getConnection()
 | 
			
		||||
    {
 | 
			
		||||
| 
						 | 
				
			
			@ -216,8 +209,8 @@ class LdapService
 | 
			
		|||
            $this->ldap->setOption(null, LDAP_OPT_X_TLS_REQUIRE_CERT, LDAP_OPT_X_TLS_NEVER);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        $serverDetails = $this->parseServerString($this->config['server']);
 | 
			
		||||
        $ldapConnection = $this->ldap->connect($serverDetails['host'], $serverDetails['port']);
 | 
			
		||||
        $ldapHost = $this->parseServerString($this->config['server']);
 | 
			
		||||
        $ldapConnection = $this->ldap->connect($ldapHost);
 | 
			
		||||
 | 
			
		||||
        if ($ldapConnection === false) {
 | 
			
		||||
            throw new LdapException(trans('errors.ldap_cannot_connect'));
 | 
			
		||||
| 
						 | 
				
			
			@ -242,23 +235,16 @@ class LdapService
 | 
			
		|||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Parse a LDAP server string and return the host and port for a connection.
 | 
			
		||||
     * Parse an LDAP server string and return the host suitable for a connection.
 | 
			
		||||
     * Is flexible to formats such as 'ldap.example.com:8069' or 'ldaps://ldap.example.com'.
 | 
			
		||||
     */
 | 
			
		||||
    protected function parseServerString(string $serverString): array
 | 
			
		||||
    protected function parseServerString(string $serverString): string
 | 
			
		||||
    {
 | 
			
		||||
        $serverNameParts = explode(':', $serverString);
 | 
			
		||||
 | 
			
		||||
        // If we have a protocol just return the full string since PHP will ignore a separate port.
 | 
			
		||||
        if ($serverNameParts[0] === 'ldaps' || $serverNameParts[0] === 'ldap') {
 | 
			
		||||
            return ['host' => $serverString, 'port' => 389];
 | 
			
		||||
        if (str_starts_with($serverString, 'ldaps://') || str_starts_with($serverString, 'ldap://')) {
 | 
			
		||||
            return $serverString;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        // Otherwise, extract the port out
 | 
			
		||||
        $hostName = $serverNameParts[0];
 | 
			
		||||
        $ldapPort = (count($serverNameParts) > 1) ? intval($serverNameParts[1]) : 389;
 | 
			
		||||
 | 
			
		||||
        return ['host' => $hostName, 'port' => $ldapPort];
 | 
			
		||||
        return "ldap://{$serverString}";
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
| 
						 | 
				
			
			@ -386,7 +372,7 @@ class LdapService
 | 
			
		|||
     * @throws LdapException
 | 
			
		||||
     * @throws JsonDebugException
 | 
			
		||||
     */
 | 
			
		||||
    public function syncGroups(User $user, string $username)
 | 
			
		||||
    public function syncGroups(User $user, string $username): void
 | 
			
		||||
    {
 | 
			
		||||
        $userLdapGroups = $this->getUserGroups($username);
 | 
			
		||||
        $this->groupSyncService->syncUserWithFoundGroups($user, $userLdapGroups, $this->config['remove_from_groups']);
 | 
			
		||||
| 
						 | 
				
			
			@ -1,15 +1,15 @@
 | 
			
		|||
<?php
 | 
			
		||||
 | 
			
		||||
namespace BookStack\Auth\Access;
 | 
			
		||||
namespace BookStack\Access;
 | 
			
		||||
 | 
			
		||||
use BookStack\Actions\ActivityType;
 | 
			
		||||
use BookStack\Auth\Access\Mfa\MfaSession;
 | 
			
		||||
use BookStack\Auth\User;
 | 
			
		||||
use BookStack\Access\Mfa\MfaSession;
 | 
			
		||||
use BookStack\Activity\ActivityType;
 | 
			
		||||
use BookStack\Exceptions\LoginAttemptException;
 | 
			
		||||
use BookStack\Exceptions\StoppedAuthenticationException;
 | 
			
		||||
use BookStack\Facades\Activity;
 | 
			
		||||
use BookStack\Facades\Theme;
 | 
			
		||||
use BookStack\Theming\ThemeEvents;
 | 
			
		||||
use BookStack\Users\Models\User;
 | 
			
		||||
use Exception;
 | 
			
		||||
 | 
			
		||||
class LoginService
 | 
			
		||||
| 
						 | 
				
			
			@ -1,6 +1,6 @@
 | 
			
		|||
<?php
 | 
			
		||||
 | 
			
		||||
namespace BookStack\Auth\Access\Mfa;
 | 
			
		||||
namespace BookStack\Access\Mfa;
 | 
			
		||||
 | 
			
		||||
use Illuminate\Support\Str;
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -1,8 +1,8 @@
 | 
			
		|||
<?php
 | 
			
		||||
 | 
			
		||||
namespace BookStack\Auth\Access\Mfa;
 | 
			
		||||
namespace BookStack\Access\Mfa;
 | 
			
		||||
 | 
			
		||||
use BookStack\Auth\User;
 | 
			
		||||
use BookStack\Users\Models\User;
 | 
			
		||||
 | 
			
		||||
class MfaSession
 | 
			
		||||
{
 | 
			
		||||
| 
						 | 
				
			
			@ -1,8 +1,8 @@
 | 
			
		|||
<?php
 | 
			
		||||
 | 
			
		||||
namespace BookStack\Auth\Access\Mfa;
 | 
			
		||||
namespace BookStack\Access\Mfa;
 | 
			
		||||
 | 
			
		||||
use BookStack\Auth\User;
 | 
			
		||||
use BookStack\Users\Models\User;
 | 
			
		||||
use Carbon\Carbon;
 | 
			
		||||
use Illuminate\Database\Eloquent\Model;
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -1,6 +1,6 @@
 | 
			
		|||
<?php
 | 
			
		||||
 | 
			
		||||
namespace BookStack\Auth\Access\Mfa;
 | 
			
		||||
namespace BookStack\Access\Mfa;
 | 
			
		||||
 | 
			
		||||
use BaconQrCode\Renderer\Color\Rgb;
 | 
			
		||||
use BaconQrCode\Renderer\Image\SvgImageBackEnd;
 | 
			
		||||
| 
						 | 
				
			
			@ -8,7 +8,7 @@ use BaconQrCode\Renderer\ImageRenderer;
 | 
			
		|||
use BaconQrCode\Renderer\RendererStyle\Fill;
 | 
			
		||||
use BaconQrCode\Renderer\RendererStyle\RendererStyle;
 | 
			
		||||
use BaconQrCode\Writer;
 | 
			
		||||
use BookStack\Auth\User;
 | 
			
		||||
use BookStack\Users\Models\User;
 | 
			
		||||
use PragmaRX\Google2FA\Google2FA;
 | 
			
		||||
use PragmaRX\Google2FA\Support\Constants;
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -1,6 +1,6 @@
 | 
			
		|||
<?php
 | 
			
		||||
 | 
			
		||||
namespace BookStack\Auth\Access\Mfa;
 | 
			
		||||
namespace BookStack\Access\Mfa;
 | 
			
		||||
 | 
			
		||||
use Illuminate\Contracts\Validation\Rule;
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -1,6 +1,6 @@
 | 
			
		|||
<?php
 | 
			
		||||
 | 
			
		||||
namespace BookStack\Auth\Access\Oidc;
 | 
			
		||||
namespace BookStack\Access\Oidc;
 | 
			
		||||
 | 
			
		||||
use InvalidArgumentException;
 | 
			
		||||
use League\OAuth2\Client\Token\AccessToken;
 | 
			
		||||
| 
						 | 
				
			
			@ -1,6 +1,6 @@
 | 
			
		|||
<?php
 | 
			
		||||
 | 
			
		||||
namespace BookStack\Auth\Access\Oidc;
 | 
			
		||||
namespace BookStack\Access\Oidc;
 | 
			
		||||
 | 
			
		||||
use Exception;
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -1,6 +1,6 @@
 | 
			
		|||
<?php
 | 
			
		||||
 | 
			
		||||
namespace BookStack\Auth\Access\Oidc;
 | 
			
		||||
namespace BookStack\Access\Oidc;
 | 
			
		||||
 | 
			
		||||
class OidcIdToken
 | 
			
		||||
{
 | 
			
		||||
| 
						 | 
				
			
			@ -1,6 +1,6 @@
 | 
			
		|||
<?php
 | 
			
		||||
 | 
			
		||||
namespace BookStack\Auth\Access\Oidc;
 | 
			
		||||
namespace BookStack\Access\Oidc;
 | 
			
		||||
 | 
			
		||||
class OidcInvalidKeyException extends \Exception
 | 
			
		||||
{
 | 
			
		||||
| 
						 | 
				
			
			@ -1,6 +1,6 @@
 | 
			
		|||
<?php
 | 
			
		||||
 | 
			
		||||
namespace BookStack\Auth\Access\Oidc;
 | 
			
		||||
namespace BookStack\Access\Oidc;
 | 
			
		||||
 | 
			
		||||
use Exception;
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -1,6 +1,6 @@
 | 
			
		|||
<?php
 | 
			
		||||
 | 
			
		||||
namespace BookStack\Auth\Access\Oidc;
 | 
			
		||||
namespace BookStack\Access\Oidc;
 | 
			
		||||
 | 
			
		||||
use Exception;
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -1,6 +1,6 @@
 | 
			
		|||
<?php
 | 
			
		||||
 | 
			
		||||
namespace BookStack\Auth\Access\Oidc;
 | 
			
		||||
namespace BookStack\Access\Oidc;
 | 
			
		||||
 | 
			
		||||
use phpseclib3\Crypt\Common\PublicKey;
 | 
			
		||||
use phpseclib3\Crypt\PublicKeyLoader;
 | 
			
		||||
| 
						 | 
				
			
			@ -1,6 +1,6 @@
 | 
			
		|||
<?php
 | 
			
		||||
 | 
			
		||||
namespace BookStack\Auth\Access\Oidc;
 | 
			
		||||
namespace BookStack\Access\Oidc;
 | 
			
		||||
 | 
			
		||||
use League\OAuth2\Client\Grant\AbstractGrant;
 | 
			
		||||
use League\OAuth2\Client\Provider\AbstractProvider;
 | 
			
		||||
| 
						 | 
				
			
			@ -1,6 +1,6 @@
 | 
			
		|||
<?php
 | 
			
		||||
 | 
			
		||||
namespace BookStack\Auth\Access\Oidc;
 | 
			
		||||
namespace BookStack\Access\Oidc;
 | 
			
		||||
 | 
			
		||||
use GuzzleHttp\Psr7\Request;
 | 
			
		||||
use Illuminate\Contracts\Cache\Repository;
 | 
			
		||||
| 
						 | 
				
			
			@ -1,16 +1,16 @@
 | 
			
		|||
<?php
 | 
			
		||||
 | 
			
		||||
namespace BookStack\Auth\Access\Oidc;
 | 
			
		||||
namespace BookStack\Access\Oidc;
 | 
			
		||||
 | 
			
		||||
use BookStack\Auth\Access\GroupSyncService;
 | 
			
		||||
use BookStack\Auth\Access\LoginService;
 | 
			
		||||
use BookStack\Auth\Access\RegistrationService;
 | 
			
		||||
use BookStack\Auth\User;
 | 
			
		||||
use BookStack\Access\GroupSyncService;
 | 
			
		||||
use BookStack\Access\LoginService;
 | 
			
		||||
use BookStack\Access\RegistrationService;
 | 
			
		||||
use BookStack\Exceptions\JsonDebugException;
 | 
			
		||||
use BookStack\Exceptions\StoppedAuthenticationException;
 | 
			
		||||
use BookStack\Exceptions\UserRegistrationException;
 | 
			
		||||
use BookStack\Facades\Theme;
 | 
			
		||||
use BookStack\Theming\ThemeEvents;
 | 
			
		||||
use BookStack\Users\Models\User;
 | 
			
		||||
use Illuminate\Support\Arr;
 | 
			
		||||
use Illuminate\Support\Facades\Cache;
 | 
			
		||||
use League\OAuth2\Client\OptionProvider\HttpBasicAuthOptionProvider;
 | 
			
		||||
| 
						 | 
				
			
			@ -1,15 +1,14 @@
 | 
			
		|||
<?php
 | 
			
		||||
 | 
			
		||||
namespace BookStack\Auth\Access;
 | 
			
		||||
namespace BookStack\Access;
 | 
			
		||||
 | 
			
		||||
use BookStack\Actions\ActivityType;
 | 
			
		||||
use BookStack\Auth\SocialAccount;
 | 
			
		||||
use BookStack\Auth\User;
 | 
			
		||||
use BookStack\Auth\UserRepo;
 | 
			
		||||
use BookStack\Activity\ActivityType;
 | 
			
		||||
use BookStack\Exceptions\UserRegistrationException;
 | 
			
		||||
use BookStack\Facades\Activity;
 | 
			
		||||
use BookStack\Facades\Theme;
 | 
			
		||||
use BookStack\Theming\ThemeEvents;
 | 
			
		||||
use BookStack\Users\Models\User;
 | 
			
		||||
use BookStack\Users\UserRepo;
 | 
			
		||||
use Exception;
 | 
			
		||||
use Illuminate\Support\Str;
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -1,12 +1,12 @@
 | 
			
		|||
<?php
 | 
			
		||||
 | 
			
		||||
namespace BookStack\Auth\Access;
 | 
			
		||||
namespace BookStack\Access;
 | 
			
		||||
 | 
			
		||||
use BookStack\Auth\User;
 | 
			
		||||
use BookStack\Exceptions\JsonDebugException;
 | 
			
		||||
use BookStack\Exceptions\SamlException;
 | 
			
		||||
use BookStack\Exceptions\StoppedAuthenticationException;
 | 
			
		||||
use BookStack\Exceptions\UserRegistrationException;
 | 
			
		||||
use BookStack\Users\Models\User;
 | 
			
		||||
use Exception;
 | 
			
		||||
use OneLogin\Saml2\Auth;
 | 
			
		||||
use OneLogin\Saml2\Constants;
 | 
			
		||||
| 
						 | 
				
			
			@ -1,9 +1,10 @@
 | 
			
		|||
<?php
 | 
			
		||||
 | 
			
		||||
namespace BookStack\Auth;
 | 
			
		||||
namespace BookStack\Access;
 | 
			
		||||
 | 
			
		||||
use BookStack\Interfaces\Loggable;
 | 
			
		||||
use BookStack\Model;
 | 
			
		||||
use BookStack\Activity\Models\Loggable;
 | 
			
		||||
use BookStack\App\Model;
 | 
			
		||||
use BookStack\Users\Models\User;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Class SocialAccount.
 | 
			
		||||
| 
						 | 
				
			
			@ -1,12 +1,12 @@
 | 
			
		|||
<?php
 | 
			
		||||
 | 
			
		||||
namespace BookStack\Auth\Access;
 | 
			
		||||
namespace BookStack\Access;
 | 
			
		||||
 | 
			
		||||
use BookStack\Auth\SocialAccount;
 | 
			
		||||
use BookStack\Auth\User;
 | 
			
		||||
use BookStack\Auth\Access\handler;
 | 
			
		||||
use BookStack\Exceptions\SocialDriverNotConfigured;
 | 
			
		||||
use BookStack\Exceptions\SocialSignInAccountNotUsed;
 | 
			
		||||
use BookStack\Exceptions\UserRegistrationException;
 | 
			
		||||
use BookStack\Users\Models\User;
 | 
			
		||||
use Illuminate\Support\Facades\Event;
 | 
			
		||||
use Illuminate\Support\Str;
 | 
			
		||||
use Laravel\Socialite\Contracts\Factory as Socialite;
 | 
			
		||||
| 
						 | 
				
			
			@ -1,9 +1,9 @@
 | 
			
		|||
<?php
 | 
			
		||||
 | 
			
		||||
namespace BookStack\Auth\Access;
 | 
			
		||||
namespace BookStack\Access;
 | 
			
		||||
 | 
			
		||||
use BookStack\Auth\User;
 | 
			
		||||
use BookStack\Notifications\UserInvite;
 | 
			
		||||
use BookStack\Users\Models\User;
 | 
			
		||||
 | 
			
		||||
class UserInviteService extends UserTokenService
 | 
			
		||||
{
 | 
			
		||||
| 
						 | 
				
			
			@ -1,10 +1,10 @@
 | 
			
		|||
<?php
 | 
			
		||||
 | 
			
		||||
namespace BookStack\Auth\Access;
 | 
			
		||||
namespace BookStack\Access;
 | 
			
		||||
 | 
			
		||||
use BookStack\Auth\User;
 | 
			
		||||
use BookStack\Exceptions\UserTokenExpiredException;
 | 
			
		||||
use BookStack\Exceptions\UserTokenNotFoundException;
 | 
			
		||||
use BookStack\Users\Models\User;
 | 
			
		||||
use Carbon\Carbon;
 | 
			
		||||
use Illuminate\Support\Facades\DB;
 | 
			
		||||
use Illuminate\Support\Str;
 | 
			
		||||
| 
						 | 
				
			
			@ -1,13 +1,14 @@
 | 
			
		|||
<?php
 | 
			
		||||
 | 
			
		||||
namespace BookStack\Actions;
 | 
			
		||||
namespace BookStack\Activity;
 | 
			
		||||
 | 
			
		||||
use BookStack\Auth\Permissions\PermissionApplicator;
 | 
			
		||||
use BookStack\Auth\User;
 | 
			
		||||
use BookStack\Activity\Models\Activity;
 | 
			
		||||
use BookStack\Entities\Models\Book;
 | 
			
		||||
use BookStack\Entities\Models\Chapter;
 | 
			
		||||
use BookStack\Entities\Models\Entity;
 | 
			
		||||
use BookStack\Entities\Models\Page;
 | 
			
		||||
use BookStack\Permissions\PermissionApplicator;
 | 
			
		||||
use BookStack\Users\Models\User;
 | 
			
		||||
use Illuminate\Database\Eloquent\Builder;
 | 
			
		||||
use Illuminate\Database\Eloquent\Relations\Relation;
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -1,6 +1,6 @@
 | 
			
		|||
<?php
 | 
			
		||||
 | 
			
		||||
namespace BookStack\Actions;
 | 
			
		||||
namespace BookStack\Activity;
 | 
			
		||||
 | 
			
		||||
class ActivityType
 | 
			
		||||
{
 | 
			
		||||
| 
						 | 
				
			
			@ -1,32 +1,20 @@
 | 
			
		|||
<?php
 | 
			
		||||
 | 
			
		||||
namespace BookStack\Actions;
 | 
			
		||||
namespace BookStack\Activity;
 | 
			
		||||
 | 
			
		||||
use BookStack\Activity\Models\Comment;
 | 
			
		||||
use BookStack\Entities\Models\Entity;
 | 
			
		||||
use BookStack\Facades\Activity as ActivityService;
 | 
			
		||||
use League\CommonMark\CommonMarkConverter;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Class CommentRepo.
 | 
			
		||||
 */
 | 
			
		||||
class CommentRepo
 | 
			
		||||
{
 | 
			
		||||
    /**
 | 
			
		||||
     * @var Comment
 | 
			
		||||
     */
 | 
			
		||||
    protected $comment;
 | 
			
		||||
 | 
			
		||||
    public function __construct(Comment $comment)
 | 
			
		||||
    {
 | 
			
		||||
        $this->comment = $comment;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Get a comment by ID.
 | 
			
		||||
     */
 | 
			
		||||
    public function getById(int $id): Comment
 | 
			
		||||
    {
 | 
			
		||||
        return $this->comment->newQuery()->findOrFail($id);
 | 
			
		||||
        return Comment::query()->findOrFail($id);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
| 
						 | 
				
			
			@ -35,7 +23,7 @@ class CommentRepo
 | 
			
		|||
    public function create(Entity $entity, string $text, ?int $parent_id): Comment
 | 
			
		||||
    {
 | 
			
		||||
        $userId = user()->id;
 | 
			
		||||
        $comment = $this->comment->newInstance();
 | 
			
		||||
        $comment = new Comment();
 | 
			
		||||
 | 
			
		||||
        $comment->text = $text;
 | 
			
		||||
        $comment->html = $this->commentToHtml($text);
 | 
			
		||||
| 
						 | 
				
			
			@ -82,7 +70,7 @@ class CommentRepo
 | 
			
		|||
            'allow_unsafe_links' => false,
 | 
			
		||||
        ]);
 | 
			
		||||
 | 
			
		||||
        return $converter->convertToHtml($commentText);
 | 
			
		||||
        return $converter->convert($commentText);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
| 
						 | 
				
			
			@ -90,9 +78,8 @@ class CommentRepo
 | 
			
		|||
     */
 | 
			
		||||
    protected function getNextLocalId(Entity $entity): int
 | 
			
		||||
    {
 | 
			
		||||
        /** @var Comment $comment */
 | 
			
		||||
        $comment = $entity->comments(false)->orderBy('local_id', 'desc')->first();
 | 
			
		||||
        $currentMaxId = $entity->comments()->max('local_id');
 | 
			
		||||
 | 
			
		||||
        return ($comment->local_id ?? 0) + 1;
 | 
			
		||||
        return $currentMaxId + 1;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -1,12 +1,12 @@
 | 
			
		|||
<?php
 | 
			
		||||
 | 
			
		||||
namespace BookStack\Http\Controllers;
 | 
			
		||||
namespace BookStack\Activity\Controllers;
 | 
			
		||||
 | 
			
		||||
use BookStack\Actions\Activity;
 | 
			
		||||
use BookStack\Actions\ActivityType;
 | 
			
		||||
use BookStack\Activity\ActivityType;
 | 
			
		||||
use BookStack\Activity\Models\Activity;
 | 
			
		||||
use BookStack\Http\Controller;
 | 
			
		||||
use BookStack\Util\SimpleListOptions;
 | 
			
		||||
use Illuminate\Http\Request;
 | 
			
		||||
use Illuminate\Support\Facades\DB;
 | 
			
		||||
 | 
			
		||||
class AuditLogController extends Controller
 | 
			
		||||
{
 | 
			
		||||
| 
						 | 
				
			
			@ -1,19 +1,18 @@
 | 
			
		|||
<?php
 | 
			
		||||
 | 
			
		||||
namespace BookStack\Http\Controllers;
 | 
			
		||||
namespace BookStack\Activity\Controllers;
 | 
			
		||||
 | 
			
		||||
use BookStack\Actions\CommentRepo;
 | 
			
		||||
use BookStack\Activity\CommentRepo;
 | 
			
		||||
use BookStack\Entities\Models\Page;
 | 
			
		||||
use BookStack\Http\Controller;
 | 
			
		||||
use Illuminate\Http\Request;
 | 
			
		||||
use Illuminate\Validation\ValidationException;
 | 
			
		||||
 | 
			
		||||
class CommentController extends Controller
 | 
			
		||||
{
 | 
			
		||||
    protected $commentRepo;
 | 
			
		||||
 | 
			
		||||
    public function __construct(CommentRepo $commentRepo)
 | 
			
		||||
    {
 | 
			
		||||
        $this->commentRepo = $commentRepo;
 | 
			
		||||
    public function __construct(
 | 
			
		||||
        protected CommentRepo $commentRepo
 | 
			
		||||
    ) {
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
| 
						 | 
				
			
			@ -42,7 +41,13 @@ class CommentController extends Controller
 | 
			
		|||
        $this->checkPermission('comment-create-all');
 | 
			
		||||
        $comment = $this->commentRepo->create($page, $request->get('text'), $request->get('parent_id'));
 | 
			
		||||
 | 
			
		||||
        return view('comments.comment', ['comment' => $comment]);
 | 
			
		||||
        return view('comments.comment-branch', [
 | 
			
		||||
            'readOnly' => false,
 | 
			
		||||
            'branch' => [
 | 
			
		||||
                'comment' => $comment,
 | 
			
		||||
                'children' => [],
 | 
			
		||||
            ]
 | 
			
		||||
        ]);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
| 
						 | 
				
			
			@ -62,7 +67,7 @@ class CommentController extends Controller
 | 
			
		|||
 | 
			
		||||
        $comment = $this->commentRepo->update($comment, $request->get('text'));
 | 
			
		||||
 | 
			
		||||
        return view('comments.comment', ['comment' => $comment]);
 | 
			
		||||
        return view('comments.comment', ['comment' => $comment, 'readOnly' => false]);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
| 
						 | 
				
			
			@ -1,11 +1,12 @@
 | 
			
		|||
<?php
 | 
			
		||||
 | 
			
		||||
namespace BookStack\Http\Controllers;
 | 
			
		||||
namespace BookStack\Activity\Controllers;
 | 
			
		||||
 | 
			
		||||
use BookStack\Activity\Models\Favouritable;
 | 
			
		||||
use BookStack\App\Model;
 | 
			
		||||
use BookStack\Entities\Models\Entity;
 | 
			
		||||
use BookStack\Entities\Queries\TopFavourites;
 | 
			
		||||
use BookStack\Interfaces\Favouritable;
 | 
			
		||||
use BookStack\Model;
 | 
			
		||||
use BookStack\Http\Controller;
 | 
			
		||||
use Illuminate\Http\Request;
 | 
			
		||||
 | 
			
		||||
class FavouriteController extends Controller
 | 
			
		||||
| 
						 | 
				
			
			@ -1,8 +1,9 @@
 | 
			
		|||
<?php
 | 
			
		||||
 | 
			
		||||
namespace BookStack\Http\Controllers;
 | 
			
		||||
namespace BookStack\Activity\Controllers;
 | 
			
		||||
 | 
			
		||||
use BookStack\Actions\TagRepo;
 | 
			
		||||
use BookStack\Activity\TagRepo;
 | 
			
		||||
use BookStack\Http\Controller;
 | 
			
		||||
use BookStack\Util\SimpleListOptions;
 | 
			
		||||
use Illuminate\Http\Request;
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -1,10 +1,11 @@
 | 
			
		|||
<?php
 | 
			
		||||
 | 
			
		||||
namespace BookStack\Http\Controllers;
 | 
			
		||||
namespace BookStack\Activity\Controllers;
 | 
			
		||||
 | 
			
		||||
use BookStack\Actions\ActivityType;
 | 
			
		||||
use BookStack\Actions\Queries\WebhooksAllPaginatedAndSorted;
 | 
			
		||||
use BookStack\Actions\Webhook;
 | 
			
		||||
use BookStack\Activity\ActivityType;
 | 
			
		||||
use BookStack\Activity\Models\Webhook;
 | 
			
		||||
use BookStack\Activity\Queries\WebhooksAllPaginatedAndSorted;
 | 
			
		||||
use BookStack\Http\Controller;
 | 
			
		||||
use BookStack\Util\SimpleListOptions;
 | 
			
		||||
use Illuminate\Http\Request;
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -1,11 +1,13 @@
 | 
			
		|||
<?php
 | 
			
		||||
 | 
			
		||||
namespace BookStack\Actions;
 | 
			
		||||
namespace BookStack\Activity;
 | 
			
		||||
 | 
			
		||||
use BookStack\Auth\User;
 | 
			
		||||
use BookStack\Activity\Models\Loggable;
 | 
			
		||||
use BookStack\Activity\Models\Webhook;
 | 
			
		||||
use BookStack\Activity\Tools\WebhookFormatter;
 | 
			
		||||
use BookStack\Facades\Theme;
 | 
			
		||||
use BookStack\Interfaces\Loggable;
 | 
			
		||||
use BookStack\Theming\ThemeEvents;
 | 
			
		||||
use BookStack\Users\Models\User;
 | 
			
		||||
use Illuminate\Bus\Queueable;
 | 
			
		||||
use Illuminate\Contracts\Queue\ShouldQueue;
 | 
			
		||||
use Illuminate\Foundation\Bus\Dispatchable;
 | 
			
		||||
| 
						 | 
				
			
			@ -1,11 +1,11 @@
 | 
			
		|||
<?php
 | 
			
		||||
 | 
			
		||||
namespace BookStack\Actions;
 | 
			
		||||
namespace BookStack\Activity\Models;
 | 
			
		||||
 | 
			
		||||
use BookStack\Auth\Permissions\JointPermission;
 | 
			
		||||
use BookStack\Auth\User;
 | 
			
		||||
use BookStack\App\Model;
 | 
			
		||||
use BookStack\Entities\Models\Entity;
 | 
			
		||||
use BookStack\Model;
 | 
			
		||||
use BookStack\Permissions\Models\JointPermission;
 | 
			
		||||
use BookStack\Users\Models\User;
 | 
			
		||||
use Illuminate\Database\Eloquent\Relations\BelongsTo;
 | 
			
		||||
use Illuminate\Database\Eloquent\Relations\HasMany;
 | 
			
		||||
use Illuminate\Database\Eloquent\Relations\MorphTo;
 | 
			
		||||
| 
						 | 
				
			
			@ -19,6 +19,8 @@ use Illuminate\Support\Str;
 | 
			
		|||
 * @property string $entity_type
 | 
			
		||||
 * @property int    $entity_id
 | 
			
		||||
 * @property int    $user_id
 | 
			
		||||
 * @property Carbon $created_at
 | 
			
		||||
 * @property Carbon $updated_at
 | 
			
		||||
 */
 | 
			
		||||
class Activity extends Model
 | 
			
		||||
{
 | 
			
		||||
| 
						 | 
				
			
			@ -1,9 +1,9 @@
 | 
			
		|||
<?php
 | 
			
		||||
 | 
			
		||||
namespace BookStack\Actions;
 | 
			
		||||
namespace BookStack\Activity\Models;
 | 
			
		||||
 | 
			
		||||
use BookStack\Model;
 | 
			
		||||
use BookStack\Traits\HasCreatorAndUpdater;
 | 
			
		||||
use BookStack\App\Model;
 | 
			
		||||
use BookStack\Users\Models\HasCreatorAndUpdater;
 | 
			
		||||
use Illuminate\Database\Eloquent\Factories\HasFactory;
 | 
			
		||||
use Illuminate\Database\Eloquent\Relations\MorphTo;
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -1,6 +1,6 @@
 | 
			
		|||
<?php
 | 
			
		||||
 | 
			
		||||
namespace BookStack\Interfaces;
 | 
			
		||||
namespace BookStack\Activity\Models;
 | 
			
		||||
 | 
			
		||||
use Illuminate\Database\Eloquent\Relations\MorphMany;
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -1,9 +1,9 @@
 | 
			
		|||
<?php
 | 
			
		||||
 | 
			
		||||
namespace BookStack\Actions;
 | 
			
		||||
namespace BookStack\Activity\Models;
 | 
			
		||||
 | 
			
		||||
use BookStack\Auth\Permissions\JointPermission;
 | 
			
		||||
use BookStack\Model;
 | 
			
		||||
use BookStack\App\Model;
 | 
			
		||||
use BookStack\Permissions\Models\JointPermission;
 | 
			
		||||
use Illuminate\Database\Eloquent\Relations\HasMany;
 | 
			
		||||
use Illuminate\Database\Eloquent\Relations\MorphTo;
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -1,6 +1,6 @@
 | 
			
		|||
<?php
 | 
			
		||||
 | 
			
		||||
namespace BookStack\Interfaces;
 | 
			
		||||
namespace BookStack\Activity\Models;
 | 
			
		||||
 | 
			
		||||
interface Loggable
 | 
			
		||||
{
 | 
			
		||||
| 
						 | 
				
			
			@ -1,9 +1,9 @@
 | 
			
		|||
<?php
 | 
			
		||||
 | 
			
		||||
namespace BookStack\Actions;
 | 
			
		||||
namespace BookStack\Activity\Models;
 | 
			
		||||
 | 
			
		||||
use BookStack\Auth\Permissions\JointPermission;
 | 
			
		||||
use BookStack\Model;
 | 
			
		||||
use BookStack\App\Model;
 | 
			
		||||
use BookStack\Permissions\Models\JointPermission;
 | 
			
		||||
use Illuminate\Database\Eloquent\Factories\HasFactory;
 | 
			
		||||
use Illuminate\Database\Eloquent\Relations\HasMany;
 | 
			
		||||
use Illuminate\Database\Eloquent\Relations\MorphTo;
 | 
			
		||||
| 
						 | 
				
			
			@ -1,10 +1,9 @@
 | 
			
		|||
<?php
 | 
			
		||||
 | 
			
		||||
namespace BookStack\Actions;
 | 
			
		||||
namespace BookStack\Activity\Models;
 | 
			
		||||
 | 
			
		||||
use BookStack\Auth\Permissions\JointPermission;
 | 
			
		||||
use BookStack\Interfaces\Viewable;
 | 
			
		||||
use BookStack\Model;
 | 
			
		||||
use BookStack\App\Model;
 | 
			
		||||
use BookStack\Permissions\Models\JointPermission;
 | 
			
		||||
use Illuminate\Database\Eloquent\Relations\HasMany;
 | 
			
		||||
use Illuminate\Database\Eloquent\Relations\MorphTo;
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -55,12 +54,4 @@ class View extends Model
 | 
			
		|||
 | 
			
		||||
        return $view->views;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Clear all views from the system.
 | 
			
		||||
     */
 | 
			
		||||
    public static function clearAll()
 | 
			
		||||
    {
 | 
			
		||||
        static::query()->truncate();
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -1,6 +1,6 @@
 | 
			
		|||
<?php
 | 
			
		||||
 | 
			
		||||
namespace BookStack\Interfaces;
 | 
			
		||||
namespace BookStack\Activity\Models;
 | 
			
		||||
 | 
			
		||||
use Illuminate\Database\Eloquent\Relations\MorphMany;
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -1,8 +1,8 @@
 | 
			
		|||
<?php
 | 
			
		||||
 | 
			
		||||
namespace BookStack\Actions;
 | 
			
		||||
namespace BookStack\Activity\Models;
 | 
			
		||||
 | 
			
		||||
use BookStack\Interfaces\Loggable;
 | 
			
		||||
use BookStack\Activity\ActivityType;
 | 
			
		||||
use Carbon\Carbon;
 | 
			
		||||
use Illuminate\Database\Eloquent\Collection;
 | 
			
		||||
use Illuminate\Database\Eloquent\Factories\HasFactory;
 | 
			
		||||
| 
						 | 
				
			
			@ -1,6 +1,6 @@
 | 
			
		|||
<?php
 | 
			
		||||
 | 
			
		||||
namespace BookStack\Actions;
 | 
			
		||||
namespace BookStack\Activity\Models;
 | 
			
		||||
 | 
			
		||||
use Illuminate\Database\Eloquent\Factories\HasFactory;
 | 
			
		||||
use Illuminate\Database\Eloquent\Model;
 | 
			
		||||
| 
						 | 
				
			
			@ -1,8 +1,8 @@
 | 
			
		|||
<?php
 | 
			
		||||
 | 
			
		||||
namespace BookStack\Actions\Queries;
 | 
			
		||||
namespace BookStack\Activity\Queries;
 | 
			
		||||
 | 
			
		||||
use BookStack\Actions\Webhook;
 | 
			
		||||
use BookStack\Activity\Models\Webhook;
 | 
			
		||||
use BookStack\Util\SimpleListOptions;
 | 
			
		||||
use Illuminate\Pagination\LengthAwarePaginator;
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -1,9 +1,10 @@
 | 
			
		|||
<?php
 | 
			
		||||
 | 
			
		||||
namespace BookStack\Actions;
 | 
			
		||||
namespace BookStack\Activity;
 | 
			
		||||
 | 
			
		||||
use BookStack\Auth\Permissions\PermissionApplicator;
 | 
			
		||||
use BookStack\Activity\Models\Tag;
 | 
			
		||||
use BookStack\Entities\Models\Entity;
 | 
			
		||||
use BookStack\Permissions\PermissionApplicator;
 | 
			
		||||
use BookStack\Util\SimpleListOptions;
 | 
			
		||||
use Illuminate\Database\Eloquent\Builder;
 | 
			
		||||
use Illuminate\Support\Collection;
 | 
			
		||||
| 
						 | 
				
			
			@ -1,10 +1,13 @@
 | 
			
		|||
<?php
 | 
			
		||||
 | 
			
		||||
namespace BookStack\Actions;
 | 
			
		||||
namespace BookStack\Activity\Tools;
 | 
			
		||||
 | 
			
		||||
use BookStack\Activity\DispatchWebhookJob;
 | 
			
		||||
use BookStack\Activity\Models\Activity;
 | 
			
		||||
use BookStack\Activity\Models\Loggable;
 | 
			
		||||
use BookStack\Activity\Models\Webhook;
 | 
			
		||||
use BookStack\Entities\Models\Entity;
 | 
			
		||||
use BookStack\Facades\Theme;
 | 
			
		||||
use BookStack\Interfaces\Loggable;
 | 
			
		||||
use BookStack\Theming\ThemeEvents;
 | 
			
		||||
use Illuminate\Database\Eloquent\Builder;
 | 
			
		||||
use Illuminate\Support\Facades\Log;
 | 
			
		||||
| 
						 | 
				
			
			@ -0,0 +1,102 @@
 | 
			
		|||
<?php
 | 
			
		||||
 | 
			
		||||
namespace BookStack\Activity\Tools;
 | 
			
		||||
 | 
			
		||||
use BookStack\Activity\Models\Comment;
 | 
			
		||||
use BookStack\Entities\Models\Page;
 | 
			
		||||
 | 
			
		||||
class CommentTree
 | 
			
		||||
{
 | 
			
		||||
    /**
 | 
			
		||||
     * The built nested tree structure array.
 | 
			
		||||
     * @var array{comment: Comment, depth: int, children: array}[]
 | 
			
		||||
     */
 | 
			
		||||
    protected array $tree;
 | 
			
		||||
    protected array $comments;
 | 
			
		||||
 | 
			
		||||
    public function __construct(
 | 
			
		||||
        protected Page $page
 | 
			
		||||
    ) {
 | 
			
		||||
        $this->comments = $this->loadComments();
 | 
			
		||||
        $this->tree = $this->createTree($this->comments);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public function enabled(): bool
 | 
			
		||||
    {
 | 
			
		||||
        return !setting('app-disable-comments');
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public function empty(): bool
 | 
			
		||||
    {
 | 
			
		||||
        return count($this->tree) === 0;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public function count(): int
 | 
			
		||||
    {
 | 
			
		||||
        return count($this->comments);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public function get(): array
 | 
			
		||||
    {
 | 
			
		||||
        return $this->tree;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * @param Comment[] $comments
 | 
			
		||||
     */
 | 
			
		||||
    protected function createTree(array $comments): array
 | 
			
		||||
    {
 | 
			
		||||
        $byId = [];
 | 
			
		||||
        foreach ($comments as $comment) {
 | 
			
		||||
            $byId[$comment->local_id] = $comment;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        $childMap = [];
 | 
			
		||||
        foreach ($comments as $comment) {
 | 
			
		||||
            $parent = $comment->parent_id;
 | 
			
		||||
            if (is_null($parent) || !isset($byId[$parent])) {
 | 
			
		||||
                $parent = 0;
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            if (!isset($childMap[$parent])) {
 | 
			
		||||
                $childMap[$parent] = [];
 | 
			
		||||
            }
 | 
			
		||||
            $childMap[$parent][] = $comment->local_id;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        $tree = [];
 | 
			
		||||
        foreach ($childMap[0] ?? [] as $childId) {
 | 
			
		||||
            $tree[] = $this->createTreeForId($childId, 0, $byId, $childMap);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        return $tree;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    protected function createTreeForId(int $id, int $depth, array &$byId, array &$childMap): array
 | 
			
		||||
    {
 | 
			
		||||
        $childIds = $childMap[$id] ?? [];
 | 
			
		||||
        $children = [];
 | 
			
		||||
 | 
			
		||||
        foreach ($childIds as $childId) {
 | 
			
		||||
            $children[] = $this->createTreeForId($childId, $depth + 1, $byId, $childMap);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        return [
 | 
			
		||||
            'comment' => $byId[$id],
 | 
			
		||||
            'depth' => $depth,
 | 
			
		||||
            'children' => $children,
 | 
			
		||||
        ];
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    protected function loadComments(): array
 | 
			
		||||
    {
 | 
			
		||||
        if (!$this->enabled()) {
 | 
			
		||||
            return [];
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        return $this->page->comments()
 | 
			
		||||
            ->with('createdBy')
 | 
			
		||||
            ->get()
 | 
			
		||||
            ->all();
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -1,6 +1,6 @@
 | 
			
		|||
<?php
 | 
			
		||||
 | 
			
		||||
namespace BookStack\Actions;
 | 
			
		||||
namespace BookStack\Activity\Tools;
 | 
			
		||||
 | 
			
		||||
class IpFormatter
 | 
			
		||||
{
 | 
			
		||||
| 
						 | 
				
			
			@ -1,6 +1,8 @@
 | 
			
		|||
<?php
 | 
			
		||||
 | 
			
		||||
namespace BookStack\Actions;
 | 
			
		||||
namespace BookStack\Activity\Tools;
 | 
			
		||||
 | 
			
		||||
use BookStack\Activity\Models\Tag;
 | 
			
		||||
 | 
			
		||||
class TagClassGenerator
 | 
			
		||||
{
 | 
			
		||||
| 
						 | 
				
			
			@ -1,12 +1,14 @@
 | 
			
		|||
<?php
 | 
			
		||||
 | 
			
		||||
namespace BookStack\Actions;
 | 
			
		||||
namespace BookStack\Activity\Tools;
 | 
			
		||||
 | 
			
		||||
use BookStack\Auth\User;
 | 
			
		||||
use BookStack\Activity\ActivityType;
 | 
			
		||||
use BookStack\Activity\Models\Loggable;
 | 
			
		||||
use BookStack\Activity\Models\Webhook;
 | 
			
		||||
use BookStack\App\Model;
 | 
			
		||||
use BookStack\Entities\Models\Entity;
 | 
			
		||||
use BookStack\Entities\Models\Page;
 | 
			
		||||
use BookStack\Interfaces\Loggable;
 | 
			
		||||
use BookStack\Model;
 | 
			
		||||
use BookStack\Users\Models\User;
 | 
			
		||||
use Illuminate\Support\Carbon;
 | 
			
		||||
 | 
			
		||||
class WebhookFormatter
 | 
			
		||||
| 
						 | 
				
			
			@ -1,8 +1,8 @@
 | 
			
		|||
<?php
 | 
			
		||||
 | 
			
		||||
namespace BookStack\Http\Controllers\Api;
 | 
			
		||||
namespace BookStack\Api;
 | 
			
		||||
 | 
			
		||||
use BookStack\Api\ApiDocsGenerator;
 | 
			
		||||
use BookStack\Http\ApiController;
 | 
			
		||||
 | 
			
		||||
class ApiDocsController extends ApiController
 | 
			
		||||
{
 | 
			
		||||
| 
						 | 
				
			
			@ -28,4 +28,12 @@ class ApiDocsController extends ApiController
 | 
			
		|||
 | 
			
		||||
        return response()->json($docs);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Redirect to the API docs page.
 | 
			
		||||
     */
 | 
			
		||||
    public function redirect()
 | 
			
		||||
    {
 | 
			
		||||
        return redirect('/api/docs');
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -2,7 +2,7 @@
 | 
			
		|||
 | 
			
		||||
namespace BookStack\Api;
 | 
			
		||||
 | 
			
		||||
use BookStack\Http\Controllers\Api\ApiController;
 | 
			
		||||
use BookStack\Http\ApiController;
 | 
			
		||||
use Exception;
 | 
			
		||||
use Illuminate\Contracts\Container\BindingResolutionException;
 | 
			
		||||
use Illuminate\Support\Collection;
 | 
			
		||||
| 
						 | 
				
			
			@ -16,8 +16,8 @@ use ReflectionMethod;
 | 
			
		|||
 | 
			
		||||
class ApiDocsGenerator
 | 
			
		||||
{
 | 
			
		||||
    protected $reflectionClasses = [];
 | 
			
		||||
    protected $controllerClasses = [];
 | 
			
		||||
    protected array $reflectionClasses = [];
 | 
			
		||||
    protected array $controllerClasses = [];
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Load the docs form the cache if existing
 | 
			
		||||
| 
						 | 
				
			
			@ -139,9 +139,10 @@ class ApiDocsGenerator
 | 
			
		|||
    protected function parseDescriptionFromMethodComment(string $comment): string
 | 
			
		||||
    {
 | 
			
		||||
        $matches = [];
 | 
			
		||||
        preg_match_all('/^\s*?\*\s((?![@\s]).*?)$/m', $comment, $matches);
 | 
			
		||||
        preg_match_all('/^\s*?\*\s?($|((?![\/@\s]).*?))$/m', $comment, $matches);
 | 
			
		||||
 | 
			
		||||
        return implode(' ', $matches[1] ?? []);
 | 
			
		||||
        $text = implode(' ', $matches[1] ?? []);
 | 
			
		||||
        return str_replace('  ', "\n", $text);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -2,8 +2,8 @@
 | 
			
		|||
 | 
			
		||||
namespace BookStack\Api;
 | 
			
		||||
 | 
			
		||||
use BookStack\Auth\User;
 | 
			
		||||
use BookStack\Interfaces\Loggable;
 | 
			
		||||
use BookStack\Activity\Models\Loggable;
 | 
			
		||||
use BookStack\Users\Models\User;
 | 
			
		||||
use Illuminate\Database\Eloquent\Model;
 | 
			
		||||
use Illuminate\Database\Eloquent\Relations\BelongsTo;
 | 
			
		||||
use Illuminate\Support\Carbon;
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -2,7 +2,7 @@
 | 
			
		|||
 | 
			
		||||
namespace BookStack\Api;
 | 
			
		||||
 | 
			
		||||
use BookStack\Auth\Access\LoginService;
 | 
			
		||||
use BookStack\Access\LoginService;
 | 
			
		||||
use BookStack\Exceptions\ApiAuthException;
 | 
			
		||||
use Illuminate\Auth\GuardHelpers;
 | 
			
		||||
use Illuminate\Contracts\Auth\Authenticatable;
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1,10 +1,10 @@
 | 
			
		|||
<?php
 | 
			
		||||
 | 
			
		||||
namespace BookStack\Http\Controllers;
 | 
			
		||||
namespace BookStack\Api;
 | 
			
		||||
 | 
			
		||||
use BookStack\Actions\ActivityType;
 | 
			
		||||
use BookStack\Api\ApiToken;
 | 
			
		||||
use BookStack\Auth\User;
 | 
			
		||||
use BookStack\Activity\ActivityType;
 | 
			
		||||
use BookStack\Http\Controller;
 | 
			
		||||
use BookStack\Users\Models\User;
 | 
			
		||||
use Illuminate\Http\Request;
 | 
			
		||||
use Illuminate\Support\Facades\Hash;
 | 
			
		||||
use Illuminate\Support\Str;
 | 
			
		||||
| 
						 | 
				
			
			@ -58,7 +58,6 @@ class UserApiTokenController extends Controller
 | 
			
		|||
        $token->save();
 | 
			
		||||
 | 
			
		||||
        session()->flash('api-token-secret:' . $token->id, $secret);
 | 
			
		||||
        $this->showSuccessNotification(trans('settings.user_api_token_create_success'));
 | 
			
		||||
        $this->logActivity(ActivityType::API_TOKEN_CREATE, $token);
 | 
			
		||||
 | 
			
		||||
        return redirect($user->getEditUrl('/api-tokens/' . $token->id));
 | 
			
		||||
| 
						 | 
				
			
			@ -96,7 +95,6 @@ class UserApiTokenController extends Controller
 | 
			
		|||
            'expires_at' => $request->get('expires_at') ?: ApiToken::defaultExpiry(),
 | 
			
		||||
        ])->save();
 | 
			
		||||
 | 
			
		||||
        $this->showSuccessNotification(trans('settings.user_api_token_update_success'));
 | 
			
		||||
        $this->logActivity(ActivityType::API_TOKEN_UPDATE, $token);
 | 
			
		||||
 | 
			
		||||
        return redirect($user->getEditUrl('/api-tokens/' . $token->id));
 | 
			
		||||
| 
						 | 
				
			
			@ -123,7 +121,6 @@ class UserApiTokenController extends Controller
 | 
			
		|||
        [$user, $token] = $this->checkPermissionAndFetchUserToken($userId, $tokenId);
 | 
			
		||||
        $token->delete();
 | 
			
		||||
 | 
			
		||||
        $this->showSuccessNotification(trans('settings.user_api_token_delete_success'));
 | 
			
		||||
        $this->logActivity(ActivityType::API_TOKEN_DELETE, $token);
 | 
			
		||||
 | 
			
		||||
        return redirect($user->getEditUrl('#api_tokens'));
 | 
			
		||||
| 
						 | 
				
			
			@ -1,6 +1,6 @@
 | 
			
		|||
<?php
 | 
			
		||||
 | 
			
		||||
namespace BookStack;
 | 
			
		||||
namespace BookStack\App;
 | 
			
		||||
 | 
			
		||||
class Application extends \Illuminate\Foundation\Application
 | 
			
		||||
{
 | 
			
		||||
| 
						 | 
				
			
			@ -1,8 +1,8 @@
 | 
			
		|||
<?php
 | 
			
		||||
 | 
			
		||||
namespace BookStack\Http\Controllers;
 | 
			
		||||
namespace BookStack\App;
 | 
			
		||||
 | 
			
		||||
use BookStack\Actions\ActivityQueries;
 | 
			
		||||
use BookStack\Activity\ActivityQueries;
 | 
			
		||||
use BookStack\Entities\Models\Book;
 | 
			
		||||
use BookStack\Entities\Models\Page;
 | 
			
		||||
use BookStack\Entities\Queries\RecentlyViewed;
 | 
			
		||||
| 
						 | 
				
			
			@ -10,6 +10,7 @@ use BookStack\Entities\Queries\TopFavourites;
 | 
			
		|||
use BookStack\Entities\Repos\BookRepo;
 | 
			
		||||
use BookStack\Entities\Repos\BookshelfRepo;
 | 
			
		||||
use BookStack\Entities\Tools\PageContent;
 | 
			
		||||
use BookStack\Http\Controller;
 | 
			
		||||
use BookStack\Uploads\FaviconHandler;
 | 
			
		||||
use BookStack\Util\SimpleListOptions;
 | 
			
		||||
use Illuminate\Http\Request;
 | 
			
		||||
| 
						 | 
				
			
			@ -1,6 +1,6 @@
 | 
			
		|||
<?php
 | 
			
		||||
 | 
			
		||||
namespace BookStack;
 | 
			
		||||
namespace BookStack\App;
 | 
			
		||||
 | 
			
		||||
use Illuminate\Database\Eloquent\Model as EloquentModel;
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -1,9 +1,9 @@
 | 
			
		|||
<?php
 | 
			
		||||
 | 
			
		||||
namespace BookStack\Providers;
 | 
			
		||||
namespace BookStack\App\Providers;
 | 
			
		||||
 | 
			
		||||
use BookStack\Actions\ActivityLogger;
 | 
			
		||||
use BookStack\Auth\Access\SocialAuthService;
 | 
			
		||||
use BookStack\Access\SocialAuthService;
 | 
			
		||||
use BookStack\Activity\Tools\ActivityLogger;
 | 
			
		||||
use BookStack\Entities\Models\Book;
 | 
			
		||||
use BookStack\Entities\Models\Bookshelf;
 | 
			
		||||
use BookStack\Entities\Models\Chapter;
 | 
			
		||||
| 
						 | 
				
			
			@ -1,14 +1,14 @@
 | 
			
		|||
<?php
 | 
			
		||||
 | 
			
		||||
namespace BookStack\Providers;
 | 
			
		||||
namespace BookStack\App\Providers;
 | 
			
		||||
 | 
			
		||||
use BookStack\Access\ExternalBaseUserProvider;
 | 
			
		||||
use BookStack\Access\Guards\AsyncExternalBaseSessionGuard;
 | 
			
		||||
use BookStack\Access\Guards\LdapSessionGuard;
 | 
			
		||||
use BookStack\Access\LdapService;
 | 
			
		||||
use BookStack\Access\LoginService;
 | 
			
		||||
use BookStack\Access\RegistrationService;
 | 
			
		||||
use BookStack\Api\ApiTokenGuard;
 | 
			
		||||
use BookStack\Auth\Access\ExternalBaseUserProvider;
 | 
			
		||||
use BookStack\Auth\Access\Guards\AsyncExternalBaseSessionGuard;
 | 
			
		||||
use BookStack\Auth\Access\Guards\LdapSessionGuard;
 | 
			
		||||
use BookStack\Auth\Access\LdapService;
 | 
			
		||||
use BookStack\Auth\Access\LoginService;
 | 
			
		||||
use BookStack\Auth\Access\RegistrationService;
 | 
			
		||||
use Illuminate\Support\Facades\Auth;
 | 
			
		||||
use Illuminate\Support\ServiceProvider;
 | 
			
		||||
use Illuminate\Validation\Rules\Password;
 | 
			
		||||
| 
						 | 
				
			
			@ -1,6 +1,6 @@
 | 
			
		|||
<?php
 | 
			
		||||
 | 
			
		||||
namespace BookStack\Providers;
 | 
			
		||||
namespace BookStack\App\Providers;
 | 
			
		||||
 | 
			
		||||
use Illuminate\Foundation\Support\Providers\EventServiceProvider as ServiceProvider;
 | 
			
		||||
use SocialiteProviders\Manager\SocialiteWasCalled;
 | 
			
		||||
| 
						 | 
				
			
			@ -1,6 +1,6 @@
 | 
			
		|||
<?php
 | 
			
		||||
 | 
			
		||||
namespace BookStack\Providers;
 | 
			
		||||
namespace BookStack\App\Providers;
 | 
			
		||||
 | 
			
		||||
use Illuminate\Cache\RateLimiting\Limit;
 | 
			
		||||
use Illuminate\Foundation\Support\Providers\RouteServiceProvider as ServiceProvider;
 | 
			
		||||
| 
						 | 
				
			
			@ -1,6 +1,6 @@
 | 
			
		|||
<?php
 | 
			
		||||
 | 
			
		||||
namespace BookStack\Providers;
 | 
			
		||||
namespace BookStack\App\Providers;
 | 
			
		||||
 | 
			
		||||
use BookStack\Theming\ThemeEvents;
 | 
			
		||||
use BookStack\Theming\ThemeService;
 | 
			
		||||
| 
						 | 
				
			
			@ -1,6 +1,6 @@
 | 
			
		|||
<?php
 | 
			
		||||
 | 
			
		||||
namespace BookStack\Providers;
 | 
			
		||||
namespace BookStack\App\Providers;
 | 
			
		||||
 | 
			
		||||
use BookStack\Translation\FileLoader;
 | 
			
		||||
use BookStack\Translation\MessageSelector;
 | 
			
		||||
| 
						 | 
				
			
			@ -1,6 +1,6 @@
 | 
			
		|||
<?php
 | 
			
		||||
 | 
			
		||||
namespace BookStack\Providers;
 | 
			
		||||
namespace BookStack\App\Providers;
 | 
			
		||||
 | 
			
		||||
use BookStack\Uploads\ImageService;
 | 
			
		||||
use Illuminate\Support\Facades\Validator;
 | 
			
		||||
| 
						 | 
				
			
			@ -1,6 +1,6 @@
 | 
			
		|||
<?php
 | 
			
		||||
 | 
			
		||||
namespace BookStack\Providers;
 | 
			
		||||
namespace BookStack\App\Providers;
 | 
			
		||||
 | 
			
		||||
use BookStack\Entities\BreadcrumbsViewComposer;
 | 
			
		||||
use Illuminate\Pagination\Paginator;
 | 
			
		||||
| 
						 | 
				
			
			@ -1,6 +1,6 @@
 | 
			
		|||
<?php
 | 
			
		||||
 | 
			
		||||
namespace BookStack\Interfaces;
 | 
			
		||||
namespace BookStack\App;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Assigned to models that can have slugs.
 | 
			
		||||
| 
						 | 
				
			
			@ -1,9 +1,9 @@
 | 
			
		|||
<?php
 | 
			
		||||
 | 
			
		||||
use BookStack\Auth\Permissions\PermissionApplicator;
 | 
			
		||||
use BookStack\Auth\User;
 | 
			
		||||
use BookStack\Model;
 | 
			
		||||
use BookStack\App\Model;
 | 
			
		||||
use BookStack\Permissions\PermissionApplicator;
 | 
			
		||||
use BookStack\Settings\SettingService;
 | 
			
		||||
use BookStack\Users\Models\User;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Get the path to a versioned file.
 | 
			
		||||
| 
						 | 
				
			
			@ -1,136 +0,0 @@
 | 
			
		|||
<?php
 | 
			
		||||
 | 
			
		||||
namespace BookStack\Auth\Access;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Class Ldap
 | 
			
		||||
 * An object-orientated thin abstraction wrapper for common PHP LDAP functions.
 | 
			
		||||
 * Allows the standard LDAP functions to be mocked for testing.
 | 
			
		||||
 */
 | 
			
		||||
class Ldap
 | 
			
		||||
{
 | 
			
		||||
    /**
 | 
			
		||||
     * Connect to an LDAP server.
 | 
			
		||||
     *
 | 
			
		||||
     * @return resource
 | 
			
		||||
     */
 | 
			
		||||
    public function connect(string $hostName, int $port)
 | 
			
		||||
    {
 | 
			
		||||
        return ldap_connect($hostName, $port);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Set the value of a LDAP option for the given connection.
 | 
			
		||||
     *
 | 
			
		||||
     * @param resource $ldapConnection
 | 
			
		||||
     * @param mixed    $value
 | 
			
		||||
     */
 | 
			
		||||
    public function setOption($ldapConnection, int $option, $value): bool
 | 
			
		||||
    {
 | 
			
		||||
        return ldap_set_option($ldapConnection, $option, $value);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Start TLS on the given LDAP connection.
 | 
			
		||||
     */
 | 
			
		||||
    public function startTls($ldapConnection): bool
 | 
			
		||||
    {
 | 
			
		||||
        return ldap_start_tls($ldapConnection);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Set the version number for the given ldap connection.
 | 
			
		||||
     *
 | 
			
		||||
     * @param resource $ldapConnection
 | 
			
		||||
     */
 | 
			
		||||
    public function setVersion($ldapConnection, int $version): bool
 | 
			
		||||
    {
 | 
			
		||||
        return $this->setOption($ldapConnection, LDAP_OPT_PROTOCOL_VERSION, $version);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Search LDAP tree using the provided filter.
 | 
			
		||||
     *
 | 
			
		||||
     * @param resource   $ldapConnection
 | 
			
		||||
     * @param string     $baseDn
 | 
			
		||||
     * @param string     $filter
 | 
			
		||||
     * @param array|null $attributes
 | 
			
		||||
     *
 | 
			
		||||
     * @return resource
 | 
			
		||||
     */
 | 
			
		||||
    public function search($ldapConnection, $baseDn, $filter, array $attributes = null)
 | 
			
		||||
    {
 | 
			
		||||
        return ldap_search($ldapConnection, $baseDn, $filter, $attributes);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Get entries from an ldap search result.
 | 
			
		||||
     *
 | 
			
		||||
     * @param resource $ldapConnection
 | 
			
		||||
     * @param resource $ldapSearchResult
 | 
			
		||||
     *
 | 
			
		||||
     * @return array
 | 
			
		||||
     */
 | 
			
		||||
    public function getEntries($ldapConnection, $ldapSearchResult)
 | 
			
		||||
    {
 | 
			
		||||
        return ldap_get_entries($ldapConnection, $ldapSearchResult);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Search and get entries immediately.
 | 
			
		||||
     *
 | 
			
		||||
     * @param resource   $ldapConnection
 | 
			
		||||
     * @param string     $baseDn
 | 
			
		||||
     * @param string     $filter
 | 
			
		||||
     * @param array|null $attributes
 | 
			
		||||
     *
 | 
			
		||||
     * @return resource
 | 
			
		||||
     */
 | 
			
		||||
    public function searchAndGetEntries($ldapConnection, $baseDn, $filter, array $attributes = null)
 | 
			
		||||
    {
 | 
			
		||||
        $search = $this->search($ldapConnection, $baseDn, $filter, $attributes);
 | 
			
		||||
 | 
			
		||||
        return $this->getEntries($ldapConnection, $search);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Bind to LDAP directory.
 | 
			
		||||
     *
 | 
			
		||||
     * @param resource $ldapConnection
 | 
			
		||||
     * @param string   $bindRdn
 | 
			
		||||
     * @param string   $bindPassword
 | 
			
		||||
     *
 | 
			
		||||
     * @return bool
 | 
			
		||||
     */
 | 
			
		||||
    public function bind($ldapConnection, $bindRdn = null, $bindPassword = null)
 | 
			
		||||
    {
 | 
			
		||||
        return ldap_bind($ldapConnection, $bindRdn, $bindPassword);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Explode a LDAP dn string into an array of components.
 | 
			
		||||
     *
 | 
			
		||||
     * @param string $dn
 | 
			
		||||
     * @param int    $withAttrib
 | 
			
		||||
     *
 | 
			
		||||
     * @return array
 | 
			
		||||
     */
 | 
			
		||||
    public function explodeDn(string $dn, int $withAttrib)
 | 
			
		||||
    {
 | 
			
		||||
        return ldap_explode_dn($dn, $withAttrib);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Escape a string for use in an LDAP filter.
 | 
			
		||||
     *
 | 
			
		||||
     * @param string $value
 | 
			
		||||
     * @param string $ignore
 | 
			
		||||
     * @param int    $flags
 | 
			
		||||
     *
 | 
			
		||||
     * @return string
 | 
			
		||||
     */
 | 
			
		||||
    public function escape(string $value, string $ignore = '', int $flags = 0)
 | 
			
		||||
    {
 | 
			
		||||
        return ldap_escape($value, $ignore, $flags);
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -139,14 +139,14 @@ return [
 | 
			
		|||
        SocialiteProviders\Manager\ServiceProvider::class,
 | 
			
		||||
 | 
			
		||||
        // BookStack custom service providers
 | 
			
		||||
        BookStack\Providers\ThemeServiceProvider::class,
 | 
			
		||||
        BookStack\Providers\AppServiceProvider::class,
 | 
			
		||||
        BookStack\Providers\AuthServiceProvider::class,
 | 
			
		||||
        BookStack\Providers\EventServiceProvider::class,
 | 
			
		||||
        BookStack\Providers\RouteServiceProvider::class,
 | 
			
		||||
        BookStack\Providers\TranslationServiceProvider::class,
 | 
			
		||||
        BookStack\Providers\ValidationRuleServiceProvider::class,
 | 
			
		||||
        BookStack\Providers\ViewTweaksServiceProvider::class,
 | 
			
		||||
        \BookStack\App\Providers\ThemeServiceProvider::class,
 | 
			
		||||
        \BookStack\App\Providers\AppServiceProvider::class,
 | 
			
		||||
        \BookStack\App\Providers\AuthServiceProvider::class,
 | 
			
		||||
        \BookStack\App\Providers\EventServiceProvider::class,
 | 
			
		||||
        \BookStack\App\Providers\RouteServiceProvider::class,
 | 
			
		||||
        \BookStack\App\Providers\TranslationServiceProvider::class,
 | 
			
		||||
        \BookStack\App\Providers\ValidationRuleServiceProvider::class,
 | 
			
		||||
        \BookStack\App\Providers\ViewTweaksServiceProvider::class,
 | 
			
		||||
    ],
 | 
			
		||||
 | 
			
		||||
    // Class Aliases
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -59,12 +59,12 @@ return [
 | 
			
		|||
    'providers' => [
 | 
			
		||||
        'users' => [
 | 
			
		||||
            'driver' => 'eloquent',
 | 
			
		||||
            'model'  => \BookStack\Auth\User::class,
 | 
			
		||||
            'model'  => \BookStack\Users\Models\User::class,
 | 
			
		||||
        ],
 | 
			
		||||
 | 
			
		||||
        'external' => [
 | 
			
		||||
            'driver' => 'external-users',
 | 
			
		||||
            'model'  => \BookStack\Auth\User::class,
 | 
			
		||||
            'model'  => \BookStack\Users\Models\User::class,
 | 
			
		||||
        ],
 | 
			
		||||
 | 
			
		||||
        // 'users' => [
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -8,6 +8,10 @@
 | 
			
		|||
 * Do not edit this file unless you're happy to maintain any changes yourself.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
// Configured mail encryption method.
 | 
			
		||||
// STARTTLS should still be attempted, but tls/ssl forces TLS usage.
 | 
			
		||||
$mailEncryption = env('MAIL_ENCRYPTION', null);
 | 
			
		||||
 | 
			
		||||
return [
 | 
			
		||||
 | 
			
		||||
    // Mail driver to use.
 | 
			
		||||
| 
						 | 
				
			
			@ -27,9 +31,9 @@ return [
 | 
			
		|||
    'mailers' => [
 | 
			
		||||
        'smtp' => [
 | 
			
		||||
            'transport' => 'smtp',
 | 
			
		||||
            'scheme' => ($mailEncryption === 'tls' || $mailEncryption === 'ssl') ? 'smtps' : null,
 | 
			
		||||
            'host' => env('MAIL_HOST', 'smtp.mailgun.org'),
 | 
			
		||||
            'port' => env('MAIL_PORT', 587),
 | 
			
		||||
            'encryption' => env('MAIL_ENCRYPTION', 'tls'),
 | 
			
		||||
            'username' => env('MAIL_USERNAME'),
 | 
			
		||||
            'password' => env('MAIL_PASSWORD'),
 | 
			
		||||
            'verify_peer' => env('MAIL_VERIFY_SSL', true),
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -6,7 +6,7 @@ use BookStack\Uploads\ImageService;
 | 
			
		|||
use Illuminate\Console\Command;
 | 
			
		||||
use Symfony\Component\Console\Output\OutputInterface;
 | 
			
		||||
 | 
			
		||||
class CleanupImages extends Command
 | 
			
		||||
class CleanupImagesCommand extends Command
 | 
			
		||||
{
 | 
			
		||||
    /**
 | 
			
		||||
     * The name and signature of the console command.
 | 
			
		||||
| 
						 | 
				
			
			@ -25,60 +25,49 @@ class CleanupImages extends Command
 | 
			
		|||
     */
 | 
			
		||||
    protected $description = 'Cleanup images and drawings';
 | 
			
		||||
 | 
			
		||||
    protected $imageService;
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Create a new command instance.
 | 
			
		||||
     *
 | 
			
		||||
     * @param \BookStack\Uploads\ImageService $imageService
 | 
			
		||||
     */
 | 
			
		||||
    public function __construct(ImageService $imageService)
 | 
			
		||||
    {
 | 
			
		||||
        $this->imageService = $imageService;
 | 
			
		||||
        parent::__construct();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Execute the console command.
 | 
			
		||||
     *
 | 
			
		||||
     * @return mixed
 | 
			
		||||
     */
 | 
			
		||||
    public function handle()
 | 
			
		||||
    public function handle(ImageService $imageService): int
 | 
			
		||||
    {
 | 
			
		||||
        $checkRevisions = $this->option('all') ? false : true;
 | 
			
		||||
        $dryRun = $this->option('force') ? false : true;
 | 
			
		||||
        $checkRevisions = !$this->option('all');
 | 
			
		||||
        $dryRun = !$this->option('force');
 | 
			
		||||
 | 
			
		||||
        if (!$dryRun) {
 | 
			
		||||
            $proceed = $this->confirm("This operation is destructive and is not guaranteed to be fully accurate.\nEnsure you have a backup of your images.\nAre you sure you want to proceed?");
 | 
			
		||||
            $this->warn("This operation is destructive and is not guaranteed to be fully accurate.\nEnsure you have a backup of your images.\n");
 | 
			
		||||
            $proceed = $this->confirm("Are you sure you want to proceed?");
 | 
			
		||||
            if (!$proceed) {
 | 
			
		||||
                return;
 | 
			
		||||
                return 0;
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        $deleted = $this->imageService->deleteUnusedImages($checkRevisions, $dryRun);
 | 
			
		||||
        $deleted = $imageService->deleteUnusedImages($checkRevisions, $dryRun);
 | 
			
		||||
        $deleteCount = count($deleted);
 | 
			
		||||
 | 
			
		||||
        if ($dryRun) {
 | 
			
		||||
            $this->comment('Dry run, No images have been deleted');
 | 
			
		||||
            $this->comment('Dry run, no images have been deleted');
 | 
			
		||||
            $this->comment($deleteCount . ' images found that would have been deleted');
 | 
			
		||||
            $this->showDeletedImages($deleted);
 | 
			
		||||
            $this->comment('Run with -f or --force to perform deletions');
 | 
			
		||||
 | 
			
		||||
            return;
 | 
			
		||||
            return 0;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        $this->showDeletedImages($deleted);
 | 
			
		||||
        $this->comment($deleteCount . ' images deleted');
 | 
			
		||||
        return 0;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    protected function showDeletedImages($paths)
 | 
			
		||||
    protected function showDeletedImages($paths): void
 | 
			
		||||
    {
 | 
			
		||||
        if ($this->getOutput()->getVerbosity() <= OutputInterface::VERBOSITY_NORMAL) {
 | 
			
		||||
            return;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        if (count($paths) > 0) {
 | 
			
		||||
            $this->line('Images to delete:');
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        foreach ($paths as $path) {
 | 
			
		||||
            $this->line($path);
 | 
			
		||||
        }
 | 
			
		||||
| 
						 | 
				
			
			@ -2,10 +2,10 @@
 | 
			
		|||
 | 
			
		||||
namespace BookStack\Console\Commands;
 | 
			
		||||
 | 
			
		||||
use BookStack\Actions\Activity;
 | 
			
		||||
use BookStack\Activity\Models\Activity;
 | 
			
		||||
use Illuminate\Console\Command;
 | 
			
		||||
 | 
			
		||||
class ClearActivity extends Command
 | 
			
		||||
class ClearActivityCommand extends Command
 | 
			
		||||
{
 | 
			
		||||
    /**
 | 
			
		||||
     * The name and signature of the console command.
 | 
			
		||||
| 
						 | 
				
			
			@ -21,27 +21,13 @@ class ClearActivity extends Command
 | 
			
		|||
     */
 | 
			
		||||
    protected $description = 'Clear user activity from the system';
 | 
			
		||||
 | 
			
		||||
    protected $activity;
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Create a new command instance.
 | 
			
		||||
     *
 | 
			
		||||
     * @param Activity $activity
 | 
			
		||||
     */
 | 
			
		||||
    public function __construct(Activity $activity)
 | 
			
		||||
    {
 | 
			
		||||
        $this->activity = $activity;
 | 
			
		||||
        parent::__construct();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Execute the console command.
 | 
			
		||||
     *
 | 
			
		||||
     * @return mixed
 | 
			
		||||
     */
 | 
			
		||||
    public function handle()
 | 
			
		||||
    public function handle(): int
 | 
			
		||||
    {
 | 
			
		||||
        $this->activity->newQuery()->truncate();
 | 
			
		||||
        Activity::query()->truncate();
 | 
			
		||||
        $this->comment('System activity cleared');
 | 
			
		||||
        return 0;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -5,7 +5,7 @@ namespace BookStack\Console\Commands;
 | 
			
		|||
use BookStack\Entities\Models\PageRevision;
 | 
			
		||||
use Illuminate\Console\Command;
 | 
			
		||||
 | 
			
		||||
class ClearRevisions extends Command
 | 
			
		||||
class ClearRevisionsCommand extends Command
 | 
			
		||||
{
 | 
			
		||||
    /**
 | 
			
		||||
     * The name and signature of the console command.
 | 
			
		||||
| 
						 | 
				
			
			@ -23,28 +23,14 @@ class ClearRevisions extends Command
 | 
			
		|||
     */
 | 
			
		||||
    protected $description = 'Clear page revisions';
 | 
			
		||||
 | 
			
		||||
    protected $pageRevision;
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Create a new command instance.
 | 
			
		||||
     *
 | 
			
		||||
     * @param PageRevision $pageRevision
 | 
			
		||||
     */
 | 
			
		||||
    public function __construct(PageRevision $pageRevision)
 | 
			
		||||
    {
 | 
			
		||||
        $this->pageRevision = $pageRevision;
 | 
			
		||||
        parent::__construct();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Execute the console command.
 | 
			
		||||
     *
 | 
			
		||||
     * @return mixed
 | 
			
		||||
     */
 | 
			
		||||
    public function handle()
 | 
			
		||||
    public function handle(): int
 | 
			
		||||
    {
 | 
			
		||||
        $deleteTypes = $this->option('all') ? ['version', 'update_draft'] : ['version'];
 | 
			
		||||
        $this->pageRevision->newQuery()->whereIn('type', $deleteTypes)->delete();
 | 
			
		||||
        PageRevision::query()->whereIn('type', $deleteTypes)->delete();
 | 
			
		||||
        $this->comment('Revisions deleted');
 | 
			
		||||
        return 0;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -2,10 +2,10 @@
 | 
			
		|||
 | 
			
		||||
namespace BookStack\Console\Commands;
 | 
			
		||||
 | 
			
		||||
use BookStack\Actions\View;
 | 
			
		||||
use BookStack\Activity\Models\View;
 | 
			
		||||
use Illuminate\Console\Command;
 | 
			
		||||
 | 
			
		||||
class ClearViews extends Command
 | 
			
		||||
class ClearViewsCommand extends Command
 | 
			
		||||
{
 | 
			
		||||
    /**
 | 
			
		||||
     * The name and signature of the console command.
 | 
			
		||||
| 
						 | 
				
			
			@ -21,22 +21,13 @@ class ClearViews extends Command
 | 
			
		|||
     */
 | 
			
		||||
    protected $description = 'Clear all view-counts for all entities';
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Create a new command instance.
 | 
			
		||||
     */
 | 
			
		||||
    public function __construct()
 | 
			
		||||
    {
 | 
			
		||||
        parent::__construct();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Execute the console command.
 | 
			
		||||
     *
 | 
			
		||||
     * @return mixed
 | 
			
		||||
     */
 | 
			
		||||
    public function handle()
 | 
			
		||||
    public function handle(): int
 | 
			
		||||
    {
 | 
			
		||||
        View::clearAll();
 | 
			
		||||
        View::query()->truncate();
 | 
			
		||||
        $this->comment('Views cleared');
 | 
			
		||||
        return 0;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -6,7 +6,7 @@ use BookStack\Entities\Models\Bookshelf;
 | 
			
		|||
use BookStack\Entities\Tools\PermissionsUpdater;
 | 
			
		||||
use Illuminate\Console\Command;
 | 
			
		||||
 | 
			
		||||
class CopyShelfPermissions extends Command
 | 
			
		||||
class CopyShelfPermissionsCommand extends Command
 | 
			
		||||
{
 | 
			
		||||
    /**
 | 
			
		||||
     * The name and signature of the console command.
 | 
			
		||||
| 
						 | 
				
			
			@ -25,25 +25,10 @@ class CopyShelfPermissions extends Command
 | 
			
		|||
     */
 | 
			
		||||
    protected $description = 'Copy shelf permissions to all child books';
 | 
			
		||||
 | 
			
		||||
    protected PermissionsUpdater $permissionsUpdater;
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Create a new command instance.
 | 
			
		||||
     *
 | 
			
		||||
     * @return void
 | 
			
		||||
     */
 | 
			
		||||
    public function __construct(PermissionsUpdater $permissionsUpdater)
 | 
			
		||||
    {
 | 
			
		||||
        $this->permissionsUpdater = $permissionsUpdater;
 | 
			
		||||
        parent::__construct();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Execute the console command.
 | 
			
		||||
     *
 | 
			
		||||
     * @return mixed
 | 
			
		||||
     */
 | 
			
		||||
    public function handle()
 | 
			
		||||
    public function handle(PermissionsUpdater $permissionsUpdater): int
 | 
			
		||||
    {
 | 
			
		||||
        $shelfSlug = $this->option('slug');
 | 
			
		||||
        $cascadeAll = $this->option('all');
 | 
			
		||||
| 
						 | 
				
			
			@ -52,7 +37,7 @@ class CopyShelfPermissions extends Command
 | 
			
		|||
        if (!$cascadeAll && !$shelfSlug) {
 | 
			
		||||
            $this->error('Either a --slug or --all option must be provided.');
 | 
			
		||||
 | 
			
		||||
            return;
 | 
			
		||||
            return 1;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        if ($cascadeAll) {
 | 
			
		||||
| 
						 | 
				
			
			@ -63,7 +48,7 @@ class CopyShelfPermissions extends Command
 | 
			
		|||
            );
 | 
			
		||||
 | 
			
		||||
            if (!$continue && !$this->hasOption('no-interaction')) {
 | 
			
		||||
                return;
 | 
			
		||||
                return 0;
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            $shelves = Bookshelf::query()->get(['id']);
 | 
			
		||||
| 
						 | 
				
			
			@ -77,10 +62,11 @@ class CopyShelfPermissions extends Command
 | 
			
		|||
        }
 | 
			
		||||
 | 
			
		||||
        foreach ($shelves as $shelf) {
 | 
			
		||||
            $this->permissionsUpdater->updateBookPermissionsFromShelf($shelf, false);
 | 
			
		||||
            $permissionsUpdater->updateBookPermissionsFromShelf($shelf, false);
 | 
			
		||||
            $this->info('Copied permissions for shelf [' . $shelf->id . ']');
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        $this->info('Permissions copied for ' . $shelves->count() . ' shelves.');
 | 
			
		||||
        return 0;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
Some files were not shown because too many files have changed in this diff Show More
		Loading…
	
		Reference in New Issue