boboko lulnar
This commit is contained in:
@@ -7,15 +7,11 @@ use Lucent\Primitive\Collection;
|
||||
|
||||
readonly class AccountService
|
||||
{
|
||||
|
||||
public function __construct(
|
||||
private AuthService $authService,
|
||||
private AuthService $authService,
|
||||
private ChannelService $channelService,
|
||||
private UserRepo $userRepo,
|
||||
)
|
||||
{
|
||||
|
||||
}
|
||||
private UserRepo $userRepo,
|
||||
) {}
|
||||
|
||||
/**
|
||||
* @return Collection<User>
|
||||
@@ -25,13 +21,11 @@ readonly class AccountService
|
||||
return $this->userRepo->all();
|
||||
}
|
||||
|
||||
|
||||
public function countUsers(): int
|
||||
{
|
||||
return $this->userRepo->count();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @return Collection<UserProfile>
|
||||
*/
|
||||
@@ -54,6 +48,4 @@ readonly class AccountService
|
||||
$roles = $this->authService->currentUserRoles();
|
||||
return $this->channelService->schemasWritableByRoles($roles);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
+15
-198
@@ -2,235 +2,52 @@
|
||||
|
||||
namespace Lucent\Account;
|
||||
|
||||
use Carbon\Carbon;
|
||||
use Illuminate\Contracts\Session\Session;
|
||||
use Illuminate\Support\Facades\Mail;
|
||||
use Illuminate\Support\Str;
|
||||
use Lucent\Channel\ChannelService;
|
||||
use Lucent\LucentException;
|
||||
use Lucent\Mail\LoginMail;
|
||||
|
||||
readonly class AuthService
|
||||
interface AuthService
|
||||
{
|
||||
public function currentUserId(): ?string;
|
||||
|
||||
public function __construct(
|
||||
private ChannelService $channelService,
|
||||
private UserRepo $userRepo,
|
||||
public Session $session,
|
||||
)
|
||||
{
|
||||
public function currentUserRoles(): array;
|
||||
public function getCurrentUser(): User;
|
||||
|
||||
}
|
||||
|
||||
|
||||
public function currentUserId(): ?string
|
||||
{
|
||||
|
||||
if (app()->runningInConsole()) {
|
||||
return config("lucent.systemUserId");
|
||||
} elseif(request()->segment(1) !== "lucent") {
|
||||
return config("lucent.systemUserId");
|
||||
} else {
|
||||
return $this->session->get("user.id");
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public
|
||||
function currentUserRoles(): array
|
||||
{
|
||||
return $this->session->get("user.roles") ?? [];
|
||||
}
|
||||
|
||||
public
|
||||
function isLoggedIn(): bool
|
||||
{
|
||||
return !empty($this->currentUserId());
|
||||
}
|
||||
public function isLoggedIn(): bool;
|
||||
|
||||
/**
|
||||
* @throws LucentException
|
||||
*/
|
||||
public
|
||||
function login(string $email, string $token): void
|
||||
{
|
||||
public function login(string $email, string $token): void;
|
||||
|
||||
$user = $this->userRepo->findByEmail(new Email($email));
|
||||
public function refreshSession();
|
||||
|
||||
if ($user->isEmpty()) {
|
||||
throw new LucentException("Your account was not found");
|
||||
}
|
||||
|
||||
if ($user->get()->isRemoved()) {
|
||||
throw new LucentException("Your account is not active");
|
||||
}
|
||||
|
||||
if ($user->get()->mailToken !== $token) {
|
||||
throw new LucentException("Token has expired or is invalid");
|
||||
}
|
||||
|
||||
if (Carbon::parse($user->get()->loggedInAt)->lte(Carbon::now()->subHours(1))) {
|
||||
throw new LucentException("Token has expired.");
|
||||
}
|
||||
|
||||
$newUser = $user->get();
|
||||
$newUser->updatedAt = Carbon::now()->toJson();
|
||||
$newUser->mailToken = null;
|
||||
$this->userRepo->update($newUser);
|
||||
$this->session->put(["user" => $user->get()->safe()]);
|
||||
}
|
||||
|
||||
public
|
||||
function refreshSession()
|
||||
{
|
||||
|
||||
|
||||
$user = $this->userRepo->findById($this->currentUserId());
|
||||
|
||||
if ($user->isEmpty()) {
|
||||
throw new LucentException("Your account was not found");
|
||||
}
|
||||
|
||||
if ($user->get()->isRemoved()) {
|
||||
throw new LucentException("Your account is not active");
|
||||
}
|
||||
|
||||
$newUser = $user->get();
|
||||
$this->session->put(["user" => $user->get()->safe()]);
|
||||
}
|
||||
|
||||
|
||||
public
|
||||
function create(string $name, string $email, array $roles): User
|
||||
{
|
||||
$user = new User(
|
||||
id: (string)Str::uuid(),
|
||||
name: new Name($name),
|
||||
email: new Email($email),
|
||||
roles: $this->validateRoles($roles),
|
||||
createdAt: Carbon::now()->toJson(),
|
||||
updatedAt: Carbon::now()->toJson(),
|
||||
loggedInAt: Carbon::now()->toJson(),
|
||||
mailToken: Token::new(32),
|
||||
);
|
||||
|
||||
$this->userRepo->insert($user);
|
||||
return $user;
|
||||
}
|
||||
|
||||
|
||||
|
||||
public function sendLoginEmail(string $email): void
|
||||
{
|
||||
$emailAddress = (new Email($email));
|
||||
$user = $this->userRepo->findByEmail($emailAddress);
|
||||
|
||||
if ($user->isEmpty()) {
|
||||
return;
|
||||
}
|
||||
|
||||
if ($user->get()->isRemoved()) {
|
||||
return;
|
||||
}
|
||||
|
||||
$newToken = $this->userRepo->updateLoginToken($user->get()->id);
|
||||
|
||||
Mail::to($email)->send(
|
||||
new LoginMail(
|
||||
$email,
|
||||
$newToken,
|
||||
$this->channelService->channel->lucentUrl
|
||||
)
|
||||
);
|
||||
}
|
||||
public function create(string $name, string $email, array $roles): User;
|
||||
|
||||
public function sendLoginEmail(string $email): void;
|
||||
|
||||
/**
|
||||
* @throws LucentException
|
||||
*/
|
||||
public
|
||||
function changeRoles(string $userId, array $roles): void
|
||||
{
|
||||
$user = $this->userRepo->findById($userId);
|
||||
|
||||
if ($user->isEmpty()) {
|
||||
throw new LucentException("User not found");
|
||||
}
|
||||
|
||||
$newUser = $user->get();
|
||||
$newUser->roles = $this->validateRoles($roles);
|
||||
$newUser->updatedAt = Carbon::now()->toJson();
|
||||
$this->userRepo->update($newUser);
|
||||
}
|
||||
public function changeRoles(string $userId, array $roles): void;
|
||||
|
||||
/**
|
||||
* @throws LucentException
|
||||
*/
|
||||
public
|
||||
function updateName(string $name): void
|
||||
{
|
||||
$name = (new Name($name));
|
||||
$this->userRepo->updateName($this->currentUserId(), $name);
|
||||
$user = $this->userRepo->findById($this->currentUserId());
|
||||
$this->session->put(["user" => $user->get()->safe()]);
|
||||
}
|
||||
public function updateName(string $name): void;
|
||||
|
||||
/**
|
||||
* @throws LucentException
|
||||
*/
|
||||
public
|
||||
function updateEmail(string $email): void
|
||||
{
|
||||
$email = (new Email($email));
|
||||
$user = $this->userRepo->findByEmail($email);
|
||||
if ($user->isDefined()) {
|
||||
throw new LucentException("Email already assigned to user");
|
||||
}
|
||||
|
||||
$this->userRepo->updateEmail($this->currentUserId(), $email);
|
||||
$user = $this->userRepo->findById($this->currentUserId());
|
||||
$this->session->put(["user" => $user->get()->safe()]);
|
||||
}
|
||||
|
||||
public function updateEmail(string $email): void;
|
||||
|
||||
/**
|
||||
* @throws LucentException
|
||||
*/
|
||||
public
|
||||
function invite(
|
||||
string $name,
|
||||
string $email,
|
||||
array $roles
|
||||
): User
|
||||
{
|
||||
$user = $this->create($name, $email, $roles);
|
||||
$this->sendLoginEmail($user->email);
|
||||
return $user;
|
||||
}
|
||||
public function invite(string $name, string $email, array $roles): User;
|
||||
|
||||
/**
|
||||
* @throws LucentException
|
||||
*/
|
||||
public
|
||||
function registerAdmin(
|
||||
string $name,
|
||||
string $email
|
||||
): User
|
||||
{
|
||||
$user = $this->invite($name, $email, ["admin"]);
|
||||
$this->sendLoginEmail($user->email);
|
||||
return $user;
|
||||
}
|
||||
|
||||
public
|
||||
function validateRoles(array $roles): array
|
||||
{
|
||||
return collect($roles)
|
||||
->filter(fn(string $role) => in_array($role, $this->channelService->channel->roles))
|
||||
->unique()
|
||||
->values()
|
||||
->toArray();
|
||||
}
|
||||
|
||||
public function registerAdmin(string $name, string $email): User;
|
||||
|
||||
public function validateRoles(array $roles): array;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,224 @@
|
||||
<?php
|
||||
|
||||
namespace Lucent\Account;
|
||||
|
||||
use Carbon\Carbon;
|
||||
use Illuminate\Contracts\Session\Session;
|
||||
use Illuminate\Support\Facades\Mail;
|
||||
use Illuminate\Support\Str;
|
||||
use Lucent\Channel\ChannelService;
|
||||
use Lucent\LucentException;
|
||||
use Lucent\Mail\LoginMail;
|
||||
use Filament\Facades\Filament;
|
||||
|
||||
readonly class AuthServiceLucent implements AuthService
|
||||
{
|
||||
public function __construct(
|
||||
private ChannelService $channelService,
|
||||
private UserRepo $userRepo,
|
||||
public Session $session,
|
||||
) {}
|
||||
|
||||
public function currentUserId(): ?string
|
||||
{
|
||||
if (app()->runningInConsole()) {
|
||||
return config("lucent.systemUserId");
|
||||
} elseif (request()->segment(1) !== "lucent") {
|
||||
return config("lucent.systemUserId");
|
||||
}
|
||||
return $this->session->get("user.id");
|
||||
}
|
||||
|
||||
public function currentUserRoles(): array
|
||||
{
|
||||
return $this->session->get("user.roles") ?? [];
|
||||
}
|
||||
|
||||
public function getCurrentUser(): User
|
||||
{
|
||||
return new User(
|
||||
id: $this->session->get("user.id"),
|
||||
name: new Name($this->session->get("user.name")),
|
||||
email: new Email($this->session->get("user.email")),
|
||||
roles: $this->session->get("user.roles"),
|
||||
createdAt: $this->session->get("user.createdAt"),
|
||||
updatedAt: $this->session->get("user.updatedAt"),
|
||||
loggedInAt: null,
|
||||
mailToken: null,
|
||||
);
|
||||
}
|
||||
|
||||
public function isLoggedIn(): bool
|
||||
{
|
||||
return !empty($this->currentUserId());
|
||||
}
|
||||
|
||||
/**
|
||||
* @throws LucentException
|
||||
*/
|
||||
public function login(string $email, string $token): void
|
||||
{
|
||||
$user = $this->userRepo->findByEmail(new Email($email));
|
||||
|
||||
if ($user->isEmpty()) {
|
||||
throw new LucentException("Your account was not found");
|
||||
}
|
||||
|
||||
if ($user->get()->isRemoved()) {
|
||||
throw new LucentException("Your account is not active");
|
||||
}
|
||||
|
||||
if ($user->get()->mailToken !== $token) {
|
||||
throw new LucentException("Token has expired or is invalid");
|
||||
}
|
||||
|
||||
if (
|
||||
Carbon::parse($user->get()->loggedInAt)->lte(
|
||||
Carbon::now()->subHours(1),
|
||||
)
|
||||
) {
|
||||
throw new LucentException("Token has expired.");
|
||||
}
|
||||
|
||||
$newUser = $user->get();
|
||||
$newUser->updatedAt = Carbon::now()->toJson();
|
||||
$newUser->mailToken = null;
|
||||
$this->userRepo->update($newUser);
|
||||
$this->session->put(["user" => $user->get()->safe()]);
|
||||
}
|
||||
|
||||
public function refreshSession()
|
||||
{
|
||||
$user = $this->userRepo->findById($this->currentUserId());
|
||||
|
||||
if ($user->isEmpty()) {
|
||||
throw new LucentException("Your account was not found");
|
||||
}
|
||||
|
||||
if ($user->get()->isRemoved()) {
|
||||
throw new LucentException("Your account is not active");
|
||||
}
|
||||
|
||||
$newUser = $user->get();
|
||||
$this->session->put(["user" => $user->get()->safe()]);
|
||||
}
|
||||
|
||||
public function create(string $name, string $email, array $roles): User
|
||||
{
|
||||
$user = new User(
|
||||
id: (string) Str::uuid(),
|
||||
name: new Name($name),
|
||||
email: new Email($email),
|
||||
roles: $this->validateRoles($roles),
|
||||
createdAt: Carbon::now()->toJson(),
|
||||
updatedAt: Carbon::now()->toJson(),
|
||||
loggedInAt: Carbon::now()->toJson(),
|
||||
mailToken: Token::new(32),
|
||||
);
|
||||
|
||||
$this->userRepo->insert($user);
|
||||
return $user;
|
||||
}
|
||||
|
||||
public function sendLoginEmail(string $email): void
|
||||
{
|
||||
$emailAddress = new Email($email);
|
||||
$user = $this->userRepo->findByEmail($emailAddress);
|
||||
|
||||
if ($user->isEmpty()) {
|
||||
return;
|
||||
}
|
||||
|
||||
if ($user->get()->isRemoved()) {
|
||||
return;
|
||||
}
|
||||
|
||||
$newToken = $this->userRepo->updateLoginToken($user->get()->id);
|
||||
|
||||
Mail::to($email)->send(
|
||||
new LoginMail(
|
||||
$email,
|
||||
$newToken,
|
||||
$this->channelService->channel->lucentUrl,
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @throws LucentException
|
||||
*/
|
||||
public function changeRoles(string $userId, array $roles): void
|
||||
{
|
||||
$user = $this->userRepo->findById($userId);
|
||||
|
||||
if ($user->isEmpty()) {
|
||||
throw new LucentException("User not found");
|
||||
}
|
||||
|
||||
$newUser = $user->get();
|
||||
$newUser->roles = $this->validateRoles($roles);
|
||||
$newUser->updatedAt = Carbon::now()->toJson();
|
||||
$this->userRepo->update($newUser);
|
||||
}
|
||||
|
||||
/**
|
||||
* @throws LucentException
|
||||
*/
|
||||
public function updateName(string $name): void
|
||||
{
|
||||
$name = new Name($name);
|
||||
$this->userRepo->updateName($this->currentUserId(), $name);
|
||||
$user = $this->userRepo->findById($this->currentUserId());
|
||||
$this->session->put(["user" => $user->get()->safe()]);
|
||||
}
|
||||
|
||||
/**
|
||||
* @throws LucentException
|
||||
*/
|
||||
public function updateEmail(string $email): void
|
||||
{
|
||||
$email = new Email($email);
|
||||
$user = $this->userRepo->findByEmail($email);
|
||||
if ($user->isDefined()) {
|
||||
throw new LucentException("Email already assigned to user");
|
||||
}
|
||||
|
||||
$this->userRepo->updateEmail($this->currentUserId(), $email);
|
||||
$user = $this->userRepo->findById($this->currentUserId());
|
||||
$this->session->put(["user" => $user->get()->safe()]);
|
||||
}
|
||||
|
||||
/**
|
||||
* @throws LucentException
|
||||
*/
|
||||
public function invite(string $name, string $email, array $roles): User
|
||||
{
|
||||
$user = $this->create($name, $email, $roles);
|
||||
$this->sendLoginEmail($user->email);
|
||||
return $user;
|
||||
}
|
||||
|
||||
/**
|
||||
* @throws LucentException
|
||||
*/
|
||||
public function registerAdmin(string $name, string $email): User
|
||||
{
|
||||
$user = $this->invite($name, $email, ["admin"]);
|
||||
$this->sendLoginEmail($user->email);
|
||||
return $user;
|
||||
}
|
||||
|
||||
public function validateRoles(array $roles): array
|
||||
{
|
||||
return collect($roles)
|
||||
->filter(
|
||||
fn(string $role) => in_array(
|
||||
$role,
|
||||
$this->channelService->channel->roles,
|
||||
),
|
||||
)
|
||||
->unique()
|
||||
->values()
|
||||
->toArray();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,104 @@
|
||||
<?php
|
||||
|
||||
namespace Lucent\Account;
|
||||
|
||||
use Illuminate\Contracts\Session\Session;
|
||||
use Lucent\Channel\ChannelService;
|
||||
use Lucent\LucentException;
|
||||
use Filament\Facades\Filament;
|
||||
|
||||
readonly class AuthServiceLunar implements AuthService
|
||||
{
|
||||
public function __construct(
|
||||
private ChannelService $channelService,
|
||||
private UserRepo $userRepo,
|
||||
public Session $session,
|
||||
) {}
|
||||
|
||||
public function currentUserId(): ?string
|
||||
{
|
||||
if (app()->runningInConsole()) {
|
||||
return config("lucent.systemUserId");
|
||||
} elseif (request()->segment(1) !== "lucent") {
|
||||
return config("lucent.systemUserId");
|
||||
}
|
||||
return Filament::auth()->user()->id;
|
||||
}
|
||||
public function getCurrentUser(): User
|
||||
{
|
||||
return new User(
|
||||
id: Filament::auth()->user()->id,
|
||||
name: new Name(
|
||||
Filament::auth()->user()->first_name .
|
||||
" " .
|
||||
Filament::auth()->user()->last_name,
|
||||
),
|
||||
email: new Email(Filament::auth()->user()->email),
|
||||
roles: [],
|
||||
createdAt: Filament::auth()->user()->created_at,
|
||||
updatedAt: Filament::auth()->user()->updated_at,
|
||||
loggedInAt: null,
|
||||
mailToken: null,
|
||||
);
|
||||
}
|
||||
|
||||
public function currentUserRoles(): array
|
||||
{
|
||||
return [];
|
||||
}
|
||||
|
||||
public function isLoggedIn(): bool
|
||||
{
|
||||
return !empty($this->currentUserId());
|
||||
}
|
||||
|
||||
/**
|
||||
* @throws LucentException
|
||||
*/
|
||||
public function login(string $email, string $token): void {}
|
||||
|
||||
public function refreshSession() {}
|
||||
|
||||
public function create(string $name, string $email, array $roles): User {}
|
||||
|
||||
public function sendLoginEmail(string $email): void {}
|
||||
|
||||
/**
|
||||
* @throws LucentException
|
||||
*/
|
||||
public function changeRoles(string $userId, array $roles): void {}
|
||||
|
||||
/**
|
||||
* @throws LucentException
|
||||
*/
|
||||
public function updateName(string $name): void {}
|
||||
|
||||
/**
|
||||
* @throws LucentException
|
||||
*/
|
||||
public function updateEmail(string $email): void {}
|
||||
|
||||
/**
|
||||
* @throws LucentException
|
||||
*/
|
||||
public function invite(string $name, string $email, array $roles): User {}
|
||||
|
||||
/**
|
||||
* @throws LucentException
|
||||
*/
|
||||
public function registerAdmin(string $name, string $email): User {}
|
||||
|
||||
public function validateRoles(array $roles): array
|
||||
{
|
||||
return collect($roles)
|
||||
->filter(
|
||||
fn(string $role) => in_array(
|
||||
$role,
|
||||
$this->channelService->channel->roles,
|
||||
),
|
||||
)
|
||||
->unique()
|
||||
->values()
|
||||
->toArray();
|
||||
}
|
||||
}
|
||||
+11
-85
@@ -2,111 +2,37 @@
|
||||
|
||||
namespace Lucent\Account;
|
||||
|
||||
use Carbon\Carbon;
|
||||
use Lucent\Database\Database;
|
||||
use Lucent\Primitive\Collection;
|
||||
use PhpOption\Option;
|
||||
|
||||
class UserRepo
|
||||
interface UserRepo
|
||||
{
|
||||
|
||||
public function count(): int
|
||||
{
|
||||
return Database::make()->table("users")->count();
|
||||
}
|
||||
public function count(): int;
|
||||
|
||||
/**
|
||||
* @return Collection<User>
|
||||
*/
|
||||
public function all(): Collection
|
||||
{
|
||||
$usersData = Database::make()->table("users")->get();
|
||||
public function all(): Collection;
|
||||
|
||||
$users = array_map(fn($userData) => $this->fromArray((array)$userData), $usersData->toArray());
|
||||
return new Collection($users);
|
||||
}
|
||||
public static function insert(User $user): void;
|
||||
|
||||
public function update(User $user): void;
|
||||
|
||||
public static function insert(User $user): void
|
||||
{
|
||||
$userData = toArray($user);
|
||||
$userData["roles"] = json_encode($userData["roles"]);
|
||||
Database::make()->table("users")->insert($userData);
|
||||
}
|
||||
|
||||
public function update(User $user): void
|
||||
{
|
||||
$userData = toArray($user);
|
||||
$userData["roles"] = json_encode($userData["roles"]);
|
||||
Database::make()->table("users")->where("id", $user->id)->update($userData);
|
||||
}
|
||||
|
||||
|
||||
public function updateLoginToken(string $id): string
|
||||
{
|
||||
$newToken = Token::new(32);
|
||||
|
||||
Database::make()->table("users")
|
||||
->where("id", $id)
|
||||
->update([
|
||||
'loggedInAt' => Carbon::now()->toJson(),
|
||||
'mailToken' => $newToken,
|
||||
]);
|
||||
|
||||
return $newToken;
|
||||
}
|
||||
|
||||
public function updateLoginToken(string $id): string;
|
||||
|
||||
/**
|
||||
* @return Option<User>
|
||||
*/
|
||||
public function findByEmail(Email $email): Option
|
||||
{
|
||||
$user = Database::make()->table("users")->where("email", $email->value())->first();
|
||||
|
||||
if (empty($user)) {
|
||||
return none();
|
||||
}
|
||||
|
||||
return some($this->fromArray((array)$user));
|
||||
}
|
||||
public function findByEmail(Email $email): Option;
|
||||
|
||||
/**
|
||||
* @return Option<User>
|
||||
*/
|
||||
public function findById(string $id): Option
|
||||
{
|
||||
$user = Database::make()->table("users")->where("id", $id)->first();
|
||||
public function findById(string $id): Option;
|
||||
|
||||
if (empty($user)) {
|
||||
return none();
|
||||
}
|
||||
public function updateName(string $userId, Name $name): void;
|
||||
|
||||
return some($this->fromArray((array)$user));
|
||||
}
|
||||
public function updateEmail(string $userId, Email $email): void;
|
||||
|
||||
|
||||
public function updateName(string $userId, Name $name): void
|
||||
{
|
||||
Database::make()->table("users")->where("id", $userId)->update(["name" => $name->value]);
|
||||
}
|
||||
|
||||
public function updateEmail(string $userId, Email $email): void
|
||||
{
|
||||
Database::make()->table("users")->where("id", $userId)->update(["email" => $email->value()]);
|
||||
}
|
||||
|
||||
public function fromArray(array $data): User
|
||||
{
|
||||
return new User(
|
||||
id: $data["id"],
|
||||
name: new Name($data["name"] ?? ""),
|
||||
email: new Email($data["email"]),
|
||||
roles: json_decode($data["roles"] ?? "[]", true),
|
||||
createdAt: $data["createdAt"],
|
||||
updatedAt: $data["updatedAt"],
|
||||
loggedInAt: $data["loggedInAt"] ?? null,
|
||||
mailToken: $data["mailToken"] ?? null,
|
||||
);
|
||||
}
|
||||
public function fromArray(array $data): User;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,128 @@
|
||||
<?php
|
||||
|
||||
namespace Lucent\Account;
|
||||
|
||||
use Carbon\Carbon;
|
||||
use Lucent\Database\Database;
|
||||
use Lucent\Primitive\Collection;
|
||||
use PhpOption\Option;
|
||||
|
||||
class UserRepoLucent implements UserRepo
|
||||
{
|
||||
private $tableName = "lucent_users";
|
||||
|
||||
public function count(): int
|
||||
{
|
||||
return Database::make()->table($this->tableName)->count();
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Collection<User>
|
||||
*/
|
||||
public function all(): Collection
|
||||
{
|
||||
$usersData = Database::make()->table($this->tableName)->get();
|
||||
|
||||
$users = array_map(
|
||||
fn($userData) => $this->fromArray((array) $userData),
|
||||
$usersData->toArray(),
|
||||
);
|
||||
return new Collection($users);
|
||||
}
|
||||
|
||||
public static function insert(User $user): void
|
||||
{
|
||||
$userData = toArray($user);
|
||||
$userData["roles"] = json_encode($userData["roles"]);
|
||||
Database::make()->table($this->tableName)->insert($userData);
|
||||
}
|
||||
|
||||
public function update(User $user): void
|
||||
{
|
||||
$userData = toArray($user);
|
||||
$userData["roles"] = json_encode($userData["roles"]);
|
||||
Database::make()
|
||||
->table($this->tableName)
|
||||
->where("id", $user->id)
|
||||
->update($userData);
|
||||
}
|
||||
|
||||
public function updateLoginToken(string $id): string
|
||||
{
|
||||
$newToken = Token::new(32);
|
||||
|
||||
Database::make()
|
||||
->table($this->tableName)
|
||||
->where("id", $id)
|
||||
->update([
|
||||
"loggedInAt" => Carbon::now()->toJson(),
|
||||
"mailToken" => $newToken,
|
||||
]);
|
||||
|
||||
return $newToken;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Option<User>
|
||||
*/
|
||||
public function findByEmail(Email $email): Option
|
||||
{
|
||||
$user = Database::make()
|
||||
->table($this->tableName)
|
||||
->where("email", $email->value())
|
||||
->first();
|
||||
|
||||
if (empty($user)) {
|
||||
return none();
|
||||
}
|
||||
|
||||
return some($this->fromArray((array) $user));
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Option<User>
|
||||
*/
|
||||
public function findById(string $id): Option
|
||||
{
|
||||
$user = Database::make()
|
||||
->table($this->tableName)
|
||||
->where("id", $id)
|
||||
->first();
|
||||
|
||||
if (empty($user)) {
|
||||
return none();
|
||||
}
|
||||
|
||||
return some($this->fromArray((array) $user));
|
||||
}
|
||||
|
||||
public function updateName(string $userId, Name $name): void
|
||||
{
|
||||
Database::make()
|
||||
->table($this->tableName)
|
||||
->where("id", $userId)
|
||||
->update(["name" => $name->value]);
|
||||
}
|
||||
|
||||
public function updateEmail(string $userId, Email $email): void
|
||||
{
|
||||
Database::make()
|
||||
->table($this->tableName)
|
||||
->where("id", $userId)
|
||||
->update(["email" => $email->value()]);
|
||||
}
|
||||
|
||||
public function fromArray(array $data): User
|
||||
{
|
||||
return new User(
|
||||
id: $data["id"],
|
||||
name: new Name($data["name"] ?? ""),
|
||||
email: new Email($data["email"]),
|
||||
roles: json_decode($data["roles"] ?? "[]", true),
|
||||
createdAt: $data["createdAt"],
|
||||
updatedAt: $data["updatedAt"],
|
||||
loggedInAt: $data["loggedInAt"] ?? null,
|
||||
mailToken: $data["mailToken"] ?? null,
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,130 @@
|
||||
<?php
|
||||
|
||||
namespace Lucent\Account;
|
||||
|
||||
use Carbon\Carbon;
|
||||
use Lucent\Database\Database;
|
||||
use Lucent\Primitive\Collection;
|
||||
use PhpOption\Option;
|
||||
|
||||
class UserRepoLunar implements UserRepo
|
||||
{
|
||||
private $tableName = "lunar_staff";
|
||||
|
||||
public function count(): int
|
||||
{
|
||||
return Database::make()->table($this->tableName)->count();
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Collection<User>
|
||||
*/
|
||||
public function all(): Collection
|
||||
{
|
||||
$usersData = Database::make()->table($this->tableName)->get();
|
||||
|
||||
$users = array_map(
|
||||
fn($userData) => $this->fromArray((array) $userData),
|
||||
$usersData->toArray(),
|
||||
);
|
||||
return new Collection($users);
|
||||
}
|
||||
|
||||
public static function insert(User $user): void
|
||||
{
|
||||
$userData = toArray($user);
|
||||
$userData["roles"] = json_encode($userData["roles"]);
|
||||
Database::make()->table($this->tableName)->insert($userData);
|
||||
}
|
||||
|
||||
public function update(User $user): void
|
||||
{
|
||||
$userData = toArray($user);
|
||||
$userData["roles"] = json_encode($userData["roles"]);
|
||||
Database::make()
|
||||
->table($this->tableName)
|
||||
->where("id", $user->id)
|
||||
->update($userData);
|
||||
}
|
||||
|
||||
public function updateLoginToken(string $id): string
|
||||
{
|
||||
$newToken = Token::new(32);
|
||||
|
||||
Database::make()
|
||||
->table($this->tableName)
|
||||
->where("id", $id)
|
||||
->update([
|
||||
"loggedInAt" => Carbon::now()->toJson(),
|
||||
"mailToken" => $newToken,
|
||||
]);
|
||||
|
||||
return $newToken;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Option<User>
|
||||
*/
|
||||
public function findByEmail(Email $email): Option
|
||||
{
|
||||
$user = Database::make()
|
||||
->table($this->tableName)
|
||||
->where("email", $email->value())
|
||||
->first();
|
||||
|
||||
if (empty($user)) {
|
||||
return none();
|
||||
}
|
||||
|
||||
return some($this->fromArray((array) $user));
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Option<User>
|
||||
*/
|
||||
public function findById(string $id): Option
|
||||
{
|
||||
$user = Database::make()
|
||||
->table($this->tableName)
|
||||
->where("id", $id)
|
||||
->first();
|
||||
|
||||
if (empty($user)) {
|
||||
return none();
|
||||
}
|
||||
|
||||
return some($this->fromArray((array) $user));
|
||||
}
|
||||
|
||||
public function updateName(string $userId, Name $name): void
|
||||
{
|
||||
Database::make()
|
||||
->table($this->tableName)
|
||||
->where("id", $userId)
|
||||
->update(["name" => $name->value]);
|
||||
}
|
||||
|
||||
public function updateEmail(string $userId, Email $email): void
|
||||
{
|
||||
Database::make()
|
||||
->table($this->tableName)
|
||||
->where("id", $userId)
|
||||
->update(["email" => $email->value()]);
|
||||
}
|
||||
|
||||
public function fromArray(array $data): User
|
||||
{
|
||||
return new User(
|
||||
id: $data["id"],
|
||||
name: new Name(
|
||||
$data["first_name"] . " " . $data["last_name"] ?? "",
|
||||
),
|
||||
email: new Email($data["email"]),
|
||||
roles: [],
|
||||
createdAt: $data["created_at"],
|
||||
updatedAt: $data["updated_at"],
|
||||
loggedInAt: null,
|
||||
mailToken: null,
|
||||
);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user