Synk fra arbeidsrepoet

This commit is contained in:
Vaultnord
2026-08-31 21:12:36 +00:00
parent c5dc020a5a
commit e0994317c6
3 changed files with 279 additions and 66 deletions
+15 -12
View File
@@ -17,15 +17,25 @@ ARG VW_DIGEST=
FROM vaultwarden/server:${VW_VERSION}@${VW_DIGEST} AS kilde
FROM alpine:3.21@sha256:48b0309ca019d89d40f670aa1bc06e426dc0931948452e8491e3d65087abc07d AS sprak
RUN apk add --no-cache jq
COPY --from=kilde /web-vault/locales/nb/messages.json /nb.json
RUN apk add --no-cache python3
COPY --from=kilde /web-vault/locales /locales
ARG LOCALE_DIR=vault-image/locale
COPY ${LOCALE_DIR}/nb.json /over.json
RUN jq -s '.[0] * .[1]' /nb.json /over.json > /merged.json \
&& jq -e '.vaultWelcomeDialogTitle.message | test("Velkommen")' /merged.json >/dev/null
COPY ${LOCALE_DIR}/sprak.py /sprak.py
# Navnet byttes i verdiene, ikke i nøklene. En sed over hele fila døpte om
# atten oppslagsord, og da fant klienten dem ikke lenger - hele onboardingen
# forsvant i stillhet. Kontrollene i sprak.py stopper bygget hvis det gjentar seg.
RUN set -eux; \
for f in /locales/*/messages.json; do \
case "$f" in \
*/nb/messages.json) python3 /sprak.py "$f" Vaultnord /over.json ;; \
*) python3 /sprak.py "$f" Vaultnord ;; \
esac; \
done; \
python3 /sprak.py --sjekk /locales/nb/messages.json
FROM vaultwarden/server:${VW_VERSION}@${VW_DIGEST}
COPY --from=sprak /merged.json /web-vault/locales/nb/messages.json
COPY --from=sprak /locales /web-vault/locales
# Ressursene ligger i brand/ i det offentlige repoet og i
# vault-image/brand/ i arbeidsrepoet. Byggekonteksten avgjør hvilken.
@@ -45,13 +55,6 @@ RUN set -eux; \
sed -i 's#</body>#<div id="vaultnord-footer">Driftet av <a href="https://vaultnord.no">Vaultnord</a> \&middot; <a href="/_vaultnord/kilde.html">kildekode og lisens</a></div></body>#' /web-vault/index.html; \
grep -q '_vaultnord/brand.css' /web-vault/index.html; \
\
# Web-klienten sier "Bitwarden" i grensesnittet - i velkomstskjermen, i
# hjelpetekster og i knappene. Vi bytter navnet i språkfilene. URL-er går
# klar: de skriver bitwarden.com med liten forbokstav.
find /web-vault/locales -name messages.json -exec \
sed -i 's/Bitwarden/Vaultnord/g' {} +; \
grep -q 'Vaultnord' /web-vault/locales/nb/messages.json; \
\
# Brandingen henger på navn i web-klienten. Finnes de ikke lenger, har
# oppstrøms endret noe, og pynten ville blitt stille borte. Da skal bygget
# stoppe her i stedet - se lista øverst i brand.css.
+153 -54
View File
@@ -1,56 +1,155 @@
{
"vaultWelcomeDialogTitle": { "message": "Du er inne! Velkommen til Vaultnord" },
"vaultWelcomeDialogDescription": { "message": "Her lagrer du passordene og den personlige informasjonen din. Vi viser deg rundt." },
"vaultWelcomeDialogPrimaryCta": { "message": "Ta omvisningen" },
"vaultWelcomeDialogDismissCta": { "message": "Hopp over" },
"welcome": { "message": "Velkommen" },
"continue": { "message": "Fortsett" },
"skip": { "message": "Hopp over" },
"close": { "message": "Lukk" },
"next": { "message": "Neste" },
"back": { "message": "Tilbake" },
"done": { "message": "Ferdig" },
"getStarted": { "message": "Kom i gang" },
"learnMore": { "message": "Les mer" },
"logInToBitwarden": { "message": "Logg inn i Vaultnord" },
"newToBitwarden": { "message": "Ny hos Vaultnord?" },
"loggingInAs": { "message": "Logger inn som" },
"notYou": { "message": "Ikke deg?" },
"masterPass": { "message": "Hovedpassord" },
"masterPassDesc": { "message": "Hovedpassordet låser opp hvelvet ditt. Det kan ikke gjenopprettes hvis du glemmer det." },
"unlock": { "message": "Lås opp" },
"lock": { "message": "Lås" },
"loggedOut": { "message": "Logget ut" },
"myVault": { "message": "Mitt hvelv" },
"allItems": { "message": "Alle elementer" },
"favorites": { "message": "Favoritter" },
"trash": { "message": "Papirkurv" },
"addItem": { "message": "Legg til element" },
"editItem": { "message": "Rediger element" },
"itemInformation": { "message": "Om elementet" },
"noItemsInList": { "message": "Ingen elementer her ennå." },
"searchVault": { "message": "Søk i hvelvet" },
"copyValue": { "message": "Kopier" },
"toggleVisibility": { "message": "Vis eller skjul" },
"generatePassword": { "message": "Generer passord" },
"checkPassword": { "message": "Sjekk om passordet er lekket" },
"collections": { "message": "Samlinger" },
"members": { "message": "Medlemmer" },
"organizations": { "message": "Organisasjoner" },
"newOrganization": { "message": "Ny organisasjon" },
"confirmMembers": { "message": "Bekreft medlemmer" },
"inviteMember": { "message": "Inviter medlem" },
"settings": { "message": "Innstillinger" },
"security": { "message": "Sikkerhet" },
"twoStepLogin": { "message": "To-trinns innlogging" },
"changeMasterPassword": { "message": "Bytt hovedpassord" },
"exportVault": { "message": "Eksporter hvelvet" },
"importData": { "message": "Importer data" },
"language": { "message": "Språk" },
"helpAndFeedback": { "message": "Hjelp" }
"vaultWelcomeDialogTitle": {
"message": "Du er inne! Velkommen til Vaultnord"
},
"vaultWelcomeDialogDescription": {
"message": "Her lagrer du passordene og den personlige informasjonen din. Vi viser deg rundt."
},
"vaultWelcomeDialogPrimaryCta": {
"message": "Ta omvisningen"
},
"vaultWelcomeDialogDismissCta": {
"message": "Hopp over"
},
"welcome": {
"message": "Velkommen"
},
"continue": {
"message": "Fortsett"
},
"skip": {
"message": "Hopp over"
},
"close": {
"message": "Lukk"
},
"next": {
"message": "Neste"
},
"back": {
"message": "Tilbake"
},
"done": {
"message": "Ferdig"
},
"getStarted": {
"message": "Kom i gang"
},
"learnMore": {
"message": "Les mer"
},
"logInToBitwarden": {
"message": "Logg inn i Vaultnord"
},
"newToBitwarden": {
"message": "Ny hos Vaultnord?"
},
"loggingInAs": {
"message": "Logger inn som"
},
"notYou": {
"message": "Ikke deg?"
},
"masterPass": {
"message": "Hovedpassord"
},
"masterPassDesc": {
"message": "Hovedpassordet låser opp hvelvet ditt. Det kan ikke gjenopprettes hvis du glemmer det."
},
"unlock": {
"message": "Lås opp"
},
"lock": {
"message": "Lås"
},
"loggedOut": {
"message": "Logget ut"
},
"myVault": {
"message": "Mitt hvelv"
},
"allItems": {
"message": "Alle elementer"
},
"favorites": {
"message": "Favoritter"
},
"trash": {
"message": "Papirkurv"
},
"addItem": {
"message": "Legg til element"
},
"editItem": {
"message": "Rediger element"
},
"itemInformation": {
"message": "Om elementet"
},
"noItemsInList": {
"message": "Ingen elementer her ennå."
},
"searchVault": {
"message": "Søk i hvelvet"
},
"copyValue": {
"message": "Kopier"
},
"toggleVisibility": {
"message": "Vis eller skjul"
},
"generatePassword": {
"message": "Generer passord"
},
"checkPassword": {
"message": "Sjekk om passordet er lekket"
},
"collections": {
"message": "Samlinger"
},
"members": {
"message": "Medlemmer"
},
"organizations": {
"message": "Organisasjoner"
},
"newOrganization": {
"message": "Ny organisasjon"
},
"confirmMembers": {
"message": "Bekreft medlemmer"
},
"inviteMember": {
"message": "Inviter medlem"
},
"settings": {
"message": "Innstillinger"
},
"security": {
"message": "Sikkerhet"
},
"twoStepLogin": {
"message": "To-trinns innlogging"
},
"changeMasterPassword": {
"message": "Bytt hovedpassord"
},
"exportVault": {
"message": "Eksporter hvelvet"
},
"importData": {
"message": "Importer data"
},
"language": {
"message": "Språk"
},
"helpAndFeedback": {
"message": "Hjelp"
},
"emailPlaceholder": {
"message": "navn@firma.no"
},
"emailPlaceholderMultiple": {
"message": "navn@firma.no, kollega@firma.no"
}
}
+111
View File
@@ -0,0 +1,111 @@
"""Norske tekster og vårt navn inn i web-klientens språkfiler.
Erstatter en `sed 's/Bitwarden/Vaultnord/g'` over hele fila. Den byttet navn
også i JSON-nøklene, og da slutter klienten å finne strengen - atten tekster
forsvant i stillhet, blant dem hele onboardingen. Samtidig slapp atten andre
unna, fordi de skriver navnet med liten forbokstav midt i en setning.
Reglene her:
* Nøkler røres aldri. De er klientens oppslagsord.
* Bare verdier byttes, og bare som helt ord.
* URL-er står urørt. bitwarden.com er deres adresse, ikke vår.
* Noen tekster handler faktisk om Bitwarden sine egne produkter - nettleser-
utvidelsen, Authenticator, Families. Å kalle dem våre ville vært å påstå at
vi eier noe andre har laget.
"""
import json
import re
import sys
# Tekster som virkelig handler om Bitwarden, og som skal fortsette å gjøre det.
BEHOLD = {
"twoStepContinueToBitwardenUrlTitle",
"twoStepContinueToBitwardenUrlDesc",
"openBitwardenExtension",
"contactBitwardenSupport",
"moreProductsFromBitwarden",
"moreFromBitwarden",
"sponsoredBitwardenFamilies",
"sponsorshipFreeBitwardenFamilies",
"acceptBitwardenFamiliesHelp",
"youHaveBitwardenPremium",
"startYour7DayFreeTrialOfBitwarden",
"startYour7DayFreeTrialOfBitwardenFor",
"startYour7DayFreeTrialOfBitwardenSecretsManagerFor",
"toHostBitwardenOnYourOwnServer",
}
URL = re.compile(r"https?://[^\s\"<>]+|[\w.-]+@[\w.-]+|bitwarden\.com", re.I)
ORD = re.compile(r"\bbitwarden\b", re.I)
def bytt(tekst: str, navn: str) -> str:
"""Bytter navnet i en tekst, men lar adresser stå."""
vern = []
def gjem(m):
vern.append(m.group(0))
return f"\x00{len(vern) - 1}\x00"
trygg = URL.sub(gjem, tekst)
trygg = ORD.sub(navn, trygg)
return re.sub(r"\x00(\d+)\x00", lambda m: vern[int(m.group(1))], trygg)
def rebrand(data: dict, navn: str) -> dict:
ut = {}
for nokkel, verdi in data.items():
if nokkel in BEHOLD or not isinstance(verdi, dict):
ut[nokkel] = verdi
continue
ny = dict(verdi)
if isinstance(ny.get("message"), str):
ny["message"] = bytt(ny["message"], navn)
ut[nokkel] = ny # nøkkelen selv står urørt
return ut
# Det bygget skal stoppe på. Hver linje er en feil vi har hatt.
KONTROLLER = [
("vaultWelcomeDialogTitle", "Velkommen", True, "norsk velkomsttekst mangler"),
("logInToBitwarden", "Vaultnord", True, "verdien er ikke byttet"),
("turnOnNewDeviceLoginProtectionModalDesc", "bitwarden", False,
"liten forbokstav slapp unna"),
("openBitwardenExtension", "Bitwarden", True, "unntaket ble overkjørt"),
]
def sjekk(sti: str) -> int:
data = json.load(open(sti))
feil = []
for nokkel, ord_, skal_finnes, hvorfor in KONTROLLER:
if nokkel not in data:
feil.append(f"{nokkel}: nøkkelen er borte - er den døpt om?")
continue
har = ord_.lower() in data[nokkel].get("message", "").lower()
if har != skal_finnes:
feil.append(f"{nokkel}: {hvorfor}")
if "bitwarden.com" not in json.dumps(data):
feil.append("adressene til bitwarden.com skal stå urørt")
for f in feil:
print(f" FEIL {f}", file=sys.stderr)
if not feil:
print(" språkfilene ser riktige ut")
return 1 if feil else 0
def main() -> int:
if sys.argv[1] == "--sjekk":
return sjekk(sys.argv[2])
sti, navn = sys.argv[1], sys.argv[2]
over = json.load(open(sys.argv[3])) if len(sys.argv) > 3 else {}
data = json.load(open(sti))
data.update(over) # våre egne tekster først
json.dump(rebrand(data, navn), open(sti, "w"), ensure_ascii=False, indent=1)
return 0
if __name__ == "__main__":
sys.exit(main())