1
0
mirror of https://git.sr.ht/~tsileo/microblog.pub synced 2025-06-05 21:59:23 +02:00

4 Commits

9 changed files with 230 additions and 174 deletions

View File

@ -109,6 +109,8 @@ class Config(pydantic.BaseModel):
inbox_retention_days: int = 15
custom_content_security_policy: str | None = None
# Config items to make tests easier
sqlalchemy_database: str | None = None
key_path: str | None = None
@ -165,6 +167,7 @@ if CONFIG.privacy_replace:
BLOCKED_SERVERS = {blocked_server.hostname for blocked_server in CONFIG.blocked_servers}
ALSO_KNOWN_AS = CONFIG.also_known_as
CUSTOM_CONTENT_SECURITY_POLICY = CONFIG.custom_content_security_policy
INBOX_RETENTION_DAYS = CONFIG.inbox_retention_days
CUSTOM_FOOTER = (

View File

@ -137,10 +137,16 @@ class CustomMiddleware:
headers["x-frame-options"] = "DENY"
headers["permissions-policy"] = "interest-cohort=()"
headers["content-security-policy"] = (
(
f"default-src 'self'; "
f"style-src 'self' 'sha256-{HIGHLIGHT_CSS_HASH}'; "
f"frame-ancestors 'none'; base-uri 'self'; form-action 'self';"
)
if not config.CUSTOM_CONTENT_SECURITY_POLICY
else config.CUSTOM_CONTENT_SECURITY_POLICY.format(
HIGHLIGHT_CSS_HASH=HIGHLIGHT_CSS_HASH
)
)
if not DEBUG:
headers["strict-transport-security"] = "max-age=63072000;"

View File

@ -1,9 +1,11 @@
$font-stack: Helvetica, sans-serif;
$font-stack: -apple-system, BlinkMacSystemFont, avenir next, avenir, segoe ui, helvetica neue, helvetica, Cantarell,
Ubuntu, roboto, noto, arial, sans-serif;
$background: #ddd;
$light-background: #e6e6e6;
$text-color: #111;
$primary-color: #1d781d;
$secondary-color: #781D78;
$secondary-color: #781d78;
$form-background-color: #ccc;
$form-text-color: #333;
$muted-color: #555; // solarized comment text
@ -13,6 +15,46 @@ $code-highlight-background: #f0f0f0;
// Load custom theme
@import "theme.scss";
/* Box sizing rules */
*,
*::before,
*::after {
box-sizing: border-box;
}
/* Set core root defaults */
html:focus-within {
scroll-behavior: smooth;
}
/* Inherit fonts for inputs and buttons */
input,
button,
textarea,
select {
font: inherit;
}
html {
max-width: 90ch;
padding: 3em 1em;
margin: auto;
line-height: 1.75;
font-size: 1.25em;
}
body {
font-family: $font-stack;
background: $background;
color: $text-color;
display: flex;
min-height: 100vh;
flex-direction: column;
}
a {
text-decoration: none;
}
.primary-color {
color: $primary-color;
}
@ -84,7 +126,6 @@ $code-highlight-background: #f0f0f0;
}
}
blockquote {
border-left: 3px solid $secondary-color;
margin-left: 0;
@ -99,23 +140,6 @@ blockquote {
background: $light-background;
}
body {
font-family: $font-stack;
font-size: 20px;
line-height: 32px;
background: $background;
color: $text-color;
margin: 0;
padding: 0;
display: flex;
min-height: 100vh;
flex-direction: column;
}
a {
text-decoration: none;
}
dl {
display: flex;
dt {
@ -160,13 +184,16 @@ div.highlight {
padding: 0 20px;
}
code, pre {
code,
pre {
color: $secondary-color; // #cb4b16; // #268bd2; // #2aa198;
font-family: monospace;
}
.form {
input, select, textarea {
input,
select,
textarea {
font-size: 20px;
border: 0;
padding: 5px;
@ -176,7 +203,7 @@ code, pre {
outline: 1px solid $secondary-color;
}
}
input[type=submit] {
input[type="submit"] {
font-size: 20px;
outline: none;
background: $primary-color;
@ -217,7 +244,6 @@ a {
}
main {
width: 100%;
max-width: 1000px;
margin: 30px auto;
}
@ -237,8 +263,8 @@ main {
}
footer {
font-size: 1em;
width: 100%;
max-width: 1000px;
margin: 20px auto;
color: $muted-color;
p {
@ -279,7 +305,9 @@ footer {
}
}
#notifications, #followers, #following {
#notifications,
#followers,
#following {
ul {
list-style-type: none;
margin: 0;
@ -304,7 +332,9 @@ footer {
}
}
.show-sensitive-btn, .show-more-btn, .label-btn {
.show-sensitive-btn,
.show-more-btn,
.label-btn {
@include admin-button;
padding: 10px 5px;
margin: 20px 0;
@ -335,13 +365,13 @@ ul.poll-items {
}
.poll-bar {
width:100%;height:20px;
width: 100%;
height: 20px;
line {
stroke: $secondary-color;
stroke-width: 20px;
}
}
}
}
@ -365,7 +395,8 @@ nav {
form {
margin: 15px 0;
}
input[type=submit], button {
input[type="submit"],
button {
@include admin-button;
}
}
@ -378,7 +409,6 @@ nav.flexbox {
list-style-type: none;
margin: 0;
padding: 0;
}
ul li {
@ -391,7 +421,8 @@ nav.flexbox {
a:not(.label-btn) {
color: $primary-color;
text-decoration: none;
&:hover, &:active {
&:hover,
&:active {
color: $secondary-color;
text-decoration: underline;
}
@ -421,14 +452,17 @@ a.label-btn {
display: inline;
color: $muted-color;
}
.e-content, .activity-og-meta {
.e-content,
.activity-og-meta {
a:hover {
text-decoration: underline;
}
}
.activity-attachment {
margin: 30px 0 20px 0;
img, audio, video {
img,
audio,
video {
width: 100%;
max-width: 740px;
}
@ -471,7 +505,8 @@ a.label-btn {
.actor-metadata {
color: $muted-color;
}
.emoji, .custom-emoji {
.emoji,
.custom-emoji {
max-width: 25px;
}

View File

@ -424,3 +424,4 @@ _templates.env.globals["BASE_URL"] = config.BASE_URL
_templates.env.globals["HIDES_FOLLOWERS"] = config.HIDES_FOLLOWERS
_templates.env.globals["HIDES_FOLLOWING"] = config.HIDES_FOLLOWING
_templates.env.globals["NAVBAR_ITEMS"] = config.NavBarItems
_templates.env.globals["ICON_URL"] = config.CONFIG.icon_url

View File

@ -14,7 +14,7 @@
<meta content="{{ local_actor.display_name }}'s microblog" property="og:site_name" />
<meta content="Homepage" property="og:title" />
<meta content="{{ local_actor.summary | html2text | trim }}" property="og:description" />
<meta content="{{ local_actor.url }}" property="og:image" />
<meta content="{{ ICON_URL }}" property="og:image" />
<meta content="summary" property="twitter:card" />
<meta content="{{ local_actor.handle }}" property="profile:username" />
{% endif %}

View File

@ -26,11 +26,12 @@
{%- macro header_link(url, text) -%}
{% set url_for = BASE_URL + request.app.router.url_path_for(url) %}
<a href="{{ url_for }}" {% if request.url.path == url_for %}class="active"{% endif %}>{{ text }}</a>
<a href="{{ url_for }}" {% if BASE_URL + request.url.path == url_for %}class="active"{% endif %}>{{ text }}</a>
{% endmacro %}
{%- macro navbar_item_link(navbar_item) -%}
<a href="{{ navbar_item[0] }}" {% if request.url.path == navbar_item[0] %}class="active"{% endif %}>{{ navbar_item[1] }}</a>
{% set url_for = BASE_URL + navbar_item[0] %}
<a href="{{ navbar_item[0] }}" {% if BASE_URL + request.url.path == url_for %}class="active"{% endif %}>{{ navbar_item[1] }}</a>
{% endmacro %}
<div class="public-top-menu">

View File

@ -13,7 +13,7 @@
<meta content="{{ local_actor.display_name }}'s microblog" property="og:site_name" />
<meta content="Homepage" property="og:title" />
<meta content="{{ local_actor.summary | html2text | trim }}" property="og:description" />
<meta content="{{ local_actor.url }}" property="og:image" />
<meta content="{{ ICON_URL }}" property="og:image" />
<meta content="summary" property="twitter:card" />
<meta content="{{ local_actor.handle }}" property="profile:username" />
{% endblock %}

View File

@ -19,7 +19,7 @@
<div id="admin">
{% macro admin_link(url, text) %}
{% set url_for = BASE_URL + request.app.router.url_path_for(url) %}
<a href="{{ url_for }}" {% if request.url.path == url_for %}class="active"{% endif %}>{{ text }}</a>
<a href="{{ url_for }}" {% if BASE_URL + request.url.path == url_for %}class="active"{% endif %}>{{ text }}</a>
{% endmacro %}
<div class="admin-menu">
<nav class="flexbox">

View File

@ -131,9 +131,19 @@ See `app/scss/main.scss` to see what variables can be overridden.
If you'd like to customize your instance's theme beyond CSS, you can modify the app's HTML by placing templates in `data/templates` which overwrite the defaults in `app/templates`.
#### Custom Content Security Policy (CSP)
You can override the default Content Security Policy by adding a line in `data/profile.toml`:
```toml
custom_content_security_policy = "default-src 'self'; style-src 'self' 'sha256-{HIGHLIGHT_CSS_HASH}'; frame-ancestors 'none'; base-uri 'self'; form-action 'self';"
```
This example will output the default CSP, note that `{HIGHLIGHT_CSS_HASH}` will be dynamically replaced by the correct value (the hash of the CSS needed for syntax highlighting).
#### Code highlighting theme
You can switch to one of the [styles supported by Pygments](https://pygments.org/styles/) by adding a line in `profile.toml`:
You can switch to one of the [styles supported by Pygments](https://pygments.org/styles/) by adding a line in `data/profile.toml`:
```toml
code_highlighting_theme = "solarized-dark"