1
0
mirror of https://github.com/BookStackApp/BookStack.git synced 2024-11-25 04:13:42 +01:00
BookStack/app/Auth/Access/UserTokenService.php
Dan Brown a641b4da2c
Swapped injected db instance with facade
Injected db instance was causing the DB connection to be
made a lot earlier than desired or required.
Swapped to a facade for now but ideally this extension of services needs
to be cleaned up with a better approach in general.
2021-08-31 21:50:23 +01:00

143 lines
3.2 KiB
PHP

<?php
namespace BookStack\Auth\Access;
use BookStack\Auth\User;
use BookStack\Exceptions\UserTokenExpiredException;
use BookStack\Exceptions\UserTokenNotFoundException;
use Carbon\Carbon;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Str;
use stdClass;
class UserTokenService
{
/**
* Name of table where user tokens are stored.
*
* @var string
*/
protected $tokenTable = 'user_tokens';
/**
* Token expiry time in hours.
*
* @var int
*/
protected $expiryTime = 24;
/**
* Delete all email confirmations that belong to a user.
*
* @param User $user
*
* @return mixed
*/
public function deleteByUser(User $user)
{
return DB::table($this->tokenTable)
->where('user_id', '=', $user->id)
->delete();
}
/**
* Get the user id from a token, while check the token exists and has not expired.
*
* @param string $token
*
* @throws UserTokenNotFoundException
* @throws UserTokenExpiredException
*
* @return int
*/
public function checkTokenAndGetUserId(string $token): int
{
$entry = $this->getEntryByToken($token);
if (is_null($entry)) {
throw new UserTokenNotFoundException('Token "' . $token . '" not found');
}
if ($this->entryExpired($entry)) {
throw new UserTokenExpiredException("Token of id {$entry->id} has expired.", $entry->user_id);
}
return $entry->user_id;
}
/**
* Creates a unique token within the email confirmation database.
*
* @return string
*/
protected function generateToken(): string
{
$token = Str::random(24);
while ($this->tokenExists($token)) {
$token = Str::random(25);
}
return $token;
}
/**
* Generate and store a token for the given user.
*
* @param User $user
*
* @return string
*/
protected function createTokenForUser(User $user): string
{
$token = $this->generateToken();
DB::table($this->tokenTable)->insert([
'user_id' => $user->id,
'token' => $token,
'created_at' => Carbon::now(),
'updated_at' => Carbon::now(),
]);
return $token;
}
/**
* Check if the given token exists.
*
* @param string $token
*
* @return bool
*/
protected function tokenExists(string $token): bool
{
return DB::table($this->tokenTable)
->where('token', '=', $token)->exists();
}
/**
* Get a token entry for the given token.
*
* @param string $token
*
* @return object|null
*/
protected function getEntryByToken(string $token)
{
return DB::table($this->tokenTable)
->where('token', '=', $token)
->first();
}
/**
* Check if the given token entry has expired.
*
* @param stdClass $tokenEntry
*
* @return bool
*/
protected function entryExpired(stdClass $tokenEntry): bool
{
return Carbon::now()->subHours($this->expiryTime)
->gt(new Carbon($tokenEntry->created_at));
}
}