Moved user asset serving out of profile.php.

This commit is contained in:
flash 2019-02-27 15:46:18 +01:00
parent 8cebfb6fae
commit 5fbad79c23
11 changed files with 108 additions and 117 deletions

View file

@ -203,7 +203,7 @@ function commentConstruct(comment: CommentPostInfo, layer: number = 0): HTMLElem
const commentAvatar: HTMLAnchorElement = commentContainer.appendChild(document.createElement('a'));
commentAvatar.className = 'avatar comment__avatar';
commentAvatar.href = '/profile.php?u=' + comment.user_id;
commentAvatar.style.backgroundImage = `url('/profile.php?m=avatar&u=${comment.user_id}')`;
commentAvatar.style.backgroundImage = `url('/user-assets.php?m=avatar&u=${comment.user_id}')`;
const commentContent: HTMLDivElement = commentContainer.appendChild(document.createElement('div'));
commentContent.className = 'comment__content';
@ -303,7 +303,7 @@ function commentConstruct(comment: CommentPostInfo, layer: number = 0): HTMLElem
// reply container
const replyAvatar: HTMLDivElement = replyContainer.appendChild(document.createElement('div'));
replyAvatar.className = 'avatar comment__avatar';
replyAvatar.style.backgroundImage = `url('/profile.php?m=avatar&u=${comment.user_id}')`;
replyAvatar.style.backgroundImage = `url('/user-assets.php?m=avatar&u=${comment.user_id}')`;
const replyContent: HTMLDivElement = replyContainer.appendChild(document.createElement('div'));
replyContent.className = 'comment__content';

View file

@ -74,7 +74,7 @@ function loginFormUpdateAvatar(avatarElement: HTMLElement, usernameElement: HTML
if (xhr.readyState !== 4)
return;
avatarElement.style.backgroundImage = `url('/profile.php?m=avatar&u=${xhr.responseText}')`;
avatarElement.style.backgroundImage = `url('/user-assets.php?m=avatar&u=${xhr.responseText}')`;
});
xhr.open('GET', `/auth.php?m=get_user&u=${encodeURI(usernameElement.value)}`);
xhr.send();
@ -162,7 +162,7 @@ function loginModal(): boolean {
const authAvatar: HTMLDivElement = titleHeader.appendChild(document.createElement('div'));
authAvatar.className = 'avatar auth__avatar';
authAvatar.style.backgroundImage = "url('/profile.php?u=0&m=avatar')";
authAvatar.style.backgroundImage = "url('/user-assets.php?u=0&m=avatar')";
const hiddenMode: HTMLInputElement = container.appendChild(document.createElement('input'));
hiddenMode.type = 'hidden';

View file

@ -5,100 +5,6 @@ $misuzuBypassLockdown = $mode === 'avatar';
require_once '../misuzu.php';
switch ($mode) {
case 'avatar':
$userId = (int)($_GET['u'] ?? 0);
if (user_warning_check_expiration($userId, MSZ_WARN_BAN) > 0 && !(
parse_url($_SERVER['HTTP_REFERER'], PHP_URL_PATH) === '/profile.php'
&& perms_check(
perms_get_user(
MSZ_PERMS_USER,
user_session_current('user_id', 0)
),
MSZ_PERM_USER_MANAGE_USERS
)
)) {
$avatarFilename = config_get_default(MSZ_ROOT . '/public/images/banned-avatar.png', 'Avatar', 'banned_path');
} else {
$avatarFilename = config_get_default(MSZ_ROOT . '/public/images/no-avatar.png', 'Avatar', 'default_path');
$userAvatar = "{$userId}.msz";
$storageDir = MSZ_STORAGE . '/avatars/200x200';
$croppedAvatar = $storageDir . '/' . $userAvatar;
if (is_file($croppedAvatar)) {
$avatarFilename = $croppedAvatar;
} else {
$originalAvatar = MSZ_STORAGE . '/avatars/original/' . $userAvatar;
if (is_file($originalAvatar)) {
try {
mkdirs($storageDir, true);
file_put_contents(
$croppedAvatar,
crop_image_centred_path($originalAvatar, 200, 200)->getImagesBlob(),
LOCK_EX
);
$avatarFilename = $croppedAvatar;
} catch (Exception $ex) {
}
}
}
}
$fileTime = filemtime($avatarFilename);
$entityTag = "\"avatar-{$userId}-{$fileTime}\"";
if (!empty($_SERVER['HTTP_IF_NONE_MATCH']) && strtolower($_SERVER['HTTP_IF_NONE_MATCH']) === $entityTag) {
http_response_code(304);
break;
}
header('Content-Type: ' . mime_content_type($avatarFilename));
header("ETag: {$entityTag}");
echo file_get_contents($avatarFilename);
break;
case 'background':
$userId = (int)($_GET['u'] ?? 0);
if (user_warning_check_expiration($userId, MSZ_WARN_BAN) > 0 && !(
parse_url($_SERVER['HTTP_REFERER'], PHP_URL_PATH) === '/profile.php'
&& perms_check(
perms_get_user(
MSZ_PERMS_USER,
user_session_current('user_id', 0)
),
MSZ_PERM_USER_MANAGE_USERS
)
)) {
echo render_error(404);
break;
}
$storageDir = MSZ_STORAGE . '/backgrounds/original';
$userBackground = "{$storageDir}/{$userId}.msz";
mkdirs($storageDir, true);
if (!is_file($userBackground)) {
echo render_error(404);
break;
}
$fileTime = filemtime($userBackground);
$entityTag = "\"background-{$userId}-{$fileTime}\"";
if (!empty($_SERVER['HTTP_IF_NONE_MATCH']) && strtolower($_SERVER['HTTP_IF_NONE_MATCH']) === $entityTag) {
http_response_code(304);
break;
}
header('Content-Type: ' . mime_content_type($userBackground));
header("ETag: {$entityTag}");
echo file_get_contents($userBackground);
break;
case 'following':
$userId = (int)($_GET['u'] ?? 0);

87
public/user-assets.php Normal file
View file

@ -0,0 +1,87 @@
<?php
$userAssetsMode = (string)($_GET['m'] ?? null);
$misuzuBypassLockdown = $userAssetsMode === 'avatar';
require_once '../misuzu.php';
$userId = (int)($_GET['u'] ?? 0);
$userExists = user_exists($userId);
$fromProfile = parse_url($_SERVER['HTTP_REFERER'] ?? '', PHP_URL_PATH) === '/profile.php';
$canViewImages = !$userExists
|| !user_warning_check_expiration($userId, MSZ_WARN_BAN)
|| (
parse_url($_SERVER['HTTP_REFERER'] ?? '', PHP_URL_PATH) === '/profile.php'
&& perms_check(
perms_get_user(MSZ_PERMS_USER, user_session_current('user_id', 0)),
MSZ_PERM_USER_MANAGE_USERS
)
);
switch ($userAssetsMode) {
case 'avatar':
if (!$canViewImages) {
$filename = config_get_default(MSZ_ROOT . '/public/images/banned-avatar.png', 'Avatar', 'banned_path');
break;
}
$filename = config_get_default(MSZ_ROOT . '/public/images/no-avatar.png', 'Avatar', 'default_path');
if (!$userExists) {
break;
}
$dimensions = 200;
$avatarFilename = sprintf('%d.msz', $userId);
$avatarStorage = sprintf('%1$s/avatars/%2$dx%2$d', MSZ_STORAGE, $dimensions);
$avatarCropped = sprintf('%s/%s', $avatarStorage, $avatarFilename);
if (is_file($avatarCropped)) {
$filename = $avatarCropped;
} else {
$avatarOriginal = sprintf('%s/avatars/original/%s', MSZ_STORAGE, $avatarFilename);
if (is_file($avatarOriginal)) {
try {
mkdirs($avatarStorage, true);
file_put_contents(
$avatarCropped,
crop_image_centred_path($avatarOriginal, $dimensions, $dimensions)->getImagesBlob(),
LOCK_EX
);
$filename = $avatarCropped;
} catch (Exception $ex) {
}
}
}
break;
case 'background':
if (!$canViewImages && !$userExists) {
break;
}
$backgroundStorage = sprintf('%s/backgrounds/original', MSZ_STORAGE);
$filename = sprintf('%s/%d.msz', $backgroundStorage, $userId);
mkdirs($backgroundStorage, true);
break;
}
if (empty($filename) || !is_file($filename)) {
http_response_code(404);
return;
}
$entityTag = sprintf('W/"{%s-%d-%d}"', $userAssetsMode, $userId, filemtime($filename));
if (!empty($_SERVER['HTTP_IF_NONE_MATCH']) && $_SERVER['HTTP_IF_NONE_MATCH'] === $entityTag) {
http_response_code(304);
return;
}
http_response_code(200);
header(sprintf('Content-Type: %s', mime_content_type($filename)));
header(sprintf('ETag: %s', $entityTag));
echo file_get_contents($filename);

View file

@ -42,12 +42,10 @@ define('MSZ_URLS', [
'user-profile' => ['/profile.php', ['u' => '<user>']],
'user-profile-edit' => ['/profile.php', ['u' => '<user>', 'm' => 'edit']],
'user-avatar' => ['/profile.php', ['u' => '<user>', 'm' => 'avatar']],
'user-background' => ['/profile.php', ['u' => '<user>', 'm' => 'background']],
'user-avatar' => ['/user-assets.php', ['u' => '<user>', 'm' => 'avatar']],
'user-background' => ['/user-assets.php', ['u' => '<user>', 'm' => 'background']],
'user-account-standing' => ['/profile.php', ['u' => '<user>'], 'account-standing'],
'guest-avatar' => ['/profile.php', ['m' => 'avatar']],
'user-relation-none' => ['/relations.php', ['u' => '<user>', 'm' => '[MSZ_USER_RELATION_NONE]', 'c' => '{user_relation}']],
'user-relation-follow' => ['/relations.php', ['u' => '<user>', 'm' => '[MSZ_USER_RELATION_FOLLOW]', 'c' => '{user_relation}']],

View file

@ -15,7 +15,7 @@
<div class="comment__container">
<div class="avatar comment__avatar"
style="background-image:url('/profile.php?m=avatar&amp;u={{ user.user_id }}')">
style="background-image:url('{{ url('user-avatar', {'user':user.user_id}) }}')">
</div>
<div class="comment__content">
<textarea
@ -50,7 +50,7 @@
<div class="comment{% if is_deleted %} comment--deleted{% endif %}" id="comment-{{ comment.comment_id }}">
<div class="comment__container">
{% if hide_details %}
<div class="avatar comment__avatar" style="background-image:url('/profile.php?m=avatar')"></div>
<div class="avatar comment__avatar" style="background-image:url('{{ url('user-avatar') }}')"></div>
{% else %}
<a class="avatar comment__avatar"
href="{{ url('user-profile', {'user':comment.user_id}) }}"

View file

@ -46,7 +46,7 @@
? [
{
'title': 'Profile',
'url': '/profile.php?u=' ~ current_user.user_id,
'url': url('user-profile', {'user': current_user.user_id}),
'icon': 'fas fa-user fa-fw',
},
{
@ -128,7 +128,7 @@
style="background-image:url('{{ url('user-avatar', {'user': current_user.user_id}) }}');{{ current_user.user_colour|html_colour }}"></a>
{% else %}
<a href="{{ url('auth-login') }}" class="avatar header__desktop__user__avatar js-login-button"
style="background-image:url('{{ url('guest-avatar') }}');"></a>
style="background-image:url('{{ url('user-avatar') }}');"></a>
{% endif %}
</div>
</div>
@ -144,7 +144,7 @@
</a>
<label class="header__mobile__icon avatar header__mobile__avatar" for="toggle-mobile-header"
style="background-image:url('/profile.php?u={{ current_user.user_id|default(0) }}&amp;m=avatar');">
style="background-image:url('{{ url('user-avatar', {'user': current_user.user_id|default(0)}) }}');">
</label>
</div>

View file

@ -15,7 +15,7 @@
<div class="container__title">
<div class="container__title__background"></div>
<div class="auth__header">
<div class="avatar auth__avatar js-login-avatar" style="background-image:url('/profile.php?u=0&amp;m=avatar');"></div>
<div class="avatar auth__avatar js-login-avatar" style="background-image:url('{{ url('user-avatar') }}');"></div>
</div>
</div>

View file

@ -3,7 +3,7 @@
{% from 'manage/macros.twig' import permissions_table %}
{% from '_layout/input.twig' import input_csrf, input_text, input_checkbox, input_file, input_select, input_colour %}
{% set site_link = '/profile.php?u=' ~ manage_user.user_id %}
{% set site_link = url('user-profile', {'user': manage_user.user_id}) %}
{% block manage_content %}
<div class="manage__user"{% if manage_user is defined %} style="{{ manage_user.user_colour|html_colour('--accent-colour') }}"{% endif %}>

View file

@ -6,7 +6,7 @@
<div class="usercard__container">
<div class="usercard__main">
<div class="avatar usercard__avatar"
style="background-image:url('/profile.php?u={{ user.user_id }}&amp;m=avatar')">
style="background-image:url('{{ url('user-avatar', {'user': user.user_id}) }}')">
</div>
<div class="usercard__details">
@ -173,8 +173,8 @@
{% macro user_account_log(data, strings) %}
<div class="settings__account-log" id="account-log-{{ data.log_id }}">
{% if data.user_id is defined %}
<a href="/profile.php?u={{ data.user_id }}" class="settings__account-log__user" style="{{ data.user_colour|html_colour }}">
<div class="avatar settings__account-log__user__avatar" style="background-image:url('/profile.php?u={{ data.user_id }}&amp;m=avatar');"></div>
<a href="{{ url('user-profile', {'user': data.user_id}) }}" class="settings__account-log__user" style="{{ data.user_colour|html_colour }}">
<div class="avatar settings__account-log__user__avatar" style="background-image:url('{{ url('user-avatar', {'user': data.user_id}) }}');"></div>
<div class="settings__account-log__user__name">{{ data.username }}</div>
</a>
{% endif %}
@ -239,7 +239,7 @@
{% if warning.username is defined or warning.user_ip is defined %}
<div class="profile__warning__user">
{% if warning.username is defined %}
<div class="avatar profile__warning__user__avatar" style="background-image:url('/profile.php?m=avatar&amp;u={{ warning.user_id }}');"></div>
<div class="avatar profile__warning__user__avatar" style="background-image:url('{{ url('user-avatar', {'user': warning.user_id}) }}');"></div>
<div class="profile__warning__user__username">
{{ warning.username }}
</div>
@ -254,7 +254,7 @@
{% endif %}
<div class="profile__warning__user">
<div class="avatar profile__warning__user__avatar" style="background-image:url('/profile.php?m=avatar&amp;u={{ warning.issuer_id }}');"></div>
<div class="avatar profile__warning__user__avatar" style="background-image:url('{{ url('user-avatar', {'user': warning.issuer_id}) }}');"></div>
<div class="profile__warning__user__username">
{{ warning.issuer_username }}
</div>

View file

@ -3,8 +3,8 @@
{% from 'user/macros.twig' import user_profile_warning %}
{% from '_layout/input.twig' import input_hidden, input_csrf, input_text, input_checkbox, input_file, input_file_raw, input_select %}
{% set image = '/profile.php?u=' ~ profile.user_id ~ '&m=avatar' %}
{% set canonical_url = '/profile.php?u=' ~ profile.user_id %}
{% set image = url('user-avatar', {'user': profile.user_id}) %}
{% set canonical_url = url('user-profile', {'user': profile.user_id}) %}
{% set title = 'Profile of ' ~ profile.username %}
{% set manage_link = '/manage/users.php?v=view&u=' ~ profile.user_id %}
@ -56,7 +56,7 @@
<script>
function updateAvatarPreview(name, url, preview) {
url = url || "/profile.php?u={{ profile.user_id }}&m=avatar";
url = url || "{{ url('user-avatar', {'user': profile.user_id})|raw }}";
preview = preview || document.getElementById('avatar-preview');
preview.style.backgroundImage = 'url(\'{0}\')'.replace('{0}', url);
preview.title = name;