forked from 4ducky/4ducky
Port 4ducky to Rust (Axum + SQLite)
Same design, layout, URLs and features as the PHP version: browse grid, image view with AJAX comments, BBCode, likes, uploads (file, URL and bookmarklet), quicktagger, profile, block list, inbox, invites, Hall of Ducks, Truhe, abuse reports and the admin tools. - Parameterized SQL, escaped templates (askama), argon2 passwords, server-side sessions, CSRF tokens on every write, strict script CSP - SSRF-safe remote image fetching, magic-byte upload checks - Self-hosted captcha replaces reCAPTCHA v1; analytics/social widgets removed - Vanilla JS replaces jQuery and its plugins with the same DOM behaviour - Reverse proxy support (frontend_path, trust_proxy, secure_cookies) - Admin CLI: admin, settings, invites See README.md for running it and the full list of changes. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,127 @@
|
||||
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
|
||||
<html xmlns="http://www.w3.org/1999/xhtml">
|
||||
<head>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
|
||||
<title>{{ l.title }}</title>
|
||||
<meta name="description" content="ENTE ✔ ENTE ✔ ENTE ✔ ENTE ✔ ENTE ✔ ENTE ✔ ENTE ✔ ENTE ✔ ENTE ✔ ENTE ✔ ENTE ✔ ENTE ✔ ENTE ✔ ENTE ✔ ENTE ✔ ENTE ✔ ENTE ✔ ENTE ✔ ENTE ✔"/>
|
||||
<meta name="csrf-token" content="{{ l.csrf }}"/>
|
||||
<link rel="icon" href="/favicon.ico"/>
|
||||
{%- if l.white %}
|
||||
<link rel="stylesheet" type="text/css" href="/media/styles_fb.css" />
|
||||
{%- else %}
|
||||
<link rel="stylesheet" type="text/css" href="/media/styles_b.css" />
|
||||
{%- endif %}
|
||||
<link rel="stylesheet" href="/media/lightbox/lightbox.css" type="text/css" />
|
||||
<link rel="stylesheet" href="/media/4ducky.css" type="text/css" />
|
||||
{%- if l.jscolor %}
|
||||
<script type="text/javascript" src="/media/jscolor.js"></script>
|
||||
{%- endif %}
|
||||
<script type="text/javascript" src="/media/4ducky.js" defer="defer"></script>
|
||||
</head>
|
||||
|
||||
<body{% if l.user.is_none() %} data-guest="1"{% endif %}{% if l.view_image > 0 %} data-image-id="{{ l.view_image }}"{% endif %}>
|
||||
<div id="site">
|
||||
<div id="menu"> <a href="/" id="logo"></a>
|
||||
{%- if let Some(u) = l.user %}
|
||||
<div id="MenuLoad"{% if !l.upload_errors.is_empty() %} data-error="1"{% endif %}>
|
||||
<div id="UploadD"><div style="float:right;margin:5px;"><img data-action="close-upload" src="/media/close.png" /></div><div id="UploadD_d">
|
||||
{%- if !l.upload_errors.is_empty() %}
|
||||
<ul>
|
||||
{%- for msg in l.upload_errors %}
|
||||
<li>{{ msg|safe }}</li>
|
||||
{%- endfor %}
|
||||
</ul>
|
||||
{%- else %}
|
||||
<div style="margin-top:12px;text-align:center;" id="UbLoad">
|
||||
<div align="center">
|
||||
<img src="/media/load_b.gif" />
|
||||
</div>
|
||||
</div>
|
||||
{%- endif %}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div id="MenuRightBlock"></div>
|
||||
|
||||
<div class="menuItems">
|
||||
<a href="#" data-menu="upload">Upload</a> <a href="#" data-menu="addon">Addon</a> <a href="/truhe">Truhe</a> <a href="/fame">HoD</a>
|
||||
</div>
|
||||
|
||||
<div class="menuItems2"><a id="nigger" href="/logout?t={{ l.csrf }}" original-title="Hello World"><img width="28" height="28" src="/media/logout{{ l.b }}.png" /></a></div>
|
||||
<div class="menuItems2"><a href="/profile"><img width="28" height="28" src="/media/profile{{ l.b }}.png" /></a></div>
|
||||
<div class="menuItems2"><a href="/favorites"><img width="28" height="28" src="/media/p{{ l.b }}.png" /></a></div>
|
||||
<div class="menuItems2">
|
||||
{%- if u.unread_msgs > 0 %}
|
||||
<div class="inboxalert">{{ u.unread_msgs }}</div>
|
||||
{%- endif %}
|
||||
<div><a href="/inbox"><img width="28" height="28" src="/media/n{{ l.b }}.png" /></a></div>
|
||||
</div>
|
||||
<div class="menuItems2">
|
||||
{%- if u.unread_count > 0 %}
|
||||
<div class="inboxalert"> {{ u.unread_count }}</div>
|
||||
<a data-hover="Last5Div" href="/unread" ><img width="28" height="28" src="/media/w{{ l.b }}.png" /></a>
|
||||
{%- else %}
|
||||
<a href="/comments" ><img width="28" height="28" src="/media/w{{ l.b }}.png" /></a>
|
||||
{%- endif %}
|
||||
</div>
|
||||
|
||||
<div id="Last5Div" class="Last5Div" data-hover="Last5Div">
|
||||
{%- for c in u.unread %}
|
||||
<a href="/all/view/{{ c.keyword }}">
|
||||
<table width="100%" border="0" cellspacing="0" cellpadding="0">
|
||||
<tr height="45px">
|
||||
<td valign="middle" align="left" width="45px"><img width="40" height="40" src="{{ c.thumb }}" /></td>
|
||||
<td align="left"><strong>Image:</strong><br />{{ c.short }}</td>
|
||||
</tr>
|
||||
</table>
|
||||
</a>
|
||||
{%- endfor %}
|
||||
<div style="text-align:right;padding:2px;">
|
||||
<a href="/comments/reset?t={{ l.csrf }}">» reset unread</a>
|
||||
<a href="/unread">» watch all</a>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="menuItems2">
|
||||
<table width="100%" border="0" cellspacing="0" cellpadding="0">
|
||||
<tr>
|
||||
<td align="center" valign="middle" ><a href="#" id="del_cookie"><img title="Reload page, activate sidebar" width="28" height="28" src="/{{ u.avatar }}" /></a></td>
|
||||
<td align="center" valign="middle"><a href="/user/{{ u.name_enc }}">{{ u.name }}</a></td>
|
||||
</tr>
|
||||
</table>
|
||||
</div>
|
||||
{%- else %}
|
||||
<div class="menuItems2">
|
||||
<table width="100%" border="0" cellspacing="0" cellpadding="0">
|
||||
<tr>
|
||||
<td align="center" valign="middle" ><a href="/impressum"><img title="contact" width="28" height="28" src="/media/mailme.png" alt="login"/></a></td>
|
||||
<td align="center" valign="middle"><a href="/impressum">Contact</a></td>
|
||||
</tr>
|
||||
</table>
|
||||
</div>
|
||||
|
||||
<div class="menuItems2">
|
||||
<table width="100%" border="0" cellspacing="0" cellpadding="0">
|
||||
<tr>
|
||||
<td align="center" valign="middle" ><a href="/register"><img title="Register" width="28" height="28" src="/media/register_fb.png" alt="register"/></a></td>
|
||||
<td align="center" valign="middle"><a href="/register">Register</a></td>
|
||||
</tr>
|
||||
</table>
|
||||
</div>
|
||||
|
||||
<div class="menuItems2">
|
||||
<table width="100%" border="0" cellspacing="0" cellpadding="0">
|
||||
<tr>
|
||||
<td align="center" valign="middle" ><a href="/login"><img title="Login" width="28" height="28" src="/media/login_fb.png" alt="login"/></a></td>
|
||||
<td align="center" valign="middle"><a href="/login">Login</a></td>
|
||||
</tr>
|
||||
</table>
|
||||
</div>
|
||||
{%- endif %}
|
||||
<div style="clear:both;"></div>
|
||||
</div>
|
||||
<div id="content">
|
||||
<div class="alert" id="dolan">
|
||||
{%- if l.user.is_some() %}{{ l.message|safe }} <img style="float: right;" id="stfu" height="16" width="16" src="{% if l.white %}/media/xfb.png{% else %}/media/xd.png{% endif %}" alt="close"/>
|
||||
{%- else %}Dolan: "Hate annoying advertisements? <a href="/register">Register now for free</a> to have them removed!" Like us on <a href="http://www.facebook.com/fuehls">Facebook.com</a>
|
||||
{%- endif %}</div>
|
||||
Reference in New Issue
Block a user