tighten CSP
parent
35d9d7c3bc
commit
6114111654
|
@ -1,7 +1,7 @@
|
||||||
'use strict';
|
'use strict';
|
||||||
|
|
||||||
const CACHE_NAME = "offlineCache-v1";
|
const CACHE_NAME = "offlineCache-v1";
|
||||||
const OFFLINE_URL = "/assets/offline.html";
|
const OFFLINE_URL = "/offline.html";
|
||||||
|
|
||||||
self.addEventListener("install", () => {
|
self.addEventListener("install", () => {
|
||||||
const cacheOfflinePage = async () => {
|
const cacheOfflinePage = async () => {
|
||||||
|
|
|
@ -13,26 +13,30 @@ def session_init():
|
||||||
|
|
||||||
@app.before_request
|
@app.before_request
|
||||||
def before_request():
|
def before_request():
|
||||||
g.desires_auth = False
|
|
||||||
if not IS_LOCALHOST:
|
|
||||||
app.config["COOKIE_DOMAIN"] = f".{request.host}"
|
|
||||||
app.config["SESSION_COOKIE_DOMAIN"] = app.config["COOKIE_DOMAIN"]
|
|
||||||
if SITE == 'marsey.world' and request.path != '/kofi':
|
|
||||||
abort(404)
|
|
||||||
|
|
||||||
g.agent = request.headers.get("User-Agent", "")
|
|
||||||
if not g.agent and request.path != '/kofi':
|
|
||||||
return 'Please use a "User-Agent" header!', 403
|
|
||||||
|
|
||||||
ua = g.agent.lower()
|
|
||||||
|
|
||||||
if request.host != SITE:
|
if request.host != SITE:
|
||||||
abort(403, "Unauthorized host provided!")
|
abort(403, "Unauthorized host provided!")
|
||||||
|
|
||||||
|
if SITE == 'marsey.world' and request.path != '/kofi':
|
||||||
|
abort(404)
|
||||||
|
|
||||||
if request.headers.get("CF-Worker"):
|
if request.headers.get("CF-Worker"):
|
||||||
abort(403, "Cloudflare workers are not allowed to access this website.")
|
abort(403, "Cloudflare workers are not allowed to access this website.")
|
||||||
|
|
||||||
if not get_setting('bots') and request.headers.get("Authorization"): abort(403)
|
g.agent = request.headers.get("User-Agent", "")
|
||||||
|
if not g.agent and request.path != '/kofi':
|
||||||
|
abort(403, 'Please use a "User-Agent" header!')
|
||||||
|
|
||||||
|
if not get_setting('bots') and request.headers.get("Authorization"):
|
||||||
|
abort(403)
|
||||||
|
|
||||||
|
g.desires_auth = False
|
||||||
|
if not IS_LOCALHOST:
|
||||||
|
app.config["COOKIE_DOMAIN"] = f".{request.host}"
|
||||||
|
app.config["SESSION_COOKIE_DOMAIN"] = app.config["COOKIE_DOMAIN"]
|
||||||
|
|
||||||
|
ua = g.agent.lower()
|
||||||
|
|
||||||
|
g.nonce = None
|
||||||
|
|
||||||
if '; wv) ' in ua:
|
if '; wv) ' in ua:
|
||||||
g.browser = 'webview'
|
g.browser = 'webview'
|
||||||
|
@ -54,11 +58,57 @@ def before_request():
|
||||||
limiter.check()
|
limiter.check()
|
||||||
g.db = db_session()
|
g.db = db_session()
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
CSP = {
|
||||||
|
"upgrade-insecure-requests": "",
|
||||||
|
|
||||||
|
"default-src": "'none'",
|
||||||
|
"frame-ancestors": "'none'",
|
||||||
|
|
||||||
|
"form-action": "'self'",
|
||||||
|
"manifest-src": "'self'",
|
||||||
|
"worker-src": "'self'",
|
||||||
|
"base-uri": "'self'",
|
||||||
|
"font-src": "'self'",
|
||||||
|
"media-src": "'self'",
|
||||||
|
|
||||||
|
"style-src-elem": "'self' 'nonce-{nonce}'",
|
||||||
|
"style-src-attr": "'unsafe-inline'",
|
||||||
|
"style-src": "'self' 'unsafe-inline'",
|
||||||
|
|
||||||
|
"script-src-elem": "'self' 'nonce-{nonce}' challenges.cloudflare.com",
|
||||||
|
"script-src-attr": "'unsafe-inline'",
|
||||||
|
"script-src": "'self' 'unsafe-inline' challenges.cloudflare.com",
|
||||||
|
|
||||||
|
"img-src": "https:",
|
||||||
|
"frame-src": "challenges.cloudflare.com www.youtube-nocookie.com platform.twitter.com",
|
||||||
|
"connect-src": "'self' tls-use1.fpapi.io api.fpjs.io",
|
||||||
|
|
||||||
|
"report-to": "csp",
|
||||||
|
"report-uri": "/csp_violations",
|
||||||
|
}
|
||||||
|
|
||||||
|
if IS_LOCALHOST:
|
||||||
|
CSP["style-src-elem"] += " rdrama.net"
|
||||||
|
CSP["script-src-elem"] += " rdrama.net"
|
||||||
|
CSP["img-src"] += " http:"
|
||||||
|
|
||||||
|
CSP_str = ''
|
||||||
|
|
||||||
|
for k, val in CSP.items():
|
||||||
|
CSP_str += f'{k} {val}; '
|
||||||
|
|
||||||
@app.after_request
|
@app.after_request
|
||||||
def after_request(response:Response):
|
def after_request(response:Response):
|
||||||
if response.status_code < 400:
|
if response.status_code < 400:
|
||||||
_set_cloudflare_cookie(response)
|
_set_cloudflare_cookie(response)
|
||||||
_commit_and_close_db()
|
_commit_and_close_db()
|
||||||
|
|
||||||
|
if g.nonce:
|
||||||
|
response.headers.add("Report-To", {"group":"csp","max_age":10886400,"endpoints":[{"url":"/csp_violations"}]})
|
||||||
|
response.headers.add("Content-Security-Policy", CSP_str.format(nonce=g.nonce))
|
||||||
|
|
||||||
return response
|
return response
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -333,3 +333,11 @@ if not os.path.exists(f'files/templates/donate_{SITE_NAME}.html'):
|
||||||
@auth_desired_with_logingate
|
@auth_desired_with_logingate
|
||||||
def donate(v):
|
def donate(v):
|
||||||
return render_template(f'donate_{SITE_NAME}.html', v=v)
|
return render_template(f'donate_{SITE_NAME}.html', v=v)
|
||||||
|
|
||||||
|
|
||||||
|
@app.post('/csp_violations')
|
||||||
|
@limiter.limit("10/minute;50/day")
|
||||||
|
def csp_violations():
|
||||||
|
content = request.get_json(force=True)
|
||||||
|
print(json.dumps(content, indent=4, sort_keys=True), flush=True)
|
||||||
|
return ''
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
import time
|
import time
|
||||||
|
import secrets
|
||||||
from flask import g, request, session
|
from flask import g, request, session
|
||||||
|
|
||||||
from files.classes.clients import ClientAuth
|
from files.classes.clients import ClientAuth
|
||||||
|
@ -40,7 +41,8 @@ def get_logged_in_user():
|
||||||
else:
|
else:
|
||||||
session.pop("lo_user")
|
session.pop("lo_user")
|
||||||
|
|
||||||
g.is_api_or_xhr = bool((v and v.client) or request.headers.get("xhr"))
|
g.is_api = v and v.client
|
||||||
|
g.is_api_or_xhr = bool(g.is_api or request.headers.get("xhr"))
|
||||||
|
|
||||||
if request.method.lower() != "get" and get_setting('read_only_mode') and not (v and v.admin_level >= PERMS['SITE_BYPASS_READ_ONLY_MODE']):
|
if request.method.lower() != "get" and get_setting('read_only_mode') and not (v and v.admin_level >= PERMS['SITE_BYPASS_READ_ONLY_MODE']):
|
||||||
abort(403)
|
abort(403)
|
||||||
|
@ -67,6 +69,10 @@ def get_logged_in_user():
|
||||||
if f'@{v.username}, ' not in f.read():
|
if f'@{v.username}, ' not in f.read():
|
||||||
t = time.strftime("%d/%B/%Y %H:%M:%S UTC", time.gmtime(time.time()))
|
t = time.strftime("%d/%B/%Y %H:%M:%S UTC", time.gmtime(time.time()))
|
||||||
log_file(f'@{v.username}, {v.truescore}, {ip}, {t}\n', 'eg.log')
|
log_file(f'@{v.username}, {v.truescore}, {ip}, {t}\n', 'eg.log')
|
||||||
|
|
||||||
|
if not g.is_api:
|
||||||
|
g.nonce = secrets.token_urlsafe(16)
|
||||||
|
|
||||||
return v
|
return v
|
||||||
|
|
||||||
def auth_desired(f):
|
def auth_desired(f):
|
||||||
|
|
|
@ -66,7 +66,7 @@
|
||||||
</section>
|
</section>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
|
|
||||||
<script>
|
<script nonce="{{g.nonce}}">
|
||||||
function submitAddAlt(element) {
|
function submitAddAlt(element) {
|
||||||
if (!element || !element.form) return;
|
if (!element || !element.form) return;
|
||||||
const isLinking = element.id == 'add-alt-form-link';
|
const isLinking = element.id == 'add-alt-form-link';
|
||||||
|
|
|
@ -54,7 +54,7 @@
|
||||||
|
|
||||||
</form>
|
</form>
|
||||||
|
|
||||||
<style>
|
<style nonce="{{g.nonce}}">
|
||||||
@media (max-width: 767.98px) {
|
@media (max-width: 767.98px) {
|
||||||
table {
|
table {
|
||||||
display: inline-block;
|
display: inline-block;
|
||||||
|
|
|
@ -3,7 +3,7 @@
|
||||||
|
|
||||||
{% block content %}
|
{% block content %}
|
||||||
|
|
||||||
<script>
|
<script nonce="{{g.nonce}}">
|
||||||
function unbanDomain(t, domain) {
|
function unbanDomain(t, domain) {
|
||||||
postToastSwitch(t,'/admin/unban_domain/' + domain);
|
postToastSwitch(t,'/admin/unban_domain/' + domain);
|
||||||
t.parentElement.parentElement.remove();
|
t.parentElement.parentElement.remove();
|
||||||
|
|
|
@ -50,7 +50,7 @@
|
||||||
{% endif %}
|
{% endif %}
|
||||||
|
|
||||||
{% if p.award_count("tilt", v) %}
|
{% if p.award_count("tilt", v) %}
|
||||||
<style>
|
<style nonce="{{g.nonce}}">
|
||||||
@keyframes post-tilt {
|
@keyframes post-tilt {
|
||||||
0% {transform: rotate(0deg);}
|
0% {transform: rotate(0deg);}
|
||||||
25% {transform: rotate({{p.award_count("tilt", v)}}deg);}
|
25% {transform: rotate({{p.award_count("tilt", v)}}deg);}
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
{% extends "casino/game_screen.html" %}
|
{% extends "casino/game_screen.html" %}
|
||||||
|
|
||||||
{% block script %}
|
{% block script %}
|
||||||
<script>
|
<script nonce="{{g.nonce}}">
|
||||||
function makeBlackjackRequest(action) {
|
function makeBlackjackRequest(action) {
|
||||||
const xhr = new XMLHttpRequest();
|
const xhr = new XMLHttpRequest();
|
||||||
xhr.open("post", `/casino/twentyone/${action}`);
|
xhr.open("post", `/casino/twentyone/${action}`);
|
||||||
|
@ -236,7 +236,7 @@
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
|
|
||||||
{% block actions %}
|
{% block actions %}
|
||||||
<style>
|
<style nonce="{{g.nonce}}">
|
||||||
.blackjack-cardset {
|
.blackjack-cardset {
|
||||||
position: relative;
|
position: relative;
|
||||||
display: flex;
|
display: flex;
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
{% extends "default.html" %}
|
{% extends "default.html" %}
|
||||||
{% block pagetitle %}{{game.capitalize()}}{% endblock %}
|
{% block pagetitle %}{{game.capitalize()}}{% endblock %}
|
||||||
{% block content %}
|
{% block content %}
|
||||||
<style>
|
<style nonce="{{g.nonce}}">
|
||||||
.game_screen-title {
|
.game_screen-title {
|
||||||
display: flex;
|
display: flex;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
|
@ -27,7 +27,7 @@
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|
||||||
<script type="text/javascript">
|
<script nonce="{{g.nonce}}">
|
||||||
/**
|
/**
|
||||||
* This script block contains generic helper function usable across casino games:
|
* This script block contains generic helper function usable across casino games:
|
||||||
* - Wagers
|
* - Wagers
|
||||||
|
@ -233,7 +233,7 @@
|
||||||
|
|
||||||
{% block script %} {% endblock %}
|
{% block script %} {% endblock %}
|
||||||
|
|
||||||
<style>
|
<style nonce="{{g.nonce}}">
|
||||||
@keyframes drawing {
|
@keyframes drawing {
|
||||||
from {
|
from {
|
||||||
left: 0;
|
left: 0;
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
{% extends "casino/game_screen.html" %} {% block result %} N/A {% endblock %}
|
{% extends "casino/game_screen.html" %} {% block result %} N/A {% endblock %}
|
||||||
|
|
||||||
{% block script %}
|
{% block script %}
|
||||||
<script type="text/javascript">
|
<script nonce="{{g.nonce}}">
|
||||||
if (
|
if (
|
||||||
document.readyState === "complete" ||
|
document.readyState === "complete" ||
|
||||||
(document.readyState !== "loading" && !document.documentElement.doScroll)
|
(document.readyState !== "loading" && !document.documentElement.doScroll)
|
||||||
|
@ -393,7 +393,7 @@
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
|
|
||||||
{% block screen %}
|
{% block screen %}
|
||||||
<style>
|
<style nonce="{{g.nonce}}">
|
||||||
.roulette-table-number {
|
.roulette-table-number {
|
||||||
flex: 1;
|
flex: 1;
|
||||||
height: 60px;
|
height: 60px;
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
{% extends "casino/game_screen.html" %} {% block result %} N/A {% endblock %}
|
{% extends "casino/game_screen.html" %} {% block result %} N/A {% endblock %}
|
||||||
|
|
||||||
{% block script %}
|
{% block script %}
|
||||||
<script type="text/javascript">
|
<script nonce="{{g.nonce}}">
|
||||||
function pullSlots() {
|
function pullSlots() {
|
||||||
const { amount, currency } = getWager();
|
const { amount, currency } = getWager();
|
||||||
|
|
||||||
|
@ -73,7 +73,7 @@
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
|
|
||||||
{% block screen %}
|
{% block screen %}
|
||||||
<style>
|
<style nonce="{{g.nonce}}">
|
||||||
.slots_reels {
|
.slots_reels {
|
||||||
display: flex;
|
display: flex;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
|
|
|
@ -17,7 +17,7 @@
|
||||||
data-avatar="{{v.profile_url}}"
|
data-avatar="{{v.profile_url}}"
|
||||||
data-hat="{{v.hat_active(v)[0]}}">
|
data-hat="{{v.hat_active(v)[0]}}">
|
||||||
</div>
|
</div>
|
||||||
<script>window.global = window</script>
|
<script nonce="{{g.nonce}}">window.global = window</script>
|
||||||
{% if IS_LOCALHOST %}
|
{% if IS_LOCALHOST %}
|
||||||
<script defer src="https://rdrama.net/assets/js/chat_done.js"></script>
|
<script defer src="https://rdrama.net/assets/js/chat_done.js"></script>
|
||||||
{% else %}
|
{% else %}
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
{%- import 'util/macros.html' as macros with context -%}
|
{%- import 'util/macros.html' as macros with context -%}
|
||||||
{% if not request.headers.get("xhr") %}
|
{% if not request.headers.get("xhr") %}
|
||||||
{% if comment_info %}
|
{% if comment_info %}
|
||||||
<script>
|
<script nonce="{{g.nonce}}">
|
||||||
if (location.hash != 'context')
|
if (location.hash != 'context')
|
||||||
location.hash = 'context'
|
location.hash = 'context'
|
||||||
</script>
|
</script>
|
||||||
|
@ -246,7 +246,7 @@
|
||||||
{% endif %}
|
{% endif %}
|
||||||
|
|
||||||
{% if c.award_count("tilt", v) %}
|
{% if c.award_count("tilt", v) %}
|
||||||
<style>
|
<style nonce="{{g.nonce}}">
|
||||||
@keyframes c{{c.id}}-tilt {
|
@keyframes c{{c.id}}-tilt {
|
||||||
0% {transform: rotate(0deg);}
|
0% {transform: rotate(0deg);}
|
||||||
25% {transform: rotate({{c.award_count("tilt", v)}}deg);}
|
25% {transform: rotate({{c.award_count("tilt", v)}}deg);}
|
||||||
|
@ -786,7 +786,7 @@
|
||||||
<script defer src="{{'js/comments+submission_listing.js' | asset}}"></script>
|
<script defer src="{{'js/comments+submission_listing.js' | asset}}"></script>
|
||||||
<script defer src="{{'js/comments.js' | asset}}"></script>
|
<script defer src="{{'js/comments.js' | asset}}"></script>
|
||||||
|
|
||||||
<script>
|
<script nonce="{{g.nonce}}">
|
||||||
{% if p and (not v or v.highlightcomments) %}
|
{% if p and (not v or v.highlightcomments) %}
|
||||||
comments = JSON.parse(localStorage.getItem("comment-counts")) || {}
|
comments = JSON.parse(localStorage.getItem("comment-counts")) || {}
|
||||||
lastCount = comments['{{p.id}}']
|
lastCount = comments['{{p.id}}']
|
||||||
|
@ -852,7 +852,7 @@
|
||||||
{# TODO: disabled pending fix #}
|
{# TODO: disabled pending fix #}
|
||||||
{% if false %}
|
{% if false %}
|
||||||
<div id="detection" style="display:none;background-color:canvas;color-scheme:light"></div>
|
<div id="detection" style="display:none;background-color:canvas;color-scheme:light"></div>
|
||||||
<script>
|
<script nonce="{{g.nonce}}">
|
||||||
const detectionDiv = document.querySelector('#detection');
|
const detectionDiv = document.querySelector('#detection');
|
||||||
const isAutoDark = getComputedStyle(detectionDiv).backgroundColor != 'rgb(255, 255, 255)';
|
const isAutoDark = getComputedStyle(detectionDiv).backgroundColor != 'rgb(255, 255, 255)';
|
||||||
if (!isAutoDark) {
|
if (!isAutoDark) {
|
||||||
|
|
|
@ -80,7 +80,7 @@
|
||||||
{% endif %}
|
{% endif %}
|
||||||
|
|
||||||
{% if g.browser == 'apple' %}
|
{% if g.browser == 'apple' %}
|
||||||
<script>
|
<script nonce="{{g.nonce}}">
|
||||||
document.addEventListener('DOMContentLoaded', function() {
|
document.addEventListener('DOMContentLoaded', function() {
|
||||||
const videos = document.querySelectorAll('video')
|
const videos = document.querySelectorAll('video')
|
||||||
|
|
||||||
|
|
|
@ -3,8 +3,6 @@
|
||||||
<html>
|
<html>
|
||||||
<head>
|
<head>
|
||||||
<meta name="description" content="{{DESCRIPTION}}">
|
<meta name="description" content="{{DESCRIPTION}}">
|
||||||
<meta http-equiv="Content-Security-Policy" content="script-src 'self' 'unsafe-inline'; connect-src 'self'; object-src 'none';">
|
|
||||||
|
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||||
<meta name="x-apple-disable-message-reformatting">
|
<meta name="x-apple-disable-message-reformatting">
|
||||||
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
|
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
|
||||||
|
|
|
@ -3,35 +3,8 @@
|
||||||
<head>
|
<head>
|
||||||
<meta name="description" content="People die and this is the place to see it. You only have one life, don't make the mistakes seen here.">
|
<meta name="description" content="People die and this is the place to see it. You only have one life, don't make the mistakes seen here.">
|
||||||
|
|
||||||
<meta http-equiv="Content-Security-Policy" content="script-src 'self' 'unsafe-inline'; connect-src 'self'; object-src 'none';">
|
<meta http-equiv="Content-Security-Policy" content="default-src 'none'; style-src 'self'; font-src 'self'; img-src 'self';">
|
||||||
|
|
||||||
<style>
|
|
||||||
:root{--primary:#ff66ac}
|
|
||||||
.mod:before {
|
|
||||||
content: "(((";
|
|
||||||
}
|
|
||||||
.mod:after {
|
|
||||||
content: ")))";
|
|
||||||
}
|
|
||||||
body {
|
|
||||||
padding-top: 54px !important;
|
|
||||||
}
|
|
||||||
@media (max-width: 767.98px) {
|
|
||||||
body {
|
|
||||||
padding-top: 44px !important;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@media (min-width: 380px) {
|
|
||||||
#logo {
|
|
||||||
width: 100px;
|
|
||||||
margin-left: 0.5rem !important;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
.pad {
|
|
||||||
padding-bottom: 7.4px;
|
|
||||||
padding-top: 7.4px;
|
|
||||||
}
|
|
||||||
</style>
|
|
||||||
<link rel="stylesheet" href="/assets/css/main.css?v=4032">
|
<link rel="stylesheet" href="/assets/css/main.css?v=4032">
|
||||||
<link rel="stylesheet" href="/assets/css/midnight.css?v=4000">
|
<link rel="stylesheet" href="/assets/css/midnight.css?v=4000">
|
||||||
|
|
||||||
|
@ -50,7 +23,6 @@
|
||||||
<meta name="viewport" content="width=device-width,initial-scale=1">
|
<meta name="viewport" content="width=device-width,initial-scale=1">
|
||||||
|
|
||||||
<link rel="apple-touch-icon" sizes="180x180" href="/icon.webp?v=1">
|
<link rel="apple-touch-icon" sizes="180x180" href="/icon.webp?v=1">
|
||||||
<link rel="manifest" href="/assets/manifest_WPD.json?v=426">
|
|
||||||
<link rel="mask-icon" href="/icon.webp?v=1">
|
<link rel="mask-icon" href="/icon.webp?v=1">
|
||||||
<link rel="shortcut icon" href="/icon.webp?v=1">
|
<link rel="shortcut icon" href="/icon.webp?v=1">
|
||||||
<meta name="apple-mobile-web-app-title" content="WPD">
|
<meta name="apple-mobile-web-app-title" content="WPD">
|
||||||
|
@ -93,7 +65,7 @@
|
||||||
|
|
||||||
<nav class="shadow-md fixed-top">
|
<nav class="shadow-md fixed-top">
|
||||||
<div class="navbar navbar-expand-md navbar-light" id="navbar">
|
<div class="navbar navbar-expand-md navbar-light" id="navbar">
|
||||||
<div class="container-fluid" style="padding: 0;">
|
<div class="container-fluid p-0">
|
||||||
<a href="/" class="navbar-brand mr-auto">
|
<a href="/" class="navbar-brand mr-auto">
|
||||||
<img id="header--icon" alt="header icon" src="/i/WPD/headericon.webp?v=3009">
|
<img id="header--icon" alt="header icon" src="/i/WPD/headericon.webp?v=3009">
|
||||||
</a>
|
</a>
|
||||||
|
@ -105,10 +77,10 @@
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="flex-grow-1 d-fl d-mob-none pad">
|
<div class="flex-grow-1 d-fl d-mob-none pad">
|
||||||
<form class="form-inline search flex-nowrap mx-0 mx-lg-auto" style="margin-right: 40rem !important;" action="/search/posts/" method="get">
|
<form class="form-inline search flex-nowrap mx-0 mx-lg-auto" action="/search/posts/" method="get">
|
||||||
<input autocomplete="off" class="form-control w-100" type="search" placeholder="Search" name="q" value="">
|
<input autocomplete="off" class="form-control w-100" type="search" placeholder="Search" name="q" value="">
|
||||||
<span class="input-group-append">
|
<span class="input-group-append">
|
||||||
<span class="input-group-text border-0 bg-transparent" style="margin-left: -2.5rem;">
|
<span class="input-group-text border-0 bg-transparent">
|
||||||
<i class="fa fa-search"></i>
|
<i class="fa fa-search"></i>
|
||||||
</span>
|
</span>
|
||||||
</span>
|
</span>
|
||||||
|
|
|
@ -3,35 +3,8 @@
|
||||||
<head>
|
<head>
|
||||||
<meta name="description" content="rdrama.net caters to drama in all forms such as: Real life, videos, photos, gossip, rumors, news sites, Reddit, and Beyond™. There isn't drama we won't touch, and we want it all!">
|
<meta name="description" content="rdrama.net caters to drama in all forms such as: Real life, videos, photos, gossip, rumors, news sites, Reddit, and Beyond™. There isn't drama we won't touch, and we want it all!">
|
||||||
|
|
||||||
<meta http-equiv="Content-Security-Policy" content="script-src 'self' 'unsafe-inline'; connect-src 'self'; object-src 'none';">
|
<meta http-equiv="Content-Security-Policy" content="default-src 'none'; style-src 'self'; font-src 'self'; img-src 'self';">
|
||||||
|
|
||||||
<style>
|
|
||||||
:root{--primary:#ff66ac}
|
|
||||||
.mod:before {
|
|
||||||
content: "(((";
|
|
||||||
}
|
|
||||||
.mod:after {
|
|
||||||
content: ")))";
|
|
||||||
}
|
|
||||||
body {
|
|
||||||
padding-top: 54px !important;
|
|
||||||
}
|
|
||||||
@media (max-width: 767.98px) {
|
|
||||||
body {
|
|
||||||
padding-top: 44px !important;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@media (min-width: 380px) {
|
|
||||||
#logo {
|
|
||||||
width: 100px;
|
|
||||||
margin-left: 0.5rem !important;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
.pad {
|
|
||||||
padding-bottom: 7.4px;
|
|
||||||
padding-top: 7.4px;
|
|
||||||
}
|
|
||||||
</style>
|
|
||||||
<link rel="stylesheet" href="/assets/css/main.css?v=4032">
|
<link rel="stylesheet" href="/assets/css/main.css?v=4032">
|
||||||
<link rel="stylesheet" href="/assets/css/midnight.css?v=4000">
|
<link rel="stylesheet" href="/assets/css/midnight.css?v=4000">
|
||||||
|
|
||||||
|
@ -50,7 +23,6 @@
|
||||||
<meta name="viewport" content="width=device-width,initial-scale=1">
|
<meta name="viewport" content="width=device-width,initial-scale=1">
|
||||||
|
|
||||||
<link rel="apple-touch-icon" sizes="180x180" href="/icon.webp?v=1">
|
<link rel="apple-touch-icon" sizes="180x180" href="/icon.webp?v=1">
|
||||||
<link rel="manifest" href="/assets/manifest_rDrama.json?v=426">
|
|
||||||
<link rel="mask-icon" href="/icon.webp?v=1">
|
<link rel="mask-icon" href="/icon.webp?v=1">
|
||||||
<link rel="shortcut icon" href="/icon.webp?v=1">
|
<link rel="shortcut icon" href="/icon.webp?v=1">
|
||||||
<meta name="apple-mobile-web-app-title" content="rDrama">
|
<meta name="apple-mobile-web-app-title" content="rDrama">
|
||||||
|
@ -93,7 +65,7 @@
|
||||||
|
|
||||||
<nav class="shadow-md fixed-top">
|
<nav class="shadow-md fixed-top">
|
||||||
<div class="navbar navbar-expand-md navbar-light" id="navbar">
|
<div class="navbar navbar-expand-md navbar-light" id="navbar">
|
||||||
<div class="container-fluid" style="padding: 0;">
|
<div class="container-fluid p-0">
|
||||||
<a href="/" class="navbar-brand mr-auto">
|
<a href="/" class="navbar-brand mr-auto">
|
||||||
<img id="header--icon" alt="header icon" src="/i/rDrama/headericon.webp?v=3009">
|
<img id="header--icon" alt="header icon" src="/i/rDrama/headericon.webp?v=3009">
|
||||||
</a>
|
</a>
|
||||||
|
@ -105,10 +77,10 @@
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="flex-grow-1 d-fl d-mob-none pad">
|
<div class="flex-grow-1 d-fl d-mob-none pad">
|
||||||
<form class="form-inline search flex-nowrap mx-0 mx-lg-auto" style="margin-right: 40rem !important;" action="/search/posts/" method="get">
|
<form class="form-inline search flex-nowrap mx-0 mx-lg-auto" action="/search/posts/" method="get">
|
||||||
<input autocomplete="off" class="form-control w-100" type="search" placeholder="Search" name="q" value="">
|
<input autocomplete="off" class="form-control w-100" type="search" placeholder="Search" name="q" value="">
|
||||||
<span class="input-group-append">
|
<span class="input-group-append">
|
||||||
<span class="input-group-text border-0 bg-transparent" style="margin-left: -2.5rem;">
|
<span class="input-group-text border-0 bg-transparent">
|
||||||
<i class="fa fa-search"></i>
|
<i class="fa fa-search"></i>
|
||||||
</span>
|
</span>
|
||||||
</span>
|
</span>
|
||||||
|
|
|
@ -9,19 +9,19 @@
|
||||||
{# idk why snow isn't working vvvvvvvvvv #}
|
{# idk why snow isn't working vvvvvvvvvv #}
|
||||||
{% if p.award_count("snow", v) %}
|
{% if p.award_count("snow", v) %}
|
||||||
<script src="{{'event/js/snow.js'|asset}}"></script>
|
<script src="{{'event/js/snow.js'|asset}}"></script>
|
||||||
<script>snow(80);</script>
|
<script nonce="{{g.nonce}}">snow(80);</script>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
|
|
||||||
{% if p.award_count("frostbite", v) %}
|
{% if p.award_count("frostbite", v) %}
|
||||||
<div class="frost"></div>
|
<div class="frost"></div>
|
||||||
<script>
|
<script nonce="{{g.nonce}}">
|
||||||
const root = document.querySelector(':root');
|
const root = document.querySelector(':root');
|
||||||
|
|
||||||
const count = 5;
|
const count = 5;
|
||||||
const opacity = count * 0.1;
|
const opacity = count * 0.1;
|
||||||
root.style.setProperty('--opacity-frost', opacity);
|
root.style.setProperty('--opacity-frost', opacity);
|
||||||
</script>
|
</script>
|
||||||
<style>
|
<style nonce="{{g.nonce}}">
|
||||||
:root {
|
:root {
|
||||||
--opacity-frost: 0.25;
|
--opacity-frost: 0.25;
|
||||||
}
|
}
|
||||||
|
@ -41,7 +41,7 @@
|
||||||
{% if p.award_count("snowed-in", v) %}
|
{% if p.award_count("snowed-in", v) %}
|
||||||
<canvas id="canvas-snowed-in-overlay"></canvas>
|
<canvas id="canvas-snowed-in-overlay"></canvas>
|
||||||
<canvas id="canvas-snowed-in-lines"></canvas>
|
<canvas id="canvas-snowed-in-lines"></canvas>
|
||||||
<style>
|
<style nonce="{{g.nonce}}">
|
||||||
#canvas-snowed-in-overlay {
|
#canvas-snowed-in-overlay {
|
||||||
position: fixed;
|
position: fixed;
|
||||||
top: 0;
|
top: 0;
|
||||||
|
@ -64,7 +64,7 @@
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
{% if p.award_count("lights", v) %}
|
{% if p.award_count("lights", v) %}
|
||||||
<style>
|
<style nonce="{{g.nonce}}">
|
||||||
#post-root::before {
|
#post-root::before {
|
||||||
content: "";
|
content: "";
|
||||||
position: absolute;
|
position: absolute;
|
||||||
|
@ -81,7 +81,7 @@
|
||||||
{% endif %}
|
{% endif %}
|
||||||
|
|
||||||
{% if p.award_count("candycane", v) %}
|
{% if p.award_count("candycane", v) %}
|
||||||
<style>
|
<style nonce="{{g.nonce}}">
|
||||||
#post-title, #post-content p {
|
#post-title, #post-content p {
|
||||||
--color2: #cc4145;
|
--color2: #cc4145;
|
||||||
--color1: rgb(12, 128, 101);
|
--color1: rgb(12, 128, 101);
|
||||||
|
@ -108,7 +108,7 @@
|
||||||
{% endif %}
|
{% endif %}
|
||||||
|
|
||||||
{% if p.award_count("fireplace", v) %}
|
{% if p.award_count("fireplace", v) %}
|
||||||
<style>
|
<style nonce="{{g.nonce}}">
|
||||||
#banner-skybox {
|
#banner-skybox {
|
||||||
fill: url(#skybox-gradient-night)
|
fill: url(#skybox-gradient-night)
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
{# <script src="{{'event/js/neko.js'|asset}}"></script> #}
|
{# <script src="{{'event/js/neko.js'|asset}}"></script> #}
|
||||||
{% if request.path == '/' %}
|
{% if request.path == '/' %}
|
||||||
<script src="{{'event/js/snow.js'|asset}}"></script>
|
<script src="{{'event/js/snow.js'|asset}}"></script>
|
||||||
<script>snow(80);</script>
|
<script nonce="{{g.nonce}}">snow(80);</script>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
|
|
||||||
<a rel="nofollow noopener noreferrer" href="https://www.youtube.com/watch?v=BuKft9LpL_0" style="text-decoration: none !important">
|
<a rel="nofollow noopener noreferrer" href="https://www.youtube.com/watch?v=BuKft9LpL_0" style="text-decoration: none !important">
|
||||||
|
|
|
@ -199,7 +199,7 @@
|
||||||
<circle cx="169.44" cy="10.935"/>
|
<circle cx="169.44" cy="10.935"/>
|
||||||
</g>
|
</g>
|
||||||
<defs>
|
<defs>
|
||||||
<style>.star1 circle {r: 0.5;}
|
<style nonce="{{g.nonce}}">.star1 circle {r: 0.5;}
|
||||||
.star2 circle {r: 0.75;}
|
.star2 circle {r: 0.75;}
|
||||||
.star3 circle {r: 1.0;}
|
.star3 circle {r: 1.0;}
|
||||||
.star4 circle {r: 1.2;}
|
.star4 circle {r: 1.2;}
|
||||||
|
|
Before Width: | Height: | Size: 17 KiB After Width: | Height: | Size: 17 KiB |
|
@ -199,7 +199,7 @@
|
||||||
<circle cx="169.44" cy="10.935"/>
|
<circle cx="169.44" cy="10.935"/>
|
||||||
</g>
|
</g>
|
||||||
<defs>
|
<defs>
|
||||||
<style>.star1 circle {r: 0.5;}
|
<style nonce="{{g.nonce}}">.star1 circle {r: 0.5;}
|
||||||
.star2 circle {r: 0.75;}
|
.star2 circle {r: 0.75;}
|
||||||
.star3 circle {r: 1.0;}
|
.star3 circle {r: 1.0;}
|
||||||
.star4 circle {r: 1.2;}
|
.star4 circle {r: 1.2;}
|
||||||
|
|
Before Width: | Height: | Size: 17 KiB After Width: | Height: | Size: 17 KiB |
|
@ -3,7 +3,7 @@
|
||||||
{% set path = "assets/event/media/music" %}
|
{% set path = "assets/event/media/music" %}
|
||||||
{% set song = "/" ~ path ~ "/" ~ listdir('files/' ~ path)|random() ~ '?v=45' %}
|
{% set song = "/" ~ path ~ "/" ~ listdir('files/' ~ path)|random() ~ '?v=45' %}
|
||||||
{% endif %}
|
{% endif %}
|
||||||
<script>
|
<script nonce="{{g.nonce}}">
|
||||||
const audio = new Audio("{{song}}");
|
const audio = new Audio("{{song}}");
|
||||||
audio.loop=true;
|
audio.loop=true;
|
||||||
|
|
||||||
|
|
|
@ -3,7 +3,7 @@
|
||||||
{% block pagetype %}message{% endblock %}
|
{% block pagetype %}message{% endblock %}
|
||||||
|
|
||||||
{% block banner %}
|
{% block banner %}
|
||||||
<style>
|
<style nonce="{{g.nonce}}">
|
||||||
.shop-tabs {
|
.shop-tabs {
|
||||||
padding-top: 50px;
|
padding-top: 50px;
|
||||||
}
|
}
|
||||||
|
@ -59,7 +59,7 @@
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
|
|
||||||
{% block content %}
|
{% block content %}
|
||||||
<script>
|
<script nonce="{{g.nonce}}">
|
||||||
function equip_hat(t, hat_id, hat_name) {
|
function equip_hat(t, hat_id, hat_name) {
|
||||||
const profile_pic_hat = document.getElementById("profile-pic-35-hat");
|
const profile_pic_hat = document.getElementById("profile-pic-35-hat");
|
||||||
function extra_actions(xhr) {
|
function extra_actions(xhr) {
|
||||||
|
|
|
@ -4,7 +4,7 @@
|
||||||
{%- endif -%}
|
{%- endif -%}
|
||||||
|
|
||||||
<nav class="shadow-md fixed-top">
|
<nav class="shadow-md fixed-top">
|
||||||
<style>
|
<style nonce="{{g.nonce}}">
|
||||||
body {padding-top: 83px !important}
|
body {padding-top: 83px !important}
|
||||||
@media (max-width: 767.98px) {
|
@media (max-width: 767.98px) {
|
||||||
body {
|
body {
|
||||||
|
@ -50,7 +50,7 @@
|
||||||
{% endif %}
|
{% endif %}
|
||||||
</div>
|
</div>
|
||||||
{% else %}
|
{% else %}
|
||||||
<style>
|
<style nonce="{{g.nonce}}">
|
||||||
body {padding-top: 54px !important}
|
body {padding-top: 54px !important}
|
||||||
@media (max-width: 767.98px) {
|
@media (max-width: 767.98px) {
|
||||||
body {
|
body {
|
||||||
|
@ -75,7 +75,7 @@
|
||||||
{% if sub %}
|
{% if sub %}
|
||||||
<a id="sub-name" href="/h/{{sub}}" class="font-weight-bold ml-2 flex-grow-1 mt-1" {% if sub.name|length >= 17 %}style="font-size:max(10px,1.2vw)"{% else %}style="font-size:max(14px,1.2vw)"{% endif %}>{% if not HOLE_STYLE_FLAIR %}/h/{% endif %}{{sub}}</a>
|
<a id="sub-name" href="/h/{{sub}}" class="font-weight-bold ml-2 flex-grow-1 mt-1" {% if sub.name|length >= 17 %}style="font-size:max(10px,1.2vw)"{% else %}style="font-size:max(14px,1.2vw)"{% endif %}>{% if not HOLE_STYLE_FLAIR %}/h/{% endif %}{{sub}}</a>
|
||||||
{% elif has_logo %}
|
{% elif has_logo %}
|
||||||
<style>
|
<style nonce="{{g.nonce}}">
|
||||||
{% if SITE_NAME == 'WPD' %}
|
{% if SITE_NAME == 'WPD' %}
|
||||||
@media (min-width: 1000px) {
|
@media (min-width: 1000px) {
|
||||||
{% else %}
|
{% else %}
|
||||||
|
@ -358,12 +358,12 @@
|
||||||
<div id="formkey" class="d-none">{{v|formkey}}</div>
|
<div id="formkey" class="d-none">{{v|formkey}}</div>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
|
|
||||||
<script>
|
<script nonce="{{g.nonce}}">
|
||||||
IMAGE_FORMATS = {{IMAGE_FORMATS|safe}};
|
IMAGE_FORMATS = {{IMAGE_FORMATS|safe}};
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
{% if not v %}
|
{% if not v %}
|
||||||
<style>
|
<style nonce="{{g.nonce}}">
|
||||||
.pad {
|
.pad {
|
||||||
padding-bottom: 7.4px;
|
padding-bottom: 7.4px;
|
||||||
padding-top: 7.4px;
|
padding-top: 7.4px;
|
||||||
|
@ -372,7 +372,7 @@
|
||||||
{% endif %}
|
{% endif %}
|
||||||
|
|
||||||
{% if v and v.poor -%}
|
{% if v and v.poor -%}
|
||||||
<style>
|
<style nonce="{{g.nonce}}">
|
||||||
* :not(img[src="/i/hand.webp"] + img, img.golden, img[g], img[glow], .live-circle) {
|
* :not(img[src="/i/hand.webp"] + img, img.golden, img[g], img[glow], .live-circle) {
|
||||||
animation: unset !important;
|
animation: unset !important;
|
||||||
}
|
}
|
||||||
|
|
|
@ -62,7 +62,7 @@
|
||||||
{% block navbar %}
|
{% block navbar %}
|
||||||
<div class="d-flex align-items-center">
|
<div class="d-flex align-items-center">
|
||||||
{% if SITE_NAME != 'WPD' and not sub %}
|
{% if SITE_NAME != 'WPD' and not sub %}
|
||||||
<style>
|
<style nonce="{{g.nonce}}">
|
||||||
@media (max-width: 427px) {
|
@media (max-width: 427px) {
|
||||||
.smol-fp {
|
.smol-fp {
|
||||||
font-size: 2.7vw;
|
font-size: 2.7vw;
|
||||||
|
@ -169,7 +169,7 @@
|
||||||
|
|
||||||
{% if request.path == '/' and v %}
|
{% if request.path == '/' and v %}
|
||||||
<script defer src="/assets/js/register_service_worker.js"></script>
|
<script defer src="/assets/js/register_service_worker.js"></script>
|
||||||
<script>
|
<script nonce="{{g.nonce}}">
|
||||||
document.addEventListener('DOMContentLoaded', function () {
|
document.addEventListener('DOMContentLoaded', function () {
|
||||||
registerServiceWorker(
|
registerServiceWorker(
|
||||||
"/assets/js/service_worker.js",
|
"/assets/js/service_worker.js",
|
||||||
|
@ -180,7 +180,7 @@
|
||||||
{% endif %}
|
{% endif %}
|
||||||
|
|
||||||
{% if request.path == '/' and g.browser != 'webview' and time.time() > session.get('tooltip_last_dismissed',0)+86400*30 %}
|
{% if request.path == '/' and g.browser != 'webview' and time.time() > session.get('tooltip_last_dismissed',0)+86400*30 %}
|
||||||
<style>
|
<style nonce="{{g.nonce}}">
|
||||||
.dismiss-beg {
|
.dismiss-beg {
|
||||||
color: #919191;
|
color: #919191;
|
||||||
float: left;
|
float: left;
|
||||||
|
@ -193,7 +193,7 @@
|
||||||
<div id="mobile-prompt" data-bs-toggle="tooltip" data-bs-container="#mobile-prompt-container" data-bs-placement="top" data-bs-trigger="click" data-bs-html="true" title="<i class='dismiss-beg fas fa-x'></i>Click me to install the {{SITE_NAME}} mobile app!"></div>
|
<div id="mobile-prompt" data-bs-toggle="tooltip" data-bs-container="#mobile-prompt-container" data-bs-placement="top" data-bs-trigger="click" data-bs-html="true" title="<i class='dismiss-beg fas fa-x'></i>Click me to install the {{SITE_NAME}} mobile app!"></div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<script>
|
<script nonce="{{g.nonce}}">
|
||||||
if (!window.matchMedia('(display-mode: minimal-ui)')['matches']) {
|
if (!window.matchMedia('(display-mode: minimal-ui)')['matches']) {
|
||||||
if (window.innerWidth <= 737) {
|
if (window.innerWidth <= 737) {
|
||||||
document.addEventListener('DOMContentLoaded', function() {
|
document.addEventListener('DOMContentLoaded', function() {
|
||||||
|
@ -214,7 +214,7 @@
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style>
|
<style nonce="{{g.nonce}}">
|
||||||
#mobile-prompt + .bs-tooltip-bottom {
|
#mobile-prompt + .bs-tooltip-bottom {
|
||||||
transform: None !important;
|
transform: None !important;
|
||||||
inset: 0px 0px auto auto !important;
|
inset: 0px 0px auto auto !important;
|
||||||
|
@ -224,7 +224,7 @@
|
||||||
|
|
||||||
{% if request.path == '/' and v and FP %}
|
{% if request.path == '/' and v and FP %}
|
||||||
{% if not v.fp %}
|
{% if not v.fp %}
|
||||||
<script>
|
<script nonce="{{g.nonce}}">
|
||||||
function fp(fp) {
|
function fp(fp) {
|
||||||
const xhr = new XMLHttpRequest();
|
const xhr = new XMLHttpRequest();
|
||||||
xhr.open("POST", '/fp/'+fp);
|
xhr.open("POST", '/fp/'+fp);
|
||||||
|
|
|
@ -2,25 +2,25 @@
|
||||||
{% block pagetitle %}Moderation Log{% endblock %}
|
{% block pagetitle %}Moderation Log{% endblock %}
|
||||||
{% block content %}
|
{% block content %}
|
||||||
{% if v %}
|
{% if v %}
|
||||||
<style>:root{--primary:#{{v.themecolor}}}</style>
|
<style nonce="{{g.nonce}}">:root{--primary:#{{v.themecolor}}}</style>
|
||||||
<link rel="stylesheet" href="{{'css/main.css' | asset}}">
|
<link rel="stylesheet" href="{{'css/main.css' | asset}}">
|
||||||
{% if v.theme == 'classic_dark' %}
|
{% if v.theme == 'classic_dark' %}
|
||||||
<link rel="stylesheet" href="{{('css/classic.css') | asset}}">
|
<link rel="stylesheet" href="{{('css/classic.css') | asset}}">
|
||||||
{% endif %}
|
{% endif %}
|
||||||
<link rel="stylesheet" href="{{('css/'~v.theme~'.css') | asset}}">
|
<link rel="stylesheet" href="{{('css/'~v.theme~'.css') | asset}}">
|
||||||
{% if v.agendaposter %}
|
{% if v.agendaposter %}
|
||||||
<style>
|
<style nonce="{{g.nonce}}">
|
||||||
html {
|
html {
|
||||||
cursor:url('/i/dildo.webp?v=2000'), auto;
|
cursor:url('/i/dildo.webp?v=2000'), auto;
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
{% elif v.css %}
|
{% elif v.css %}
|
||||||
<style>
|
<style nonce="{{g.nonce}}">
|
||||||
{{v.css | safe}}
|
{{v.css | safe}}
|
||||||
</style>
|
</style>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
{% else %}
|
{% else %}
|
||||||
<style>:root{--primary:#{{DEFAULT_COLOR}}</style>
|
<style nonce="{{g.nonce}}">:root{--primary:#{{DEFAULT_COLOR}}</style>
|
||||||
<link rel="stylesheet" href="{{'css/main.css' | asset}}">
|
<link rel="stylesheet" href="{{'css/main.css' | asset}}">
|
||||||
<link rel="stylesheet" href="{{('css/'~DEFAULT_THEME~'.css') | asset}}">
|
<link rel="stylesheet" href="{{('css/'~DEFAULT_THEME~'.css') | asset}}">
|
||||||
{% endif %}
|
{% endif %}
|
||||||
|
|
|
@ -23,7 +23,7 @@
|
||||||
<small><a href="/lost_2fa">Lost your 2FA device?</a></small>
|
<small><a href="/lost_2fa">Lost your 2FA device?</a></small>
|
||||||
<button type="submit" class="btn btn-primary login w-100 mt-3" id="login_button">Sign in</button>
|
<button type="submit" class="btn btn-primary login w-100 mt-3" id="login_button">Sign in</button>
|
||||||
</form>
|
</form>
|
||||||
<script>
|
<script nonce="{{g.nonce}}">
|
||||||
document.getElementById('2fa_token').focus()
|
document.getElementById('2fa_token').focus()
|
||||||
</script>
|
</script>
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
<div id="form" class="d-none"></div>
|
<div id="form" class="d-none"></div>
|
||||||
<div class="modal fade" id="emojiModal" tabindex="-1" role="dialog">
|
<div class="modal fade" id="emojiModal" tabindex="-1" role="dialog">
|
||||||
<style>
|
<style nonce="{{g.nonce}}">
|
||||||
#emojiTabs {height: 80%;}
|
#emojiTabs {height: 80%;}
|
||||||
@media (max-width: 650px) {
|
@media (max-width: 650px) {
|
||||||
#emojiTabs {height: 100%;}
|
#emojiTabs {height: 100%;}
|
||||||
|
@ -70,7 +70,7 @@
|
||||||
I've took the liberty to populate this tab with a selection of Anton's emojis 😽. Next time you'll find the ones you used the most in there 📚
|
I've took the liberty to populate this tab with a selection of Anton's emojis 😽. Next time you'll find the ones you used the most in there 📚
|
||||||
</div>
|
</div>
|
||||||
<div id="tab-content" class="tab-content d-flex flex-wrap py-3 pl-2" hidden style="text-align:center;">
|
<div id="tab-content" class="tab-content d-flex flex-wrap py-3 pl-2" hidden style="text-align:center;">
|
||||||
<style>
|
<style nonce="{{g.nonce}}">
|
||||||
.emoji2 {
|
.emoji2 {
|
||||||
/*background: None!important;*/
|
/*background: None!important;*/
|
||||||
width:60px;
|
width:60px;
|
||||||
|
|
|
@ -152,7 +152,7 @@
|
||||||
</ul>
|
</ul>
|
||||||
</nav>
|
</nav>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
<style>
|
<style nonce="{{g.nonce}}">
|
||||||
.comment {
|
.comment {
|
||||||
margin-top: 0.3rem;
|
margin-top: 0.3rem;
|
||||||
}
|
}
|
||||||
|
|
|
@ -42,7 +42,7 @@
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<script>
|
<script nonce="{{g.nonce}}">
|
||||||
document.addEventListener('DOMContentLoaded', function() {
|
document.addEventListener('DOMContentLoaded', function() {
|
||||||
for (const x of ['css','profilecss']) {
|
for (const x of ['css','profilecss']) {
|
||||||
const ta = document.getElementById(`${x}-textarea`);
|
const ta = document.getElementById(`${x}-textarea`);
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
{% extends "settings.html" %}
|
{% extends "settings.html" %}
|
||||||
{% block pagetitle %}Personal Settings{% endblock %}
|
{% block pagetitle %}Personal Settings{% endblock %}
|
||||||
{% block content %}
|
{% block content %}
|
||||||
<style>
|
<style nonce="{{g.nonce}}">
|
||||||
.bg-image {
|
.bg-image {
|
||||||
padding: 0.25rem;
|
padding: 0.25rem;
|
||||||
width: 15rem;
|
width: 15rem;
|
||||||
|
@ -279,7 +279,7 @@
|
||||||
{% include "modals/gif.html" %}
|
{% include "modals/gif.html" %}
|
||||||
|
|
||||||
{% if v.flairchanged %}
|
{% if v.flairchanged %}
|
||||||
<script>
|
<script nonce="{{g.nonce}}">
|
||||||
document.addEventListener('DOMContentLoaded', function() {
|
document.addEventListener('DOMContentLoaded', function() {
|
||||||
const date = formatDate(new Date({{v.flairchanged}}*1000));
|
const date = formatDate(new Date({{v.flairchanged}}*1000));
|
||||||
const text = ` - Your flair has been locked until ${date}`;
|
const text = ` - Your flair has been locked until ${date}`;
|
||||||
|
@ -326,7 +326,7 @@
|
||||||
{{permanent_filter_modal('profanityreplacer', '/settings/personal', 'profanityreplacer', 'Profanity Replacer', 'Soapy-Mouthed Angel')}}
|
{{permanent_filter_modal('profanityreplacer', '/settings/personal', 'profanityreplacer', 'Profanity Replacer', 'Soapy-Mouthed Angel')}}
|
||||||
{%- endif %}
|
{%- endif %}
|
||||||
{% if FEATURES['USERS_PERMANENT_WORD_FILTERS'] -%}
|
{% if FEATURES['USERS_PERMANENT_WORD_FILTERS'] -%}
|
||||||
<script>
|
<script nonce="{{g.nonce}}">
|
||||||
document.addEventListener("DOMContentLoaded", function (event) {
|
document.addEventListener("DOMContentLoaded", function (event) {
|
||||||
const sr_toggle = document.getElementById("slurreplacer");
|
const sr_toggle = document.getElementById("slurreplacer");
|
||||||
const sr_link = document.getElementById('slurreplacer-perma-link');
|
const sr_link = document.getElementById('slurreplacer-perma-link');
|
||||||
|
|
|
@ -7,7 +7,7 @@
|
||||||
{% block pagetitle %}Shop{% endblock %}
|
{% block pagetitle %}Shop{% endblock %}
|
||||||
{% block pagetype %}message{% endblock %}
|
{% block pagetype %}message{% endblock %}
|
||||||
{% block banner %}
|
{% block banner %}
|
||||||
<style>
|
<style nonce="{{g.nonce}}">
|
||||||
.shop-tabs {
|
.shop-tabs {
|
||||||
padding-top: 50px;
|
padding-top: 50px;
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
{% block pagetitle %}/h/{{sub}} Mods{% endblock %}
|
{% block pagetitle %}/h/{{sub}} Mods{% endblock %}
|
||||||
{% block content %}
|
{% block content %}
|
||||||
|
|
||||||
<script>
|
<script nonce="{{g.nonce}}">
|
||||||
function removeMod(e) {
|
function removeMod(e) {
|
||||||
sendFormXHR(e,
|
sendFormXHR(e,
|
||||||
() => {
|
() => {
|
||||||
|
|
|
@ -8,7 +8,7 @@
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
{% block pagetype %}thread{% endblock %}
|
{% block pagetype %}thread{% endblock %}
|
||||||
{% block head_final %}
|
{% block head_final %}
|
||||||
<style>
|
<style nonce="{{g.nonce}}">
|
||||||
body > .container {
|
body > .container {
|
||||||
padding-left: 20px !important;
|
padding-left: 20px !important;
|
||||||
padding-right: 20px !important;
|
padding-right: 20px !important;
|
||||||
|
@ -350,7 +350,7 @@
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
{% if offset %}
|
{% if offset %}
|
||||||
<script>
|
<script nonce="{{g.nonce}}">
|
||||||
function viewmore(pid,sort,offset,ids) {
|
function viewmore(pid,sort,offset,ids) {
|
||||||
btn = document.getElementById("viewbtn");
|
btn = document.getElementById("viewbtn");
|
||||||
btn.disabled = true;
|
btn.disabled = true;
|
||||||
|
@ -417,7 +417,7 @@
|
||||||
{% if not p.replies %}{% include "comments.html" %}{% endif %}
|
{% if not p.replies %}{% include "comments.html" %}{% endif %}
|
||||||
|
|
||||||
{% if not v or v.highlightcomments %}
|
{% if not v or v.highlightcomments %}
|
||||||
<script>
|
<script nonce="{{g.nonce}}">
|
||||||
document.addEventListener('DOMContentLoaded', function() {
|
document.addEventListener('DOMContentLoaded', function() {
|
||||||
showNewCommentCounts('{{p.id}}', {{p.comment_count}})
|
showNewCommentCounts('{{p.id}}', {{p.comment_count}})
|
||||||
{% if "?context" not in request.full_path %}
|
{% if "?context" not in request.full_path %}
|
||||||
|
@ -429,10 +429,11 @@
|
||||||
localStorage.setItem("comment-counts", JSON.stringify(comments))
|
localStorage.setItem("comment-counts", JSON.stringify(comments))
|
||||||
{% endif %}
|
{% endif %}
|
||||||
})
|
})
|
||||||
</script>
|
</script>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
|
|
||||||
{% if success %}
|
{% if success %}
|
||||||
<script>
|
<script nonce="{{g.nonce}}">
|
||||||
history.pushState(null, null, '{{p.permalink}}');
|
history.pushState(null, null, '{{p.permalink}}');
|
||||||
localStorage.setItem("post-title", "")
|
localStorage.setItem("post-title", "")
|
||||||
localStorage.setItem("post-text", "")
|
localStorage.setItem("post-text", "")
|
||||||
|
@ -448,7 +449,7 @@
|
||||||
{% endif %}
|
{% endif %}
|
||||||
|
|
||||||
{% if fart and not (v and v.has_badge(128)) %}
|
{% if fart and not (v and v.has_badge(128)) %}
|
||||||
<script>
|
<script nonce="{{g.nonce}}">
|
||||||
fart = Math.floor(Math.random() * 5) + 1
|
fart = Math.floor(Math.random() * 5) + 1
|
||||||
let audio = new Audio(`/assets/images/${fart}.webp`);
|
let audio = new Audio(`/assets/images/${fart}.webp`);
|
||||||
|
|
||||||
|
|
|
@ -75,7 +75,7 @@
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
{% if offset %}
|
{% if offset %}
|
||||||
<script>
|
<script nonce="{{g.nonce}}">
|
||||||
function viewmore(pid,sort,offset,ids) {
|
function viewmore(pid,sort,offset,ids) {
|
||||||
btn = document.getElementById("viewbtn");
|
btn = document.getElementById("viewbtn");
|
||||||
btn.disabled = true;
|
btn.disabled = true;
|
||||||
|
|
|
@ -214,7 +214,7 @@
|
||||||
</div>
|
</div>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
|
|
||||||
<script>
|
<script nonce="{{g.nonce}}">
|
||||||
{% if not v or v.highlightcomments %}
|
{% if not v or v.highlightcomments %}
|
||||||
document.addEventListener('DOMContentLoaded', function() {
|
document.addEventListener('DOMContentLoaded', function() {
|
||||||
showNewCommentCounts({{p.id}}, {{p.comment_count}})
|
showNewCommentCounts({{p.id}}, {{p.comment_count}})
|
||||||
|
|
|
@ -105,7 +105,7 @@
|
||||||
</div>
|
</div>
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
{% if request.path == '/submit' %}
|
{% if request.path == '/submit' %}
|
||||||
<script>
|
<script nonce="{{g.nonce}}">
|
||||||
let sub = document.getElementById('sub')
|
let sub = document.getElementById('sub')
|
||||||
if (sub) sub.value = localStorage.getItem("sub")
|
if (sub) sub.value = localStorage.getItem("sub")
|
||||||
</script>
|
</script>
|
||||||
|
|
|
@ -47,7 +47,7 @@
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<script>
|
<script nonce="{{g.nonce}}">
|
||||||
document.onpaste = function(event) {
|
document.onpaste = function(event) {
|
||||||
files = structuredClone(event.clipboardData.files);
|
files = structuredClone(event.clipboardData.files);
|
||||||
|
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
{% block pagetitle %}Submit Marseys{% endblock %}
|
{% block pagetitle %}Submit Marseys{% endblock %}
|
||||||
{% block pagetype %}message{% endblock %}
|
{% block pagetype %}message{% endblock %}
|
||||||
{% block content %}
|
{% block content %}
|
||||||
<style>
|
<style nonce="{{g.nonce}}">
|
||||||
input:not(.btn) {
|
input:not(.btn) {
|
||||||
text-transform: lowercase;
|
text-transform: lowercase;
|
||||||
}
|
}
|
||||||
|
@ -47,7 +47,7 @@
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<script>
|
<script nonce="{{g.nonce}}">
|
||||||
document.onpaste = function(event) {
|
document.onpaste = function(event) {
|
||||||
files = structuredClone(event.clipboardData.files);
|
files = structuredClone(event.clipboardData.files);
|
||||||
|
|
||||||
|
|
|
@ -41,7 +41,7 @@
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<script>
|
<script nonce="{{g.nonce}}">
|
||||||
document.onpaste = function(event) {
|
document.onpaste = function(event) {
|
||||||
files = structuredClone(event.clipboardData.files);
|
files = structuredClone(event.clipboardData.files);
|
||||||
|
|
||||||
|
|
|
@ -7,7 +7,7 @@
|
||||||
{% if not HOLIDAY_EVENT %}
|
{% if not HOLIDAY_EVENT %}
|
||||||
<link rel="stylesheet" href="{{('css/transparent.css') | asset}}">
|
<link rel="stylesheet" href="{{('css/transparent.css') | asset}}">
|
||||||
{% endif %}
|
{% endif %}
|
||||||
<style>
|
<style nonce="{{g.nonce}}">
|
||||||
body {
|
body {
|
||||||
background-image: url('{{u.profile_background}}') !important;
|
background-image: url('{{u.profile_background}}') !important;
|
||||||
}
|
}
|
||||||
|
|
|
@ -10,7 +10,7 @@
|
||||||
<script defer src="{{'js/vendor/bootstrap.js' | asset}}"></script>
|
<script defer src="{{'js/vendor/bootstrap.js' | asset}}"></script>
|
||||||
<script defer src="{{'js/core.js' | asset}}"></script>
|
<script defer src="{{'js/core.js' | asset}}"></script>
|
||||||
|
|
||||||
<script>
|
<script nonce="{{g.nonce}}">
|
||||||
if (window.matchMedia('(display-mode: minimal-ui)')['matches']) {
|
if (window.matchMedia('(display-mode: minimal-ui)')['matches']) {
|
||||||
const links = document.querySelectorAll('a[data-target="t"]');
|
const links = document.querySelectorAll('a[data-target="t"]');
|
||||||
for (const link of links) {
|
for (const link of links) {
|
||||||
|
@ -106,9 +106,9 @@
|
||||||
<link rel="stylesheet" href="{{'css/main.css' | asset}}">
|
<link rel="stylesheet" href="{{'css/main.css' | asset}}">
|
||||||
<link id="favicon" rel="icon" type="image/webp" href="/icon.webp?v=1">
|
<link id="favicon" rel="icon" type="image/webp" href="/icon.webp?v=1">
|
||||||
{% if v %}
|
{% if v %}
|
||||||
<style>:root{--primary:#{{v.themecolor}}}</style>
|
<style nonce="{{g.nonce}}">:root{--primary:#{{v.themecolor}}}</style>
|
||||||
{% if v.agendaposter %}
|
{% if v.agendaposter %}
|
||||||
<style>
|
<style nonce="{{g.nonce}}">
|
||||||
html {
|
html {
|
||||||
cursor:url('/i/dildo.webp?v=2000'), auto;
|
cursor:url('/i/dildo.webp?v=2000'), auto;
|
||||||
}
|
}
|
||||||
|
@ -120,12 +120,12 @@
|
||||||
{% endif %}
|
{% endif %}
|
||||||
<link rel="stylesheet" href="{{('css/'~v.theme~'.css') | asset}}">
|
<link rel="stylesheet" href="{{('css/'~v.theme~'.css') | asset}}">
|
||||||
{% if v.css and not request.path.startswith('/settings') %}
|
{% if v.css and not request.path.startswith('/settings') %}
|
||||||
<style>
|
<style nonce="{{g.nonce}}">
|
||||||
{{v.css | safe}}
|
{{v.css | safe}}
|
||||||
</style>
|
</style>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
{% if v.themecolor == '30409f' %}
|
{% if v.themecolor == '30409f' %}
|
||||||
<style>
|
<style nonce="{{g.nonce}}">
|
||||||
p a {
|
p a {
|
||||||
color: #2a96f3;
|
color: #2a96f3;
|
||||||
}
|
}
|
||||||
|
@ -145,7 +145,7 @@
|
||||||
{% endif %}
|
{% endif %}
|
||||||
|
|
||||||
{% if SITE_NAME == 'rDrama' %}
|
{% if SITE_NAME == 'rDrama' %}
|
||||||
<style>
|
<style nonce="{{g.nonce}}">
|
||||||
.mod:before {
|
.mod:before {
|
||||||
content: '(((';
|
content: '(((';
|
||||||
}
|
}
|
||||||
|
@ -188,7 +188,7 @@
|
||||||
{% if not HOLIDAY_EVENT %}
|
{% if not HOLIDAY_EVENT %}
|
||||||
<link rel="stylesheet" href="{{('css/transparent.css') | asset}}">
|
<link rel="stylesheet" href="{{('css/transparent.css') | asset}}">
|
||||||
{% endif %}
|
{% endif %}
|
||||||
<style>
|
<style nonce="{{g.nonce}}">
|
||||||
body {
|
body {
|
||||||
background:url("{{background}}") center center fixed;
|
background:url("{{background}}") center center fixed;
|
||||||
background-color: rgb(var(--background));
|
background-color: rgb(var(--background));
|
||||||
|
@ -202,7 +202,7 @@
|
||||||
{% endmacro %}
|
{% endmacro %}
|
||||||
|
|
||||||
{% macro default_theme() %}
|
{% macro default_theme() %}
|
||||||
<style>:root{--primary:#{{DEFAULT_COLOR}}}</style>
|
<style nonce="{{g.nonce}}">:root{--primary:#{{DEFAULT_COLOR}}}</style>
|
||||||
<link rel="stylesheet" href="{{('css/'~DEFAULT_THEME~'.css') | asset}}">
|
<link rel="stylesheet" href="{{('css/'~DEFAULT_THEME~'.css') | asset}}">
|
||||||
{% endmacro %}
|
{% endmacro %}
|
||||||
|
|
||||||
|
|
|
@ -2,4 +2,3 @@ add_header Referrer-Policy "same-origin";
|
||||||
add_header Strict-Transport-Security "max-age=31536000; includeSubDomains; preload";
|
add_header Strict-Transport-Security "max-age=31536000; includeSubDomains; preload";
|
||||||
add_header X-Frame-Options "deny";
|
add_header X-Frame-Options "deny";
|
||||||
add_header X-Content-Type-Options "nosniff";
|
add_header X-Content-Type-Options "nosniff";
|
||||||
add_header Content-Security-Policy "script-src 'self' 'unsafe-inline' challenges.cloudflare.com rdrama.net; connect-src 'self' tls-use1.fpapi.io api.fpjs.io; object-src 'none';";
|
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
include includes/headers;
|
include includes/headers;
|
||||||
|
add_header Content-Security-Policy "default-src 'none';";
|
||||||
sendfile on;
|
sendfile on;
|
||||||
sendfile_max_chunk 1m;
|
sendfile_max_chunk 1m;
|
||||||
tcp_nopush on;
|
tcp_nopush on;
|
||||||
|
|
12
nginx.conf
12
nginx.conf
|
@ -5,6 +5,7 @@ server {
|
||||||
listen [::]:80;
|
listen [::]:80;
|
||||||
proxy_set_header Host $http_host;
|
proxy_set_header Host $http_host;
|
||||||
include includes/headers;
|
include includes/headers;
|
||||||
|
add_header Content-Security-Policy "default-src 'none';";
|
||||||
|
|
||||||
location / {
|
location / {
|
||||||
proxy_pass http://localhost:5000/;
|
proxy_pass http://localhost:5000/;
|
||||||
|
@ -18,6 +19,7 @@ server {
|
||||||
proxy_set_header Connection "Upgrade";
|
proxy_set_header Connection "Upgrade";
|
||||||
proxy_pass http://localhost:5001/socket.io;
|
proxy_pass http://localhost:5001/socket.io;
|
||||||
include includes/headers;
|
include includes/headers;
|
||||||
|
add_header Content-Security-Policy "default-src 'none';";
|
||||||
}
|
}
|
||||||
location /chat {
|
location /chat {
|
||||||
proxy_pass http://localhost:5001/chat;
|
proxy_pass http://localhost:5001/chat;
|
||||||
|
@ -70,6 +72,16 @@ server {
|
||||||
alias /rDrama/files/assets/images/rDrama/icon.webp;
|
alias /rDrama/files/assets/images/rDrama/icon.webp;
|
||||||
include includes/serve-static;
|
include includes/serve-static;
|
||||||
}
|
}
|
||||||
|
location =/favicon.ico {
|
||||||
|
alias /rDrama/files/assets/images/rDrama/icon.webp;
|
||||||
|
include includes/serve-static;
|
||||||
|
}
|
||||||
|
location =/offline.html {
|
||||||
|
alias /rDrama/files/assets/offline.html;
|
||||||
|
add_header Content-Security-Policy "default-src 'none'; style-src 'unsafe-inline'; img-src data:;";
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
error_page 502 = /502.html;
|
error_page 502 = /502.html;
|
||||||
location =/502.html {
|
location =/502.html {
|
||||||
|
|
Loading…
Reference in New Issue