Update to Kirby 4.7.0
This commit is contained in:
parent
02a9ab387c
commit
ba25a9a198
509 changed files with 26604 additions and 14872 deletions
|
@ -32,55 +32,37 @@ class Auth
|
|||
/**
|
||||
* Available auth challenge classes
|
||||
* from the core and plugins
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
public static $challenges = [];
|
||||
public static array $challenges = [];
|
||||
|
||||
/**
|
||||
* Currently impersonated user
|
||||
*
|
||||
* @var \Kirby\Cms\User|null
|
||||
*/
|
||||
protected $impersonate;
|
||||
|
||||
/**
|
||||
* Kirby instance
|
||||
*
|
||||
* @var \Kirby\Cms\App
|
||||
*/
|
||||
protected $kirby;
|
||||
protected User|null $impersonate = null;
|
||||
|
||||
/**
|
||||
* Cache of the auth status object
|
||||
*
|
||||
* @var \Kirby\Cms\Auth\Status
|
||||
*/
|
||||
protected $status;
|
||||
protected Status|null $status = null;
|
||||
|
||||
/**
|
||||
* Instance of the currently logged in user or
|
||||
* `false` if the user was not yet determined
|
||||
*
|
||||
* @var \Kirby\Cms\User|null|false
|
||||
*/
|
||||
protected $user = false;
|
||||
protected User|false|null $user = false;
|
||||
|
||||
/**
|
||||
* Exception that was thrown while
|
||||
* determining the current user
|
||||
*
|
||||
* @var \Throwable
|
||||
*/
|
||||
protected $userException;
|
||||
protected Throwable|null $userException = null;
|
||||
|
||||
/**
|
||||
* @param \Kirby\Cms\App $kirby
|
||||
* @codeCoverageIgnore
|
||||
*/
|
||||
public function __construct(App $kirby)
|
||||
{
|
||||
$this->kirby = $kirby;
|
||||
public function __construct(
|
||||
protected App $kirby
|
||||
) {
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -88,17 +70,18 @@ class Auth
|
|||
* (one-time auth code)
|
||||
* @since 3.5.0
|
||||
*
|
||||
* @param string $email
|
||||
* @param bool $long If `true`, a long session will be created
|
||||
* @param string $mode Either 'login' or 'password-reset'
|
||||
* @return \Kirby\Cms\Auth\Status
|
||||
* @param 'login'|'password-reset'|'2fa' $mode Purpose of the code
|
||||
*
|
||||
* @throws \Kirby\Exception\LogicException If there is no suitable authentication challenge (only in debug mode)
|
||||
* @throws \Kirby\Exception\NotFoundException If the user does not exist (only in debug mode)
|
||||
* @throws \Kirby\Exception\PermissionException If the rate limit is exceeded
|
||||
*/
|
||||
public function createChallenge(string $email, bool $long = false, string $mode = 'login')
|
||||
{
|
||||
public function createChallenge(
|
||||
string $email,
|
||||
bool $long = false,
|
||||
string $mode = 'login'
|
||||
): Status {
|
||||
$email = Idn::decodeEmail($email);
|
||||
|
||||
$session = $this->kirby->session([
|
||||
|
@ -145,7 +128,10 @@ class Auth
|
|||
$session->set('kirby.challenge.type', $challenge);
|
||||
|
||||
if ($code !== null) {
|
||||
$session->set('kirby.challenge.code', password_hash($code, PASSWORD_DEFAULT));
|
||||
$session->set(
|
||||
'kirby.challenge.code',
|
||||
password_hash($code, PASSWORD_DEFAULT)
|
||||
);
|
||||
}
|
||||
|
||||
break;
|
||||
|
@ -179,10 +165,8 @@ class Auth
|
|||
|
||||
/**
|
||||
* Returns the csrf token if it exists and if it is valid
|
||||
*
|
||||
* @return string|false
|
||||
*/
|
||||
public function csrf()
|
||||
public function csrf(): string|false
|
||||
{
|
||||
// get the csrf from the header
|
||||
$fromHeader = $this->kirby->request()->csrf();
|
||||
|
@ -201,8 +185,6 @@ class Auth
|
|||
/**
|
||||
* Returns either predefined csrf or the one from session
|
||||
* @since 3.6.0
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function csrfFromSession(): string
|
||||
{
|
||||
|
@ -217,11 +199,10 @@ class Auth
|
|||
* valid credentials
|
||||
*
|
||||
* @param \Kirby\Http\Request\Auth\BasicAuth|null $auth
|
||||
* @return \Kirby\Cms\User|null
|
||||
* @throws \Kirby\Exception\InvalidArgumentException if the authorization header is invalid
|
||||
* @throws \Kirby\Exception\PermissionException if basic authentication is not allowed
|
||||
*/
|
||||
public function currentUserFromBasicAuth(BasicAuth $auth = null)
|
||||
public function currentUserFromBasicAuth(BasicAuth|null $auth = null): User|null
|
||||
{
|
||||
if ($this->kirby->option('api.basicAuth', false) !== true) {
|
||||
throw new PermissionException('Basic authentication is not activated');
|
||||
|
@ -240,8 +221,8 @@ class Auth
|
|||
}
|
||||
}
|
||||
|
||||
$request = $this->kirby->request();
|
||||
$auth = $auth ?? $request->auth();
|
||||
$request = $this->kirby->request();
|
||||
$auth ??= $request->auth();
|
||||
|
||||
if (!$auth || $auth->type() !== 'basic') {
|
||||
throw new InvalidArgumentException('Invalid authorization header');
|
||||
|
@ -257,10 +238,8 @@ class Auth
|
|||
|
||||
/**
|
||||
* Returns the currently impersonated user
|
||||
*
|
||||
* @return \Kirby\Cms\User|null
|
||||
*/
|
||||
public function currentUserFromImpersonation()
|
||||
public function currentUserFromImpersonation(): User|null
|
||||
{
|
||||
return $this->impersonate;
|
||||
}
|
||||
|
@ -269,12 +248,10 @@ class Auth
|
|||
* Returns the logged in user by checking
|
||||
* the current session and finding a valid
|
||||
* valid user id in there
|
||||
*
|
||||
* @param \Kirby\Session\Session|array|null $session
|
||||
* @return \Kirby\Cms\User|null
|
||||
*/
|
||||
public function currentUserFromSession($session = null)
|
||||
{
|
||||
public function currentUserFromSession(
|
||||
Session|array|null $session = null
|
||||
): User|null {
|
||||
$session = $this->session($session);
|
||||
|
||||
$id = $session->data()->get('kirby.userId');
|
||||
|
@ -318,12 +295,12 @@ class Auth
|
|||
* Returns the list of enabled challenges in the
|
||||
* configured order
|
||||
* @since 3.5.1
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function enabledChallenges(): array
|
||||
{
|
||||
return A::wrap($this->kirby->option('auth.challenges', ['email']));
|
||||
return A::wrap(
|
||||
$this->kirby->option('auth.challenges', ['totp', 'email'])
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -333,10 +310,9 @@ class Auth
|
|||
* `null` to use the actual user again,
|
||||
* `'kirby'` for a virtual admin user or
|
||||
* `'nobody'` to disable the actual user
|
||||
* @return \Kirby\Cms\User|null
|
||||
* @throws \Kirby\Exception\NotFoundException if the given user cannot be found
|
||||
*/
|
||||
public function impersonate(string|null $who = null)
|
||||
public function impersonate(string|null $who = null): User|null
|
||||
{
|
||||
// clear the status cache
|
||||
$this->status = null;
|
||||
|
@ -360,8 +336,6 @@ class Auth
|
|||
/**
|
||||
* Returns the hashed ip of the visitor
|
||||
* which is used to track invalid logins
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function ipHash(): string
|
||||
{
|
||||
|
@ -373,9 +347,6 @@ class Auth
|
|||
|
||||
/**
|
||||
* Check if logins are blocked for the current ip or email
|
||||
*
|
||||
* @param string $email
|
||||
* @return bool
|
||||
*/
|
||||
public function isBlocked(string $email): bool
|
||||
{
|
||||
|
@ -450,16 +421,12 @@ class Auth
|
|||
/**
|
||||
* Sets a user object as the current user in the cache
|
||||
* @internal
|
||||
*
|
||||
* @param \Kirby\Cms\User $user
|
||||
* @return void
|
||||
*/
|
||||
public function setUser(User $user): void
|
||||
{
|
||||
// stop impersonating
|
||||
$this->impersonate = null;
|
||||
|
||||
$this->user = $user;
|
||||
$this->user = $user;
|
||||
|
||||
// clear the status cache
|
||||
$this->status = null;
|
||||
|
@ -469,13 +436,13 @@ class Auth
|
|||
* Returns the authentication status object
|
||||
* @since 3.5.1
|
||||
*
|
||||
* @param \Kirby\Session\Session|array|null $session
|
||||
* @param bool $allowImpersonation If set to false, only the actually
|
||||
* logged in user will be returned
|
||||
* @return \Kirby\Cms\Auth\Status
|
||||
*/
|
||||
public function status($session = null, bool $allowImpersonation = true)
|
||||
{
|
||||
public function status(
|
||||
Session|array|null $session = null,
|
||||
bool $allowImpersonation = true
|
||||
): Status {
|
||||
// try to return from cache
|
||||
if ($this->status && $session === null && $allowImpersonation === true) {
|
||||
return $this->status;
|
||||
|
@ -588,8 +555,6 @@ class Auth
|
|||
|
||||
/**
|
||||
* Returns the absolute path to the logins log
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function logfile(): string
|
||||
{
|
||||
|
@ -598,8 +563,6 @@ class Auth
|
|||
|
||||
/**
|
||||
* Read all tracked logins
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function log(): array
|
||||
{
|
||||
|
@ -612,8 +575,8 @@ class Auth
|
|||
}
|
||||
|
||||
// ensure that the category arrays are defined
|
||||
$log['by-ip'] = $log['by-ip'] ?? [];
|
||||
$log['by-email'] = $log['by-email'] ?? [];
|
||||
$log['by-ip'] ??= [];
|
||||
$log['by-email'] ??= [];
|
||||
|
||||
// remove all elements on the top level with different keys (old structure)
|
||||
$log = array_intersect_key($log, array_flip(['by-ip', 'by-email']));
|
||||
|
@ -642,8 +605,6 @@ class Auth
|
|||
|
||||
/**
|
||||
* Logout the current user
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function logout(): void
|
||||
{
|
||||
|
@ -668,8 +629,6 @@ class Auth
|
|||
/**
|
||||
* Clears the cached user data after logout
|
||||
* @internal
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function flush(): void
|
||||
{
|
||||
|
@ -681,12 +640,12 @@ class Auth
|
|||
/**
|
||||
* Tracks a login
|
||||
*
|
||||
* @param string|null $email
|
||||
* @param bool $triggerHook If `false`, no user.login:failed hook is triggered
|
||||
* @return bool
|
||||
*/
|
||||
public function track(string|null $email, bool $triggerHook = true): bool
|
||||
{
|
||||
public function track(
|
||||
string|null $email,
|
||||
bool $triggerHook = true
|
||||
): bool {
|
||||
if ($triggerHook === true) {
|
||||
$this->kirby->trigger('user.login:failed', compact('email'));
|
||||
}
|
||||
|
@ -730,7 +689,6 @@ class Auth
|
|||
* @param bool $allowImpersonation If set to false, 'impersonate' won't
|
||||
* be returned as authentication type
|
||||
* even if an impersonation is active
|
||||
* @return string
|
||||
*/
|
||||
public function type(bool $allowImpersonation = true): string
|
||||
{
|
||||
|
@ -759,15 +717,15 @@ class Auth
|
|||
/**
|
||||
* Validates the currently logged in user
|
||||
*
|
||||
* @param \Kirby\Session\Session|array|null $session
|
||||
* @param bool $allowImpersonation If set to false, only the actually
|
||||
* logged in user will be returned
|
||||
* @return \Kirby\Cms\User|null
|
||||
*
|
||||
* @throws \Throwable If an authentication error occurred
|
||||
*/
|
||||
public function user($session = null, bool $allowImpersonation = true)
|
||||
{
|
||||
public function user(
|
||||
Session|array|null $session = null,
|
||||
bool $allowImpersonation = true
|
||||
): User|null {
|
||||
if ($allowImpersonation === true && $this->impersonate !== null) {
|
||||
return $this->impersonate;
|
||||
}
|
||||
|
@ -820,7 +778,7 @@ class Auth
|
|||
public function verifyChallenge(
|
||||
#[SensitiveParameter]
|
||||
string $code
|
||||
) {
|
||||
): User {
|
||||
try {
|
||||
$session = $this->kirby->session();
|
||||
|
||||
|
@ -887,9 +845,11 @@ class Auth
|
|||
throw new PermissionException(['key' => 'access.code']);
|
||||
}
|
||||
|
||||
throw new LogicException('Invalid authentication challenge: ' . $challenge);
|
||||
throw new LogicException(
|
||||
'Invalid authentication challenge: ' . $challenge
|
||||
);
|
||||
} catch (Throwable $e) {
|
||||
$details = $e instanceof \Kirby\Exception\Exception ? $e->getDetails() : [];
|
||||
$details = $e instanceof Exception ? $e->getDetails() : [];
|
||||
|
||||
if (
|
||||
empty($email) === false &&
|
||||
|
@ -925,8 +885,10 @@ class Auth
|
|||
* @throws \Throwable Either the passed `$exception` or the `$fallback`
|
||||
* (no exception if debugging is disabled and no fallback was passed)
|
||||
*/
|
||||
protected function fail(Throwable $exception, Throwable $fallback = null): void
|
||||
{
|
||||
protected function fail(
|
||||
Throwable $exception,
|
||||
Throwable|null $fallback = null
|
||||
): void {
|
||||
$debug = $this->kirby->option('auth.debug', 'log');
|
||||
|
||||
// throw the original exception only in debug mode
|
||||
|
@ -948,11 +910,8 @@ class Auth
|
|||
|
||||
/**
|
||||
* Creates a session object from the passed options
|
||||
*
|
||||
* @param \Kirby\Session\Session|array|null $session
|
||||
* @return \Kirby\Session\Session
|
||||
*/
|
||||
protected function session($session = null)
|
||||
protected function session(Session|array|null $session = null): Session
|
||||
{
|
||||
// use passed session options or session object if set
|
||||
if (is_array($session) === true) {
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue