forked from 4ducky/4ducky
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>
160 lines
4.0 KiB
HTML
160 lines
4.0 KiB
HTML
{% include "header.html" %}
|
|
<div align="center">
|
|
|
|
<form action="/profile" enctype="multipart/form-data" method="post">
|
|
<input type="hidden" name="_csrf" value="{{ l.csrf }}"/>
|
|
<fieldset>
|
|
<legend>Change Profile</legend>
|
|
|
|
{%- if m.pass_short %}
|
|
<div class="warn">Your password must be at least 6 characters long!</div>
|
|
{%- endif %}
|
|
|
|
{%- if m.pass_not_equal %}
|
|
<div class="warn">Your both passwords are not equal!</div>
|
|
{%- endif %}
|
|
|
|
{%- if m.avatar_failed %}
|
|
<div class="warn">Your avatar Image could not be processed!</div>
|
|
{%- endif %}
|
|
|
|
{%- if m.color_failed %}
|
|
<div class="warn">Not a valid colorcode!</div>
|
|
{%- endif %}
|
|
|
|
|
|
|
|
|
|
<dl class="form">
|
|
<dt>Passwort:</dt>
|
|
<dd>
|
|
<input type="password" name="cpass" /> (leave empty, if you don't want to change it)
|
|
</dd>
|
|
|
|
<dt>(Repeat)</dt>
|
|
<dd>
|
|
<input type="password" name="cpass2" />
|
|
</dd>
|
|
|
|
|
|
{%- if !has_email %}
|
|
<dt>E-Mail:</dt>
|
|
<dd>
|
|
<input type="text" name="email" />
|
|
</dd>
|
|
{%- endif %}
|
|
|
|
<dt>Website:</dt>
|
|
<dd>
|
|
<input type="text" name="website" value="{{ website }}"/>
|
|
</dd>
|
|
|
|
<dt>Avatar:</dt>
|
|
<dd>
|
|
<input type="file" name="avatar" accept="image/jpeg,image/png,image/gif" style="color: #000; background-color: #fff;"/><br/>
|
|
</dd>
|
|
<dt>Color:</dt>
|
|
<dd>
|
|
<input class="color" maxlength="6" type="text" name="color" value="{{ color }}" style="width:100px;"/> (default:: 000000)
|
|
<br/>
|
|
</dd>
|
|
|
|
<dt>Style:</dt>
|
|
<dd>
|
|
<select name="stylecolor">
|
|
{%- if style == "white" %}<option value="white">White</option><option value="black">Black</option>{% else %}<option value="black">Black</option><option value="white">White</option>{% endif %}
|
|
</select>
|
|
</dd>
|
|
|
|
<dt> </dt>
|
|
<dd>
|
|
<input type="submit" name="save" class="button" value="Save" />
|
|
</dd>
|
|
|
|
|
|
</dl>
|
|
</fieldset>
|
|
</form>
|
|
|
|
|
|
|
|
<form action="/profile" enctype="multipart/form-data" method="post">
|
|
<input type="hidden" name="_csrf" value="{{ l.csrf }}"/>
|
|
<fieldset>
|
|
<legend>Block user</legend>
|
|
|
|
{%- if m.blocked %}
|
|
<div class="success">User blocked!</div>
|
|
{%- endif %}
|
|
{%- if m.block_failed %}
|
|
<div class="warn">Could not block user!</div>
|
|
{%- endif %}
|
|
{%- if m.block_already %}
|
|
<div class="warn">User already blocked!</div>
|
|
{%- endif %}
|
|
{%- if m.user_failed %}
|
|
<div class="warn">User not found!</div>
|
|
{%- endif %}
|
|
{%- if m.unblocked %}
|
|
<div class="success">User unblocked!</div>
|
|
{%- endif %}
|
|
{%- if m.unblock_failed %}
|
|
<div class="warn">Could not unblock user!</div>
|
|
{%- endif %}
|
|
{%- if m.not_blocked %}
|
|
<div class="warn">User not blocked!</div>
|
|
{%- endif %}
|
|
|
|
|
|
<dl class="form">
|
|
{%- for b in blocked %}
|
|
<div style="text-align:left" class="userInfo">
|
|
<img class="avatar" width="40" height="40" src="/{{ b.avatar }}"/>
|
|
<div class="name">
|
|
<strong>
|
|
<a href="/user/{{ b.name_enc }}">{{ b.name }}</a>
|
|
</strong>
|
|
</div>
|
|
<div class="info">
|
|
|
|
Images: <strong>{{ b.images }}</strong>
|
|
|
|
</div>
|
|
<div style="clear:both;"></div>
|
|
</div>
|
|
{%- else %}
|
|
|
|
<div class="success">No users blocked!</div>
|
|
|
|
{%- endfor %}
|
|
|
|
<dt>User:</dt>
|
|
<dd>
|
|
<input type="text" name="blockuser" />
|
|
</dd>
|
|
<dt> </dt>
|
|
<dd>
|
|
<input type="submit" name="block" class="button" value="Block" />
|
|
</dd>
|
|
|
|
<dt>User:</dt>
|
|
<dd>
|
|
{%- if !blocked.is_empty() %}
|
|
<select name="unblockuser">
|
|
<option value="select">Select user</option>
|
|
{%- for b in blocked %}
|
|
<option value="{{ b.name }}">{{ b.name }}</option>
|
|
{%- endfor %}
|
|
</select>
|
|
{%- else %}No user blocked!{% endif %}
|
|
</dd>
|
|
<dt> </dt>
|
|
<dd>
|
|
<input type="submit" name="unblock" class="button" value="Unblock" />
|
|
</dd>
|
|
</dl>
|
|
</fieldset>
|
|
</form>
|
|
</div>
|
|
{% include "footer.html" %}
|