Synk fra arbeidsrepoet
This commit is contained in:
+15
-12
@@ -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> \· <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
@@ -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
@@ -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())
|
||||
Reference in New Issue
Block a user