aboutsummaryrefslogtreecommitdiffhomepage
path: root/Digitigrade
diff options
context:
space:
mode:
Diffstat (limited to 'Digitigrade')
-rw-r--r--Digitigrade/HttpResponseStatus/TemporaryRedirect.php9
-rw-r--r--Digitigrade/Model/Session.php43
-rw-r--r--Digitigrade/Model/UserAccount.php52
3 files changed, 103 insertions, 1 deletions
diff --git a/Digitigrade/HttpResponseStatus/TemporaryRedirect.php b/Digitigrade/HttpResponseStatus/TemporaryRedirect.php
index fbf0def..4c9a794 100644
--- a/Digitigrade/HttpResponseStatus/TemporaryRedirect.php
+++ b/Digitigrade/HttpResponseStatus/TemporaryRedirect.php
@@ -12,6 +12,9 @@ class TemporaryRedirect extends \Exception implements HttpResponseStatus {
}
public function httpCode(): int {
+ if (isset($_SERVER['HTTP_HX_REQUEST'])) {
+ return 200;
+ }
return 302;
}
@@ -20,6 +23,10 @@ class TemporaryRedirect extends \Exception implements HttpResponseStatus {
}
public function httpHeaders() {
- header("Location: $this->target");
+ if (isset($_SERVER['HTTP_HX_REQUEST'])) {
+ header("HX-Location: $this->target");
+ } else {
+ header("Location: $this->target");
+ }
}
} \ No newline at end of file
diff --git a/Digitigrade/Model/Session.php b/Digitigrade/Model/Session.php
new file mode 100644
index 0000000..31fb8bb
--- /dev/null
+++ b/Digitigrade/Model/Session.php
@@ -0,0 +1,43 @@
+<?php
+namespace Digitigrade\Model;
+
+use Digitigrade\GlobalConfig;
+use Digitigrade\Model;
+
+class Session extends Model {
+ public string $token;
+ public UserAccount $userAccount;
+
+ public static function create(UserAccount $user): self {
+ $session = new self();
+ $session->userAccount = $user;
+ $session->token = random_printable_bytes();
+ $session->save();
+ return $session;
+ }
+
+ protected function getUpdateWhereClause(\PDO $db): ?string {
+ if (self::findByToken($this->token) != null) {
+ return 'token = ' . $db->quote($this->token);
+ }
+ return null;
+ }
+
+ public static function findByToken(#[\SensitiveParameter] string $token): ?self {
+ return self::findWhere('token = ?', [$token]);
+ }
+
+ public static function findAllByAccount(UserAccount $userAccount): array {
+ return self::findAllWhere('user_account = ?', [$userAccount->id]);
+ }
+
+ public function setCookie(bool $rememberSession) {
+ setcookie('digitigrade-session', $this->token, [
+ 'expires' => $rememberSession ? (new \DateTimeImmutable('1 year'))->getTimestamp() : null,
+ 'httponly' => true,
+ 'samesite' => 'Lax',
+ 'path' => '/',
+ 'secure' => GlobalConfig::getInstance()->isHttps()
+ ]);
+ }
+} \ No newline at end of file
diff --git a/Digitigrade/Model/UserAccount.php b/Digitigrade/Model/UserAccount.php
new file mode 100644
index 0000000..3d0e2a4
--- /dev/null
+++ b/Digitigrade/Model/UserAccount.php
@@ -0,0 +1,52 @@
+<?php
+namespace Digitigrade\Model;
+
+use Digitigrade\Model;
+
+class UserAccount extends Model {
+ public ?int $id;
+ public string $email;
+ public string $passwordHash;
+ public ?Actor $actor;
+ public bool $banned = false;
+
+ public static function create(string $email, #[\SensitiveParameter] string $password): self {
+ $user = new self();
+ $user->email = $email;
+ $user->passwordHash = defaults_password_hash($password);
+ $user->actor = null;
+ $user->save();
+ return $user;
+ }
+
+ public function createLinkedActor(string $handle) {
+ $this->actor = Actor::create($handle);
+ $this->save();
+ }
+
+ protected function getUpdateWhereClause(\PDO $db): ?string {
+ if (isset($this->id) && self::find($this->{'id'}) != null) {
+ return 'id = ' . $this->{'id'};
+ }
+ if (self::findByEmail($this->email) != null) {
+ return 'email = ' . $db->quote($this->email);
+ }
+ return null;
+ }
+
+ public static function findByEmail(string $email): ?self {
+ return self::findWhere('email = ?', [$email]);
+ }
+
+ public static function findByCurrentSession(): ?self {
+ if (!isset($_COOKIE['digitigrade-session'])) {
+ return null;
+ }
+ $token = $_COOKIE['digitigrade-session'];
+ return Session::findByToken($token)?->userAccount;
+ }
+
+ public function verifyPassword(#[\SensitiveParameter] $attemptedPassword): bool {
+ return password_verify($attemptedPassword, $this->passwordHash);
+ }
+} \ No newline at end of file