✨ feat(footer/socials): add base64 encoded email protection
This commit is contained in:
parent
68e37f4574
commit
427ffc7241
@ -208,6 +208,14 @@ menu = [
|
||||
# The RSS icon will be shown if (1) it's enabled and (2) the following variable is set to true.
|
||||
feed_icon = true
|
||||
|
||||
# Email address for footer's social section.
|
||||
# Protect against spambots:
|
||||
# 1. Use base64 for email (convert at https://www.base64encode.org/ or `printf 'your@email.com' | base64`).
|
||||
# 2. Or, set 'encode_plaintext_email' to true for auto-encoding (only protects on site, not in public repos).
|
||||
email = "bWFpbEBleGFtcGxlLmNvbQ==" # base64 encoded version of "mail@example.com"
|
||||
# Decoding requires ~400 bytes of JavaScript. If JS is disabled, the email won't be displayed.
|
||||
encode_plaintext_email = true # Setting is ignored if email is already encoded.
|
||||
|
||||
# The icons available can be found in "social_icons" in the "static" folder.
|
||||
socials = [
|
||||
{ name = "github", url = "https://github.com/welpo/", icon = "github" },
|
||||
|
@ -1,18 +1,23 @@
|
||||
+++
|
||||
title = "Sense JavaScript obligatori"
|
||||
date = 2023-01-06
|
||||
updated = 2023-08-02
|
||||
updated = 2023-08-18
|
||||
description = "JavaScript només s'utilitza quan HTML i CSS no són suficients."
|
||||
|
||||
[taxonomies]
|
||||
tags = ["funcionalitat", "tutorial"]
|
||||
|
||||
[extra]
|
||||
footnote_backlinks = true
|
||||
+++
|
||||
|
||||
Aquest tema no requereix JavaScript obligatori. Opcionalment, pot carregar una quantitat mínima per afegir algunes característiques que són impossibles d'aconseguir amb HTML i CSS.
|
||||
|
||||
## Opcions habilitades globalment
|
||||
|
||||
L'**interruptor de mode clar/fosc** pot habilitar-se configurant `theme_switcher = true` a la secció `[extra]` del teu `config.toml` (~900 bytes de JavaScript).
|
||||
- L'**interruptor de mode clar/fosc** pot habilitar-se configurant `theme_switcher = true` a la secció `[extra]` del teu `config.toml` (~900 bytes de JavaScript).
|
||||
|
||||
- **Decodificació del correu** (~400 bytes). Per protegir el teu lloc correu dels [robots de correu brossa](https://ca.wikipedia.org/wiki/Robot_de_correu_brossa), pots configurar `encode_plaintext_email = true`. Si el teu lloc web està en un repositori públic, per a una protecció millorada, considera configurar el teu `email` com una cadena codificada en base64[^1] directament (per exemple: `email = "bWFpbEBleGFtcGxlLmNvbQ=="`).
|
||||
|
||||
## Configuracions que es poden habilitar tant globalment com en publicacions individuals
|
||||
|
||||
@ -28,3 +33,7 @@ Per habilitar aquestes configuracions globalment, afegeix-les a la secció `[ext
|
||||
- [**Comentaris**](@/blog/comments.ca.md). giscus (2 KB), utterances (1 KB), Hyvor Talk (~800 bytes) o Isso (1KB) es poden habilitar globalment configurant `enabled_for_all_posts = true` a la secció apropiada del teu fitxer `config.toml` (`[extra.giscus]`, `[extra.utterances]`, `[extra.hyvortalk]` o `[extra.isso]`). Per habilitar comentaris en publicacions individuals, configura el nom del sistema `= true` (per exemple, `hyvortalk = true`) al front matter del post.
|
||||
|
||||
A part d'això, és un tema ràpid amb HTML i CSS que funciona sense JavaScript. Just com hauria de ser (la majoria de) la web :-)
|
||||
|
||||
<hr>
|
||||
|
||||
[^1]: Per codificar el teu correu en base64 pots utilitzar [eines en línia](https://www.base64encode.org/) o, al terminal, executa: `printf 'mail@example.com' | base64`.
|
||||
|
@ -1,18 +1,23 @@
|
||||
+++
|
||||
title = "Sin JavaScript obligatorio"
|
||||
date = 2023-01-06
|
||||
updated = 2023-08-02
|
||||
updated = 2023-08-18
|
||||
description = "JavaScript solo se utiliza cuando HTML y CSS no son suficientes."
|
||||
|
||||
[taxonomies]
|
||||
tags = ["funcionalidad", "tutorial"]
|
||||
|
||||
[extra]
|
||||
footnote_backlinks = true
|
||||
+++
|
||||
|
||||
Este tema no tiene JavaScript obligatorio. Opcionalmente, puede cargar una cantidad mínima para agregar algunas características que son imposibles de lograr con HTML y CSS.
|
||||
|
||||
## Opciones habilitadas globalmente
|
||||
|
||||
El **interruptor de modo claro/oscuro** puede habilitarse configurando `theme_switcher = true` en la sección `[extra]` de tu `config.toml` (~900 bytes de JavaScript).
|
||||
- El **interruptor de modo claro/oscuro** puede habilitarse configurando `theme_switcher = true` en la sección `[extra]` de tu `config.toml` (~900 bytes de JavaScript).
|
||||
|
||||
- **Decodificación de correo electrónico** (~400 bytes). Para protegerte contra los bots que escanean tu correo electrónico desde tu sitio web, puedes configurar `encode_plaintext_email = true`. Si tu sitio está en un repositorio público, para una protección extra, considera configurar tu `email` como una cadena codificada en base64[^1] directamente.
|
||||
|
||||
## Configuraciones que pueden habilitarse tanto globalmente como en publicaciones individuales
|
||||
|
||||
@ -27,3 +32,7 @@ Para habilitar estas configuraciones globalmente, añádelas en la sección `[ex
|
||||
- [**Comentarios**](@/blog/comments.es.md). giscus (2 KB), utterances (1 KB), Hyvor Talk (~800 bytes) o Isso (1KB) se pueden habilitar globalmente configurando `enabled_for_all_posts = true` en el apartado apropiado de tu archivo `config.toml` (`[extra.giscus]`, `[extra.utterances]`, `[extra.hyvortalk]` o `[extra.isso]`). Para habilitar comentarios en publicaciones individuales, configura el nombre del sistema `= true` (por ejemplo, `hyvortalk = true`) en el front matter del post.
|
||||
|
||||
Aparte de eso, es un tema rápido con HTML y CSS que funciona con JavaScript deshabilitado. Justo como debería ser (en su mayoría) la web :-)
|
||||
|
||||
<hr>
|
||||
|
||||
[^1]: Para codificar tu correo en base64 puedes usar [herramientas en línea](https://www.base64encode.org/) o, en tu terminal, ejecuta: `printf '
|
||||
|
@ -1,18 +1,23 @@
|
||||
+++
|
||||
title = "No mandatory JavaScript"
|
||||
date = 2023-01-06
|
||||
updated = 2023-08-02
|
||||
updated = 2023-08-18
|
||||
description = "JavaScript is only used when HTML and CSS aren't enough."
|
||||
|
||||
[taxonomies]
|
||||
tags = ["showcase", "tutorial"]
|
||||
|
||||
[extra]
|
||||
footnote_backlinks = true
|
||||
+++
|
||||
|
||||
This theme has no mandatory JavaScript. Optionally, it can load a minimal amount to add some features that are impossible to achieve with HTML and CSS.
|
||||
|
||||
## Globally enabled settings
|
||||
|
||||
The **light/dark mode switch** can be enabled by setting `theme_switcher = true` in the `[extra]` section of your `config.toml` (~900 bytes of JavaScript).
|
||||
- The **light/dark mode switch** can be enabled by setting `theme_switcher = true` in the `[extra]` section of your `config.toml` (~900 bytes of JavaScript).
|
||||
|
||||
- **E-mail decoding** (~400 bytes). To protect against spambots scraping your e-mail from your website, you can set `encode_plaintext_email = true`. If your site is on a public repository, for extra protection, consider setting your `email` as a base64-encoded string[^1] directly.
|
||||
|
||||
## Settings that can be enabled globally and for individual posts
|
||||
|
||||
@ -27,3 +32,7 @@ To enable these settings globally, add them in the `[extra]` section of your `co
|
||||
- [**Comments**](@/blog/comments.md). giscus (2 KB), utterances (1 KB), Hyvor Talk (~800 bytes) or Isso (1KB) can be globally enabled by setting `enabled_for_all_posts = true` in the right section of your `config.toml` (i.e. `[extra.giscus]`, `[extra.utterances]`, `[extra.hyvortalk]` or `[extra.isso]`). To enable comments on individual posts, set the name of the system `= true` (e.g. `hyvortalk = true`) in the post's front matter.
|
||||
|
||||
Other than that, it's a fast theme with HTML and CSS which works with JavaScript disabled. Just the way (most of) the web should be :-)
|
||||
|
||||
<hr>
|
||||
|
||||
[^1]: To encode your email in base64 you can use [online tools](https://www.base64encode.org/) or, on your terminal, run: `printf 'mail@example.com' | base64`.
|
||||
|
44
static/js/decodeMail.js
Normal file
44
static/js/decodeMail.js
Normal file
@ -0,0 +1,44 @@
|
||||
(function () {
|
||||
'use strict';
|
||||
|
||||
// Utility function: Base64 Decoding.
|
||||
function decodeBase64(encodedString) {
|
||||
try {
|
||||
// Can't use atob() directly because it doesn't support non-ascii characters.
|
||||
// And non-ascii characters are allowed in email addresses and domains.
|
||||
// See https://en.wikipedia.org/wiki/Email_address#Internationalization
|
||||
// Code below adapted from Jackie Han: https://stackoverflow.com/a/64752311
|
||||
const byteString = atob(encodedString);
|
||||
|
||||
// Convert byteString to an array of char codes.
|
||||
const charCodes = [...byteString].map(char => char.charCodeAt(0));
|
||||
|
||||
// Use TypedArray.prototype.set() to copy the char codes into a Uint8Array.
|
||||
const bytes = new Uint8Array(charCodes.length);
|
||||
bytes.set(charCodes);
|
||||
|
||||
const decoder = new TextDecoder("utf-8");
|
||||
return decoder.decode(bytes);
|
||||
} catch (e) {
|
||||
console.error("Failed to decode Base64 string: ", e);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
// Utility function: Update href of an element with a decoded email.
|
||||
function updateEmailHref(element) {
|
||||
const encodedEmail = element.getAttribute('data-encoded-email');
|
||||
const decodedEmail = decodeBase64(encodedEmail);
|
||||
|
||||
if (decodedEmail) {
|
||||
element.setAttribute('href', `mailto:${decodedEmail}`);
|
||||
} else {
|
||||
// If the decoding fails, hide the email link.
|
||||
element.style.display = 'none';
|
||||
}
|
||||
}
|
||||
|
||||
// Fetch and process email elements with the "data-encoded-email" attribute.
|
||||
const encodedEmailElements = document.querySelectorAll('[data-encoded-email]');
|
||||
encodedEmailElements.forEach(updateEmailHref);
|
||||
})();
|
1
static/js/decodeMail.min.js
vendored
Normal file
1
static/js/decodeMail.min.js
vendored
Normal file
@ -0,0 +1 @@
|
||||
!function(){"use strict";document.querySelectorAll("[data-encoded-email]").forEach(function(e){var t=function(e){try{var t=[...atob(e)].map(e=>e.charCodeAt(0)),r=new Uint8Array(t.length);return r.set(t),new TextDecoder("utf-8").decode(r)}catch(e){return console.error("Failed to decode Base64 string: ",e),null}}(e.getAttribute("data-encoded-email"));t?e.setAttribute("href","mailto:"+t):e.style.display="none"})}();
|
@ -10,6 +10,34 @@
|
||||
</a>
|
||||
</li>
|
||||
{%- endif -%}
|
||||
|
||||
{# Mail icon #}
|
||||
{%- if config.extra.email -%}
|
||||
{%- set email_already_encoded = (config.extra.email is not containing("@")) -%}
|
||||
{%- set email_needs_decoding = email_already_encoded or config.extra.encode_plaintext_email -%}
|
||||
|
||||
{%- if email_already_encoded -%}
|
||||
{%- set encoded_email = config.extra.email -%}
|
||||
{# Verify the pre-encoded e-mail is valid (i.e. contains an '@') #}
|
||||
{%- set decoded_email = encoded_email | base64_decode -%}
|
||||
{%- if '@' not in decoded_email -%}
|
||||
{{ throw(message="ERROR: The provided e-mail appears to be base64-encoded, but does not decode to a valid e-mail address.")}}
|
||||
{%- endif -%}
|
||||
{%- elif config.extra.encode_plaintext_email -%}
|
||||
{%- set encoded_email = config.extra.email | base64_encode -%}
|
||||
{%- endif -%}
|
||||
|
||||
<li class="{% if email_needs_decoding %}js{% endif %}">
|
||||
{%- if email_needs_decoding -%}
|
||||
<a rel="noopener noreferrer" target="_blank" class="nav-links no-hover-padding social" href="#" data-encoded-email="{{ encoded_email | safe }}">
|
||||
{%- else -%}
|
||||
<a rel="noopener noreferrer" target="_blank" class="nav-links no-hover-padding social" href="mailto:{{ config.extra.email | safe }}">
|
||||
{%- endif -%}
|
||||
<img alt="email" title="email" src="{{ get_url(path='social_icons/email.svg') }}">
|
||||
</a>
|
||||
</li>
|
||||
{%- endif -%}
|
||||
|
||||
{% for social in config.extra.socials %}
|
||||
<li>
|
||||
<a rel="noopener noreferrer me" target="_blank" class="nav-links no-hover-padding social" href={{ social.url | safe }}>
|
||||
@ -24,4 +52,9 @@
|
||||
<small>{%- if lang != config.default_language %} {{ trans(key="powered_by" | safe, lang=lang) }} {% else %} Powered by {% endif %} <a href="https://www.getzola.org" target="_blank">Zola</a> {%- if lang != config.default_language %} {{ trans(key="and" | safe, lang=lang) }} {% else %} & {% endif %} <a href="https://github.com/welpo/tabi" target="_blank">tabi</a></small>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
{# Load the decoding script if email is encoded #}
|
||||
{%- if email_needs_decoding -%}
|
||||
<script src="{{ get_url(path='js/decodeMail.min.js') }}" async></script>
|
||||
{%- endif -%}
|
||||
</footer>
|
||||
|
Loading…
x
Reference in New Issue
Block a user