admin schmadmin
All checks were successful
fetch npm modules / f0ck the f0cker (push) Successful in 19s
All checks were successful
fetch npm modules / f0ck the f0cker (push) Successful in 19s
This commit is contained in:
parent
486580b21c
commit
2ff1842d09
|
@ -134,15 +134,6 @@ export default new class {
|
||||||
const derivedKey = await scrypt(str, salt, 64);
|
const derivedKey = await scrypt(str, salt, 64);
|
||||||
return crypto.timingSafeEqual(keyBuffer, derivedKey);
|
return crypto.timingSafeEqual(keyBuffer, derivedKey);
|
||||||
};
|
};
|
||||||
async auth(req, res, next) {
|
|
||||||
if(!req.session) {
|
|
||||||
return res.reply({
|
|
||||||
code: 401,
|
|
||||||
body: "401 - Unauthorized"
|
|
||||||
});
|
|
||||||
}
|
|
||||||
return next();
|
|
||||||
};
|
|
||||||
async getTags(itemid) {
|
async getTags(itemid) {
|
||||||
const tags = await db`
|
const tags = await db`
|
||||||
select "tags".id, "tags".tag, "tags".normalized, "user".user
|
select "tags".id, "tags".tag, "tags".normalized, "user".user
|
||||||
|
@ -217,6 +208,27 @@ export default new class {
|
||||||
TABLE_NAME='user_options' and
|
TABLE_NAME='user_options' and
|
||||||
COLUMN_NAME = 'avatar'
|
COLUMN_NAME = 'avatar'
|
||||||
`)[0].avatar;
|
`)[0].avatar;
|
||||||
|
};
|
||||||
|
|
||||||
|
// meddlware
|
||||||
|
async auth(req, res, next) {
|
||||||
|
if(!req.session || !req.session.admin) {
|
||||||
|
return res.reply({
|
||||||
|
code: 401,
|
||||||
|
body: "401 - Unauthorized"
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
return next();
|
||||||
|
};
|
||||||
|
|
||||||
|
async loggedin(req, res, next) {
|
||||||
|
if(!req.session) {
|
||||||
|
return res.reply({
|
||||||
|
code: 401,
|
||||||
|
body: "401 - Unauthorized"
|
||||||
|
});
|
||||||
|
}
|
||||||
|
return next();
|
||||||
|
};
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
|
@ -3,18 +3,7 @@ import lib from "../lib.mjs";
|
||||||
import { exec } from "child_process";
|
import { exec } from "child_process";
|
||||||
import { promises as fs } from "fs";
|
import { promises as fs } from "fs";
|
||||||
|
|
||||||
const auth = async (req, res, next) => {
|
|
||||||
if(!req.session) {
|
|
||||||
return res.reply({
|
|
||||||
code: 401,
|
|
||||||
body: "401 - Unauthorized"
|
|
||||||
});
|
|
||||||
}
|
|
||||||
return next();
|
|
||||||
};
|
|
||||||
|
|
||||||
export default (router, tpl) => {
|
export default (router, tpl) => {
|
||||||
|
|
||||||
router.get(/^\/login(\/)?$/, async (req, res) => {
|
router.get(/^\/login(\/)?$/, async (req, res) => {
|
||||||
if(req.cookies.session) {
|
if(req.cookies.session) {
|
||||||
return res.reply({
|
return res.reply({
|
||||||
|
@ -72,7 +61,7 @@ export default (router, tpl) => {
|
||||||
}).end();
|
}).end();
|
||||||
});
|
});
|
||||||
|
|
||||||
router.get(/^\/logout$/, auth, async (req, res) => {
|
router.get(/^\/logout$/, lib.loggedin, async (req, res) => {
|
||||||
const usersession = await db`
|
const usersession = await db`
|
||||||
select *
|
select *
|
||||||
from "user_sessions"
|
from "user_sessions"
|
||||||
|
@ -103,7 +92,7 @@ export default (router, tpl) => {
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
router.get(/^\/admin(\/)?$/, auth, async (req, res) => { // frontpage
|
router.get(/^\/admin(\/)?$/, lib.auth, async (req, res) => { // frontpage
|
||||||
|
|
||||||
res.reply({
|
res.reply({
|
||||||
body: tpl.render("admin", {
|
body: tpl.render("admin", {
|
||||||
|
@ -114,7 +103,7 @@ export default (router, tpl) => {
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
router.get(/^\/admin\/sessions(\/)?$/, auth, async (req, res) => {
|
router.get(/^\/admin\/sessions(\/)?$/, lib.auth, async (req, res) => {
|
||||||
const rows = await db`
|
const rows = await db`
|
||||||
select "user_sessions".*, "user".user
|
select "user_sessions".*, "user".user
|
||||||
from "user_sessions"
|
from "user_sessions"
|
||||||
|
@ -132,7 +121,7 @@ export default (router, tpl) => {
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
router.get(/^\/admin\/log(\/)?$/, auth, async (req, res) => {
|
router.get(/^\/admin\/log(\/)?$/, lib.auth, async (req, res) => {
|
||||||
exec("journalctl -qeu f0ck --no-pager", (err, stdout) => {
|
exec("journalctl -qeu f0ck --no-pager", (err, stdout) => {
|
||||||
res.reply({
|
res.reply({
|
||||||
body: tpl.render("admin/log", {
|
body: tpl.render("admin/log", {
|
||||||
|
@ -143,7 +132,7 @@ export default (router, tpl) => {
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
router.get(/^\/admin\/recover\/?/, auth, async (req, res) => {
|
router.get(/^\/admin\/recover\/?/, lib.auth, async (req, res) => {
|
||||||
if(req.url.qs?.id) {
|
if(req.url.qs?.id) {
|
||||||
const id = +req.url.qs.id;
|
const id = +req.url.qs.id;
|
||||||
const f0ck = await db`
|
const f0ck = await db`
|
||||||
|
|
|
@ -139,7 +139,7 @@ export default router => {
|
||||||
|
|
||||||
// tags lol
|
// tags lol
|
||||||
|
|
||||||
group.put(/\/admin\/tags\/(?<tagname>.*)/, lib.auth, async (req, res) => {
|
group.put(/\/admin\/tags\/(?<tagname>.*)/, lib.loggedin, async (req, res) => {
|
||||||
if(!req.params.tagname || !req.post.newtag) {
|
if(!req.params.tagname || !req.post.newtag) {
|
||||||
return res.json({
|
return res.json({
|
||||||
success: false,
|
success: false,
|
||||||
|
@ -187,7 +187,7 @@ export default router => {
|
||||||
return res.json(q, tagname === newtag ? 200 : 201); // created (modified)
|
return res.json(q, tagname === newtag ? 200 : 201); // created (modified)
|
||||||
});
|
});
|
||||||
|
|
||||||
group.get(/\/admin\/tags\/suggest$/, lib.auth, async (req, res) => {
|
group.get(/\/admin\/tags\/suggest$/, lib.loggedin, async (req, res) => {
|
||||||
const reply = {
|
const reply = {
|
||||||
success: false,
|
success: false,
|
||||||
suggestions: {}
|
suggestions: {}
|
||||||
|
@ -267,7 +267,7 @@ export default router => {
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
group.post(/\/admin\/togglefav$/, lib.auth, async (req, res) => {
|
group.post(/\/admin\/togglefav$/, lib.loggedin, async (req, res) => {
|
||||||
const postid = +req.post.postid;
|
const postid = +req.post.postid;
|
||||||
|
|
||||||
let favs = await db`
|
let favs = await db`
|
||||||
|
|
|
@ -3,7 +3,7 @@ import lib from '../../lib.mjs';
|
||||||
|
|
||||||
export default router => {
|
export default router => {
|
||||||
router.group(/^\/api\/v2\/settings/, group => {
|
router.group(/^\/api\/v2\/settings/, group => {
|
||||||
group.put(/\/setAvatar/, lib.auth, async (req, res) => {
|
group.put(/\/setAvatar/, lib.loggedin, async (req, res) => {
|
||||||
if(!req.post.avatar) {
|
if(!req.post.avatar) {
|
||||||
return res.json({
|
return res.json({
|
||||||
msg: 'no avatar provided',
|
msg: 'no avatar provided',
|
||||||
|
|
|
@ -3,7 +3,7 @@ import lib from '../../lib.mjs';
|
||||||
|
|
||||||
export default router => {
|
export default router => {
|
||||||
router.group(/^\/api\/v2\/admin\/(?<postid>\d+)\/tags/, group => {
|
router.group(/^\/api\/v2\/admin\/(?<postid>\d+)\/tags/, group => {
|
||||||
group.get(/$/, lib.auth, async (req, res) => {
|
group.get(/$/, lib.loggedin, async (req, res) => {
|
||||||
// get tags
|
// get tags
|
||||||
if(!req.params.postid) {
|
if(!req.params.postid) {
|
||||||
return res.json({
|
return res.json({
|
||||||
|
@ -18,7 +18,7 @@ export default router => {
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
group.post(/$/, lib.auth, async (req, res) => {
|
group.post(/$/, lib.loggedin, async (req, res) => {
|
||||||
// assign and/or create tag
|
// assign and/or create tag
|
||||||
if(!req.params.postid || !req.post.tagname) {
|
if(!req.params.postid || !req.post.tagname) {
|
||||||
return res.json({
|
return res.json({
|
||||||
|
@ -80,7 +80,7 @@ export default router => {
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
group.put(/\/toggle$/, lib.auth, async (req, res) => {
|
group.put(/\/toggle$/, lib.loggedin, async (req, res) => {
|
||||||
// xD
|
// xD
|
||||||
if(!req.params.postid) {
|
if(!req.params.postid) {
|
||||||
return res.json({
|
return res.json({
|
||||||
|
|
|
@ -100,7 +100,7 @@ export default (router, tpl) => {
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
router.get(/^\/mode\/(\d)/, auth, async (req, res) => {
|
router.get(/^\/mode\/(\d)/, lib.loggedin, async (req, res) => {
|
||||||
const mode = +req.url.split[1];
|
const mode = +req.url.split[1];
|
||||||
let referertmp = req.headers.referer;
|
let referertmp = req.headers.referer;
|
||||||
let referer = "";
|
let referer = "";
|
||||||
|
|
|
@ -5,7 +5,7 @@ import search from "../routeinc/search.mjs";
|
||||||
const _eps = 20;
|
const _eps = 20;
|
||||||
|
|
||||||
export default (router, tpl) => {
|
export default (router, tpl) => {
|
||||||
router.get(/^\/search(\/)?$/, lib.auth, async (req, res) => {
|
router.get(/^\/search(\/)?$/, lib.loggedin, async (req, res) => {
|
||||||
let ret;
|
let ret;
|
||||||
let tag = req.url.qs.tag ?? [];
|
let tag = req.url.qs.tag ?? [];
|
||||||
let page = req.url.qs.page ?? 1;
|
let page = req.url.qs.page ?? 1;
|
||||||
|
|
|
@ -71,7 +71,7 @@ process.on('unhandledRejection', err => {
|
||||||
|
|
||||||
if(req.cookies.session) {
|
if(req.cookies.session) {
|
||||||
const user = await db`
|
const user = await db`
|
||||||
select "user".id, "user".login, "user".user, "user".level, "user_sessions".id as sess_id, "user_options".*
|
select "user".id, "user".login, "user".user, "user".admin, "user_sessions".id as sess_id, "user_options".*
|
||||||
from "user_sessions"
|
from "user_sessions"
|
||||||
left join "user" on "user".id = "user_sessions".user_id
|
left join "user" on "user".id = "user_sessions".user_id
|
||||||
left join "user_options" on "user_options".user_id = "user_sessions".user_id
|
left join "user_options" on "user_options".user_id = "user_sessions".user_id
|
||||||
|
|
|
@ -14,7 +14,7 @@
|
||||||
<div class="gapRight">
|
<div class="gapRight">
|
||||||
<svg class="iconset" id="a_favo"><use href="/s/img/iconset.svg#heart_{{ Object.values(item.favorites).filter(u => u.user == session.user)[0] ? 'solid' : 'regular' }}"></use></svg>
|
<svg class="iconset" id="a_favo"><use href="/s/img/iconset.svg#heart_{{ Object.values(item.favorites).filter(u => u.user == session.user)[0] ? 'solid' : 'regular' }}"></use></svg>
|
||||||
<svg class="iconset" id="a_tfull"><use href="/s/img/iconset.svg#window-{{ fullscreen == 1 ? 'minimize' : 'maximize' }}"></use></svg>
|
<svg class="iconset" id="a_tfull"><use href="/s/img/iconset.svg#window-{{ fullscreen == 1 ? 'minimize' : 'maximize' }}"></use></svg>
|
||||||
<svg class="iconset" id="a_delete"><use href="/s/img/iconset.svg#cross"></use></svg>
|
@if(session.admin)<svg class="iconset" id="a_delete"><use href="/s/img/iconset.svg#cross"></use></svg>@endif
|
||||||
</div>
|
</div>
|
||||||
@endif
|
@endif
|
||||||
</div>
|
</div>
|
||||||
|
@ -83,7 +83,7 @@
|
||||||
@if(typeof item.tags !== "undefined")
|
@if(typeof item.tags !== "undefined")
|
||||||
@each(item.tags as tag)
|
@each(item.tags as tag)
|
||||||
<span @if(session)tooltip="{{ tag.user }}"@endif class="badge {{ tag.badge }} mr-2">
|
<span @if(session)tooltip="{{ tag.user }}"@endif class="badge {{ tag.badge }} mr-2">
|
||||||
<a href="/tag/{{ tag.normalized }}">{!! tag.tag !!}</a>@if(session) <a class="removetag" href="#">×</a>@endif
|
<a href="/tag/{{ tag.normalized }}">{!! tag.tag !!}</a>@if(session.admin) <a class="removetag" href="#">×</a>@endif
|
||||||
</span>
|
</span>
|
||||||
@endeach
|
@endeach
|
||||||
@endif
|
@endif
|
||||||
|
|
|
@ -12,7 +12,7 @@
|
||||||
<li><a href="/user/{{ session.user.toLowerCase() }}/f0cks">my f0cks</a></li>
|
<li><a href="/user/{{ session.user.toLowerCase() }}/f0cks">my f0cks</a></li>
|
||||||
<li><a href="/user/{{ session.user.toLowerCase() }}/favs">my favs</a></li>
|
<li><a href="/user/{{ session.user.toLowerCase() }}/favs">my favs</a></li>
|
||||||
<li><a href="/search">search</a></li>
|
<li><a href="/search">search</a></li>
|
||||||
<li><a href="/admin">Admin</a></li>
|
@if(session.admin)<li><a href="/admin">Admin</a></li>@endif
|
||||||
<li><a href="/about">About</a></li>
|
<li><a href="/about">About</a></li>
|
||||||
<li><a href="/ranking">ranking</a></li>
|
<li><a href="/ranking">ranking</a></li>
|
||||||
<li><a href="/settings">settings</a></li>
|
<li><a href="/settings">settings</a></li>
|
||||||
|
|
|
@ -1,133 +0,0 @@
|
||||||
@if(session)
|
|
||||||
<nav class="navbar navbar-expand-lg">
|
|
||||||
<a class="navbar-brand" href="/"><span class="f0ck" width="" height="">F0CK</span></a>
|
|
||||||
<div class="navigation-links">
|
|
||||||
<ul class="navbar-nav">
|
|
||||||
<li class="nav-item dropdown">
|
|
||||||
<a class="nav-link" href="#" content="{{ session.user }}" data-toggle="dropdown">
|
|
||||||
<img src="@if(session.avatar)/t/{{ session.avatar }}.webp@else/s/img/ava/default.png@endif" class="avatar" /><span>{{ session.user }}</span>
|
|
||||||
</a>
|
|
||||||
<ul class="dropdown-menu">
|
|
||||||
<li><a href="/admin">adminpanel</a></li>
|
|
||||||
<li><a href="/user/{{ session.user.toLowerCase() }}/f0cks">my f0cks</a></li>
|
|
||||||
<li><a href="/user/{{ session.user.toLowerCase() }}/favs">my favs</a></li>
|
|
||||||
<li><a href="/settings">settings</a></li>
|
|
||||||
<li><a href="/search">search</a></li>
|
|
||||||
<li><a href="/about">About</a></li>
|
|
||||||
<li><a href="/ranking">Ranking</a></li>
|
|
||||||
<li><a href="/logout">logout</a></li>
|
|
||||||
</ul>
|
|
||||||
</li>
|
|
||||||
<li class="nav-item dropdown" id="themes">
|
|
||||||
<a class="nav-link ddcontent" href="#" content="{{ theme }}" data-toggle="dropdown">Themes</a>
|
|
||||||
<ul class="dropdown-menu">
|
|
||||||
@each(themes as t)
|
|
||||||
<li><a href="/theme/{{ t }}">{{ t }}</a></li>
|
|
||||||
@endeach
|
|
||||||
</ul>
|
|
||||||
</li>
|
|
||||||
<li class="nav-item dropdown">
|
|
||||||
<a class="nav-link ddcontent" href="#"@if(tmp?.mime) content="{{ tmp?.mime }}" data-toggle="dropdown"@endif>Filter@if(!tmp?.mime) ▼@endif</a>
|
|
||||||
<ul class="dropdown-menu">
|
|
||||||
<li><a class="dropdown-item" href="/@if(tmp?.user)user/{{ tmp?.user }}/@endif">All</a></li>
|
|
||||||
<li><a class="dropdown-item" href="/@if(tmp?.user)user/{{ tmp?.user }}/@endifaudio">Audio</a></li>
|
|
||||||
<li><a class="dropdown-item" href="/@if(tmp?.user)user/{{ tmp?.user }}/@endifvideo">Video</a></li>
|
|
||||||
<li><a class="dropdown-item" href="/@if(tmp?.user)user/{{ tmp?.user }}/@endifimage">Image</a></li>
|
|
||||||
</ul>
|
|
||||||
</li>
|
|
||||||
<li class="nav-item @if(session)dropdown@endif">
|
|
||||||
<a class="nav-link ddcontent" href="#"@if(typeof session.mode !== "undefined") content="{{ modes[session.mode] ?? 'sfw' }}" data-toggle="dropdown"@endif>Mode</a>
|
|
||||||
<ul class="dropdown-menu">
|
|
||||||
@for(let i = 0; i < modes.length; i++)
|
|
||||||
<li><a class="dropdown-item" href="/mode/{{ i }}">{{ modes[i] }}</a></li>
|
|
||||||
@endfor
|
|
||||||
</ul>
|
|
||||||
</li>
|
|
||||||
<li class="nav-item">
|
|
||||||
<a id="random" class="nav-link" href="/random">
|
|
||||||
<span class="nav-link-identifier">Random</span>
|
|
||||||
</a>
|
|
||||||
</li>
|
|
||||||
</ul>
|
|
||||||
</div>
|
|
||||||
<div class="collapse navbar-collapse show" id="navbarSupportedContent">
|
|
||||||
<div class="pagination-container-fluid">
|
|
||||||
<div class="pagination-wrapper">
|
|
||||||
@if(typeof pagination !== "undefined")
|
|
||||||
<nav class="pagination">
|
|
||||||
<a href="{{ link.main }}{{ link.path }}{{ pagination.start }}" class="page-item-1 btn start@if(!pagination.prev) disabled@endif">«</a>
|
|
||||||
<a href="{{ link.main }}{{ link.path }}{{ pagination.prev }}" class="page-item-2 btn prev@if(!pagination.prev) disabled@endif">‹</a>
|
|
||||||
@each(pagination.cheat as i)
|
|
||||||
@if(i == pagination.page)
|
|
||||||
<span class="btn disabled">{{ i }}</span>
|
|
||||||
@else
|
|
||||||
<a href="{{ link.main }}{{ link.path }}{{ i }}" class="pagination-int-item btn">{{ i }}</a>
|
|
||||||
@endif
|
|
||||||
@endeach
|
|
||||||
<a href="{{ link.main }}{{ link.path }}{{ pagination.next }}" class="page-item-3 btn next@if(!pagination.next) disabled@endif">›</a>
|
|
||||||
<a href="{{ link.main }}{{ link.path }}{{ pagination.end }}" class="page-item-4 btn start@if(!pagination.next) disabled@endif">»</a>
|
|
||||||
</nav>
|
|
||||||
@endif
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</nav>
|
|
||||||
@else
|
|
||||||
<nav class="navbar navbar-expand-lg">
|
|
||||||
<a class="navbar-brand" href="/"><span class="f0ck" width="" height="">F0CK</span></a>
|
|
||||||
|
|
||||||
<div class="navigation-links-guest">
|
|
||||||
<ul class="navbar-nav-guests">
|
|
||||||
<li class="nav-item dropdown">
|
|
||||||
<a class="nav-link" href="/about" data-toggle="dropdown">About</a>
|
|
||||||
<ul class="dropdown-menu">
|
|
||||||
<li><a href="/login">login</a></li>
|
|
||||||
</ul>
|
|
||||||
</li>
|
|
||||||
<li class="nav-item dropdown" id="themes">
|
|
||||||
<a class="nav-link ddcontent" href="#" content="{{ theme }}" data-toggle="dropdown">Themes</a>
|
|
||||||
<ul class="dropdown-menu">
|
|
||||||
@each(themes as t)
|
|
||||||
<li><a href="/theme/{{ t }}">{{ t }}</a></li>
|
|
||||||
@endeach
|
|
||||||
</ul>
|
|
||||||
</li>
|
|
||||||
<li class="nav-item dropdown">
|
|
||||||
<a class="nav-link ddcontent" href="#"@if(tmp?.mime) content="{{ tmp?.mime }}" data-toggle="dropdown"@endif>Filter@if(!tmp?.mime) ▼@endif</a>
|
|
||||||
<ul class="dropdown-menu">
|
|
||||||
<li><a class="dropdown-item" href="/@if(tmp?.user)user/{{ tmp?.user }}/@endif">All</a></li>
|
|
||||||
<li><a class="dropdown-item" href="/@if(tmp?.user)user/{{ tmp?.user }}/@endifaudio">Audio</a></li>
|
|
||||||
<li><a class="dropdown-item" href="/@if(tmp?.user)user/{{ tmp?.user }}/@endifvideo">Video</a></li>
|
|
||||||
<li><a class="dropdown-item" href="/@if(tmp?.user)user/{{ tmp?.user }}/@endifimage">Image</a></li>
|
|
||||||
</ul>
|
|
||||||
</li>
|
|
||||||
<li class="nav-item">
|
|
||||||
<a id="random" class="nav-link" href="/random">
|
|
||||||
<span class="nav-link-identifier">Random</span>
|
|
||||||
</a>
|
|
||||||
</li>
|
|
||||||
</ul>
|
|
||||||
</div>
|
|
||||||
<div class="collapse navbar-collapse show" id="navbarSupportedContent">
|
|
||||||
<div class="pagination-container-fluid">
|
|
||||||
<div class="pagination-wrapper">
|
|
||||||
@if(typeof pagination !== "undefined")
|
|
||||||
<nav class="pagination">
|
|
||||||
<a href="{{ link.main }}{{ link.path }}{{ pagination.start }}" class="page-item-1 btn start@if(!pagination.prev) disabled@endif">«</a>
|
|
||||||
<a href="{{ link.main }}{{ link.path }}{{ pagination.prev }}" class="page-item-2 btn prev@if(!pagination.prev) disabled@endif">‹</a>
|
|
||||||
@each(pagination.cheat as i)
|
|
||||||
@if(i == pagination.page)
|
|
||||||
<span class="btn disabled">{{ i }}</span>
|
|
||||||
@else
|
|
||||||
<a href="{{ link.main }}{{ link.path }}{{ i }}" class="pagination-int-item btn">{{ i }}</a>
|
|
||||||
@endif
|
|
||||||
@endeach
|
|
||||||
<a href="{{ link.main }}{{ link.path }}{{ pagination.next }}" class="page-item-3 btn next@if(!pagination.next) disabled@endif">›</a>
|
|
||||||
<a href="{{ link.main }}{{ link.path }}{{ pagination.end }}" class="page-item-4 btn start@if(!pagination.next) disabled@endif">»</a>
|
|
||||||
</nav>
|
|
||||||
@endif
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</nav>
|
|
||||||
@endif
|
|
Loading…
Reference in New Issue
Block a user