Synk fra arbeidsrepoet
This commit is contained in:
+13
-2
@@ -34,6 +34,18 @@ RUN set -eux; \
|
||||
done; \
|
||||
python3 /sprak.py --sjekk /locales/nb/messages.json
|
||||
|
||||
# E-postmalene bygges av maler.py, ett sett per språk. Serveren peker på ett av
|
||||
# settene per kunde, så en engelsktalende bedrift kan få engelske e-poster uten
|
||||
# at noen tekst skrives to steder.
|
||||
FROM alpine:3.21@sha256:48b0309ca019d89d40f670aa1bc06e426dc0931948452e8491e3d65087abc07d AS maler
|
||||
RUN apk add --no-cache python3
|
||||
COPY --from=kilde /vaultwarden /vaultwarden
|
||||
ARG MAIL_DIR=vault-image/mail
|
||||
COPY ${MAIL_DIR}/maler.py /maler.py
|
||||
# Første kall sammenligner med malene serveren faktisk kan sende: kommer det en
|
||||
# ny i en oppgradering, stopper bygget her i stedet for at den går ut på engelsk.
|
||||
RUN python3 /maler.py --mot /vaultwarden && python3 /maler.py /maler
|
||||
|
||||
FROM vaultwarden/server:${VW_VERSION}@${VW_DIGEST}
|
||||
COPY --from=sprak /locales /web-vault/locales
|
||||
|
||||
@@ -44,8 +56,7 @@ COPY ${BRAND_DIR}/ /web-vault/_vaultnord/
|
||||
|
||||
# Egne e-postmaler. Uten disse går invitasjonene ut med Vaultwardens navn og
|
||||
# utseende - det er kundens første inntrykk av tjenesten, og det skal være vårt.
|
||||
ARG MAIL_DIR=vault-image/mail
|
||||
COPY ${MAIL_DIR}/ /vaultnord/templates/
|
||||
COPY --from=maler /maler/ /vaultnord/templates/
|
||||
|
||||
RUN set -eux; \
|
||||
cp /web-vault/_vaultnord/favicon.png /web-vault/images/favicon-32x32.png; \
|
||||
|
||||
@@ -1,12 +0,0 @@
|
||||
{{{email}}} har takket ja til invitasjonen
|
||||
<!---------------->
|
||||
{{email}} har satt hovedpassordet sitt og takket ja til invitasjonen til {{org_name}}.
|
||||
|
||||
Siste steg må gjøres av deg: logg inn på {{url}} og bekreft brukeren under
|
||||
Medlemmer i organisasjonen. Først da får de tilgang til det som deles.
|
||||
|
||||
Bekreftelsen kan bare gjøres av deg - den krever organisasjonsnøkkelen, som
|
||||
bare finnes i din egen innloggede klient. Det er derfor vi ikke kan gjøre det
|
||||
for deg.
|
||||
|
||||
Vaultnord
|
||||
@@ -1,21 +0,0 @@
|
||||
{{{email}}} har takket ja til invitasjonen
|
||||
<!---------------->
|
||||
<!doctype html>
|
||||
<html lang="no"><body style="margin:0;padding:0;background:#f3f6fa">
|
||||
<table role="presentation" cellpadding="0" cellspacing="0" width="100%" style="background:#f3f6fa">
|
||||
<tr><td align="center" style="padding:32px 16px">
|
||||
<table role="presentation" cellpadding="0" cellspacing="0" width="100%" style="max-width:560px;background:#ffffff;border:1px solid #dbe2ec;border-radius:12px;font-family:-apple-system,'Segoe UI',Roboto,Helvetica,Arial,sans-serif">
|
||||
<tr><td style="padding:28px 32px 4px;font-size:20px;font-weight:700;letter-spacing:-.02em;color:#2e3440">vaultnord</td></tr>
|
||||
<tr><td style="padding:12px 32px 0">
|
||||
<h1 style="margin:0 0 18px;font-size:20px;line-height:1.3;color:#2e3440;font-weight:650">{{email}} har takket ja</h1>
|
||||
<p style="margin:0 0 16px;color:#2e3440;font-size:15px;line-height:1.6"><strong>{{email}}</strong> har satt hovedpassordet sitt og takket ja til invitasjonen til {{org_name}}.</p>
|
||||
<p style="margin:0 0 16px;color:#2e3440;font-size:15px;line-height:1.6">Siste steg må gjøres av deg: logg inn på <a href="{{{url}}}" style="color:#17807d">hvelvet</a> og bekreft brukeren under <em>Medlemmer</em>. Først da får de tilgang til det som deles.</p>
|
||||
<p style="margin:0 0 16px;color:#2e3440;font-size:15px;line-height:1.6">Bekreftelsen krever organisasjonsnøkkelen, som bare finnes i din egen innloggede klient — derfor kan ikke vi gjøre den for deg.</p>
|
||||
</td></tr>
|
||||
<tr><td style="padding:18px 32px 26px;border-top:1px solid #dbe2ec;color:#55617a;font-size:13px;line-height:1.6">
|
||||
Vaultnord · drift i Finland, backup i Tyskland — alt innenfor EU.
|
||||
</td></tr>
|
||||
</table>
|
||||
</td></tr>
|
||||
</table>
|
||||
</body></html>
|
||||
@@ -1,10 +0,0 @@
|
||||
Du har fått tilgang til {{{org_name}}}
|
||||
<!---------------->
|
||||
Du er nå bekreftet som medlem av {{org_name}}.
|
||||
|
||||
Passordene organisasjonen deler med deg dukker opp i hvelvet ditt: {{url}}
|
||||
|
||||
Bruker du Bitwarden-appen eller nettleserutvidelsen, kan du måtte synkronisere
|
||||
en gang for å se dem.
|
||||
|
||||
Vaultnord
|
||||
@@ -1,20 +0,0 @@
|
||||
Du har fått tilgang til {{{org_name}}}
|
||||
<!---------------->
|
||||
<!doctype html>
|
||||
<html lang="no"><body style="margin:0;padding:0;background:#f3f6fa">
|
||||
<table role="presentation" cellpadding="0" cellspacing="0" width="100%" style="background:#f3f6fa">
|
||||
<tr><td align="center" style="padding:32px 16px">
|
||||
<table role="presentation" cellpadding="0" cellspacing="0" width="100%" style="max-width:560px;background:#ffffff;border:1px solid #dbe2ec;border-radius:12px;font-family:-apple-system,'Segoe UI',Roboto,Helvetica,Arial,sans-serif">
|
||||
<tr><td style="padding:28px 32px 4px;font-size:20px;font-weight:700;letter-spacing:-.02em;color:#2e3440">vaultnord</td></tr>
|
||||
<tr><td style="padding:12px 32px 0">
|
||||
<h1 style="margin:0 0 18px;font-size:20px;line-height:1.3;color:#2e3440;font-weight:650">Du har fått tilgang til {{org_name}}</h1>
|
||||
<p style="margin:0 0 16px;color:#2e3440;font-size:15px;line-height:1.6">Du er nå bekreftet som medlem, og passordene organisasjonen deler med deg dukker opp i <a href="{{{url}}}" style="color:#17807d">hvelvet ditt</a>.</p>
|
||||
<p style="margin:0 0 16px;color:#2e3440;font-size:15px;line-height:1.6">Bruker du appen eller nettleserutvidelsen, kan du måtte synkronisere én gang for å se dem.</p>
|
||||
</td></tr>
|
||||
<tr><td style="padding:18px 32px 26px;border-top:1px solid #dbe2ec;color:#55617a;font-size:13px;line-height:1.6">
|
||||
Vaultnord · drift i Finland, backup i Tyskland — alt innenfor EU.
|
||||
</td></tr>
|
||||
</table>
|
||||
</td></tr>
|
||||
</table>
|
||||
</body></html>
|
||||
@@ -1,16 +0,0 @@
|
||||
Ny innlogging fra {{{device_name}}}
|
||||
<!---------------->
|
||||
Hei,
|
||||
|
||||
Kontoen din ble nettopp brukt til å logge inn fra en ny enhet.
|
||||
|
||||
Tidspunkt: {{datetime}}
|
||||
IP-adresse: {{ip}}
|
||||
Enhet: {{device_name}} ({{device_type}})
|
||||
|
||||
Var det deg, trenger du ikke gjøre noe.
|
||||
|
||||
Kjenner du deg ikke igjen: bytt hovedpassord med en gang, og logg ut alle
|
||||
enheter under Innstillinger i hvelvet ({{url}}).
|
||||
|
||||
Vaultnord
|
||||
@@ -1,25 +0,0 @@
|
||||
Ny innlogging fra {{{device_name}}}
|
||||
<!---------------->
|
||||
<!doctype html>
|
||||
<html lang="no"><body style="margin:0;padding:0;background:#f3f6fa">
|
||||
<table role="presentation" cellpadding="0" cellspacing="0" width="100%" style="background:#f3f6fa">
|
||||
<tr><td align="center" style="padding:32px 16px">
|
||||
<table role="presentation" cellpadding="0" cellspacing="0" width="100%" style="max-width:560px;background:#ffffff;border:1px solid #dbe2ec;border-radius:12px;font-family:-apple-system,'Segoe UI',Roboto,Helvetica,Arial,sans-serif">
|
||||
<tr><td style="padding:28px 32px 4px;font-size:20px;font-weight:700;letter-spacing:-.02em;color:#2e3440">vaultnord</td></tr>
|
||||
<tr><td style="padding:12px 32px 0">
|
||||
<h1 style="margin:0 0 18px;font-size:20px;line-height:1.3;color:#2e3440;font-weight:650">Ny innlogging på kontoen din</h1>
|
||||
<p style="margin:0 0 16px;color:#2e3440;font-size:15px;line-height:1.6">Kontoen din ble nettopp brukt til å logge inn fra en ny enhet.</p>
|
||||
<table role="presentation" cellpadding="0" cellspacing="0" style="margin:0 0 16px;font-size:14px;color:#55617a">
|
||||
<tr><td style="padding:2px 12px 2px 0">Tidspunkt</td><td style="color:#2e3440">{{datetime}}</td></tr>
|
||||
<tr><td style="padding:2px 12px 2px 0">IP-adresse</td><td style="color:#2e3440">{{ip}}</td></tr>
|
||||
<tr><td style="padding:2px 12px 2px 0">Enhet</td><td style="color:#2e3440">{{device_name}} ({{device_type}})</td></tr>
|
||||
</table>
|
||||
<p style="margin:0 0 16px;color:#2e3440;font-size:15px;line-height:1.6">Var det deg, trenger du ikke gjøre noe. Kjenner du deg ikke igjen: bytt hovedpassord med en gang, og logg ut alle enheter under Innstillinger i <a href="{{{url}}}" style="color:#17807d">hvelvet</a>.</p>
|
||||
</td></tr>
|
||||
<tr><td style="padding:18px 32px 26px;border-top:1px solid #dbe2ec;color:#55617a;font-size:13px;line-height:1.6">
|
||||
Vaultnord · drift i Finland, backup i Tyskland — alt innenfor EU.
|
||||
</td></tr>
|
||||
</table>
|
||||
</td></tr>
|
||||
</table>
|
||||
</body></html>
|
||||
@@ -1,18 +0,0 @@
|
||||
Invitasjon til passordhvelvet hos {{{org_name}}}
|
||||
<!---------------->
|
||||
Hei,
|
||||
|
||||
Du er invitert til passordhvelvet til {{org_name}}.
|
||||
|
||||
Åpne denne lenken for å komme i gang. Der setter du ditt eget hovedpassord —
|
||||
det er bare du som kjenner det, og det kan ikke gjenopprettes av noen andre:
|
||||
|
||||
{{{url}}}
|
||||
|
||||
Lenken er gyldig i fem dager. Bruk hele adressen, også den lange tegnrekken
|
||||
til slutt.
|
||||
|
||||
Var ikke dette ventet? Da kan du se bort fra e-posten.
|
||||
|
||||
Vaultnord
|
||||
Passordhvelv driftet i Norden
|
||||
@@ -1,29 +0,0 @@
|
||||
Invitasjon til passordhvelvet hos {{{org_name}}}
|
||||
<!---------------->
|
||||
<!doctype html>
|
||||
<html lang="no"><body style="margin:0;padding:0;background:#f3f6fa">
|
||||
<table role="presentation" cellpadding="0" cellspacing="0" width="100%" style="background:#f3f6fa">
|
||||
<tr><td align="center" style="padding:32px 16px">
|
||||
<table role="presentation" cellpadding="0" cellspacing="0" width="100%" style="max-width:560px;background:#ffffff;border:1px solid #dbe2ec;border-radius:12px;font-family:-apple-system,'Segoe UI',Roboto,Helvetica,Arial,sans-serif">
|
||||
<tr><td style="padding:28px 32px 4px;font-size:20px;font-weight:700;letter-spacing:-.02em;color:#2e3440">vaultnord</td></tr>
|
||||
<tr><td style="padding:12px 32px 0">
|
||||
<h1 style="margin:0 0 18px;font-size:20px;line-height:1.3;color:#2e3440;font-weight:650">Du er invitert til passordhvelvet hos {{org_name}}</h1>
|
||||
<p style="margin:0 0 16px;color:#2e3440;font-size:15px;line-height:1.6">Åpne lenken under for å komme i gang. Der setter du ditt eget hovedpassord — det er bare du som kjenner det, og det kan ikke gjenopprettes av noen andre.</p>
|
||||
</td></tr>
|
||||
<tr><td style="padding:8px 32px 24px">
|
||||
<table role="presentation" cellpadding="0" cellspacing="0"><tr>
|
||||
<td style="border-radius:8px;background:#17807d">
|
||||
<a href="{{{url}}}" clicktracking=off target="_blank" style="display:inline-block;padding:12px 22px;color:#ffffff;font-size:15px;font-weight:600;text-decoration:none">Sett hovedpassord</a>
|
||||
</td>
|
||||
</tr></table>
|
||||
</td></tr>
|
||||
<tr><td style="padding:0 32px 20px;color:#55617a;font-size:13px;line-height:1.6">
|
||||
Lenken er gyldig i fem dager. Var ikke dette ventet, kan du se bort fra e-posten.
|
||||
</td></tr>
|
||||
<tr><td style="padding:18px 32px 26px;border-top:1px solid #dbe2ec;color:#55617a;font-size:13px;line-height:1.6">
|
||||
Vaultnord · passordhvelv driftet i Norden
|
||||
</td></tr>
|
||||
</table>
|
||||
</td></tr>
|
||||
</table>
|
||||
</body></html>
|
||||
@@ -1,9 +0,0 @@
|
||||
Innloggingskode: {{{token}}}
|
||||
<!---------------->
|
||||
Koden din er: {{token}}
|
||||
|
||||
Bruk den for å fullføre innloggingen. Den varer i noen få minutter.
|
||||
|
||||
Var det ikke du som logget inn, bør du bytte hovedpassord.
|
||||
|
||||
Vaultnord
|
||||
@@ -1,21 +0,0 @@
|
||||
Innloggingskode: {{{token}}}
|
||||
<!---------------->
|
||||
<!doctype html>
|
||||
<html lang="no"><body style="margin:0;padding:0;background:#f3f6fa">
|
||||
<table role="presentation" cellpadding="0" cellspacing="0" width="100%" style="background:#f3f6fa">
|
||||
<tr><td align="center" style="padding:32px 16px">
|
||||
<table role="presentation" cellpadding="0" cellspacing="0" width="100%" style="max-width:560px;background:#ffffff;border:1px solid #dbe2ec;border-radius:12px;font-family:-apple-system,'Segoe UI',Roboto,Helvetica,Arial,sans-serif">
|
||||
<tr><td style="padding:28px 32px 4px;font-size:20px;font-weight:700;letter-spacing:-.02em;color:#2e3440">vaultnord</td></tr>
|
||||
<tr><td style="padding:12px 32px 0">
|
||||
<h1 style="margin:0 0 18px;font-size:20px;line-height:1.3;color:#2e3440;font-weight:650">Innloggingskode</h1>
|
||||
<p style="margin:0 0 16px;color:#2e3440;font-size:15px;line-height:1.6">Koden din er:</p>
|
||||
<p style="margin:0 0 16px;font-size:30px;letter-spacing:.18em;font-weight:700;color:#17807d">{{token}}</p>
|
||||
<p style="margin:0 0 16px;color:#2e3440;font-size:15px;line-height:1.6">Den varer i noen få minutter. Var det ikke du som logget inn, bør du bytte hovedpassord.</p>
|
||||
</td></tr>
|
||||
<tr><td style="padding:18px 32px 26px;border-top:1px solid #dbe2ec;color:#55617a;font-size:13px;line-height:1.6">
|
||||
Vaultnord · drift i Finland, backup i Tyskland — alt innenfor EU.
|
||||
</td></tr>
|
||||
</table>
|
||||
</td></tr>
|
||||
</table>
|
||||
</body></html>
|
||||
@@ -1,9 +0,0 @@
|
||||
Bekreft e-postadressen din
|
||||
<!---------------->
|
||||
Bekreft e-postadressen for kontoen din ved å åpne lenken under:
|
||||
|
||||
{{url}}/#/verify-email/?userId={{user_id}}&token={{token}}
|
||||
|
||||
Var det ikke du som ba om dette, kan du se bort fra e-posten.
|
||||
|
||||
Vaultnord
|
||||
@@ -1,24 +0,0 @@
|
||||
Bekreft e-postadressen din
|
||||
<!---------------->
|
||||
<!doctype html>
|
||||
<html lang="no"><body style="margin:0;padding:0;background:#f3f6fa">
|
||||
<table role="presentation" cellpadding="0" cellspacing="0" width="100%" style="background:#f3f6fa">
|
||||
<tr><td align="center" style="padding:32px 16px">
|
||||
<table role="presentation" cellpadding="0" cellspacing="0" width="100%" style="max-width:560px;background:#ffffff;border:1px solid #dbe2ec;border-radius:12px;font-family:-apple-system,'Segoe UI',Roboto,Helvetica,Arial,sans-serif">
|
||||
<tr><td style="padding:28px 32px 4px;font-size:20px;font-weight:700;letter-spacing:-.02em;color:#2e3440">vaultnord</td></tr>
|
||||
<tr><td style="padding:12px 32px 0">
|
||||
<h1 style="margin:0 0 18px;font-size:20px;line-height:1.3;color:#2e3440;font-weight:650">Bekreft e-postadressen din</h1>
|
||||
<p style="margin:0 0 16px;color:#2e3440;font-size:15px;line-height:1.6">Åpne lenken under for å bekrefte adressen for kontoen din.</p>
|
||||
<table role="presentation" cellpadding="0" cellspacing="0" style="margin:8px 0 20px"><tr>
|
||||
<td style="border-radius:8px;background:#17807d">
|
||||
<a href="{{{url}}}/#/verify-email/?userId={{user_id}}&token={{token}}" clicktracking=off target="_blank" style="display:inline-block;padding:12px 22px;color:#ffffff;font-size:15px;font-weight:600;text-decoration:none">Bekreft adressen</a>
|
||||
</td></tr></table>
|
||||
<p style="margin:0 0 16px;color:#2e3440;font-size:15px;line-height:1.6">Var det ikke du som ba om dette, kan du se bort fra e-posten.</p>
|
||||
</td></tr>
|
||||
<tr><td style="padding:18px 32px 26px;border-top:1px solid #dbe2ec;color:#55617a;font-size:13px;line-height:1.6">
|
||||
Vaultnord · drift i Finland, backup i Tyskland — alt innenfor EU.
|
||||
</td></tr>
|
||||
</table>
|
||||
</td></tr>
|
||||
</table>
|
||||
</body></html>
|
||||
@@ -1,11 +0,0 @@
|
||||
Hvelvet ditt er klart til bruk
|
||||
<!---------------->
|
||||
Hei,
|
||||
|
||||
Hovedpassordet ditt er satt, og hvelvet er klart: {{url}}
|
||||
|
||||
Ett tips til slutt: installer Bitwarden-appen eller nettleserutvidelsen og oppgi
|
||||
adressen over som serveradresse. Nettleserversjonen låser seg hver gang siden
|
||||
lastes på nytt, fordi nøkkelen bare finnes i minnet - utvidelsen holder økten.
|
||||
|
||||
Vaultnord
|
||||
@@ -1,20 +0,0 @@
|
||||
Hvelvet ditt er klart til bruk
|
||||
<!---------------->
|
||||
<!doctype html>
|
||||
<html lang="no"><body style="margin:0;padding:0;background:#f3f6fa">
|
||||
<table role="presentation" cellpadding="0" cellspacing="0" width="100%" style="background:#f3f6fa">
|
||||
<tr><td align="center" style="padding:32px 16px">
|
||||
<table role="presentation" cellpadding="0" cellspacing="0" width="100%" style="max-width:560px;background:#ffffff;border:1px solid #dbe2ec;border-radius:12px;font-family:-apple-system,'Segoe UI',Roboto,Helvetica,Arial,sans-serif">
|
||||
<tr><td style="padding:28px 32px 4px;font-size:20px;font-weight:700;letter-spacing:-.02em;color:#2e3440">vaultnord</td></tr>
|
||||
<tr><td style="padding:12px 32px 0">
|
||||
<h1 style="margin:0 0 18px;font-size:20px;line-height:1.3;color:#2e3440;font-weight:650">Hvelvet ditt er klart</h1>
|
||||
<p style="margin:0 0 16px;color:#2e3440;font-size:15px;line-height:1.6">Hovedpassordet ditt er satt, og hvelvet er klart til bruk på <a href="{{{url}}}" style="color:#17807d">{{url}}</a>.</p>
|
||||
<p style="margin:0 0 16px;color:#2e3440;font-size:15px;line-height:1.6">Ett tips: installer Bitwarden-appen eller nettleserutvidelsen og oppgi adressen over som serveradresse. Nettleserversjonen låser seg hver gang siden lastes på nytt, fordi nøkkelen bare finnes i minnet — utvidelsen holder økten.</p>
|
||||
</td></tr>
|
||||
<tr><td style="padding:18px 32px 26px;border-top:1px solid #dbe2ec;color:#55617a;font-size:13px;line-height:1.6">
|
||||
Vaultnord · drift i Finland, backup i Tyskland — alt innenfor EU.
|
||||
</td></tr>
|
||||
</table>
|
||||
</td></tr>
|
||||
</table>
|
||||
</body></html>
|
||||
+599
@@ -0,0 +1,599 @@
|
||||
"""Bygger e-postmalene til hvelvet, ett sett per språk.
|
||||
|
||||
Vaultwarden har 30 maler. Vi hadde skrevet sju av dem om til norsk; resten gikk
|
||||
ut på engelsk med Bitwardens navn i teksten - altså midt i onboardingen. Å
|
||||
håndskrive de 23 siste i to formater og to språk blir 92 filer som må holdes i
|
||||
takt, så teksten ligger heller i tabellen under og formene genereres.
|
||||
|
||||
Kjøres under bygget: python3 maler.py <utmappe>
|
||||
og legger igjen <utmappe>/<språk>/email/<navn>.hbs og <navn>.html.hbs.
|
||||
|
||||
Et nytt språk er en kolonne til i tabellen, ikke en ny mappe med filer.
|
||||
"""
|
||||
|
||||
import re
|
||||
import sys
|
||||
import textwrap
|
||||
from pathlib import Path
|
||||
|
||||
SPRÅK = ("nb", "en")
|
||||
|
||||
# Bunnteksten under strekend i hver e-post.
|
||||
BUNN = {
|
||||
"nb": "Vaultnord · drift i Finland, backup i Tyskland — alt innenfor EU.",
|
||||
"en": "Vaultnord · hosted in Finland, backed up in Germany — all within the EU.",
|
||||
}
|
||||
BUNN_TEKST = {"nb": "Vaultnord", "en": "Vaultnord"}
|
||||
|
||||
# Navnet på appen kunden faktisk installerer. Den heter Bitwarden i butikkene,
|
||||
# og å kalle den noe annet ville sende folk på et umulig søk.
|
||||
APP = "Bitwarden"
|
||||
|
||||
|
||||
# --- oppmerking ------------------------------------------------------------
|
||||
# Teksten skrives én gang. [tekst](lenke) blir en lenke, *ord* blir uthevet, og
|
||||
# linjer som begynner med "- " blir en liste. Alt annet er avsnitt.
|
||||
|
||||
LENKE = re.compile(r"\[([^\]]+)\]\(([^)]+)\)")
|
||||
UTHEVET = re.compile(r"\*([^*]+)\*")
|
||||
|
||||
|
||||
BARE_LENKE = re.compile(r"^\[([^\]]+)\]\(([^)]+)\)$")
|
||||
|
||||
|
||||
def _tekst(avsnitt: list[str]) -> str:
|
||||
ut = []
|
||||
for a in avsnitt:
|
||||
if a.startswith("- "):
|
||||
ut.append("\n".join(" " + linje[2:] for linje in a.split("\n")))
|
||||
continue
|
||||
# En lenke som står alene er en oppfordring: sett adressen på egen linje,
|
||||
# uinnpakket, så den blir klikkbar i alle klienter.
|
||||
alene = BARE_LENKE.match(a)
|
||||
if alene:
|
||||
ut.append(f"{alene.group(1)}:\n{alene.group(2)}")
|
||||
continue
|
||||
ut.append(textwrap.fill(LENKE.sub(_flat, a), 78,
|
||||
break_long_words=False, break_on_hyphens=False))
|
||||
return "\n\n".join(ut)
|
||||
|
||||
|
||||
def _flat(m: re.Match) -> str:
|
||||
"""Lenke midt i en setning. Er teksten adressen selv, skal den ikke stå to
|
||||
ganger - da ble det «{{url}}: {{{url}}}» i innboksen."""
|
||||
tekst, adresse = m.group(1), m.group(2)
|
||||
if tekst.strip("{} ") == adresse.strip("{} "):
|
||||
return tekst
|
||||
return f"{tekst} ({adresse})"
|
||||
|
||||
|
||||
def _html(avsnitt: list[str]) -> str:
|
||||
p = ('margin:0 0 16px;color:#2e3440;font-size:15px;line-height:1.6')
|
||||
ut = []
|
||||
for a in avsnitt:
|
||||
if a.startswith("- "):
|
||||
punkter = "".join(
|
||||
f'<li style="margin:0 0 4px">{_inline(linje[2:])}</li>'
|
||||
for linje in a.split("\n"))
|
||||
ut.append(f'<ul style="{p};padding-left:20px">{punkter}</ul>')
|
||||
else:
|
||||
ut.append(f'<p style="{p}">{_inline(a)}</p>')
|
||||
return "\n ".join(ut)
|
||||
|
||||
|
||||
def _inline(s: str) -> str:
|
||||
s = LENKE.sub(r'<a href="\2" style="color:#17807d">\1</a>', s)
|
||||
return UTHEVET.sub(r"<strong>\1</strong>", s)
|
||||
|
||||
|
||||
RAMME = """<!doctype html>
|
||||
<html lang="{lang}"><body style="margin:0;padding:0;background:#f3f6fa">
|
||||
<table role="presentation" cellpadding="0" cellspacing="0" width="100%" style="background:#f3f6fa">
|
||||
<tr><td align="center" style="padding:32px 16px">
|
||||
<table role="presentation" cellpadding="0" cellspacing="0" width="100%" style="max-width:560px;background:#ffffff;border:1px solid #dbe2ec;border-radius:12px;font-family:-apple-system,'Segoe UI',Roboto,Helvetica,Arial,sans-serif">
|
||||
<tr><td style="padding:28px 32px 4px;font-size:20px;font-weight:700;letter-spacing:-.02em;color:#2e3440">vaultnord</td></tr>
|
||||
<tr><td style="padding:12px 32px 0">
|
||||
<h1 style="margin:0 0 18px;font-size:20px;line-height:1.3;color:#2e3440;font-weight:650">{tittel}</h1>
|
||||
{kropp}
|
||||
</td></tr>
|
||||
<tr><td style="padding:18px 32px 26px;border-top:1px solid #dbe2ec;color:#55617a;font-size:13px;line-height:1.6">
|
||||
{bunn}
|
||||
</td></tr>
|
||||
</table>
|
||||
</td></tr>
|
||||
</table>
|
||||
</body></html>"""
|
||||
|
||||
HTML_LANG = {"nb": "no", "en": "en"}
|
||||
|
||||
|
||||
# --- teksten ---------------------------------------------------------------
|
||||
# Per mal og språk: (emne, overskrift, avsnitt). Variabelnavnene er
|
||||
# Vaultwardens egne - endres de her, kommer e-posten ut med tomme felter.
|
||||
|
||||
MALER: dict[str, dict[str, tuple[str, str, list[str]]]] = {
|
||||
|
||||
"welcome": {
|
||||
"nb": ("Hvelvet ditt er klart til bruk", "Hvelvet ditt er klart", [
|
||||
"Hovedpassordet ditt er satt, og hvelvet er klart til bruk på [{{url}}]({{{url}}}).",
|
||||
f"Ett tips til slutt: installer {APP}-appen eller nettleserutvidelsen og oppgi "
|
||||
"adressen over som serveradresse. Nettleserversjonen låser seg hver gang siden "
|
||||
"lastes på nytt, fordi nøkkelen bare finnes i minnet — utvidelsen holder økten.",
|
||||
]),
|
||||
"en": ("Your vault is ready", "Your vault is ready", [
|
||||
"Your master password is set, and your vault is ready at [{{url}}]({{{url}}}).",
|
||||
f"One tip: install the {APP} app or browser extension and enter the address "
|
||||
"above as the server address. The web version locks every time the page "
|
||||
"reloads, because the key only lives in memory — the extension keeps the session.",
|
||||
]),
|
||||
},
|
||||
|
||||
"welcome_must_verify": {
|
||||
"nb": ("Bekreft e-postadressen din", "Ett steg igjen", [
|
||||
"Kontoen din på [{{url}}]({{{url}}}) er opprettet. Før du kan logge inn må du "
|
||||
"bekrefte at adressen er din.",
|
||||
"[Bekreft e-postadressen]({{url}}/#/verify-email/?userId={{user_id}}&token={{token}})",
|
||||
"Var det ikke du som opprettet kontoen, kan du se bort fra e-posten.",
|
||||
]),
|
||||
"en": ("Verify your email address", "One step left", [
|
||||
"Your account at [{{url}}]({{{url}}}) has been created. Before you can log in, "
|
||||
"you need to confirm that this address is yours.",
|
||||
"[Verify your email address]({{url}}/#/verify-email/?userId={{user_id}}&token={{token}})",
|
||||
"If you did not create this account, you can ignore this email.",
|
||||
]),
|
||||
},
|
||||
|
||||
"verify_email": {
|
||||
"nb": ("Bekreft e-postadressen din", "Bekreft e-postadressen", [
|
||||
"Bekreft e-postadressen for kontoen din ved å åpne lenken under:",
|
||||
"[Bekreft e-postadressen]({{url}}/#/verify-email/?userId={{user_id}}&token={{token}})",
|
||||
"Var det ikke du som ba om dette, kan du se bort fra e-posten.",
|
||||
]),
|
||||
"en": ("Verify your email address", "Verify your email address", [
|
||||
"Confirm the email address on your account by opening the link below:",
|
||||
"[Verify your email address]({{url}}/#/verify-email/?userId={{user_id}}&token={{token}})",
|
||||
"If you did not ask for this, you can ignore this email.",
|
||||
]),
|
||||
},
|
||||
|
||||
"register_verify_email": {
|
||||
"nb": ("Bekreft e-postadressen din", "Bekreft e-postadressen", [
|
||||
"Bekreft adressen for å fullføre opprettelsen av kontoen.",
|
||||
"[Bekreft e-postadressen]({{{url}}})",
|
||||
"Var det ikke du som ba om dette, kan du se bort fra e-posten.",
|
||||
]),
|
||||
"en": ("Verify your email address", "Verify your email address", [
|
||||
"Confirm this address to finish creating your account.",
|
||||
"[Verify your email address]({{{url}}})",
|
||||
"If you did not ask for this, you can ignore this email.",
|
||||
]),
|
||||
},
|
||||
|
||||
"send_org_invite": {
|
||||
"nb": ("Invitasjon til passordhvelvet hos {{{org_name}}}", "Du er invitert", [
|
||||
"Du er invitert til passordhvelvet til {{org_name}}.",
|
||||
"Åpne lenken under for å komme i gang. Der setter du ditt eget hovedpassord — "
|
||||
"det er bare du som kjenner det, og det kan ikke gjenopprettes av noen andre.",
|
||||
"[Bli med]({{{url}}})",
|
||||
"Lenken er gyldig i fem dager. Bruk hele adressen, også den lange tegnrekken til slutt.",
|
||||
"Var ikke dette ventet? Da kan du se bort fra e-posten.",
|
||||
]),
|
||||
"en": ("Invitation to the password vault at {{{org_name}}}", "You have been invited", [
|
||||
"You have been invited to the password vault of {{org_name}}.",
|
||||
"Open the link below to get started. There you set your own master password — "
|
||||
"you are the only one who knows it, and nobody else can recover it.",
|
||||
"[Join]({{{url}}})",
|
||||
"The link is valid for five days. Use the whole address, including the long string at the end.",
|
||||
"Were you not expecting this? Then you can ignore this email.",
|
||||
]),
|
||||
},
|
||||
|
||||
"invite_accepted": {
|
||||
"nb": ("{{{email}}} har takket ja til invitasjonen", "Én bekreftelse gjenstår", [
|
||||
"{{email}} har satt hovedpassordet sitt og takket ja til invitasjonen til {{org_name}}.",
|
||||
"Siste steg må gjøres av deg: logg inn på [{{url}}]({{{url}}}) og bekreft brukeren "
|
||||
"under Medlemmer i organisasjonen. Først da får de tilgang til det som deles.",
|
||||
"Bekreftelsen kan bare gjøres av deg — den krever organisasjonsnøkkelen, som bare "
|
||||
"finnes i din egen innloggede klient. Det er derfor vi ikke kan gjøre det for deg.",
|
||||
]),
|
||||
"en": ("{{{email}}} accepted the invitation", "One confirmation left", [
|
||||
"{{email}} has set their master password and accepted the invitation to {{org_name}}.",
|
||||
"The last step is yours: log in at [{{url}}]({{{url}}}) and confirm the user under "
|
||||
"Members in the organisation. Only then do they get access to what is shared.",
|
||||
"Only you can confirm — it requires the organisation key, which exists solely in "
|
||||
"your own logged-in client. That is why we cannot do it for you.",
|
||||
]),
|
||||
},
|
||||
|
||||
"invite_confirmed": {
|
||||
"nb": ("Du har fått tilgang til {{{org_name}}}", "Du er med", [
|
||||
"Du er nå bekreftet som medlem av {{org_name}}.",
|
||||
"Passordene organisasjonen deler med deg dukker opp i hvelvet ditt: [{{url}}]({{{url}}}).",
|
||||
f"Bruker du {APP}-appen eller nettleserutvidelsen, kan du måtte synkronisere en gang for å se dem.",
|
||||
]),
|
||||
"en": ("You now have access to {{{org_name}}}", "You are in", [
|
||||
"You have been confirmed as a member of {{org_name}}.",
|
||||
"The passwords the organisation shares with you appear in your vault: [{{url}}]({{{url}}}).",
|
||||
f"If you use the {APP} app or browser extension, you may need to sync once to see them.",
|
||||
]),
|
||||
},
|
||||
|
||||
"new_device_logged_in": {
|
||||
"nb": ("Ny innlogging fra {{{device_name}}}", "Ny innlogging", [
|
||||
"Kontoen din ble nettopp brukt til å logge inn fra en ny enhet.",
|
||||
"- Tidspunkt: {{datetime}}\n- IP-adresse: {{ip}}\n- Enhet: {{device_name}} ({{device_type}})",
|
||||
"Var det deg, trenger du ikke gjøre noe.",
|
||||
"Kjenner du deg ikke igjen: bytt hovedpassord med en gang, og logg ut alle enheter "
|
||||
"under Innstillinger i hvelvet ([{{url}}]({{{url}}})).",
|
||||
]),
|
||||
"en": ("New login from {{{device_name}}}", "New login", [
|
||||
"Your account was just used to log in from a new device.",
|
||||
"- Time: {{datetime}}\n- IP address: {{ip}}\n- Device: {{device_name}} ({{device_type}})",
|
||||
"If this was you, there is nothing to do.",
|
||||
"If you do not recognise it: change your master password right away, and sign out "
|
||||
"all devices under Settings in the vault ([{{url}}]({{{url}}})).",
|
||||
]),
|
||||
},
|
||||
|
||||
"incomplete_2fa_login": {
|
||||
"nb": ("Avbrutt innlogging fra {{{device_name}}}", "Noen kom halvveis inn", [
|
||||
"Noen logget inn på kontoen din med riktig hovedpassord, men fullførte ikke "
|
||||
"totrinnsbekreftelsen innen {{time_limit}} minutter.",
|
||||
"- Tidspunkt: {{datetime}}\n- IP-adresse: {{ip}}\n- Enhet: {{device_name}} ({{device_type}})",
|
||||
"Var det ikke du eller noen du kjenner: *bytt hovedpassord med en gang*. At passordet "
|
||||
"var riktig betyr at det er på avveie.",
|
||||
]),
|
||||
"en": ("Interrupted login from {{{device_name}}}", "Someone got halfway in", [
|
||||
"Someone logged into your account with the correct master password, but did not "
|
||||
"complete two-step verification within {{time_limit}} minutes.",
|
||||
"- Time: {{datetime}}\n- IP address: {{ip}}\n- Device: {{device_name}} ({{device_type}})",
|
||||
"If this was not you or someone you know: *change your master password immediately*. "
|
||||
"The password being correct means it has leaked.",
|
||||
]),
|
||||
},
|
||||
|
||||
"twofactor_email": {
|
||||
"nb": ("Innloggingskode: {{{token}}}", "Innloggingskode", [
|
||||
"Koden din er: *{{token}}*",
|
||||
"Bruk den for å fullføre innloggingen. Den varer i noen få minutter.",
|
||||
"Var det ikke du som logget inn, bør du bytte hovedpassord.",
|
||||
]),
|
||||
"en": ("Login code: {{{token}}}", "Login code", [
|
||||
"Your code is: *{{token}}*",
|
||||
"Use it to finish logging in. It lasts a few minutes.",
|
||||
"If you were not the one logging in, you should change your master password.",
|
||||
]),
|
||||
},
|
||||
|
||||
"protected_action": {
|
||||
"nb": ("Bekreftelseskode: {{{token}}}", "Bekreftelseskode", [
|
||||
"Koden din er: *{{token}}*",
|
||||
"Bruk den for å fullføre handlingen du startet i hvelvet.",
|
||||
]),
|
||||
"en": ("Verification code: {{{token}}}", "Verification code", [
|
||||
"Your code is: *{{token}}*",
|
||||
"Use it to complete the action you started in the vault.",
|
||||
]),
|
||||
},
|
||||
|
||||
"change_email": {
|
||||
"nb": ("Bytte av e-postadresse", "Bekreft den nye adressen", [
|
||||
"Skriv denne koden i hvelvet for å fullføre byttet av e-postadresse: *{{token}}*",
|
||||
"Var det ikke du som ba om byttet, ta kontakt med administratoren din.",
|
||||
]),
|
||||
"en": ("Email address change", "Confirm the new address", [
|
||||
"Enter this code in the vault to finish changing your email address: *{{token}}*",
|
||||
"If you did not ask for the change, contact your administrator.",
|
||||
]),
|
||||
},
|
||||
|
||||
"change_email_existing": {
|
||||
"nb": ("Noen forsøkte å bruke adressen din", "Adressen er allerede i bruk", [
|
||||
"En bruker ({{ acting_address }}) forsøkte nettopp å flytte kontoen sin til denne "
|
||||
"adressen ({{ existing_address }}). Det finnes allerede en konto her.",
|
||||
"Var det ikke du som forsøkte, ta kontakt med administratoren din.",
|
||||
]),
|
||||
"en": ("Someone tried to use your address", "The address is already in use", [
|
||||
"A user ({{ acting_address }}) just tried to move their account to this address "
|
||||
"({{ existing_address }}). An account already exists here.",
|
||||
"If it was not you, contact your administrator.",
|
||||
]),
|
||||
},
|
||||
|
||||
"change_email_invited": {
|
||||
"nb": ("Noen forsøkte å bruke adressen din", "Adressen er allerede invitert", [
|
||||
"En bruker ({{ acting_address }}) forsøkte nettopp å flytte kontoen sin til denne "
|
||||
"adressen ({{ existing_address }}). Adressen er allerede invitert til et hvelv.",
|
||||
"Skal adressen brukes til noe annet, må kontoen som hører til den slettes først: "
|
||||
"[be om sletting]({{url}}/#/recover-delete). Invitasjonen må da sendes på nytt.",
|
||||
"Var det ikke du som forsøkte, ta kontakt med administratoren din.",
|
||||
]),
|
||||
"en": ("Someone tried to use your address", "The address is already invited", [
|
||||
"A user ({{ acting_address }}) just tried to move their account to this address "
|
||||
"({{ existing_address }}). The address has already been invited to a vault.",
|
||||
"To use the address for something else, the account tied to it must be deleted "
|
||||
"first: [request deletion]({{url}}/#/recover-delete). The invitation then has to be resent.",
|
||||
"If it was not you, contact your administrator.",
|
||||
]),
|
||||
},
|
||||
|
||||
"delete_account": {
|
||||
"nb": ("Slett kontoen din", "Bekreft sletting", [
|
||||
"Åpne lenken under for å slette kontoen din. *Alt innholdet i hvelvet forsvinner, "
|
||||
"og det kan ikke hentes tilbake.*",
|
||||
"[Slett kontoen]({{url}}/#/verify-recover-delete?userId={{user_id}}&token={{token}}&email={{email}})",
|
||||
"Var det ikke du som ba om dette, kan du se bort fra e-posten.",
|
||||
]),
|
||||
"en": ("Delete your account", "Confirm deletion", [
|
||||
"Open the link below to delete your account. *Everything in the vault is lost, "
|
||||
"and it cannot be brought back.*",
|
||||
"[Delete the account]({{url}}/#/verify-recover-delete?userId={{user_id}}&token={{token}}&email={{email}})",
|
||||
"If you did not ask for this, you can ignore this email.",
|
||||
]),
|
||||
},
|
||||
|
||||
"pw_hint_some": {
|
||||
"nb": ("Hintet til hovedpassordet ditt", "Hintet ditt", [
|
||||
"Noen ba om hintet til hovedpassordet ditt.",
|
||||
"Hintet er: *{{hint}}*",
|
||||
"[Logg inn i hvelvet]({{{url}}})",
|
||||
"Husker du ikke hovedpassordet, finnes det ingen vei tilbake til innholdet — det er "
|
||||
"kryptert med nøkkelen bare du har. Eneste utvei er å [slette kontoen]({{url}}/#/recover-delete) "
|
||||
"og begynne på nytt. Alt innholdet forsvinner da.",
|
||||
"Var det ikke du som ba om hintet, kan du se bort fra e-posten.",
|
||||
]),
|
||||
"en": ("Your master password hint", "Your hint", [
|
||||
"Someone asked for your master password hint.",
|
||||
"The hint is: *{{hint}}*",
|
||||
"[Log in to the vault]({{{url}}})",
|
||||
"If you cannot remember your master password, there is no way back to the contents — "
|
||||
"they are encrypted with a key only you hold. The only way out is to "
|
||||
"[delete the account]({{url}}/#/recover-delete) and start over. Everything in it is lost.",
|
||||
"If you did not ask for the hint, you can ignore this email.",
|
||||
]),
|
||||
},
|
||||
|
||||
"pw_hint_none": {
|
||||
"nb": ("Hintet til hovedpassordet ditt", "Du har ikke lagret noe hint", [
|
||||
"Noen ba om hintet til hovedpassordet ditt, men kontoen din har ikke noe hint lagret.",
|
||||
"Husker du ikke hovedpassordet, finnes det ingen vei tilbake til innholdet — det er "
|
||||
"kryptert med nøkkelen bare du har. Eneste utvei er å [slette kontoen]({{url}}/#/recover-delete) "
|
||||
"og begynne på nytt. Alt innholdet forsvinner da.",
|
||||
"Var det ikke du som ba om hintet, kan du se bort fra e-posten.",
|
||||
]),
|
||||
"en": ("Your master password hint", "You have no hint saved", [
|
||||
"Someone asked for your master password hint, but your account has none saved.",
|
||||
"If you cannot remember your master password, there is no way back to the contents — "
|
||||
"they are encrypted with a key only you hold. The only way out is to "
|
||||
"[delete the account]({{url}}/#/recover-delete) and start over. Everything in it is lost.",
|
||||
"If you did not ask for the hint, you can ignore this email.",
|
||||
]),
|
||||
},
|
||||
|
||||
"admin_reset_password": {
|
||||
"nb": ("Hovedpassordet ditt er endret", "Hovedpassordet er endret", [
|
||||
"Hovedpassordet til {{user_name}} er endret av en administrator i {{org_name}}.",
|
||||
"Var det ikke avtalt, ta kontakt med administratoren din med en gang.",
|
||||
]),
|
||||
"en": ("Your master password has been changed", "Master password changed", [
|
||||
"The master password for {{user_name}} was changed by an administrator in {{org_name}}.",
|
||||
"If this was not agreed, contact your administrator immediately.",
|
||||
]),
|
||||
},
|
||||
|
||||
"send_2fa_removed_from_org": {
|
||||
"nb": ("Tilgangen din til {{{org_name}}} er fjernet", "Tilgangen er fjernet", [
|
||||
"Du er tatt ut av {{org_name}} fordi kontoen din ikke har totrinnsbekreftelse.",
|
||||
"Slå på totrinnsbekreftelse under Innstillinger i hvelvet, så kan du bli med igjen.",
|
||||
]),
|
||||
"en": ("Your access to {{{org_name}}} has been removed", "Access removed", [
|
||||
"You were removed from {{org_name}} because your account has no two-step verification.",
|
||||
"Turn on two-step verification under Settings in the vault, and you can rejoin.",
|
||||
]),
|
||||
},
|
||||
|
||||
"send_single_org_removed_from_org": {
|
||||
"nb": ("Tilgangen din til {{{org_name}}} er fjernet", "Tilgangen er fjernet", [
|
||||
"Du er tatt ut av {{org_name}} fordi du også er medlem av en annen organisasjon. "
|
||||
"{{org_name}} tillater ikke det.",
|
||||
"Meld deg ut av de andre organisasjonene, eller bli med med en annen konto.",
|
||||
]),
|
||||
"en": ("Your access to {{{org_name}}} has been removed", "Access removed", [
|
||||
"You were removed from {{org_name}} because you are also a member of another "
|
||||
"organisation. {{org_name}} does not allow that.",
|
||||
"Leave the other organisations, or join with a different account.",
|
||||
]),
|
||||
},
|
||||
|
||||
"sso_change_email": {
|
||||
"nb": ("E-postadressen din er endret", "Adressen er endret hos påloggingstjenesten", [
|
||||
"E-postadressen din ble endret hos påloggingstjenesten. Oppdater den også i hvelvet, "
|
||||
"under Kontoinnstillinger: [{{url}}]({{{url}}}).",
|
||||
]),
|
||||
"en": ("Your email address has changed", "The address changed at your login provider", [
|
||||
"Your email address was changed at your login provider. Update it in the vault too, "
|
||||
"under Account settings: [{{url}}]({{{url}}}).",
|
||||
]),
|
||||
},
|
||||
|
||||
"smtp_test": {
|
||||
"nb": ("Test av e-postoppsettet", "Testen kom fram", [
|
||||
"Dette er en testmelding for e-postoppsettet til {{url}}.",
|
||||
"Kan du lese den, virker oppsettet.",
|
||||
]),
|
||||
"en": ("Email configuration test", "The test arrived", [
|
||||
"This is a test message for the email setup of {{url}}.",
|
||||
"If you can read it, the setup works.",
|
||||
]),
|
||||
},
|
||||
|
||||
"send_emergency_access_invite": {
|
||||
"nb": ("Nødtilgang for {{{grantor_name}}}", "Du er spurt om å være nødkontakt", [
|
||||
"{{grantor_name}} har spurt om du vil være nødkontakt for hvelvet sitt.",
|
||||
"[Ta imot]({{{url}}})",
|
||||
"Vil du ikke, kan du se bort fra e-posten.",
|
||||
]),
|
||||
"en": ("Emergency access for {{{grantor_name}}}", "You have been asked to be an emergency contact", [
|
||||
"{{grantor_name}} has asked you to be an emergency contact for their vault.",
|
||||
"[Accept]({{{url}}})",
|
||||
"If you would rather not, you can ignore this email.",
|
||||
]),
|
||||
},
|
||||
|
||||
"emergency_access_invite_accepted": {
|
||||
"nb": ("{{{grantee_email}}} har takket ja", "Én bekreftelse gjenstår", [
|
||||
"{{grantee_email}} har takket ja til å være nødkontakten din.",
|
||||
"Logg inn i hvelvet ([{{url}}]({{{url}}})) og bekreft dem under Innstillinger. "
|
||||
"Vil du likevel ikke, kan du fjerne dem samme sted.",
|
||||
]),
|
||||
"en": ("{{{grantee_email}}} accepted", "One confirmation left", [
|
||||
"{{grantee_email}} has accepted being your emergency contact.",
|
||||
"Log in to the vault ([{{url}}]({{{url}}})) and confirm them under Settings. "
|
||||
"If you have changed your mind, you can remove them in the same place.",
|
||||
]),
|
||||
},
|
||||
|
||||
"emergency_access_invite_confirmed": {
|
||||
"nb": ("Du er nødkontakt for {{{grantor_name}}}", "Du er bekreftet", [
|
||||
"Du er bekreftet som nødkontakt for *{{grantor_name}}*.",
|
||||
"Du kan be om nødtilgang fra hvelvet: [{{url}}]({{{url}}}).",
|
||||
]),
|
||||
"en": ("You are an emergency contact for {{{grantor_name}}}", "You are confirmed", [
|
||||
"You have been confirmed as an emergency contact for *{{grantor_name}}*.",
|
||||
"You can request emergency access from the vault: [{{url}}]({{{url}}}).",
|
||||
]),
|
||||
},
|
||||
|
||||
"emergency_access_recovery_initiated": {
|
||||
"nb": ("{{{grantee_name}}} har bedt om nødtilgang", "Noen ber om nødtilgang", [
|
||||
"{{grantee_name}} har bedt om nødtilgang for å {{atype}} kontoen din.",
|
||||
"Logg inn i hvelvet ([{{url}}]({{{url}}})) for å godta eller avslå.",
|
||||
"Gjør du ingenting, blir forespørselen *godtatt automatisk om {{wait_time_days}} dager*.",
|
||||
]),
|
||||
"en": ("{{{grantee_name}}} requested emergency access", "Someone is requesting emergency access", [
|
||||
"{{grantee_name}} has requested emergency access to {{atype}} your account.",
|
||||
"Log in to the vault ([{{url}}]({{{url}}})) to approve or reject it.",
|
||||
"If you do nothing, the request is *approved automatically in {{wait_time_days}} days*.",
|
||||
]),
|
||||
},
|
||||
|
||||
"emergency_access_recovery_reminder": {
|
||||
"nb": ("{{{grantee_name}}} venter fortsatt på nødtilgang", "Forespørselen ligger fortsatt der", [
|
||||
"{{grantee_name}} har en ubesvart forespørsel om nødtilgang for å {{atype}} kontoen din.",
|
||||
"Logg inn i hvelvet ([{{url}}]({{{url}}})) for å godta eller avslå.",
|
||||
"Gjør du ingenting, blir forespørselen *godtatt automatisk om {{days_left}} dager*.",
|
||||
]),
|
||||
"en": ("{{{grantee_name}}} is still waiting for emergency access", "The request is still open", [
|
||||
"{{grantee_name}} has a pending emergency access request to {{atype}} your account.",
|
||||
"Log in to the vault ([{{url}}]({{{url}}})) to approve or reject it.",
|
||||
"If you do nothing, the request is *approved automatically in {{days_left}} days*.",
|
||||
]),
|
||||
},
|
||||
|
||||
"emergency_access_recovery_approved": {
|
||||
"nb": ("Nødtilgangen din er godtatt", "Godtatt", [
|
||||
"{{grantor_name}} har godtatt forespørselen din om nødtilgang.",
|
||||
"Du kan nå logge inn i hvelvet: [{{url}}]({{{url}}}).",
|
||||
]),
|
||||
"en": ("Your emergency access was approved", "Approved", [
|
||||
"{{grantor_name}} approved your emergency access request.",
|
||||
"You can now log in to the vault: [{{url}}]({{{url}}}).",
|
||||
]),
|
||||
},
|
||||
|
||||
"emergency_access_recovery_rejected": {
|
||||
"nb": ("Nødtilgangen din er avslått", "Avslått", [
|
||||
"{{grantor_name}} har avslått forespørselen din om nødtilgang.",
|
||||
]),
|
||||
"en": ("Your emergency access was rejected", "Rejected", [
|
||||
"{{grantor_name}} rejected your emergency access request.",
|
||||
]),
|
||||
},
|
||||
|
||||
"emergency_access_recovery_timed_out": {
|
||||
"nb": ("{{{grantee_name}}} har fått nødtilgang", "Fristen gikk ut", [
|
||||
"{{grantee_name}} har fått nødtilgang til å {{atype}} kontoen din, fordi forespørselen "
|
||||
"ble stående ubesvart til fristen gikk ut.",
|
||||
"Var ikke dette meningen, kan du trekke tilgangen tilbake i hvelvet: [{{url}}]({{{url}}}).",
|
||||
]),
|
||||
"en": ("{{{grantee_name}}} was granted emergency access", "The deadline passed", [
|
||||
"{{grantee_name}} has been granted emergency access to {{atype}} your account, because "
|
||||
"the request went unanswered until the deadline passed.",
|
||||
"If that was not intended, you can revoke the access in the vault: [{{url}}]({{{url}}}).",
|
||||
]),
|
||||
},
|
||||
|
||||
}
|
||||
|
||||
|
||||
def mot_binær(sti: Path) -> None:
|
||||
"""Sammenlign med malene serveren faktisk kan sende.
|
||||
|
||||
Navnene ligger som tekst i binæren. Kommer det en ny mal i en oppgradering,
|
||||
ville den gått ut med serverens innebygde engelske tekst - og den sier
|
||||
Bitwarden. Da skal bygget stoppe her i stedet for at en kunde oppdager det
|
||||
i innboksen."""
|
||||
data = sti.read_bytes()
|
||||
finnes = {m.group(1).decode()
|
||||
for m in re.finditer(rb"email/([a-z0-9_]+)(?=[A-Z{])", data)}
|
||||
# Partialene har ingen egen tekst; de innebygde malene bruker dem, våre ikke.
|
||||
finnes -= {"email_header", "email_footer", "email_footer_text"}
|
||||
mangler = finnes - set(MALER)
|
||||
if mangler:
|
||||
raise SystemExit("maler.py: serveren har maler vi ikke har skrevet: "
|
||||
+ ", ".join(sorted(mangler)))
|
||||
|
||||
|
||||
def skriv(ut: Path) -> int:
|
||||
n = 0
|
||||
for navn, per_språk in MALER.items():
|
||||
for språk, (emne, tittel, avsnitt) in per_språk.items():
|
||||
mappe = ut / språk / "email"
|
||||
mappe.mkdir(parents=True, exist_ok=True)
|
||||
skille = "<!---------------->"
|
||||
(mappe / f"{navn}.hbs").write_text(
|
||||
f"{emne}\n{skille}\n{_tekst(avsnitt)}\n\n{BUNN_TEKST[språk]}\n",
|
||||
encoding="utf-8")
|
||||
(mappe / f"{navn}.html.hbs").write_text(
|
||||
f"{emne}\n{skille}\n" + RAMME.format(
|
||||
lang=HTML_LANG[språk], tittel=tittel,
|
||||
kropp=_html(avsnitt), bunn=BUNN[språk]) + "\n",
|
||||
encoding="utf-8")
|
||||
n += 2
|
||||
return n
|
||||
|
||||
|
||||
def sjekk() -> None:
|
||||
feil = []
|
||||
for navn, per_språk in MALER.items():
|
||||
if set(per_språk) != set(SPRÅK):
|
||||
feil.append(f"{navn}: mangler språk {set(SPRÅK) - set(per_språk)}")
|
||||
for språk, (emne, tittel, avsnitt) in per_språk.items():
|
||||
alt = " ".join([emne, tittel, *avsnitt])
|
||||
# Vaultwardens eget navn skal aldri stå i en e-post fra oss.
|
||||
if "vaultwarden" in alt.lower():
|
||||
feil.append(f"{navn}/{språk}: sier Vaultwarden")
|
||||
# Bitwarden er navnet på appen kunden installerer, og skal bare
|
||||
# stå der vi faktisk viser til appen eller utvidelsen.
|
||||
for treff in re.finditer(r"Bitwarden(\S*)", alt):
|
||||
if treff.group(1) not in ("-appen", "-utvidelsen", ""):
|
||||
feil.append(f"{navn}/{språk}: uventet bruk av Bitwarden")
|
||||
if alt.count("{{") != alt.count("}}"):
|
||||
feil.append(f"{navn}/{språk}: ubalanserte klammer")
|
||||
if not avsnitt:
|
||||
feil.append(f"{navn}/{språk}: ingen tekst")
|
||||
if feil:
|
||||
raise SystemExit("maler.py: " + "; ".join(feil))
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
sjekk()
|
||||
if len(sys.argv) > 2 and sys.argv[1] == "--mot":
|
||||
mot_binær(Path(sys.argv[2]))
|
||||
print("maler.py: alle malene serveren kan sende er dekket")
|
||||
raise SystemExit(0)
|
||||
if len(sys.argv) > 1:
|
||||
antall = skriv(Path(sys.argv[1]))
|
||||
print(f"maler.py: skrev {antall} filer i {len(SPRÅK)} språk")
|
||||
else:
|
||||
print(f"maler.py: {len(MALER)} maler, {len(SPRÅK)} språk - alt i orden")
|
||||
Reference in New Issue
Block a user