Compare commits

...

3 Commits

Author SHA1 Message Date
Xe Iaso
1a19d7eee4 chore: release v1.21.1 (#887)
Signed-off-by: Xe Iaso <me@xeiaso.net>
2025-07-22 16:32:06 -04:00
Sunniva Løvstad
25af5a232f feat(localization): Add in Bokmål and Nynorsk translations (#855)
* feat(localization): add bokmål and nynorsk translations

* feat(localization): update tests for Bokmål and Nynorsk

* docs(localization): document bokmål and nynorsk locales

* fix(locales/nb,nn): remove unicode ellipsis to make tests pass

Signed-off-by: Xe Iaso <me@xeiaso.net>

* style(localization): sort languages to make test output stable

Signed-off-by: Xe Iaso <me@xeiaso.net>

* chore: spelling

check-spelling run (pull_request) for main

Signed-off-by: check-spelling-bot <check-spelling-bot@users.noreply.github.com>
on-behalf-of: @check-spelling <check-spelling-bot@check-spelling.dev>

---------

Signed-off-by: Xe Iaso <me@xeiaso.net>
Signed-off-by: Xe Iaso <xe.iaso@techaro.lol>
Signed-off-by: check-spelling-bot <check-spelling-bot@users.noreply.github.com>
Co-authored-by: Xe Iaso <me@xeiaso.net>
Co-authored-by: Xe Iaso <xe.iaso@techaro.lol>
2025-07-21 22:37:49 -04:00
Xe Iaso
24d2501187 feat: Russian localization for Anubis (#882)
* feat(localization): Add Russian language translation

* test(localization): ensure Russian translations are tested

Signed-off-by: Xe Iaso <me@xeiaso.net>

* docs(changelog): update with Russian translation

Signed-off-by: Xe Iaso <me@xeiaso.net>

---------

Signed-off-by: Xe Iaso <me@xeiaso.net>
Signed-off-by: Xe Iaso <xe.iaso@techaro.lol>
Co-authored-by: MichaelAgarkov <michaelagarkov@internet.ru>
2025-07-21 23:14:51 +00:00
10 changed files with 229 additions and 9 deletions

View File

@@ -23,6 +23,7 @@ bitrate
Bluesky
blueskybot
boi
Bokm
botnet
botstopper
BPort

View File

@@ -1 +1 @@
1.21.0
1.21.1

View File

@@ -13,17 +13,24 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
<!-- This changes the project to: -->
## v1.21.1: Minfilia Warde - Echo 1
- Expired records are now properly removed from bbolt databases ([#848](https://github.com/TecharoHQ/anubis/pull/848)).
- Fix hanging on service restart ([#853](https://github.com/TecharoHQ/anubis/issues/853))
### Added
Anubis now supports the [`missingHeader`](./admin/configuration/expressions.mdx#missingHeader) to assert the absence of headers in requests.
#### New locales
Anubis now supports these new languages:
- [Czech](https://github.com/TecharoHQ/anubis/pull/849)
- [Finnish](https://github.com/TecharoHQ/anubis/pull/863)
Anubis now supports the [`missingHeader`](./admin/configuration/expressions.mdx#missingHeader) to assert the absence of headers in requests.
- [Norwegian Bokmål](https://github.com/TecharoHQ/anubis/pull/855)
- [Norwegian Nynorsk](https://github.com/TecharoHQ/anubis/pull/855)
- [Russian](https://github.com/TecharoHQ/anubis/pull/882)
### Fixes

View File

@@ -11,7 +11,10 @@
"is",
"it",
"ja",
"nb",
"nn",
"pt-BR",
"ru",
"tr",
"zh-CN",
"zh-TW"

View File

@@ -0,0 +1,64 @@
{
"loading": "Laster inn...",
"why_am_i_seeing": "Hvorfor ser jeg dette?",
"protected_by": "Beskyttet av",
"protected_from": "Fra",
"made_with": "Laget med ❤️ i 🇨🇦",
"mascot_design": "Maskotdesign av",
"ai_companies_explanation": "Du ser dette fordi administratoren av dette nettstedet har satt opp Anubis for å beskytte sørveren mot plagen av KI-selskaper som aggressivt skraper nettsteder. Dette kan, og fortsetter med å, forårsake driftstans for nettstedene, som gjør ressursene deres utilgjengelige for alle.",
"anubis_compromise": "Anubis er et kompromiss. Anubis bruker et «Proof-of-Work»-skjema som ligner på Hashcash, et lignende skjema for å redusere søppel-e-post. Idéen er at ved småstilte tilfeller er den ytterligere belastningen ignorerbar, men ved storstilt skraping samler den på seg fart og gjør det å skrape mye mer dyrt.",
"hack_purpose": "Til syvende og sist er dette en hack som har som formål å gi en «god nok» plassholderløsning slik at mer tid kan brukes på å fingeravtrykke og gjenkjenne hodeløse nettlesere (f.eks. hvordan de gjengir skrifttyper) slik at utfordringssiden ikke må bli vist til brukere som er mer sannsynligvis ekte.",
"jshelter_note": "NB: Anubis krever bruk av moderne JavaScript-funksjoner som tillegg som JShelter slår av. Vennligst slå av JShelter eller lignende tillegg for dette domenet.",
"version_info": "Dette nettstedet kjører Anubis-utgave",
"try_again": "Prøv igjen",
"go_home": "Gå hjem",
"contact_webmaster": "eller om du synes at du ikke burde være blokkert, vennligst ta kontakt med administratoren på",
"connection_security": "Vennligst vent mens vi bekrefter tryggheten av tilkoblingen din.",
"javascript_required": "Du må dessverre slå på JavaScript for å komme deg forbi denne utfordringen. Dette kreves fordi KI-selskaper har endret sosialkontrakten om hvordan nettstedsverting fungerer. En ikke-JS-løsning er i gang med å skapes.",
"benchmark_requires_js": "JavaScript må være påslått for å kjøre sammenligningsverktøyet.",
"difficulty": "Vanskelighetsnivå:",
"algorithm": "Algoritme:",
"compare": "Jevnfør:",
"time": "Tid",
"iters": "Gjentakelser",
"time_a": "Tid A",
"iters_a": "Gjentakelser A",
"time_b": "Tid B",
"iters_b": "Gjentakelser B",
"static_check_endpoint": "Dette er bare et sjekkeendepunkt for din omvendte proxy å bruke.",
"authorization_required": "Legitimasjon kreves",
"cookies_disabled": "Nettleseren din er konfigurert for å avslå informasjonskapsler. Anubis krever informasjonskapsler for å bekrefte at du er en ekte bruker. Vennligst slå på informasjonskapsler på dette domenet.",
"access_denied": "Adgang nektet: feilkode",
"dronebl_entry": "DroneBL rapporterte em oppføring.",
"see_dronebl_lookup": "se",
"internal_server_error": "Intern serverfeil: administratoren har feilkonfigurert Anubis. Vennligst ta kontakt med hen og spør hen om å se gjennom loggene om",
"invalid_redirect": "Ugyldig omdirigering",
"redirect_not_parseable": "Omdirigerings-URL-en kunne ikkj tolkes",
"redirect_domain_not_allowed": "Omdirigeringsdomenet er ikke tillatt",
"failed_to_sign_jwt": "mislyktes i å signere JWT",
"invalid_invocation": "Ugyldig fremkalling av MakeChallenge",
"client_error_browser": "Klientfeil: Vennligst sørg for at at nettleseren din er oppdatert og prøv igjen senere.",
"oh_noes": "Å nei!",
"benchmarking_anubis": "Sammenligner Anubis!",
"you_are_not_a_bot": "Du er ikke en bot!",
"making_sure_not_bot": "Bekrefter at du ikke er en bot!",
"celphase": "CELPHASE",
"js_web_crypto_error": "Nettleseren din har ikke et fungerande web.crypto-element. Ser du dette med ei sikker tilkopling?",
"js_web_workers_error": "Nettleseren din støtter ikke nettarbeidere (Anubis bruker dette for å unngå å fryse nettleseren din). Har du et tillegg som JShelter installert?",
"js_cookies_error": "Nettleseren lagrer ikke informasjonskapsler. Anubis bruker informasjonskapsler for å avgjøre hvilke klienter har lyktes i utfordringen ved å lagre en signert token i en informasjonskapsel. Vennligst slå på informasjonskapsler på dette domenet. Navnene på informasjonskapslene Anubis lagrer, kan variere uten varsel. Informasjonskapselnavn og -verdier er ikke en del av det offentlege API-et.",
"js_context_not_secure": "Du bruker ikke en sikker tilkobling!",
"js_context_not_secure_msg": "Prøv å koble til over HTTPS eller fortell administratoren å opprette HTTPS. Se <a hreflang=\"en\" href=\"https://developer.mozilla.org/en-US/docs/Web/Security/Secure_Contexts#when_is_a_context_considered_secure\">MDN</a> for mer informasjon.",
"js_calculating": "Beregner…",
"js_missing_feature": "Mangler funksjon",
"js_challenge_error": "Utfordringsfeil!",
"js_challenge_error_msg": "Mislyktes i å tolke sjekkalgoritmen. Du burde laste inn denne siden på nytt.",
"js_calculating_difficulty": "Beregner…<br/>Vanskelighetsnivå:",
"js_speed": "Hastighet:",
"js_verification_longer": "Verifisering tar lengre enn forventet. Vennligst ikke last inn denne siden på nytt.",
"js_success": "Vellykket!",
"js_done_took": "Ferdig! Tok",
"js_iterations": "gjentakelser",
"js_finished_reading": "Jeg har sluttet å lese, fortsett →",
"js_calculation_error": "Beregningsfeil!",
"js_calculation_error_msg": "Mislyktes i å beregne utfordring:"
}

View File

@@ -0,0 +1,64 @@
{
"loading": "Lastar inn...",
"why_am_i_seeing": "Kvifor ser eg dette?",
"protected_by": "Verna av",
"protected_from": "Frå",
"made_with": "Laga med ❤️ i 🇨🇦",
"mascot_design": "Maskotdesign av",
"ai_companies_explanation": "Du ser dette av di administratoren av denne nettstaden har sett opp Anubis for å verne sørvaren mot plaga av KI-selskap som aggressivt skrapar nettstader. Dette kan, og held frem med å, forårsake driftstans for nettstadene, som gjer ressursane deira utilgjengelege for alle.",
"anubis_compromise": "Anubis er eit kompromiss. Anubis brukar eit «Proof-of-Work»-skjema som liknar på Hashcash, eit liknande skjema for å redusere søppel-e-post. Idéen er at ved småstilte tilfelle er den ytterlegare lastinga ignorerbar, men ved storstilt skraping samlar ho på seg fart og gjer det å skrapa mykje meir dyrt.",
"hack_purpose": "Til sjuande og sist er dette ein hack som har som formål å gje ei «god nok» plasshaldarløysing slik at meir tid kan brukast på å fingeravtrykkje og attkjenne hovudlause nettlesarar (f.eks. korleis dei attgjev skrifttypar) slik at utfordringssida ikkje må verte synt til brukarar som er meir sannsynlegvis ekte.",
"jshelter_note": "NB: Anubis krev bruk av moderne JavaScript-funksjonar som tillegg som JShelter slår av. Venlegast slå av JShelter eller liknande tillegg for dette domenet.",
"version_info": "Denne nettstaden køyrer Anubis-utgåve",
"try_again": "Prøv att",
"go_home": "Gå heim",
"contact_webmaster": "eller om du synest at du ikkje burde vera blokkert, venlegast tak kontakt med administratoren på",
"connection_security": "Venlegast vent medan vi stadfestar tryggleiken av tilkoplinga di.",
"javascript_required": "Du lyt diverre slå på JavaScript for å koma deg forbi denne utfordringa. Dette krevst av di KI-selskap har endra sosialkontrakten om korleis nettstadsverting fungerer. Ei ikkje-JS-løysing er i gang med å skapast.",
"benchmark_requires_js": "JavaScript må vera slegen på for å køyre samanlikningsverktøyet.",
"difficulty": "Vanskenivå:",
"algorithm": "Algoritme:",
"compare": "Jamfør:",
"time": "Tid",
"iters": "Oppattakingar",
"time_a": "Tid A",
"iters_a": "Oppattakingar A",
"time_b": "Tid B",
"iters_b": "Oppattakingar B",
"static_check_endpoint": "Dette er berre eit sjekkeendepunkt for din omvende proxy å bruke.",
"authorization_required": "Legitimasjon krevst",
"cookies_disabled": "Nettlesaren din er konfigurert for å avslå informasjonskapslar. Anubis krev informasjonskapslar for å stadfeste at du er ein ekte brukar. Venlegast slå på informasjonskapslar på dette domenet.",
"access_denied": "Tilgang nekta: feilkode",
"dronebl_entry": "DroneBL rapporterte ei oppføring.",
"see_dronebl_lookup": "sjå",
"internal_server_error": "Intern serverfeil: administratoren har feilkonfigurert Anubis. Venlegast tak kontakt med hen og spør hen om å sjå gjennom loggane om",
"invalid_redirect": "Ugyldig omdirigering",
"redirect_not_parseable": "Omdirigerings-URL-en kunne ikkje tolkast",
"redirect_domain_not_allowed": "Omdirigeringsdomenet er ikkje tillate",
"failed_to_sign_jwt": "mislukkast i å signere JWT",
"invalid_invocation": "Ugyldig framkalling av MakeChallenge",
"client_error_browser": "Klientfeil: Venlegast stadfest at nettlesaren din er oppdatert og prøv att seinare.",
"oh_noes": "Å nei!",
"benchmarking_anubis": "Samanliknar Anubis!",
"you_are_not_a_bot": "Du er ikkje ein bot!",
"making_sure_not_bot": "Stadfestar at du ikkje er ein bot!",
"celphase": "CELPHASE",
"js_web_crypto_error": "Nettlesaren din har ikkje eit fungerande web.crypto-element. Ser du dette med ei sikker tilkopling?",
"js_web_workers_error": "Nettlesaren din støttar ikkje nettarbeidarar (Anubis brukar dette for å unngå å fryse nettlesaren din). Har du eit tillegg som JShelter installert?",
"js_cookies_error": "Nettlesaren lagrar ikkje informasjonskapslar. Anubis brukar informasjonskapslar for å avgjera kva klientar har lukkast i utfordringa ved å lagra ein signert token i ein informasjonskapsel. Venlegast slå på informasjonskapslar på dette domenet. Namna på informasjonskapslane Anubis lagrar, kan variere utan varsel. Informasjonskapselnamn og -verdiar er ikkje ein del av det offentlege API-et.",
"js_context_not_secure": "Du brukar ikkje ei sikker tilkopling!",
"js_context_not_secure_msg": "Prøv å kople til over HTTPS eller fortel administratoren å opprette HTTPS. Sjå <a hreflang=\"en\" href=\"https://developer.mozilla.org/en-US/docs/Web/Security/Secure_Contexts#when_is_a_context_considered_secure\">MDN</a> for fleire opplysingar.",
"js_calculating": "Reknar…",
"js_missing_feature": "Manglar funksjon",
"js_challenge_error": "Utfordringsfeil!",
"js_challenge_error_msg": "Mislukkast i å tolke sjekkalgoritmen. Du burde laste inn denne sida på nytt.",
"js_calculating_difficulty": "Reknar…<br/>Vanskenivå:",
"js_speed": "Fart:",
"js_verification_longer": "Verifisering tek lengre enn forventa. Venlegast ikkje last inn denne sida på nytt.",
"js_success": "Vellykka!",
"js_done_took": "Ferdig! Tok",
"js_iterations": "oppattakingar",
"js_finished_reading": "Eg har slutta å lesa, hald fram →",
"js_calculation_error": "Rekningsfeil!",
"js_calculation_error_msg": "Mislukkast i å rekne utfordring:"
}

View File

@@ -0,0 +1,64 @@
{
"loading": "Загрузка...",
"why_am_i_seeing": "Почему я вижу это?",
"protected_by": "Защищено",
"protected_from": "От",
"made_with": "Сделано с ❤️ из 🇨🇦",
"mascot_design": "Дизайн маскота от",
"ai_companies_explanation": "Вы это видите, потому что администратор этого сайта настроил Anubis для защиты сервера от атак, использующих ИИ, которые агрессивно копируют данные с сайтов. Это может привести к зависанию сайтов и делает их ресурсы недоступными для всех.",
"anubis_compromise": "Anubis - это компромисс. Anubis использует Proof-of-Work, похожую на Hashcash, для борьбы со спамом в электронной почте. Идея в том, что на отдельных уровнях дополнительная нагрузка не влиятельна, но на уровне массового парсинга она накапливается и значительно удорожает сбор данных.",
"hack_purpose": "В реальности, это хак, у которого настоящая цель - предоставить «достаточно хорошее» решение, чтобы можно было потратить больше времени на идентификацию headless-браузеров (например, по тому, как они выполняют отрисовку шрифтов), чтобы не отображать страницу с подтверждением пользователям, которые с гораздо большей вероятностью являются настоящими.",
"jshelter_note": "Anubis требует использования современных функций JavaScript, которые плагины, по типу JShelter, отключают. Пожалуйста, отключите JShelter и другие подобные плагины для этого домена.",
"version_info": "На сайте запущен Anubis версии",
"try_again": "Попробуйте снова",
"go_home": "Перейти на домашнюю",
"contact_webmaster": "если вы уверены, что это ошибка, свяжитесь с владельцем сайта через",
"connection_security": "Пожалуйста, подождите, пока мы проверим безопасность вашего соединения.",
"javascript_required": "К сожалению, для решения этой проверки необходимо включить JavaScript. Это необходимо, поскольку компании, занимающиеся разработкой ИИ, изменили моральные правила, касающийся хостинга веб-сайтов. Решение без использования JavaScript находится в стадии разработки.",
"benchmark_requires_js": "Для работы тестирования необходимо включить JavaScript.",
"difficulty": "Сложность:",
"algorithm": "Алгоритм:",
"compare": "Сравнить:",
"time": "Время",
"iters": "Итерации",
"time_a": "Время A",
"iters_a": "Итерации A",
"time_b": "Время B",
"iters_b": "Итерации B",
"static_check_endpoint": "Это всего лишь точка проверки, которую может использовать ваш обратный прокси-сервер.",
"authorization_required": "Требуется авторизация.",
"cookies_disabled": "В вашем браузере отключены cookie файлы. Anubis требует их для подтверждения того, что вы являетесь настоящим человеком. Пожалуйста, включите файлы cookie для этого домена",
"access_denied": "Доступ запрещён: код ошибки",
"dronebl_entry": "DroneBL сообщил о записи",
"see_dronebl_lookup": "см.",
"internal_server_error": "Внутренняя ошибка сервера: администратор неправильно настроил Anubis. Обратитесь к администратору и попросите его просмотреть логи",
"invalid_redirect": "Неверное перенаправление",
"redirect_not_parseable": "URL-адрес перенаправления не может быть анализирован",
"redirect_domain_not_allowed": "Перенаправление домена запрещено",
"failed_to_sign_jwt": "не смог подписать JWT",
"invalid_invocation": "Неверный вызов MakeChallenge",
"client_error_browser": "Ошибка клиента: убедитесь, что у вас браузер новейшей версии, и повторите попытку позже.",
"oh_noes": "О нет!",
"benchmarking_anubis": "Анализ Анубиса!",
"you_are_not_a_bot": "Вы не бот!",
"making_sure_not_bot": "Проверяем, что вы не бот!",
"celphase": "CELPHASE",
"js_web_crypto_error": "В вашем браузере отсутствует функция web.crypto. Вы просматриваете страницу через защищённый контекст?",
"js_web_workers_error": "Ваш браузер не поддерживает web worker (Anubis использует его, чтобы избежать зависания браузера). У вас установлен плагин типа JShelter?",
"js_cookies_error": "Ваш браузер не сохраняет cookie файлы. Anubis использует их для определения клиентов, прошедших проверку, сохраняя подписанный токен в файле cookie. Включите сохранение файлов cookie для этого домена. Имена файлов cookie, хранимых Anubis, могут изменяться без предварительного уведомления. Имена и значения cookie файлов не являются частью общедоступного API.",
"js_context_not_secure": "Ваш контекст небезопасен!",
"js_context_not_secure_msg": "Попробуйте подключиться по HTTPS или попросите администратора, чтобы он настроил HTTPS. Подробнее см. <a href=\"https://developer.mozilla.org/en-US/docs/Web/Security/Secure_Contexts#when_is_a_context_considered_secure\">MDN</a>.",
"js_calculating": "Расчёт...",
"js_missing_feature": "Отсутствует функция",
"js_challenge_error": "Ошибка проверки!",
"js_challenge_error_msg": "Не удалось определить алгоритм проверки. Возможно, нужно перезагрузить страницу..",
"js_calculating_difficulty": "Расчёт...<br/>Сложность:",
"js_speed": "Скорость:",
"js_verification_longer": "Проверка занимает больше времени, чем ожидалось. Пожалуйста, не обновляйте страницу.",
"js_success": "Успех!",
"js_done_took": "Получилось! Заняло",
"js_iterations": "итераций",
"js_finished_reading": "Я дочитал, продолжить →",
"js_calculation_error": "Ошибка расчёта!",
"js_calculation_error_msg": "Не удалось рассчитать задачу:"
}

View File

@@ -21,13 +21,25 @@ func TestLocalizationService(t *testing.T) {
"fr": "Chargement...",
"ja": "ロード中...",
"is": "Hleður...",
"nb": "Laster inn...",
"nn": "Lastar inn...",
"pt-BR": "Carregando...",
"tr": "Yükleniyor...",
"ru": "Загрузка...",
"zh-CN": "加载中...",
"zh-TW": "載入中...",
}
for lang, expected := range loadingStrMap {
var keys []string
for lang := range loadingStrMap {
keys = append(keys, lang)
}
sort.Strings(keys)
for _, lang := range keys {
expected := loadingStrMap[lang]
t.Run(fmt.Sprintf("%s localization", lang), func(t *testing.T) {
localizer := service.GetLocalizer(lang)
result := localizer.MustLocalize(&i18n.LocalizeConfig{MessageID: "loading"})
@@ -43,7 +55,7 @@ func TestLocalizationService(t *testing.T) {
"mascot_design", "try_again", "go_home", "javascript_required",
}
for lang := range loadingStrMap {
for _, lang := range keys {
t.Run(fmt.Sprintf("All required keys exist in %s", lang), func(t *testing.T) {
loc := service.GetLocalizer(lang)
for _, key := range requiredKeys {
@@ -57,7 +69,7 @@ func TestLocalizationService(t *testing.T) {
}
type manifest struct {
SupportedLanguages []string `json:"supported_languages"`
SupportedLanguages []string `json:"supportedLanguages"`
}
func loadManifest(t *testing.T) manifest {
@@ -98,6 +110,11 @@ func TestComprehensiveTranslations(t *testing.T) {
sort.Strings(keys)
manifest := loadManifest(t)
if len(manifest.SupportedLanguages) == 0 {
t.Fatal("no languages loaded")
}
for _, lang := range loadManifest(t).SupportedLanguages {
t.Run(lang, func(t *testing.T) {
loc := service.GetLocalizer(lang)

4
package-lock.json generated
View File

@@ -1,12 +1,12 @@
{
"name": "@techaro/anubis",
"version": "1.21.0",
"version": "1.21.1",
"lockfileVersion": 3,
"requires": true,
"packages": {
"": {
"name": "@techaro/anubis",
"version": "1.21.0",
"version": "1.21.1",
"license": "ISC",
"devDependencies": {
"cssnano": "^7.1.0",

View File

@@ -1,6 +1,6 @@
{
"name": "@techaro/anubis",
"version": "1.21.0",
"version": "1.21.1",
"description": "",
"main": "index.js",
"scripts": {