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: Carbon::parse($this->session->get("user.createdAt")), updatedAt: Carbon::parse($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(); $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(), updatedAt: Carbon::now(), loggedInAt: Carbon::now(), 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(); } }