Add last seen and user title fields to users table.

This commit is contained in:
flash 2018-04-17 23:01:49 +02:00
parent a9d1105669
commit 4965ef8700
6 changed files with 120 additions and 10 deletions

View file

@ -0,0 +1,39 @@
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Misuzu\Database;
// phpcs:disable
class AddLastSeenAndUserTitle extends Migration
{
/**
* @SuppressWarnings(PHPMD)
*/
public function up()
{
$schema = Database::connection()->getSchemaBuilder();
$schema->table('users', function (Blueprint $table) {
$table->string('user_title', 64)
->nullable()
->default(null);
$table->timestamp('last_seen')
->nullable()
->default(null);
});
}
/**
* @SuppressWarnings(PHPMD)
*/
public function down()
{
$schema = Database::connection()->getSchemaBuilder();
$schema->table('users', function (Blueprint $table) {
$table->dropColumn([
'user_title',
'last_seen',
]);
});
}
}

View file

@ -31,6 +31,13 @@ if (PHP_SAPI !== 'cli') {
if (isset($_COOKIE['msz_uid'], $_COOKIE['msz_sid'])) {
$app->startSession((int)$_COOKIE['msz_uid'], $_COOKIE['msz_sid']);
$session = $app->getSession();
if ($session !== null) {
$session->user->last_seen = \Carbon\Carbon::now();
$session->user->last_ip = \Misuzu\Net\IPAddress::remote();
$session->user->save();
}
}
$manage_mode = starts_with($_SERVER['REQUEST_URI'], '/manage');
@ -39,7 +46,7 @@ if (PHP_SAPI !== 'cli') {
$app->templating->addPath('mio', __DIR__ . '/views/mio');
if ($manage_mode) {
if (Application::getInstance()->getSession() === null || $_SERVER['HTTP_HOST'] !== 'misuzu.misaka.nl') {
if ($app->getSession() === null || $_SERVER['HTTP_HOST'] !== 'misuzu.misaka.nl') {
http_response_code(403);
echo $app->templating->render('errors.403');
exit;

View file

@ -103,18 +103,18 @@ switch ($mode) {
$session = Session::createSession($user, $user_agent, null, $ipAddress);
$app->setSession($session);
set_cookie_m('uid', $session->user_id, 604800);
set_cookie_m('sid', $session->session_key, 604800);
$cookie_life = Carbon::now()->addMonth()->timestamp;
set_cookie_m('uid', $session->user_id, $cookie_life);
set_cookie_m('sid', $session->session_key, $cookie_life);
// Temporary key generation for chat login.
// Should eventually be replaced with a callback login system.
// Also uses different cookies since $httponly is required to be false for these.
$user->last_ip = $ipAddress;
$user->user_chat_key = bin2hex(random_bytes(16));
$user->save();
setcookie('msz_tmp_id', $user->user_id, time() + 604800, '/', '.flashii.net');
setcookie('msz_tmp_key', $user->user_chat_key, time() + 604800, '/', '.flashii.net');
setcookie('msz_tmp_id', $user->user_id, $cookie_life, '/', '.flashii.net');
setcookie('msz_tmp_key', $user->user_chat_key, $cookie_life, '/', '.flashii.net');
header('Location: /');
return;
}

View file

@ -1,6 +1,7 @@
<?php
namespace Misuzu\Users;
use Carbon\Carbon;
use Illuminate\Database\Eloquent\SoftDeletes;
use Misuzu\Colour;
use Misuzu\Database;
@ -20,6 +21,8 @@ class User extends Model
protected $primaryKey = 'user_id';
private $displayRoleValidated = false;
private $displayRoleInstance;
private $userTitleValue;
public static function createUser(
string $username,
@ -110,12 +113,46 @@ class User extends Model
return '';
}
// it's probably safe to assume that this will always return a valid role
public function getDisplayRole(): ?Role
{
if ($this->displayRoleInstance === null) {
$this->displayRoleInstance = Role::find($this->display_role);
}
return $this->displayRoleInstance;
}
public function getDisplayColour(): Colour
{
$role = Role::find($this->display_role);
$role = $this->getDisplayRole();
return $role === null ? Colour::none() : $role->role_colour;
}
private function getUserTitlePrivate(): string
{
if (!empty($this->user_title)) {
return $this->user_title;
}
$role = $this->getDisplayRole();
if ($role !== null && !empty($role->role_title)) {
return $role->role_title;
}
return '';
}
public function getUserTitle(): string
{
if (empty($this->userTitleValue)) {
$this->userTitleValue = $this->getUserTitlePrivate();
}
return $this->userTitleValue;
}
public function addRole(Role $role, bool $setDisplay = false): void
{
$relation = new UserRole;
@ -159,11 +196,12 @@ class User extends Model
public function getDisplayRoleAttribute(?int $value): int
{
if (!$this->displayRoleValidated) {
if ($value === null || UserRole::where('user_id', $this->user_id)->where('role_id', $value)->count() > 0) {
if ($value === null
|| UserRole::where('user_id', $this->user_id)->where('role_id', $value)->count() < 1) {
$highestRole = Database::table('roles')
->join('user_roles', 'roles.role_id', '=', 'user_roles.role_id')
->where('user_id', $this->user_id)
->orderBy('roles.role_hierarchy')
->orderBy('roles.role_hierarchy', 'desc')
->first(['roles.role_id']);
$value = $highestRole->role_id;
@ -184,6 +222,11 @@ class User extends Model
}
}
public function getLastSeenAttribute(?string $dateTime): Carbon
{
return $dateTime === null ? Carbon::createFromTimestamp(-1) : new Carbon($dateTime);
}
public function getRegisterIpAttribute(string $ipAddress): IPAddress
{
return IPAddress::fromRaw($ipAddress);

View file

@ -30,7 +30,7 @@ function set_cookie_m(string $name, string $value, int $expires): void
setcookie(
"msz_{$name}",
$value,
time() + $expires,
$expires,
'/',
'',
!empty($_SERVER['HTTPS']),

View file

@ -71,6 +71,12 @@
<div class="profile__info">
<div class="profile__info__section">
<div class="profile__info__block">
<div class="profile__info__row">
<div class="profile__info__column profile__info__column--user-title">
{{ profile.userTitle }}
</div>
</div>
<div class="profile__info__row">
<div class="profile__info__column profile__info__column--icons">
<img class="profile__icon" src="https://static.flash.moe/flags/fff/{{ profile.user_country|lower }}.png" alt="{{ profile.user_country }}">
@ -90,6 +96,21 @@
{{ profile.created_at.diffForHumans }}
</div>
</div>
{% if profile.last_seen.timestamp > 0 %}
<div class="profile__info__row" title="{{ profile.last_seen.format('r') }}">
<div class="profile__info__column profile__info__column--heading">
Last Seen
</div>
<div class="profile__info__column">
{% if profile.last_seen.timestamp + 5 >= ''|date('U') %}
Online now
{% else %}
{{ profile.last_seen.diffForHumans }}
{% endif %}
</div>
</div>
{% endif %}
</div>
</div>