diff --git a/VKAPI/Handlers/Reports.php b/VKAPI/Handlers/Reports.php new file mode 100644 index 00000000..3a5a1d19 --- /dev/null +++ b/VKAPI/Handlers/Reports.php @@ -0,0 +1,53 @@ +<?php declare(strict_types=1); +namespace openvk\VKAPI\Handlers; +use openvk\Web\Models\Entities\Report; +use openvk\Web\Models\Repositories\Reports as ReportsRepo; + +final class Reports extends VKAPIRequestHandler +{ + function add(int $owner_id = 0, string $comment = "", int $reason = 0, string $type = "", string $report_source = ""): int + { + $this->requireUser(); + $this->willExecuteWriteAction(); + + $allowed_types = ["post", "photo", "video", "group", "comment", "note", "app", "user", "audio"]; + if($type == "" || !in_array($type, $allowed_types)) { + $this->fail(100, "One of the parameters specified was missing or invalid: type should be ".implode(", ", $allowed_types)); + } + + if($owner_id <= 0) { + $this->fail(100, "One of the parameters specified was missing or invalid: Bad input"); + } + + if(mb_strlen($comment) === 0) { + $this->fail(100, "One of the parameters specified was missing or invalid: Comment can't be empty"); + } + + if($type == "user" && $owner_id == $this->getUser()->getId()) { + return 1; + } + + if($this->getUser()->isBannedInSupport()) { + return 0; + } + + if(sizeof(iterator_to_array((new ReportsRepo)->getDuplicates($type, $owner_id, NULL, $this->getUser()->getId()))) > 0) { + return 1; + } + + try { + $report = new Report; + $report->setUser_id($this->getUser()->getId()); + $report->setTarget_id($owner_id); + $report->setType($type); + $report->setReason($comment); + $report->setCreated(time()); + + $report->save(); + } catch(\Throwable $e) { + $this->fail(-1, "Unknown error failed"); + } + + return 1; + } +} diff --git a/Web/Models/shell/processVideo.ps1 b/Web/Models/shell/processVideo.ps1 index 59f53c72..27bc2e06 100644 --- a/Web/Models/shell/processVideo.ps1 +++ b/Web/Models/shell/processVideo.ps1 @@ -13,7 +13,7 @@ Move-Item $file $temp # video stub logic was implicitly deprecated, so we start processing at once ffmpeg -i $temp -ss 00:00:01.000 -vframes 1 "$dir$hashT/$hash.gif" -ffmpeg -i $temp -c:v libx264 -q:v 7 -c:a libmp3lame -q:a 4 -tune zerolatency -vf "scale=480:-1,setsar=1" -y $temp2 +ffmpeg -i $temp -c:v libx264 -q:v 7 -c:a libmp3lame -q:a 4 -tune zerolatency -vf "scale=iw*min(1\,if(gt(iw\,ih)\,640/iw\,(640*sar)/ih)):(floor((ow/dar)/2))*2" -y $temp2 Move-Item $temp2 "$dir$hashT/$hash.mp4" Remove-Item $temp diff --git a/Web/Models/shell/processVideo.sh b/Web/Models/shell/processVideo.sh index f906544d..9fc74b98 100644 --- a/Web/Models/shell/processVideo.sh +++ b/Web/Models/shell/processVideo.sh @@ -3,7 +3,7 @@ tmpfile="$RANDOM-$(date +%s%N)" cp $2 "/tmp/vid_$tmpfile.bin" nice ffmpeg -i "/tmp/vid_$tmpfile.bin" -ss 00:00:01.000 -vframes 1 $3${4:0:2}/$4.gif -nice -n 20 ffmpeg -i "/tmp/vid_$tmpfile.bin" -c:v libx264 -q:v 7 -c:a libmp3lame -q:a 4 -tune zerolatency -vf "scale=480:-1,setsar=1" -y "/tmp/ffmOi$tmpfile.mp4" +nice -n 20 ffmpeg -i "/tmp/vid_$tmpfile.bin" -c:v libx264 -q:v 7 -c:a libmp3lame -q:a 4 -tune zerolatency -vf "scale=iw*min(1\,if(gt(iw\,ih)\,640/iw\,(640*sar)/ih)):(floor((ow/dar)/2))*2" -y "/tmp/ffmOi$tmpfile.mp4" rm -rf $3${4:0:2}/$4.mp4 mv "/tmp/ffmOi$tmpfile.mp4" $3${4:0:2}/$4.mp4 diff --git a/Web/Presenters/ReportPresenter.php b/Web/Presenters/ReportPresenter.php index a627efa4..dfd2b962 100644 --- a/Web/Presenters/ReportPresenter.php +++ b/Web/Presenters/ReportPresenter.php @@ -89,6 +89,9 @@ final class ReportPresenter extends OpenVKPresenter if(!$id) exit(json_encode([ "error" => tr("error_segmentation") ])); + + if ($this->queryParam("type") === "user" && $id === $this->user->id) + exit(json_encode([ "error" => "You can't report yourself" ])); if(in_array($this->queryParam("type"), ["post", "photo", "video", "group", "comment", "note", "app", "user", "audio"])) { if (count(iterator_to_array($this->reports->getDuplicates($this->queryParam("type"), $id, NULL, $this->user->id))) <= 0) { diff --git a/Web/Presenters/templates/Audio/Upload.xml b/Web/Presenters/templates/Audio/Upload.xml index 8433ea6e..7be039d9 100644 --- a/Web/Presenters/templates/Audio/Upload.xml +++ b/Web/Presenters/templates/Audio/Upload.xml @@ -164,11 +164,11 @@ <tbody> <tr> <td width="120" valign="top"><span class="nobold">${tr('performer')}:</span></td> - <td><input value='${audio_element.info.performer}' name="performer" type="text" autocomplete="off" maxlength="80" /></td> + <td><input value='${escapeHtml(audio_element.info.performer)}' name="performer" type="text" autocomplete="off" maxlength="80" /></td> </tr> <tr> <td width="120" valign="top"><span class="nobold">${tr('audio_name')}:</span></td> - <td><input type="text" value='${audio_element.info.name}' name="name" autocomplete="off" maxlength="80" /></td> + <td><input type="text" value='${escapeHtml(audio_element.info.name)}' name="name" autocomplete="off" maxlength="80" /></td> </tr> <tr> <td width="120" valign="top"><span class="nobold">${tr('genre')}:</span></td> @@ -178,7 +178,7 @@ </tr> <tr> <td width="120" valign="top"><span class="nobold">${tr('lyrics')}:</span></td> - <td><textarea name="lyrics" style="resize: vertical;max-height: 300px;">${audio_element.info.lyrics}</textarea></td> + <td><textarea name="lyrics" style="resize: vertical;max-height: 300px;">${escapeHtml(audio_element.info.lyrics)}</textarea></td> </tr> <tr> <td width="120" valign="top"></td> diff --git a/Web/Presenters/templates/Report/ViewContent.xml b/Web/Presenters/templates/Report/ViewContent.xml index 1f5918d5..677dc37b 100644 --- a/Web/Presenters/templates/Report/ViewContent.xml +++ b/Web/Presenters/templates/Report/ViewContent.xml @@ -16,7 +16,7 @@ {elseif $type == "group" || $type == "user"} {include "../components/group.xml", group => $object, isUser => $type == "user"} {elseif $type == "comment"} - {include "../components/comment.xml", comment => $object, timeOnly => true, linkWithPost => true} + {include "../components/comment.xml", comment => $object, timeOnly => true, correctLink => true} {elseif $type == "note"} {include "./content/note.xml", note => $object} {elseif $type == "app"} diff --git a/Web/Util/DateTime.php b/Web/Util/DateTime.php index b90de19d..991d8032 100644 --- a/Web/Util/DateTime.php +++ b/Web/Util/DateTime.php @@ -1,5 +1,6 @@ <?php declare(strict_types=1); namespace openvk\Web\Util; +use Chandler\Session\Session; class DateTime { @@ -21,17 +22,19 @@ class DateTime $then = date_create("@" . $this->timestamp); $now = date_create(); $diff = date_diff($now, $then); + + $sessionOffset = intval(Session::i()->get("_timezoneOffset")); if($diff->invert === 0) return ovk_strftime_safe("%e %B %Y ", $this->timestamp) . tr("time_at_sp") . ovk_strftime_safe(" %R", $this->timestamp); - if($this->timestamp >= strtotime("midnight")) { # Today + if(($this->timestamp + $sessionOffset) >= (strtotime("midnight") + $sessionOffset)) { # Today if($diff->h >= 1) return tr("time_today") . tr("time_at_sp") . ovk_strftime_safe(" %R", $this->timestamp); else if($diff->i < 2) return tr("time_just_now"); else return $diff->i === 5 ? tr("time_exactly_five_minutes_ago") : tr("time_minutes_ago", $diff->i); - } else if($this->timestamp >= strtotime("-1day midnight")) { # Yesterday + } else if(($this->timestamp + $sessionOffset) >= (strtotime("-1day midnight") + $sessionOffset)) { # Yesterday return tr("time_yesterday") . tr("time_at_sp") . ovk_strftime_safe(" %R", $this->timestamp); } else if(ovk_strftime_safe("%Y", $this->timestamp) === ovk_strftime_safe("%Y", time())) { # In this year return ovk_strftime_safe("%e %h ", $this->timestamp) . tr("time_at_sp") . ovk_strftime_safe(" %R", $this->timestamp); diff --git a/Web/static/js/al_music.js b/Web/static/js/al_music.js index 8b4b0a82..d9029763 100644 --- a/Web/static/js/al_music.js +++ b/Web/static/js/al_music.js @@ -1306,12 +1306,12 @@ u(document).on("click", ".musicIcon.edit-icon", (e) => { MessageBox(tr("edit_audio"), ` <div> ${tr("performer")} - <input name="performer" maxlength="256" type="text" value="${performer}"> + <input name="performer" maxlength="256" type="text" value="${escapeHtml(performer)}"> </div> <div style="margin-top: 11px"> ${tr("audio_name")} - <input name="name" maxlength="256" type="text" value="${name}"> + <input name="name" maxlength="256" type="text" value="${escapeHtml(name)}"> </div> <div style="margin-top: 11px"> @@ -1359,7 +1359,7 @@ u(document).on("click", ".musicIcon.edit-icon", (e) => { e.target.setAttribute("data-performer", escapeHtml(response.new_info.performer)) e.target.setAttribute("data-title", escapeHtml(response.new_info.name)) - e.target.setAttribute("data-lyrics", response.new_info.lyrics_unformatted) + e.target.setAttribute("data-lyrics", escapeHtml(response.new_info.lyrics_unformatted)) e.target.setAttribute("data-explicit", Number(response.new_info.explicit)) e.target.setAttribute("data-searchable", Number(!response.new_info.unlisted)) player.setAttribute("data-genre", response.new_info.genre) @@ -1374,7 +1374,7 @@ u(document).on("click", ".musicIcon.edit-icon", (e) => { } else { player.insertAdjacentHTML("beforeend", ` <div class="lyrics"> - ${response.new_info.lyrics} + ${escapeHtml(response.new_info.lyrics)} </div> `) diff --git a/Web/static/js/al_wall.js b/Web/static/js/al_wall.js index 5cecddb0..008ba3ec 100644 --- a/Web/static/js/al_wall.js +++ b/Web/static/js/al_wall.js @@ -2579,7 +2579,7 @@ async function changeStatus() { document.querySelector("#page_status_text").innerHTML = `[ ${tr("change_status")} ]`; document.querySelector("#page_status_text").className = "edit_link page_status_edit_button"; } else { - document.querySelector("#page_status_text").innerHTML = status; + document.querySelector("#page_status_text").innerHTML = escapeHtml(status); document.querySelector("#page_status_text").className = "page_status page_status_edit_button"; } diff --git a/Web/static/js/router.js b/Web/static/js/router.js index 0d748f07..b45a23f3 100644 --- a/Web/static/js/router.js +++ b/Web/static/js/router.js @@ -234,6 +234,10 @@ window.router = new class { } u(document).on('click', 'a', async (e) => { + if(e.defaultPrevented) { + return + } + const target = u(e.target).closest('a') const dom_url = target.attr('href') const id = target.attr('id') @@ -292,7 +296,7 @@ u(document).on('submit', 'form', async (e) => { if(e.defaultPrevented) { return } - + if(u('#ajloader').hasClass('shown')) { e.preventDefault() return