Merge branch 'dev' into bullseye

This commit is contained in:
Kay0u 2021-09-01 17:16:47 +02:00
commit 614f79f9e6
No known key found for this signature in database
GPG key ID: AAFEEB16CFA2AE2D
17 changed files with 349 additions and 74 deletions

View file

@ -208,17 +208,18 @@ end
if is_logged_in then if is_logged_in then
assets = { assets = {
["/ynh_portal.js"] = "js/ynh_portal.js", ["/ynh_portal.js"] = "js/ynh_portal.js",
["/ynh_userinfo.json"] = "ynh_userinfo.json",
["/ynh_overlay.css"] = "css/ynh_overlay.css" ["/ynh_overlay.css"] = "css/ynh_overlay.css"
} }
theme_dir = "/usr/share/ssowat/portal/assets/themes/"..conf.theme theme_dir = "/usr/share/ssowat/portal/assets/themes/"..conf.theme
local pfile = io.popen('find "'..theme_dir..'" -type f -exec realpath --relative-to "'..theme_dir..'" {} \\;') local pfile = io.popen('find "'..theme_dir..'" -not -path "*/\\.*" -type f -exec realpath --relative-to "'..theme_dir..'" {} \\;')
for filename in pfile:lines() do for filename in pfile:lines() do
assets["/ynhtheme/"..filename] = "themes/"..conf.theme.."/"..filename assets["/ynhtheme/"..filename] = "themes/"..conf.theme.."/"..filename
end end
pfile:close() pfile:close()
for shortcut, full in pairs(assets) do for shortcut, full in pairs(assets) do
if string.match(ngx.var.uri, "^"..shortcut.."$") then if ngx.var.uri == shortcut then
logger.debug("Serving static asset "..full) logger.debug("Serving static asset "..full)
return hlp.serve("/yunohost/sso/assets/"..full, "static_asset") return hlp.serve("/yunohost/sso/assets/"..full, "static_asset")
end end
@ -291,14 +292,20 @@ end
permission = nil permission = nil
longest_url_match = "" longest_url_match = ""
ngx_full_url = ngx.var.host..ngx.var.uri
for permission_name, permission_infos in pairs(conf["permissions"]) do for permission_name, permission_infos in pairs(conf["permissions"]) do
if next(permission_infos['uris']) ~= nil then if next(permission_infos['uris']) ~= nil then
for _, url in pairs(permission_infos['uris']) do for _, url in pairs(permission_infos['uris']) do
if string.starts(url, "re:") then if string.starts(url, "re:") then
url = string.sub(url, 4, string.len(url)) url = string.sub(url, 4, string.len(url))
end end
-- We want to match the beginning of the url
if not string.starts(url, "^") then
url = "^"..url
end
local m = hlp.match(ngx.var.host..ngx.var.uri..hlp.uri_args_string(), url) local m = hlp.match(ngx_full_url, url)
if m ~= nil and string.len(m) > string.len(longest_url_match) then if m ~= nil and string.len(m) > string.len(longest_url_match) then
longest_url_match = m longest_url_match = m
permission = permission_infos permission = permission_infos

51
debian/changelog vendored
View file

@ -4,6 +4,57 @@ ssowat (11.0.0~alpha) unstable; urgency=low
-- Alexandre Aubin <alex.aubin@mailoo.org> Fri, 05 Feb 2021 00:02:38 +0100 -- Alexandre Aubin <alex.aubin@mailoo.org> Fri, 05 Feb 2021 00:02:38 +0100
ssowat (4.2.4) stable; urgency=low
- [fix] Misc issues regarding dash filename, mime types, ynh_userinfo.json ([#189](https://github.com/yunohost/ssowat/pull/189))
- [fix] Broken Yunohost tile/overlay on iPhone ([#186](https://github.com/yunohost/ssowat/pull/186))
- [enh] Save overlay positions accross navigation ([#187](https://github.com/yunohost/ssowat/pull/187))
- [enh] security: Improve randomness of tmp filename ([#190](https://github.com/yunohost/ssowat/pull/190))
- [i18n] Translations updated for Esperanto, Finnish, Galician, German, Italian
Thanks to all contributors <3 ! (amirale qt, Christian Wehrli, Flavio Cristoforetti, José M, ljf, Luca, Mico Hauataluoma)
-- Alexandre Aubin <alex.aubin@mailoo.org> Sun, 08 Aug 2021 21:58:14 +0200
ssowat (4.2.3) stable; urgency=low
- [i18n] Translations updated for Galician
Thanks to all contributors <3 ! (José M)
-- Alexandre Aubin <alex.aubin@mailoo.org> Mon, 24 May 2021 17:39:12 +0200
ssowat (4.2.2) stable; urgency=low
- [i18n] Translations updated for Czech, Dutch, French, German, Occitan, Russian
Thanks to all contributors <3 ! (Christian Wehrli, Mathieu Massaviol, Miloš Kroulík, panomaki, ppr, Quentí, Tymur Valiiev)
-- Alexandre Aubin <alex.aubin@mailoo.org> Sat, 08 May 2021 15:13:04 +0200
ssowat (4.2.1) testing; urgency=low
- Remove SSOwAuthRedirect ([#182](https://github.com/yunohost/ssowat/pull/182))
- Avoid a syscall for cookies ([#183](https://github.com/yunohost/ssowat/pull/183))
Thanks to all contributors <3 ! (Kay0u)
-- Alexandre Aubin <alex.aubin@mailoo.org> Sat, 17 Apr 2021 03:44:14 +0200
ssowat (4.2.0) testing; urgency=low
- Bump version number for testing release
-- Alexandre Aubin <alex.aubin@mailoo.org> Thu, 25 Mar 2021 01:00:00 +0100
ssowat (4.1.3) stable; urgency=low
- [fix] Regression where users are not redirected to the ynh portal ([#179](https://github.com/YunoHost/ssowat/pull/179))
Thanks to all contributors <3 ! (Kayou)
-- Kay0u <pierre@kayou.io> Wed, 20 Jan 2021 01:54:06 +0100
ssowat (4.1.2) stable; urgency=low ssowat (4.1.2) stable; urgency=low
- [doc] Update the sso doc with the new permissions system ([#178](https://github.com/yunohost/ssowat/pull/178)) - [doc] Update the sso doc with the new permissions system ([#178](https://github.com/yunohost/ssowat/pull/178))

View file

@ -176,7 +176,7 @@ function set_auth_cookie(user, domain)
"|"..session_key) "|"..session_key)
local cookie_str = "; Domain=."..domain.. local cookie_str = "; Domain=."..domain..
"; Path=/".. "; Path=/"..
"; Expires="..os.date("%a, %d %b %Y %X UTC", expire).. "; Expires="..ngx.cookie_time(expire)..
"; Secure".. "; Secure"..
"; HttpOnly".. "; HttpOnly"..
"; SameSite=Lax" "; SameSite=Lax"
@ -192,11 +192,10 @@ end
-- Expires the 3 session cookies -- Expires the 3 session cookies
function delete_cookie() function delete_cookie()
local expired_time = "Thu, 01 Jan 1970 00:00:00 UTC"
for _, domain in ipairs(conf["domains"]) do for _, domain in ipairs(conf["domains"]) do
local cookie_str = "; Domain=."..domain.. local cookie_str = "; Domain=."..domain..
"; Path=/".. "; Path=/"..
"; Expires="..expired_time.. "; Expires="..ngx.cookie_time(0)..
"; Secure".. "; Secure"..
"; HttpOnly".. "; HttpOnly"..
"; SameSite=Lax" "; SameSite=Lax"
@ -209,18 +208,6 @@ function delete_cookie()
end end
-- Expires the redirection cookie
function delete_redirect_cookie()
local expired_time = "Thu, 01 Jan 1970 00:00:00 UTC"
local cookie_str = "; Path="..conf["portal_path"]..
"; Expires="..expired_time..
"; Secure"..
"; HttpOnly"..
"; SameSite=Lax"
ngx.header["Set-Cookie"] = "SSOwAuthRedirect=" ..cookie_str
end
-- Validate authentification -- Validate authentification
-- --
-- Check if the session cookies are set, and rehash server + client information -- Check if the session cookies are set, and rehash server + client information
@ -250,15 +237,23 @@ function refresh_logged_in()
"|"..expireTime.. "|"..expireTime..
"|"..session_key) "|"..session_key)
is_logged_in = hash == authHash is_logged_in = hash == authHash
if not is_logged_in then if is_logged_in then
logger.info("Hash "..authHash.." rejected for "..user.."@"..ngx.var.remote_addr)
else
authUser = user authUser = user
return true
else
failReason = "Hash not matching"
end end
return is_logged_in else
failReason = "No {user}-password entry in cache"
end end
else
failReason = "No session key"
end end
else
failReason = "Cookie expired"
end end
logger.debug("SSOwat cookies rejected for "..user.."@"..ngx.var.remote_addr.." : "..failReason)
return false
end end
-- If client set the `Proxy-Authorization` header before reaching the SSO, -- If client set the `Proxy-Authorization` header before reaching the SSO,
@ -290,15 +285,6 @@ function refresh_logged_in()
return is_logged_in return is_logged_in
end end
function log_access(user, uri)
local key = "ACC|"..user.."|"..uri
local block = cache:get(key)
if block == nil then
logger.info("User "..user.."@"..ngx.var.remote_addr.." accesses "..uri)
cache:set(key, "block", 60)
end
end
-- Check whether a user is allowed to access a URL using the `permissions` directive -- Check whether a user is allowed to access a URL using the `permissions` directive
-- of the configuration file -- of the configuration file
function has_access(permission, user) function has_access(permission, user)
@ -321,7 +307,6 @@ function has_access(permission, user)
-- The user has permission to access the content if he is in the list of allowed users -- The user has permission to access the content if he is in the list of allowed users
if element_is_in_table(user, permission["users"]) then if element_is_in_table(user, permission["users"]) then
logger.debug("User "..user.." can access "..ngx.var.host..ngx.var.uri..uri_args_string()) logger.debug("User "..user.." can access "..ngx.var.host..ngx.var.uri..uri_args_string())
log_access(user, ngx.var.host..ngx.var.uri..uri_args_string())
return true return true
else else
logger.debug("User "..user.." cannot access "..ngx.var.uri) logger.debug("User "..user.." cannot access "..ngx.var.uri)
@ -484,7 +469,9 @@ function refresh_user_cache(user)
else else
-- Else, just revalidate session for another day by default -- Else, just revalidate session for another day by default
password = cache:get(user.."-password") password = cache:get(user.."-password")
cache:set(user.."-password", password, conf["session_timeout"]) -- Here we don't use set method to avoid strange logout
-- See https://github.com/YunoHost/issues/issues/1830
cache:replace(user.."-password", password, conf["session_timeout"])
end end
end end
@ -563,13 +550,24 @@ function serve(uri, cache)
png = "image/png", png = "image/png",
svg = "image/svg+xml", svg = "image/svg+xml",
ico = "image/vnd.microsoft.icon", ico = "image/vnd.microsoft.icon",
woff = "application/x-font-woff", woff = "font/woff",
woff2 = "font/woff2",
ttf = "font/ttf",
json = "application/json" json = "application/json"
} }
-- Allow .ms to specify mime type
mime = ext
if ext == "ms" then
subext = string.match(file, "^.+%.(.+)%.ms$")
if subext then
mime = subext
end
end
-- Set Content-Type -- Set Content-Type
if mime_types[ext] then if mime_types[mime] then
ngx.header["Content-Type"] = mime_types[ext] ngx.header["Content-Type"] = mime_types[mime]
else else
ngx.header["Content-Type"] = "text/plain" ngx.header["Content-Type"] = "text/plain"
end end
@ -583,9 +581,10 @@ function serve(uri, cache)
elseif ext == "ms" then elseif ext == "ms" then
local data = get_data_for(file) local data = get_data_for(file)
content = lustache:render(content, data) content = lustache:render(content, data)
elseif ext == "json" then elseif uri == "/ynh_userinfo.json" then
local data = get_data_for(file) local data = get_data_for(file)
content = json.encode(data) content = json.encode(data)
cache = "dynamic"
end end
-- Reset flash messages -- Reset flash messages
@ -625,7 +624,7 @@ function get_data_for(view)
elseif view == "portal.html" elseif view == "portal.html"
or view == "edit.html" or view == "edit.html"
or view == "password.html" or view == "password.html"
or view == "ynhpanel.json" then or view == "ynh_userinfo.json" then
-- Invalidate cache before loading these views. -- Invalidate cache before loading these views.
-- Needed if the LDAP db is changed outside ssowat (from the cli for example). -- Needed if the LDAP db is changed outside ssowat (from the cli for example).
@ -722,8 +721,7 @@ end
-- Read result of a command after given it securely the password -- Read result of a command after given it securely the password
function secure_cmd_password(cmd, password, start) function secure_cmd_password(cmd, password, start)
-- Check password validity -- Check password validity
math.randomseed( os.time() ) local tmp_file = os.tmpname()
local tmp_file = "/tmp/ssowat_"..math.random()
local w_pwd = io.popen("("..cmd..") | tee -a "..tmp_file, 'w') local w_pwd = io.popen("("..cmd..") | tee -a "..tmp_file, 'w')
w_pwd:write(password) w_pwd:write(password)
-- This second write is just to validate the password question -- This second write is just to validate the password question
@ -770,7 +768,7 @@ function edit_user()
-- and the new password against the confirmation field's content -- and the new password against the confirmation field's content
if args.newpassword == args.confirm then if args.newpassword == args.confirm then
-- Check password validity -- Check password validity
local result_msg = secure_cmd_password("python /usr/lib/moulinette/yunohost/utils/password.py", args.newpassword) local result_msg = secure_cmd_password("python3 /usr/lib/moulinette/yunohost/utils/password.py", args.newpassword)
validation_error = true validation_error = true
if result_msg == nil or result_msg == "" then if result_msg == nil or result_msg == "" then
validation_error = nil validation_error = nil
@ -1073,7 +1071,6 @@ end
-- Set cookie and go on with the response (needed to properly set cookie) -- Set cookie and go on with the response (needed to properly set cookie)
function pass() function pass()
delete_redirect_cookie()
logger.debug("Allowing to pass through "..ngx.var.uri) logger.debug("Allowing to pass through "..ngx.var.uri)
-- When we are in the SSOwat portal, we need a default `content-type` -- When we are in the SSOwat portal, we need a default `content-type`

View file

@ -20,9 +20,12 @@
html.ynh-panel-active { html.ynh-panel-active {
/* Disable any scrolling on app */ /* Disable any scrolling on app */
overflow: hidden; overflow: hidden;
} }
body {/*overflow-y: scroll;*/} body {
overflow-y: auto;
}
#ynh-overlay-switch, #ynh-overlay-switch,
#ynh-overlay-switch *, #ynh-overlay-switch *,
@ -70,14 +73,14 @@ body {/*overflow-y: scroll;*/}
/* Background */ /* Background */
#ynh-overlay { #ynh-overlay {
visibility: hidden; overflow-y: hidden;
position: fixed; position: fixed;
top:0; top:0;
left: 0; left: 0;
width: 100%; width: 100%;
height: 100%; height: 100%;
z-index: 9999999; z-index: 9999999;
display: block; display: none;
border: none; border: none;
color:#fff; color:#fff;
background: #41444F; background: #41444F;
@ -176,4 +179,4 @@ body {/*overflow-y: scroll;*/}
width: 80px; width: 80px;
height: 75px; height: 75px;
} }
} }

View file

@ -18,6 +18,23 @@ if (typeof(console) === 'undefined') {
console.log = console.error = console.info = console.debug = console.warn = console.trace = console.dir = console.dirxml = console.group = console.groupEnd = console.time = console.timeEnd = console.assert = console.profile = function() {}; console.log = console.error = console.info = console.debug = console.warn = console.trace = console.dir = console.dirxml = console.group = console.groupEnd = console.time = console.timeEnd = console.assert = console.profile = function() {};
} }
/* Cookies utilities */
function setCookie(cName, cValue, expDays) {
let date = new Date();
date.setTime(date.getTime() + (expDays * 24 * 60 * 60 * 1000));
const expires = "expires=" + date.toUTCString();
document.cookie = cName + "=" + cValue + "; " + expires + "; path=/";
}
function getCookie(cName) {
const name = cName + "=";
const cDecoded = decodeURIComponent(document.cookie); //to be careful
const cArr = cDecoded .split('; ');
let res;
cArr.forEach(val => {
if (val.indexOf(name) === 0) res = val.substring(name.length);
})
return res;
}
/* Array utilities /* Array utilities
https://github.com/Darklg/JavaScriptUtilities/blob/master/assets/js/vanilla-js/libs/vanilla-arrays.js https://github.com/Darklg/JavaScriptUtilities/blob/master/assets/js/vanilla-js/libs/vanilla-arrays.js
@ -179,6 +196,9 @@ function make_element_draggable(id) {
dragged = true; dragged = true;
selected.style.left = (x_pos - x_elem) + 'px'; selected.style.left = (x_pos - x_elem) + 'px';
selected.style.top = (y_pos - y_elem) + 'px'; selected.style.top = (y_pos - y_elem) + 'px';
// Store positions in cookies
setCookie('ynh_overlay_top', selected.style.top, 30);
setCookie('ynh_overlay_left', selected.style.left, 30);
} }
}; };
@ -265,7 +285,8 @@ function init_portal_button_and_overlay()
var portalOverlay = document.createElement('iframe'); var portalOverlay = document.createElement('iframe');
portalOverlay.src = "/yunohost/sso/portal.html"; portalOverlay.src = "/yunohost/sso/portal.html";
portalOverlay.setAttribute("id","ynh-overlay"); portalOverlay.setAttribute("id","ynh-overlay");
portalOverlay.setAttribute("style","visibility: hidden;"); // make sure the overlay is invisible already when loading it portalOverlay.setAttribute("style","display: none;"); // make sure the overlay is invisible already when loading it
// portalOverlay.setAttribute("class","ynh-fadeOut"); // set overlay as masked when loading it
document.body.insertBefore(portalOverlay, null); document.body.insertBefore(portalOverlay, null);
// Inject portal button // Inject portal button
@ -273,6 +294,11 @@ function init_portal_button_and_overlay()
portalButton.setAttribute('id', 'ynh-overlay-switch'); portalButton.setAttribute('id', 'ynh-overlay-switch');
portalButton.setAttribute('href', '/yunohost/sso/'); portalButton.setAttribute('href', '/yunohost/sso/');
portalButton.setAttribute('class', 'disableAjax'); portalButton.setAttribute('class', 'disableAjax');
// Checks if cookies exist and apply positioning
if (getCookie('ynh_overlay_top') != null && getCookie('ynh_overlay_left') != null) {
portalButton.style.top = getCookie('ynh_overlay_top');
portalButton.style.left = getCookie('ynh_overlay_left');
}
document.body.insertBefore(portalButton, null); document.body.insertBefore(portalButton, null);
// Make portal button draggable, for user convenience // Make portal button draggable, for user convenience
make_element_draggable('ynh-overlay-switch'); make_element_draggable('ynh-overlay-switch');
@ -286,10 +312,12 @@ function init_portal_button_and_overlay()
Element.toggleClass(portalOverlay, 'ynh-active'); Element.toggleClass(portalOverlay, 'ynh-active');
if (Element.hasClass(portalOverlay, 'ynh-active')) { if (Element.hasClass(portalOverlay, 'ynh-active')) {
portalOverlay.setAttribute("style","display: block;");
meta_viewport.setAttribute('content', meta_viewport_content); meta_viewport.setAttribute('content', meta_viewport_content);
Element.addClass(portalOverlay, 'ynh-fadeIn'); Element.addClass(portalOverlay, 'ynh-fadeIn');
Element.removeClass(portalOverlay, 'ynh-fadeOut'); Element.removeClass(portalOverlay, 'ynh-fadeOut');
} else { } else {
portalOverlay.setAttribute("style","display: none;");
meta_viewport.setAttribute('content', "width=device-width"); meta_viewport.setAttribute('content', "width=device-width");
Element.removeClass(portalOverlay, 'ynh-fadeIn'); Element.removeClass(portalOverlay, 'ynh-fadeIn');
Element.addClass(portalOverlay, 'ynh-fadeOut'); Element.addClass(portalOverlay, 'ynh-fadeOut');
@ -341,6 +369,7 @@ function init_portal()
}); });
} }
function tweak_portal_when_in_iframe() function tweak_portal_when_in_iframe()
{ {
// Set class to body to show we're in overlay // Set class to body to show we're in overlay
@ -369,4 +398,4 @@ function tweak_portal_when_in_iframe()
window.parent.location.href = logoutButton.getAttribute("href"); window.parent.location.href = logoutButton.getAttribute("href");
}); });
} }
} }

1
portal/locales/ckb.json Normal file
View file

@ -0,0 +1 @@
{}

View file

@ -8,5 +8,42 @@
"password": "Heslo", "password": "Heslo",
"username": "Uživatelské jméno", "username": "Uživatelské jméno",
"information": "Vaše údaje", "information": "Vaše údaje",
"portal": "YunoHost Portál" "portal": "YunoHost Portál",
"footerlink_administration": "Administrace",
"footerlink_support": "Podpora",
"footerlink_documentation": "Dokumentace",
"footerlink_edit": "Upravit svůj profil",
"redirection_error_unmanaged_domain": "Chyba přesměrování: Doména není spravována",
"redirection_error_invalid_url": "Chyba přesměrování: Neplatné URL",
"please_login_from_portal": "Prosím přihlašte se z portálu",
"please_login": "Pro přístup k obsahu se prosím přihlašte",
"logged_out": "Jste odhlášen/a",
"wrong_username_password": "Chybné uživatelské jméno nebo heslo",
"missing_required_fields": "Vyplňte povinné údaje",
"user_saving_fail": "Nelze uložit uživatelské údaje",
"information_updated": "Údaje upraveny",
"mail_already_used": "Tato e-mailová adresa se už používá",
"invalid_mailforward": "Neplatná e-mailová adresa pro přeposílání",
"invalid_domain": "Neplatná doména v",
"invalid_mail": "Neplatná e-mailová adresa",
"wrong_current_password": "Současné heslo je chybné",
"good_practices_about_user_password": "Vyberte si heslo aspoň 8 znaků dlouhé - dobrou praxí je ale používat delší frázi a používat různé druhy znaků (velká a malá písmena, číslice a speciální znaky).",
"password_too_simple_4": "Heslo musí být aspoň 12 znaků dlouhé a obsahovat čísla, velká a malá písmena a speciální znaky",
"password_too_simple_3": "Heslo musí být aspoň 8 znaků dlouhé a obsahovat čísla, velká a malá písmena a speciální znaky",
"password_too_simple_2": "Heslo musí být aspoň 8 znaků dlouhé a obsahovat číslici, velká a malá písmena",
"password_too_simple_1": "Heslo musí být aspoň 8 znaků dlouhé",
"password_listed": "Toto heslo je jedním z nejpoužívanějších na světě. Zvolte si prosím něco jediněčnějšího.",
"password_not_match": "Hesla se neshodují",
"password_changed_error": "Heslo nebylo změněno",
"password_changed": "Heslo změněno",
"logout": "Odhlásit se",
"login": "Přihlásit se",
"confirm": "Potvrdit",
"new_password": "Nové heslo",
"current_password": "Současné heslo",
"edit": "Upravit",
"change_password": "Změnit heslo",
"cancel": "Storno",
"ok": "OK",
"add_forward": "Přidat e-mailovou adresu pro přeposílání"
} }

View file

@ -1,6 +1,6 @@
{ {
"add_forward": "E-Mail Weiterleitung hinzufügen", "add_forward": "E-Mail-Weiterleitung hinzufügen",
"add_mail": "E-Mail Alias hinzufügen", "add_mail": "E-Mail-Alias hinzufügen",
"cancel": "Abbrechen", "cancel": "Abbrechen",
"change_password": "Passwort ändern", "change_password": "Passwort ändern",
"confirm": "Bestätigen", "confirm": "Bestätigen",
@ -13,15 +13,15 @@
"fullname": "Vollständiger Name", "fullname": "Vollständiger Name",
"information": "Ihre Informationen", "information": "Ihre Informationen",
"information_updated": "Informationen aktualisiert", "information_updated": "Informationen aktualisiert",
"invalid_domain": "Ungültige Domain angegeben", "invalid_domain": "Ungültige Domäne angegeben",
"invalid_mail": "Ungültige E-Mail Adresse", "invalid_mail": "Ungültige E-Mail-Adresse",
"invalid_mailforward": "Ungültige E-Mail Weiterleitung", "invalid_mailforward": "Ungültige E-Mail-Weiterleitung",
"logged_out": "Abgemeldet", "logged_out": "Abgemeldet",
"login": "Anmelden", "login": "Anmelden",
"logout": "Abmelden", "logout": "Abmelden",
"mail_addresses": "E-Mail Adressen", "mail_addresses": "E-Mail-Adressen",
"mail_already_used": "Diese E-Mail Adresse wird bereits verwendet", "mail_already_used": "Diese E-Mail-Adresse wird bereits verwendet",
"mail_forward": "E-Mail Weiterleitung", "mail_forward": "E-Mail-Weiterleitung",
"missing_required_fields": "Die notwendigen Felder müssen ausgefüllt werden", "missing_required_fields": "Die notwendigen Felder müssen ausgefüllt werden",
"new_forward": "neueweiterleitung@anderedomain.org", "new_forward": "neueweiterleitung@anderedomain.org",
"new_mail": "neuemail@meinedomain.org", "new_mail": "neuemail@meinedomain.org",
@ -33,17 +33,17 @@
"password_not_match": "Die Passwörter stimmen nicht überein", "password_not_match": "Die Passwörter stimmen nicht überein",
"please_login": "Bitte melden Sie sich an, um auf diese Inhalte zuzugreifen", "please_login": "Bitte melden Sie sich an, um auf diese Inhalte zuzugreifen",
"please_login_from_portal": "Bitte melden Sie sich über das Portal an", "please_login_from_portal": "Bitte melden Sie sich über das Portal an",
"portal": "YunoHost Portal", "portal": "YunoHost-Portal",
"user_saving_fail": "Neue Benutzerinformationen konnten nicht gespeichert werden", "user_saving_fail": "Neue Benutzerinformationen konnten nicht gespeichert werden",
"username": "Benutzername", "username": "Benutzername",
"wrong_current_password": "Aktuelles Passwort ist falsch", "wrong_current_password": "Aktuelles Passwort ist falsch",
"wrong_username_password": "Falscher Benutzername oder Passwort", "wrong_username_password": "Falscher Benutzername oder Passwort",
"redirection_error_invalid_url": "Fehler bei Weiterleitung: Ungültige URL", "redirection_error_invalid_url": "Fehler bei Weiterleitung: Ungültige URL",
"redirection_error_unmanaged_domain": "Fehler bei Weiterleitung: Nicht-verwaltete Domain", "redirection_error_unmanaged_domain": "Fehler bei Weiterleitung: Nicht-verwaltete Domain",
"good_practices_about_user_password": "Wählen Sie ein Benutzerpasswort mit mindestens 8 Zeichen. Das Passwort sollte mindestens 8 Zeichen lang sein - es ist jedoch empfehlenswert, ein längeres Passwort (z.B. eine Passphrase) und/oder verschiedene Arten von Zeichen (Groß- und Kleinschreibung, Ziffern und Sonderzeichen) zu verwenden.", "good_practices_about_user_password": "Wähle ein Nutzerpasswort mit mindestens 8 Zeichen - es ist jedoch empfehlenswert, ein längeres Passwort (z.B. eine Passphrase) und/oder verschiedene Arten von Zeichen (Groß- und Kleinschreibung, Ziffern und Sonderzeichen) zu verwenden.",
"password_too_simple_3": "Das Passwort muss mindestens 8 Zeichen mit große Buchstaben, kleine Buchstaben, Zahlen und Sonderzeichen enthalten", "password_too_simple_3": "Das Passwort muss mindestens 8 Zeichen lang sein und Grossbuchstaben, Kleinbuchstaben, Zahlen und Sonderzeichen enthalten",
"password_too_simple_2": "Das Passwort muss mindestens 8 Zeichen mit große Buchstaben, kleine Buchstaben und Zahlen enthalten", "password_too_simple_2": "Das Passwort muss mindestens 8 Zeichen lang sein und Grossbuchstaben, Kleinbuchstaben und Zahlen enthalten",
"password_listed": "Dieses Passwort zählt zu den meistgenutzten Passwort der Welt . Bitte wählen Sie ein anderes einzigartigeres Passwort.", "password_listed": "Dieses Passwort zählt zu den meistgenutzten Passwörtern der Welt. Bitte wähle ein anderes, einzigartigeres Passwort.",
"password_too_simple_4": "Das Passwort muss mindestens 12 Zeichen mit große Buchstaben, kleine Buchstaben, Zahlen und Sonderzeichen enthalten", "password_too_simple_4": "Das Passwort muss mindestens 12 Zeichen lang sein und Grossbuchstaben, Kleinbuchstaben, Zahlen und Sonderzeichen enthalten",
"password_too_simple_1": "Das Passwort muss mindestens 8 Zeichen lang sein" "password_too_simple_1": "Das Passwort muss mindestens 8 Zeichen lang sein"
} }

View file

@ -13,7 +13,7 @@
"portal": "Yunohost portalo", "portal": "Yunohost portalo",
"fullname": "Plena nomo", "fullname": "Plena nomo",
"new_mail": "nova-adreso@mia-domajno.org", "new_mail": "nova-adreso@mia-domajno.org",
"confirm": "Konfirmi", "confirm": "Konfirmu",
"password_changed": "Pasvorto ŝanĝita", "password_changed": "Pasvorto ŝanĝita",
"password_changed_error": "Ne povis ŝanĝi pasvorton", "password_changed_error": "Ne povis ŝanĝi pasvorton",
"password_not_match": "La pasvortoj ne kongruas", "password_not_match": "La pasvortoj ne kongruas",
@ -35,12 +35,12 @@
"invalid_domain": "Nevalida domajno en", "invalid_domain": "Nevalida domajno en",
"invalid_mail": "Nevalida retpoŝta adreso", "invalid_mail": "Nevalida retpoŝta adreso",
"wrong_current_password": "Aktuala pasvorto estas malĝusta", "wrong_current_password": "Aktuala pasvorto estas malĝusta",
"good_practices_about_user_password": "Elektu uzanton pasvorton de almenaŭ 8 signoj - kvankam estas bone praktiki uzi pli longajn (t.e. pasfrazon) kaj / aŭ uzi diversajn specojn de signoj (majuskloj, minuskloj, ciferoj kaj specialaj signoj).", "good_practices_about_user_password": "Elektu uzantan pasvorton de almenaŭ 8 signoj - kvankam ĝi estas bona praktiko uzi pli longajn (I.E. Pasfraso) kaj / aŭ uzas diversajn specojn de karakteroj (majusklaj, minusklaj, ciferoj kaj specialaj signoj).",
"password_too_simple_4": "Pasvorto bezonas almenaŭ 12 signojn kaj enhavas ciferojn, majusklojn, minusklojn kaj specialajn signojn", "password_too_simple_4": "La pasvorto devas havi almenaŭ 12 signojn kaj enhavas ciferojn, suprajn, pli malaltajn kaj specialajn signojn",
"password_too_simple_3": "Pasvorto bezonas almenaŭ 8 signojn kaj enhavas ciferojn, majusklojn, minusklojn kaj specialajn signojn", "password_too_simple_3": "La pasvorto devas havi almenaŭ 8 signojn kaj enhavas ciferojn, suprajn, pli malaltajn kaj specialajn signojn",
"password_too_simple_2": "Pasvorto bezonas almenaŭ 8 signojn kaj enhavas ciferojn, majusklojn kaj minusklojn", "password_too_simple_2": "La pasvorto devas havi almenaŭ 8 signojn kaj enhavas ciferojn, suprajn kaj pli malaltajn signojn",
"password_too_simple_1": "Pasvorto devas esti almenaŭ 8 signojn longa", "password_too_simple_1": "Pasvorto devas esti almenaŭ 8 signojn longa",
"password_listed": "Ĉi tiu pasvorto estas inter la plej uzataj pasvortoj en la mondo. Bonvolu elekti ion iom pli unikan.", "password_listed": "Ĉi tiu pasvorto estas inter la plej uzataj pasvortoj en la mondo. Bonvolu elekti ion pli unikan.",
"ok": "bone", "ok": "bone",
"add_forward": "Aldonu poŝton antaŭen", "add_forward": "Aldonu poŝton antaŭen",
"add_mail": "Aldonu poŝton alias", "add_mail": "Aldonu poŝton alias",

49
portal/locales/fa.json Normal file
View file

@ -0,0 +1,49 @@
{
"cancel": "لغو",
"logged_out": "خارج شده",
"password": "کلمه عبور",
"ok": "خوب",
"footerlink_administration": "مدیریت",
"footerlink_support": "پشتیبانی",
"footerlink_documentation": "مستندات",
"footerlink_edit": "ویرایش پروفایل من",
"redirection_error_unmanaged_domain": "خطای تغییر مسیر: دامنه مدیریت نشده",
"redirection_error_invalid_url": "خطای تغییر مسیر: نشانی اینترنتی نامعتبر است",
"please_login_from_portal": "لطفاً از درگاه پورتال وارد شوید",
"please_login": "لطفاً برای دسترسی به این محتوا وارد شوید",
"wrong_username_password": "نام کاربری یا رمز عبور اشتباه است",
"missing_required_fields": "فیلدهای مورد نیاز را پر کنید",
"user_saving_fail": "اطلاعات کاربر جدید ذخیره نشد",
"information_updated": "اطلاعات به روز شد",
"mail_already_used": "آدرس پست الکترونیکی قبلاً استفاده می شود",
"invalid_mailforward": "آدرس ارسال ایمیل نامعتبر است",
"invalid_domain": "دامنه نامعتبر در",
"invalid_mail": "آدرس ایمیل نامعتبر است",
"wrong_current_password": "رمز فعلی اشتباه است",
"good_practices_about_user_password": "گذرواژه کاربر را حداقل با 8 کاراکتر انتخاب کنید - هرچند استفاده از کلمات طولانی تر تمرین خوبی است (مانند عبارت عبور) و/یا استفاده از انواع مختلف کاراکترها (بزرگ ، کوچک ، رقم و کاراکتر های خاص).",
"password_too_simple_4": "گذرواژه باید دارای حداقل 12 کاراکتر طول و شامل اعداد و حروف کوچک و بزرگ و کاراکترهای خاص باشد",
"password_too_simple_3": "گذرواژه باید دارای حداقل 8 کاراکتر طول و شامل اعداد و حروف کوچک و بزرگ و کاراکترهای خاص باشد",
"password_too_simple_2": "گذرواژه باید دارای حداقل 8 کاراکتر طول و شامل اعداد و حروف کوچک و بزرگ باشد",
"password_too_simple_1": "رمز عبور باید حداقل 8 کاراکتر باشد",
"password_listed": "این رمز عبور جزو پر استفاده ترین رمزهای عبور جهان بشمار میرود. لطفاً گذرواژه منحصر به فردتری انتخاب کنید.",
"password_not_match": "گذرواژه ها مطابقت ندارند",
"password_changed_error": "رمز عبور تغییر نکرد",
"password_changed": "رمز عبور تغییر کرد",
"logout": "خروج",
"login": "وارد شدن",
"confirm": "تایید",
"new_password": "رمز عبور جدید",
"current_password": "رمز عبور فعلی",
"edit": "ویرایش",
"change_password": "تغییر رمز عبور",
"add_forward": "آدرس هدایت ایمیل را اضافه کنید",
"add_mail": "یک نام مستعار ایمیل اضافه کنید",
"new_forward": "newforward@myforeigndomain.org",
"new_mail": "newmail@mydomain.org",
"mail_forward": "آدرس ارسال به جلو ایمیل",
"mail_addresses": "آدرس ایمیل",
"fullname": "نام و نام خانوادگی",
"username": "نام کاربری",
"information": "اطلاعات شما",
"portal": "پورتال YunoHost"
}

3
portal/locales/fi.json Normal file
View file

@ -0,0 +1,3 @@
{
"cancel": "Peruuta"
}

49
portal/locales/gl.json Normal file
View file

@ -0,0 +1,49 @@
{
"footerlink_administration": "Administración",
"footerlink_support": "Axuda",
"footerlink_documentation": "Documentación",
"footerlink_edit": "Editar o meu perfil",
"redirection_error_unmanaged_domain": "Erro na redirección: Dominio non xestionado",
"redirection_error_invalid_url": "Erro na redirección: URL non válido",
"please_login_from_portal": "Conéctate desde o portal",
"please_login": "Conéctate para acceder a este contido",
"logged_out": "Sesión pechada",
"wrong_username_password": "Nome de usuaria ou contrasinal incorrectos",
"missing_required_fields": "Completa os campos requeridos",
"user_saving_fail": "Non se gardou a info da nova usuaria",
"information_updated": "Info actualizada",
"mail_already_used": "Xa está en uso o enderezo de email",
"invalid_mailforward": "Enderezo de reenvío de email non válido",
"invalid_domain": "Dominio non válido",
"invalid_mail": "Enderezo de email non válido",
"wrong_current_password": "O contrasinal actual é incorrecto",
"good_practices_about_user_password": "Elixe un contrasinal con 8 caracteres como mínimo - é recomendable que sexa longo (ex. unha frase) e utilizar varios tipos de caracteres (maiúsculas, minúsculas, díxitos e caracteres especiais).",
"password_too_simple_4": "O contrasinal debe ter 12 caracteres como mínimo e ter díxitos, maiúsculas e minúsculas e caracteres especiais",
"password_too_simple_3": "O contrasinal debe ter 8 caracteres como mínimo e ter díxitos, maiúsculas e minúsculas e caracteres especiais",
"password_too_simple_2": "O contrasinal debe ter 8 caracteres como mínimo e ter díxitos e caracteres en maiúsculas e minúsculas",
"password_too_simple_1": "O contrasinal ten que ter 8 caracteres como mínimo",
"password_listed": "Este contrasinal é un dos máis utilizados no mundo. Mellor elixe un que sexa máis orixinal.",
"password_not_match": "Os contrasinais non concordan",
"password_changed_error": "Non se cambiou o contrasinal",
"password_changed": "Contrasinal cambiado",
"logout": "Pechar sesión",
"login": "Conectar",
"confirm": "Confirmar",
"new_password": "Novo contrasinal",
"current_password": "Contrasinal actual",
"edit": "Editar",
"change_password": "Cambiar contrasinal",
"cancel": "Cancelar",
"ok": "Ok",
"add_forward": "Engadir un enderezo de reenvío de email",
"add_mail": "Engadir un alias de email",
"new_forward": "novoreenvio@omeudominioexterno.org",
"new_mail": "novomail@omeudominio.org",
"mail_forward": "Enderezo de reenvío de email",
"mail_addresses": "Enderezos de email",
"fullname": "Nome completo",
"password": "Contrasinal",
"username": "Nome de usuaria",
"information": "A túa info",
"portal": "Portal YunoHost"
}

View file

@ -17,8 +17,8 @@
"invalid_mail": "Indirizzo email non valido", "invalid_mail": "Indirizzo email non valido",
"invalid_mailforward": "Indirizzo di inoltro e-mail non valido", "invalid_mailforward": "Indirizzo di inoltro e-mail non valido",
"logged_out": "Disconnesso", "logged_out": "Disconnesso",
"login": "Accesso", "login": "Accedi",
"logout": "Disconnettersi", "logout": "Esci",
"mail_addresses": "Indirizzi email", "mail_addresses": "Indirizzi email",
"mail_already_used": "Indirizzo email già in uso", "mail_already_used": "Indirizzo email già in uso",
"mail_forward": "Indirizzo di inoltro e-mail", "mail_forward": "Indirizzo di inoltro e-mail",

View file

@ -1,7 +1,7 @@
{ {
"add_forward": "Voeg een e-mail doorstuuradres toe", "add_forward": "Voeg een e-mail doorstuuradres toe",
"add_mail": "Voeg een e-mailalias toe", "add_mail": "Voeg een e-mailalias toe",
"cancel": "Annuleren", "cancel": "Annuleer",
"change_password": "Verander wachtwoord", "change_password": "Verander wachtwoord",
"confirm": "Bevestigen", "confirm": "Bevestigen",
"current_password": "Huidig wachtwoord", "current_password": "Huidig wachtwoord",

View file

@ -45,5 +45,5 @@
"password_too_simple_2": "Lo senhal deu conténer almens 8 caractèrs e nombres, majusculas e minusculas", "password_too_simple_2": "Lo senhal deu conténer almens 8 caractèrs e nombres, majusculas e minusculas",
"password_too_simple_3": "Lo senhal deu conténer almens 8 caractèrs e nombres, majusculas e minusculas e caractèrs especials", "password_too_simple_3": "Lo senhal deu conténer almens 8 caractèrs e nombres, majusculas e minusculas e caractèrs especials",
"password_too_simple_4": "Lo senhal deu conténer almens 12 caractèrs, de nombre, majusculas, minusculas e caractèrs especials", "password_too_simple_4": "Lo senhal deu conténer almens 12 caractèrs, de nombre, majusculas, minusculas e caractèrs especials",
"good_practices_about_user_password": "Causissètz un senhal dalmens 8 caractèrs, es de bon far dutilizar un senhal mai long (es a dire una frasa de senhal) e/o utilizar mantuns tipes de caractèrs (majusculas, minusculas, nombres e caractèrs especials)." "good_practices_about_user_password": "Causissètz un senhal dalmens 8 caractèrs, es de bon far dutilizar un senhal mai long (es a dire una frasa de senhal) e/o utilizar mantun tipe de caractèrs (majusculas, minusculas, nombres e caractèrs especials)."
} }

View file

@ -6,7 +6,7 @@
"fullname": "Полное имя", "fullname": "Полное имя",
"mail_addresses": "Адрес электронной почты", "mail_addresses": "Адрес электронной почты",
"ok": "ОК", "ok": "ОК",
"cancel": "Отменить", "cancel": "Отмена",
"change_password": "Сменить пароль", "change_password": "Сменить пароль",
"edit": "Редактировать", "edit": "Редактировать",
"current_password": "Действующий пароль", "current_password": "Действующий пароль",

49
portal/locales/uk.json Normal file
View file

@ -0,0 +1,49 @@
{
"cancel": "Скасувати",
"logged_out": "Ви вийшли з системи",
"footerlink_administration": "Адміністрація",
"footerlink_support": "Підтримка",
"footerlink_documentation": "Документація",
"footerlink_edit": "Редагувати мій профіль",
"redirection_error_unmanaged_domain": "Помилка перенаправлення: Некерований домен",
"redirection_error_invalid_url": "Помилка перенаправлення: Недійсна URL-адреса",
"please_login_from_portal": "Увійдіть у систему з порталу",
"please_login": "Увійдіть, щоб отримати доступ до цього вмісту",
"wrong_username_password": "Неправильне ім'я користувача або пароль",
"missing_required_fields": "Заповніть необхідні поля",
"user_saving_fail": "Не вдалося зберегти нові відомості користувача",
"information_updated": "Відомості оновлено",
"mail_already_used": "Адреса е-пошти вже використовується",
"invalid_mailforward": "Недійсна адреса переадресації е-пошти",
"invalid_domain": "Недійсний домен у",
"invalid_mail": "Недійсна адреса е-пошти",
"wrong_current_password": "Поточний пароль неправильний",
"good_practices_about_user_password": "Виберіть пароль користувача щонайменше 8 символів - хоча це хороша практика використовувати довші (тобто фрази-гасла) та/або використовувати різні символи (великі, малі, числа та спеціальні символи).",
"password_too_simple_4": "Пароль повинен бути щонайменше 12 символів довжиною і містити числа, верхній, нижній регістри та спеціальні символи",
"password_too_simple_3": "Пароль повинен бути щонайменше 8 символів довжиною і містити числа, верхній, нижній регістри та спеціальні символи",
"password_too_simple_2": "Пароль повинен бути щонайменше 8 символів довжиною і містити числа, верхній та нижній регістри",
"password_too_simple_1": "Пароль повинен бути щонайменше 8 символів",
"password_listed": "Цей пароль є одним з найбільш використовуваних паролів у світі. Будь ласка, виберіть щось трохи більш неповторюване.",
"password_not_match": "Паролі не збігаються",
"password_changed_error": "Не вдалося змінити пароль",
"password_changed": "Пароль змінено",
"logout": "Вийти",
"login": "Увійти",
"confirm": "Підтвердити",
"new_password": "Новий пароль",
"current_password": "Поточний пароль",
"edit": "Редагувати",
"change_password": "Змінити пароль",
"add_forward": "Додайте адресу переадресації е-пошти",
"add_mail": "Додайте аліас е-пошти",
"new_forward": "novapereadresaciya@myforeigndomain.org",
"new_mail": "novaeposhta@mydomain.org",
"mail_forward": "Адреса переадресації е-пошти",
"mail_addresses": "Адреси е-пошти",
"fullname": "Повне ім'я",
"username": "Ім'я користувача",
"information": "Ваші відомості",
"portal": "Портал Yunohost",
"password": "Пароль",
"ok": "Гаразд"
}