diff --git a/README.md b/README.md index ae01ce6743..92de52a2b5 100644 --- a/README.md +++ b/README.md @@ -28,9 +28,10 @@ addon | version | maintainers | summary [auth_jwt_demo](auth_jwt_demo/) | 16.0.1.1.1 | [![sbidoul](https://github.com/sbidoul.png?size=30px)](https://github.com/sbidoul) | Test/demo module for auth_jwt. [auth_jwt_server_env](auth_jwt_server_env/) | 16.0.1.0.0 | | This addon adds auth.jwt.validator fields to server env [auth_ldaps](auth_ldaps/) | 16.0.1.0.0 | | Allows to use LDAP over SSL authentication +[auth_oauth_ropc](auth_oauth_ropc/) | 16.0.1.0.0 | | Allow to login with OAuth Resource Owner Password Credentials Grant [auth_oidc](auth_oidc/) | 16.0.1.0.2 | [![sbidoul](https://github.com/sbidoul.png?size=30px)](https://github.com/sbidoul) | Allow users to login through OpenID Connect Provider [auth_oidc_environment](auth_oidc_environment/) | 16.0.1.0.0 | | This module allows to use server env for OIDC configuration -[auth_saml](auth_saml/) | 16.0.1.0.2 | [![vincent-hatakeyama](https://github.com/vincent-hatakeyama.png?size=30px)](https://github.com/vincent-hatakeyama) | SAML2 Authentication +[auth_saml](auth_saml/) | 16.0.1.0.4 | [![vincent-hatakeyama](https://github.com/vincent-hatakeyama.png?size=30px)](https://github.com/vincent-hatakeyama) | SAML2 Authentication [auth_session_timeout](auth_session_timeout/) | 16.0.1.0.0 | | This module disable all inactive sessions since a given delay [auth_signup_verify_email](auth_signup_verify_email/) | 16.0.1.0.0 | | Force uninvited users to use a good email for signup [auth_user_case_insensitive](auth_user_case_insensitive/) | 16.0.1.0.0 | | Makes the user login field case insensitive @@ -40,6 +41,7 @@ addon | version | maintainers | summary [users_ldap_groups](users_ldap_groups/) | 16.0.1.0.0 | | Adds user accounts to groups based on rules defined by the administrator. [users_ldap_mail](users_ldap_mail/) | 16.0.1.0.0 | [![joao-p-marques](https://github.com/joao-p-marques.png?size=30px)](https://github.com/joao-p-marques) | LDAP mapping for user name and e-mail [users_ldap_populate](users_ldap_populate/) | 16.0.1.0.0 | [![joao-p-marques](https://github.com/joao-p-marques.png?size=30px)](https://github.com/joao-p-marques) | LDAP Populate +[vault](vault/) | 16.0.1.0.0 | | Password vault integration in Odoo [//]: # (end addons) diff --git a/auth_admin_passkey/i18n/it.po b/auth_admin_passkey/i18n/it.po index 23262c5932..12d8de629a 100644 --- a/auth_admin_passkey/i18n/it.po +++ b/auth_admin_passkey/i18n/it.po @@ -9,15 +9,15 @@ msgstr "" "Project-Id-Version: Odoo Server 10.0\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2017-08-01 02:43+0000\n" -"PO-Revision-Date: 2022-02-21 12:17+0000\n" -"Last-Translator: Simone Rubino \n" +"PO-Revision-Date: 2024-01-03 14:33+0000\n" +"Last-Translator: mymage \n" "Language-Team: Italian (https://www.transifex.com/oca/teams/23907/it/)\n" "Language: it\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: \n" "Plural-Forms: nplurals=2; plural=n != 1;\n" -"X-Generator: Weblate 4.3.2\n" +"X-Generator: Weblate 4.17\n" #. module: auth_admin_passkey #. odoo-python @@ -40,11 +40,20 @@ msgid "" "- Login date : %(login_date)s\n" "\n" msgstr "" +"L'utente amministratore di sistemaha usato la sua passkey per accedere con " +"%(login)s.\n" +"\n" +"\n" +"\n" +"Informazioni tecniche di seguito: \n" +"\n" +"- Data accesso : %(login_date)s\n" +"\n" #. module: auth_admin_passkey #: model:ir.model,name:auth_admin_passkey.model_res_users msgid "User" -msgstr "" +msgstr "Utente" #, python-format #~ msgid "
User with login '%s' has the same password as you.
" diff --git a/auth_api_key_server_env/i18n/it.po b/auth_api_key_server_env/i18n/it.po new file mode 100644 index 0000000000..35b514e0af --- /dev/null +++ b/auth_api_key_server_env/i18n/it.po @@ -0,0 +1,37 @@ +# Translation of Odoo Server. +# This file contains the translation of the following modules: +# * auth_api_key_server_env +# +msgid "" +msgstr "" +"Project-Id-Version: Odoo Server 16.0\n" +"Report-Msgid-Bugs-To: \n" +"PO-Revision-Date: 2024-01-03 14:33+0000\n" +"Last-Translator: mymage \n" +"Language-Team: none\n" +"Language: it\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: \n" +"Plural-Forms: nplurals=2; plural=n != 1;\n" +"X-Generator: Weblate 4.17\n" + +#. module: auth_api_key_server_env +#: model:ir.model,name:auth_api_key_server_env.model_auth_api_key +msgid "API Key" +msgstr "Chiave API" + +#. module: auth_api_key_server_env +#: model:ir.model.fields,field_description:auth_api_key_server_env.field_auth_api_key__server_env_defaults +msgid "Server Env Defaults" +msgstr "Server ambiente predefinito" + +#. module: auth_api_key_server_env +#: model:ir.model.fields,field_description:auth_api_key_server_env.field_auth_api_key__tech_name +msgid "Tech Name" +msgstr "Nome tecnico" + +#. module: auth_api_key_server_env +#: model:ir.model.fields,help:auth_api_key_server_env.field_auth_api_key__tech_name +msgid "Unique name for technical purposes. Eg: server env keys." +msgstr "Nome univoco per motivi tecnici. Es: chiavi server ambiente." diff --git a/auth_jwt/i18n/it.po b/auth_jwt/i18n/it.po index 3b337b274b..9d3c3da001 100644 --- a/auth_jwt/i18n/it.po +++ b/auth_jwt/i18n/it.po @@ -6,13 +6,15 @@ msgid "" msgstr "" "Project-Id-Version: Odoo Server 16.0\n" "Report-Msgid-Bugs-To: \n" -"Last-Translator: Automatically generated\n" +"PO-Revision-Date: 2024-01-29 11:35+0000\n" +"Last-Translator: Francesco Foresti \n" "Language-Team: none\n" "Language: it\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: \n" "Plural-Forms: nplurals=2; plural=n != 1;\n" +"X-Generator: Weblate 4.17\n" #. module: auth_jwt #. odoo-python @@ -22,21 +24,23 @@ msgid "" "A cookie name must be provided on JWT validator %s because it has cookie " "mode enabled." msgstr "" +"È necessario fornire un nome del cookie sul validatore JWT %s perché ha la " +"modalità cookie abilitata." #. module: auth_jwt #: model_terms:ir.ui.view,arch_db:auth_jwt.view_auth_jwt_validator_form msgid "Algorithm" -msgstr "" +msgstr "Algoritmo" #. module: auth_jwt #: model:ir.model.fields,field_description:auth_jwt.field_auth_jwt_validator__audience msgid "Audience" -msgstr "" +msgstr "Audience" #. module: auth_jwt #: model:ir.model.fields,help:auth_jwt.field_auth_jwt_validator__audience msgid "Comma separated list of audiences, to validate aud." -msgstr "" +msgstr "Elenco di audience separati da virgole, per validare aud." #. module: auth_jwt #: model:ir.model.fields,help:auth_jwt.field_auth_jwt_validator__cookie_enabled @@ -45,303 +49,306 @@ msgid "" "Authorization header and the cookie are present in the request, the cookie " "is ignored." msgstr "" +"Converti il token JWT in un cookie HttpOnly Secure. Quando nella richiesta " +"sono presenti sia un Authorization header che il cookie, il cookie viene " +"ignorato." #. module: auth_jwt #: model_terms:ir.ui.view,arch_db:auth_jwt.view_auth_jwt_validator_form msgid "Cookie" -msgstr "" +msgstr "Cookie" #. module: auth_jwt #: model:ir.model.fields,field_description:auth_jwt.field_auth_jwt_validator__cookie_enabled msgid "Cookie Enabled" -msgstr "" +msgstr "Cookie abilitato" #. module: auth_jwt #: model:ir.model.fields,field_description:auth_jwt.field_auth_jwt_validator__cookie_max_age msgid "Cookie Max Age" -msgstr "" +msgstr "Durata massima cookie" #. module: auth_jwt #: model:ir.model.fields,field_description:auth_jwt.field_auth_jwt_validator__cookie_name msgid "Cookie Name" -msgstr "" +msgstr "Nome cookie" #. module: auth_jwt #: model:ir.model.fields,field_description:auth_jwt.field_auth_jwt_validator__cookie_path msgid "Cookie Path" -msgstr "" +msgstr "Path cookie" #. module: auth_jwt #: model:ir.model.fields,field_description:auth_jwt.field_auth_jwt_validator__cookie_secure msgid "Cookie Secure" -msgstr "" +msgstr "Cookie secure" #. module: auth_jwt #: model:ir.model.fields,field_description:auth_jwt.field_auth_jwt_validator__create_uid msgid "Created by" -msgstr "" +msgstr "Creato da" #. module: auth_jwt #: model:ir.model.fields,field_description:auth_jwt.field_auth_jwt_validator__create_date msgid "Created on" -msgstr "" +msgstr "Creato il" #. module: auth_jwt #: model:ir.model.fields,field_description:auth_jwt.field_auth_jwt_validator__display_name msgid "Display Name" -msgstr "" +msgstr "Nome visualizzato" #. module: auth_jwt #: model:ir.model.fields.selection,name:auth_jwt.selection__auth_jwt_validator__public_key_algorithm__es256 msgid "ES256 - ECDSA using SHA-256" -msgstr "" +msgstr "ES256 - ECDSA usando SHA-256" #. module: auth_jwt #: model:ir.model.fields.selection,name:auth_jwt.selection__auth_jwt_validator__public_key_algorithm__es256k msgid "ES256K - ECDSA with secp256k1 curve using SHA-256" -msgstr "" +msgstr "ES256K - ECDSA con curva secp256k1 usando SHA-256" #. module: auth_jwt #: model:ir.model.fields.selection,name:auth_jwt.selection__auth_jwt_validator__public_key_algorithm__es384 msgid "ES384 - ECDSA using SHA-384" -msgstr "" +msgstr "ES384 - ECDSA usando SHA-384" #. module: auth_jwt #: model:ir.model.fields.selection,name:auth_jwt.selection__auth_jwt_validator__public_key_algorithm__es512 msgid "ES512 - ECDSA using SHA-512" -msgstr "" +msgstr "ES512 - ECDSA usando SHA-512" #. module: auth_jwt #: model:ir.model.fields.selection,name:auth_jwt.selection__auth_jwt_validator__partner_id_strategy__email msgid "From email claim" -msgstr "" +msgstr "Da richiesta e-mail" #. module: auth_jwt #: model_terms:ir.ui.view,arch_db:auth_jwt.view_auth_jwt_validator_form msgid "General" -msgstr "" +msgstr "Generale" #. module: auth_jwt #: model:ir.model.fields.selection,name:auth_jwt.selection__auth_jwt_validator__secret_algorithm__hs256 msgid "HS256 - HMAC using SHA-256 hash algorithm" -msgstr "" +msgstr "HS256 - HMAC usando SHA-256 hash algorithm" #. module: auth_jwt #: model:ir.model.fields.selection,name:auth_jwt.selection__auth_jwt_validator__secret_algorithm__hs384 msgid "HS384 - HMAC using SHA-384 hash algorithm" -msgstr "" +msgstr "HS384 - HMAC usando SHA-384 hash algorithm" #. module: auth_jwt #: model:ir.model.fields.selection,name:auth_jwt.selection__auth_jwt_validator__secret_algorithm__hs512 msgid "HS512 - HMAC using SHA-512 hash algorithm" -msgstr "" +msgstr "HS512 - HMAC usando SHA-512 hash algorithm" #. module: auth_jwt #: model:ir.model,name:auth_jwt.model_ir_http msgid "HTTP Routing" -msgstr "" +msgstr "Instradamento HTTP" #. module: auth_jwt #: model:ir.model.fields,field_description:auth_jwt.field_auth_jwt_validator__id msgid "ID" -msgstr "" +msgstr "ID" #. module: auth_jwt #: model:ir.model.fields,field_description:auth_jwt.field_auth_jwt_validator__issuer msgid "Issuer" -msgstr "" +msgstr "Segnalatore" #. module: auth_jwt #: model_terms:ir.ui.view,arch_db:auth_jwt.view_auth_jwt_validator_form msgid "JWK URI" -msgstr "" +msgstr "URI JWK" #. module: auth_jwt #: model:ir.model,name:auth_jwt.model_auth_jwt_validator msgid "JWT Validator Configuration" -msgstr "" +msgstr "Configurazione validatore JWT" #. module: auth_jwt #: model:ir.actions.act_window,name:auth_jwt.action_auth_jwt_validator #: model:ir.ui.menu,name:auth_jwt.menu_auth_jwt_validator msgid "JWT Validators" -msgstr "" +msgstr "Validatori JWT" #. module: auth_jwt #: model:ir.model.constraint,message:auth_jwt.constraint_auth_jwt_validator_name_uniq msgid "JWT validator names must be unique !" -msgstr "" +msgstr "I nomi dei validatori JWT devono essere univoci!" #. module: auth_jwt #: model_terms:ir.ui.view,arch_db:auth_jwt.view_auth_jwt_validator_form msgid "Key" -msgstr "" +msgstr "Chiave" #. module: auth_jwt #: model:ir.model.fields,field_description:auth_jwt.field_auth_jwt_validator____last_update msgid "Last Modified on" -msgstr "" +msgstr "Ultima modifica il" #. module: auth_jwt #: model:ir.model.fields,field_description:auth_jwt.field_auth_jwt_validator__write_uid msgid "Last Updated by" -msgstr "" +msgstr "Ultimo aggiornamento di" #. module: auth_jwt #: model:ir.model.fields,field_description:auth_jwt.field_auth_jwt_validator__write_date msgid "Last Updated on" -msgstr "" +msgstr "Ultimo aggiornamento il" #. module: auth_jwt #: model:ir.model.fields,field_description:auth_jwt.field_auth_jwt_validator__name msgid "Name" -msgstr "" +msgstr "Nome" #. module: auth_jwt #. odoo-python #: code:addons/auth_jwt/models/auth_jwt_validator.py:0 #, python-format msgid "Name %r is not a valid python identifier." -msgstr "" +msgstr "Il nome %r non è un identificatore Python valido." #. module: auth_jwt #: model:ir.model.fields,field_description:auth_jwt.field_auth_jwt_validator__next_validator_id msgid "Next Validator" -msgstr "" +msgstr "Validatore successivo" #. module: auth_jwt #: model:ir.model.fields,help:auth_jwt.field_auth_jwt_validator__next_validator_id msgid "Next validator to try if this one fails" -msgstr "" +msgstr "Validatore successivo da provare se questo fallisce" #. module: auth_jwt #: model:ir.model.fields,help:auth_jwt.field_auth_jwt_validator__cookie_max_age msgid "Number of seconds until the cookie expires (Max-Age)." -msgstr "" +msgstr "Numero di secondi fino alla scadenza del cookie (Durata max)." #. module: auth_jwt #: model:ir.model.fields.selection,name:auth_jwt.selection__auth_jwt_validator__public_key_algorithm__ps256 msgid "PS256 - RSASSA-PSS using SHA-256 and MGF1 padding with SHA-256" -msgstr "" +msgstr "PS256 - RSASSA-PSS usando SHA-256 e padding MGF1 con SHA-256" #. module: auth_jwt #: model:ir.model.fields.selection,name:auth_jwt.selection__auth_jwt_validator__public_key_algorithm__ps384 msgid "PS384 - RSASSA-PSS using SHA-384 and MGF1 padding with SHA-384" -msgstr "" +msgstr "PS384 - RSASSA-PSS usando SHA-384 e padding MGF1 con SHA-384" #. module: auth_jwt #: model:ir.model.fields.selection,name:auth_jwt.selection__auth_jwt_validator__public_key_algorithm__ps512 msgid "PS512 - RSASSA-PSS using SHA-512 and MGF1 padding with SHA-512" -msgstr "" +msgstr "PS512 - RSASSA-PSS usando SHA-512 e padding MGF1 con SHA-512" #. module: auth_jwt #: model_terms:ir.ui.view,arch_db:auth_jwt.view_auth_jwt_validator_form msgid "Partner" -msgstr "" +msgstr "Partner" #. module: auth_jwt #: model:ir.model.fields,field_description:auth_jwt.field_auth_jwt_validator__partner_id_required msgid "Partner Id Required" -msgstr "" +msgstr "Partner ID obbligatorio" #. module: auth_jwt #: model:ir.model.fields,field_description:auth_jwt.field_auth_jwt_validator__partner_id_strategy msgid "Partner Id Strategy" -msgstr "" +msgstr "Strategia Partner ID" #. module: auth_jwt #: model:ir.model.fields,field_description:auth_jwt.field_auth_jwt_validator__public_key_algorithm msgid "Public Key Algorithm" -msgstr "" +msgstr "Algoritmo a chiave pubblica" #. module: auth_jwt #: model:ir.model.fields,field_description:auth_jwt.field_auth_jwt_validator__public_key_jwk_uri msgid "Public Key Jwk Uri" -msgstr "" +msgstr "Jwk Uri a chiave pubblica" #. module: auth_jwt #: model:ir.model.fields.selection,name:auth_jwt.selection__auth_jwt_validator__signature_type__public_key msgid "Public key" -msgstr "" +msgstr "Chiave pubblica" #. module: auth_jwt #: model:ir.model.fields.selection,name:auth_jwt.selection__auth_jwt_validator__public_key_algorithm__rs256 msgid "RS256 - RSASSA-PKCS1-v1_5 using SHA-256" -msgstr "" +msgstr "RS256 - RSASSA-PKCS1-v1_5 usando SHA-256" #. module: auth_jwt #: model:ir.model.fields.selection,name:auth_jwt.selection__auth_jwt_validator__public_key_algorithm__rs384 msgid "RS384 - RSASSA-PKCS1-v1_5 using SHA-384" -msgstr "" +msgstr "RS384 - RSASSA-PKCS1-v1_5 usando SHA-384" #. module: auth_jwt #: model:ir.model.fields.selection,name:auth_jwt.selection__auth_jwt_validator__public_key_algorithm__rs512 msgid "RS512 - RSASSA-PKCS1-v1_5 using SHA-512" -msgstr "" +msgstr "RS512 - RSASSA-PKCS1-v1_5 usando SHA-512" #. module: auth_jwt #: model:ir.model.fields.selection,name:auth_jwt.selection__auth_jwt_validator__signature_type__secret msgid "Secret" -msgstr "" +msgstr "Segreta" #. module: auth_jwt #: model:ir.model.fields,field_description:auth_jwt.field_auth_jwt_validator__secret_algorithm msgid "Secret Algorithm" -msgstr "" +msgstr "Algoritmo segreto" #. module: auth_jwt #: model:ir.model.fields,field_description:auth_jwt.field_auth_jwt_validator__secret_key msgid "Secret Key" -msgstr "" +msgstr "Chiave segreta" #. module: auth_jwt #: model:ir.model.fields,help:auth_jwt.field_auth_jwt_validator__cookie_secure msgid "Set to false only for development without https." -msgstr "" +msgstr "Imposta su false solo per lo sviluppo senza https." #. module: auth_jwt #: model:ir.model.fields,field_description:auth_jwt.field_auth_jwt_validator__signature_type msgid "Signature Type" -msgstr "" +msgstr "Tipo di firma" #. module: auth_jwt #: model:ir.model.fields.selection,name:auth_jwt.selection__auth_jwt_validator__user_id_strategy__static msgid "Static" -msgstr "" +msgstr "Statica" #. module: auth_jwt #: model:ir.model.fields,field_description:auth_jwt.field_auth_jwt_validator__static_user_id msgid "Static User" -msgstr "" +msgstr "Utente statico" #. module: auth_jwt #: model:ir.model.fields,help:auth_jwt.field_auth_jwt_validator__issuer msgid "To validate iss." -msgstr "" +msgstr "Per validare iss." #. module: auth_jwt #: model_terms:ir.ui.view,arch_db:auth_jwt.view_auth_jwt_validator_form msgid "Token validation" -msgstr "" +msgstr "Convalida del token" #. module: auth_jwt #: model_terms:ir.ui.view,arch_db:auth_jwt.view_auth_jwt_validator_form msgid "User" -msgstr "" +msgstr "Utente" #. module: auth_jwt #: model:ir.model.fields,field_description:auth_jwt.field_auth_jwt_validator__user_id_strategy msgid "User Id Strategy" -msgstr "" +msgstr "Strategia User ID" #. module: auth_jwt #. odoo-python #: code:addons/auth_jwt/models/auth_jwt_validator.py:0 #, python-format msgid "Validators mustn't make a closed chain: {}." -msgstr "" +msgstr "I validatori non devono creare una catena chiusa: {}." #. module: auth_jwt #: model_terms:ir.ui.view,arch_db:auth_jwt.view_auth_jwt_validator_form msgid "arch" -msgstr "" +msgstr "arch" diff --git a/auth_jwt_demo/i18n/it.po b/auth_jwt_demo/i18n/it.po new file mode 100644 index 0000000000..73388557f6 --- /dev/null +++ b/auth_jwt_demo/i18n/it.po @@ -0,0 +1,14 @@ +# Translation of Odoo Server. +# This file contains the translation of the following modules: +# +msgid "" +msgstr "" +"Project-Id-Version: Odoo Server 16.0\n" +"Report-Msgid-Bugs-To: \n" +"Last-Translator: Automatically generated\n" +"Language-Team: none\n" +"Language: it\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: \n" +"Plural-Forms: nplurals=2; plural=n != 1;\n" diff --git a/auth_jwt_server_env/i18n/it.po b/auth_jwt_server_env/i18n/it.po new file mode 100644 index 0000000000..5d664490e7 --- /dev/null +++ b/auth_jwt_server_env/i18n/it.po @@ -0,0 +1,27 @@ +# Translation of Odoo Server. +# This file contains the translation of the following modules: +# * auth_jwt_server_env +# +msgid "" +msgstr "" +"Project-Id-Version: Odoo Server 16.0\n" +"Report-Msgid-Bugs-To: \n" +"PO-Revision-Date: 2024-01-03 14:33+0000\n" +"Last-Translator: mymage \n" +"Language-Team: none\n" +"Language: it\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: \n" +"Plural-Forms: nplurals=2; plural=n != 1;\n" +"X-Generator: Weblate 4.17\n" + +#. module: auth_jwt_server_env +#: model:ir.model,name:auth_jwt_server_env.model_auth_jwt_validator +msgid "JWT Validator Configuration" +msgstr "Configurazione validatore JWT" + +#. module: auth_jwt_server_env +#: model:ir.model.fields,field_description:auth_jwt_server_env.field_auth_jwt_validator__server_env_defaults +msgid "Server Env Defaults" +msgstr "Server ambiente predefinito" diff --git a/auth_oauth_ropc/README.rst b/auth_oauth_ropc/README.rst new file mode 100644 index 0000000000..a99ac0f4f8 --- /dev/null +++ b/auth_oauth_ropc/README.rst @@ -0,0 +1,106 @@ +=============== +Auth OAuth ROPC +=============== + +.. + !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + !! This file is generated by oca-gen-addon-readme !! + !! changes will be overwritten. !! + !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + !! source digest: sha256:4a0d8a58b581d5e0b655aa88c5623aa0884cf6e0efd31437d5b2c506729fb85a + !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + +.. |badge1| image:: https://img.shields.io/badge/maturity-Beta-yellow.png + :target: https://odoo-community.org/page/development-status + :alt: Beta +.. |badge2| image:: https://img.shields.io/badge/licence-AGPL--3-blue.png + :target: http://www.gnu.org/licenses/agpl-3.0-standalone.html + :alt: License: AGPL-3 +.. |badge3| image:: https://img.shields.io/badge/github-OCA%2Fserver--auth-lightgray.png?logo=github + :target: https://github.com/OCA/server-auth/tree/16.0/auth_oauth_ropc + :alt: OCA/server-auth +.. |badge4| image:: https://img.shields.io/badge/weblate-Translate%20me-F47D42.png + :target: https://translation.odoo-community.org/projects/server-auth-16-0/server-auth-16-0-auth_oauth_ropc + :alt: Translate me on Weblate +.. |badge5| image:: https://img.shields.io/badge/runboat-Try%20me-875A7B.png + :target: https://runboat.odoo-community.org/builds?repo=OCA/server-auth&target_branch=16.0 + :alt: Try me on Runboat + +|badge1| |badge2| |badge3| |badge4| |badge5| + +This module add the possibility to login with OAuth Resource Owner Password Credentials Grant + +https://datatracker.ietf.org/doc/html/rfc6749#section-4.3 + +In most scenarios, more secure alternatives are available and recommended. This flow requires a very high degree of trust in the application, and carries risks that are not present in other flows. You should only use this flow when other more secure flows aren't viable. + +This module is useful for the Odoo mobile application, which only supports user/password authentication. + +**Table of contents** + +.. contents:: + :local: + +Configuration +============= + +The configuration of this module is based with Microsoft Azure ad OAuth provider + +https://learn.microsoft.com/en-us/azure/active-directory/develop/v2-oauth-ropc + +To configure this module, you need to: + +#. Go to Settings/Users/OAuth ROPC providers and create a new one + +.. figure:: https://raw.githubusercontent.com/OCA/server-auth/16.0/auth_oauth_ropc/static/description/configuration.png + :alt: provider description + :width: 600 px + +Usage +===== + +To use this module, you need to: + +#. Go on the login screen +#. Fill your Odoo user name (must be the same in OAuth provider) +#. Fill your OAuth password + +Bug Tracker +=========== + +Bugs are tracked on `GitHub Issues `_. +In case of trouble, please check there if your issue has already been reported. +If you spotted it first, help us to smash it by providing a detailed and welcomed +`feedback `_. + +Do not contact contributors directly about support or help with technical issues. + +Credits +======= + +Authors +~~~~~~~ + +* ACSONE SA/NV + +Contributors +~~~~~~~~~~~~ + +Adrien Peiffer + +Maintainers +~~~~~~~~~~~ + +This module is maintained by the OCA. + +.. image:: https://odoo-community.org/logo.png + :alt: Odoo Community Association + :target: https://odoo-community.org + +OCA, or the Odoo Community Association, is a nonprofit organization whose +mission is to support the collaborative development of Odoo features and +promote its widespread use. + +This module is part of the `OCA/server-auth `_ project on GitHub. + +You are welcome to contribute. To learn how please visit https://odoo-community.org/page/Contribute. diff --git a/auth_oauth_ropc/__init__.py b/auth_oauth_ropc/__init__.py new file mode 100644 index 0000000000..0650744f6b --- /dev/null +++ b/auth_oauth_ropc/__init__.py @@ -0,0 +1 @@ +from . import models diff --git a/auth_oauth_ropc/__manifest__.py b/auth_oauth_ropc/__manifest__.py new file mode 100644 index 0000000000..f055dc539f --- /dev/null +++ b/auth_oauth_ropc/__manifest__.py @@ -0,0 +1,17 @@ +# Copyright 2023 ACSONE SA/NV +# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl). + +{ + "name": "Auth OAuth ROPC", + "summary": """ + Allow to login with OAuth Resource Owner Password Credentials Grant""", + "version": "16.0.1.0.0", + "license": "AGPL-3", + "author": "ACSONE SA/NV,Odoo Community Association (OCA)", + "website": "https://github.com/OCA/server-auth", + "depends": ["base"], + "data": [ + "security/oauth_ropc_provider.xml", + "views/oauth_ropc_provider.xml", + ], +} diff --git a/auth_oauth_ropc/i18n/auth_oauth_ropc.pot b/auth_oauth_ropc/i18n/auth_oauth_ropc.pot new file mode 100644 index 0000000000..158c0b876e --- /dev/null +++ b/auth_oauth_ropc/i18n/auth_oauth_ropc.pot @@ -0,0 +1,107 @@ +# Translation of Odoo Server. +# This file contains the translation of the following modules: +# * auth_oauth_ropc +# +msgid "" +msgstr "" +"Project-Id-Version: Odoo Server 16.0\n" +"Report-Msgid-Bugs-To: \n" +"Last-Translator: \n" +"Language-Team: \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: \n" +"Plural-Forms: \n" + +#. module: auth_oauth_ropc +#: model:ir.model.fields,field_description:auth_oauth_ropc.field_oauth_ropc_provider__active +msgid "Active" +msgstr "" + +#. module: auth_oauth_ropc +#: model:ir.model.fields,field_description:auth_oauth_ropc.field_oauth_ropc_provider__auth_endpoint +msgid "Authorization URL" +msgstr "" + +#. module: auth_oauth_ropc +#: model:ir.model.fields,field_description:auth_oauth_ropc.field_oauth_ropc_provider__client_id +msgid "Client ID" +msgstr "" + +#. module: auth_oauth_ropc +#: model:ir.model.fields,field_description:auth_oauth_ropc.field_oauth_ropc_provider__client_secret +msgid "Client Secret" +msgstr "" + +#. module: auth_oauth_ropc +#: model:ir.model.fields,field_description:auth_oauth_ropc.field_oauth_ropc_provider__create_uid +msgid "Created by" +msgstr "" + +#. module: auth_oauth_ropc +#: model:ir.model.fields,field_description:auth_oauth_ropc.field_oauth_ropc_provider__create_date +msgid "Created on" +msgstr "" + +#. module: auth_oauth_ropc +#: model:ir.model.fields,field_description:auth_oauth_ropc.field_oauth_ropc_provider__display_name +msgid "Display Name" +msgstr "" + +#. module: auth_oauth_ropc +#: model:ir.model.fields,field_description:auth_oauth_ropc.field_oauth_ropc_provider__id +msgid "ID" +msgstr "" + +#. module: auth_oauth_ropc +#: model:ir.model.fields,field_description:auth_oauth_ropc.field_oauth_ropc_provider____last_update +msgid "Last Modified on" +msgstr "" + +#. module: auth_oauth_ropc +#: model:ir.model.fields,field_description:auth_oauth_ropc.field_oauth_ropc_provider__write_uid +msgid "Last Updated by" +msgstr "" + +#. module: auth_oauth_ropc +#: model:ir.model.fields,field_description:auth_oauth_ropc.field_oauth_ropc_provider__write_date +msgid "Last Updated on" +msgstr "" + +#. module: auth_oauth_ropc +#: model:ir.model.fields,field_description:auth_oauth_ropc.field_oauth_ropc_provider__name +msgid "Name" +msgstr "" + +#. module: auth_oauth_ropc +#: model:ir.model,name:auth_oauth_ropc.model_oauth_ropc_provider +msgid "OAuth ROPC Provider" +msgstr "" + +#. module: auth_oauth_ropc +#: model:ir.model.fields,field_description:auth_oauth_ropc.field_oauth_ropc_provider__resource +msgid "Resource" +msgstr "" + +#. module: auth_oauth_ropc +#: model:ir.model.fields,field_description:auth_oauth_ropc.field_oauth_ropc_provider__scope +msgid "Scope" +msgstr "" + +#. module: auth_oauth_ropc +#: model:ir.model,name:auth_oauth_ropc.model_res_users +msgid "User" +msgstr "" + +#. module: auth_oauth_ropc +#. odoo-python +#: code:addons/auth_oauth_ropc/models/oauth_ropc_provider.py:0 +#, python-format +msgid "You can define only one active provider" +msgstr "" + +#. module: auth_oauth_ropc +#: model:ir.actions.act_window,name:auth_oauth_ropc.oauth_ropc_provider_act_window +#: model:ir.ui.menu,name:auth_oauth_ropc.oauth_ropc_provider_menu +msgid "oauth ROPC Providers" +msgstr "" diff --git a/auth_oauth_ropc/i18n/it.po b/auth_oauth_ropc/i18n/it.po new file mode 100644 index 0000000000..2db10f21a6 --- /dev/null +++ b/auth_oauth_ropc/i18n/it.po @@ -0,0 +1,110 @@ +# Translation of Odoo Server. +# This file contains the translation of the following modules: +# * auth_oauth_ropc +# +msgid "" +msgstr "" +"Project-Id-Version: Odoo Server 16.0\n" +"Report-Msgid-Bugs-To: \n" +"PO-Revision-Date: 2024-01-05 10:34+0000\n" +"Last-Translator: mymage \n" +"Language-Team: none\n" +"Language: it\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: \n" +"Plural-Forms: nplurals=2; plural=n != 1;\n" +"X-Generator: Weblate 4.17\n" + +#. module: auth_oauth_ropc +#: model:ir.model.fields,field_description:auth_oauth_ropc.field_oauth_ropc_provider__active +msgid "Active" +msgstr "Attivo" + +#. module: auth_oauth_ropc +#: model:ir.model.fields,field_description:auth_oauth_ropc.field_oauth_ropc_provider__auth_endpoint +msgid "Authorization URL" +msgstr "URL autorizzazione" + +#. module: auth_oauth_ropc +#: model:ir.model.fields,field_description:auth_oauth_ropc.field_oauth_ropc_provider__client_id +msgid "Client ID" +msgstr "ID client" + +#. module: auth_oauth_ropc +#: model:ir.model.fields,field_description:auth_oauth_ropc.field_oauth_ropc_provider__client_secret +msgid "Client Secret" +msgstr "Chiave segreta client" + +#. module: auth_oauth_ropc +#: model:ir.model.fields,field_description:auth_oauth_ropc.field_oauth_ropc_provider__create_uid +msgid "Created by" +msgstr "Creato da" + +#. module: auth_oauth_ropc +#: model:ir.model.fields,field_description:auth_oauth_ropc.field_oauth_ropc_provider__create_date +msgid "Created on" +msgstr "Creato il" + +#. module: auth_oauth_ropc +#: model:ir.model.fields,field_description:auth_oauth_ropc.field_oauth_ropc_provider__display_name +msgid "Display Name" +msgstr "Nome visualizzato" + +#. module: auth_oauth_ropc +#: model:ir.model.fields,field_description:auth_oauth_ropc.field_oauth_ropc_provider__id +msgid "ID" +msgstr "ID" + +#. module: auth_oauth_ropc +#: model:ir.model.fields,field_description:auth_oauth_ropc.field_oauth_ropc_provider____last_update +msgid "Last Modified on" +msgstr "Ultima modifica il" + +#. module: auth_oauth_ropc +#: model:ir.model.fields,field_description:auth_oauth_ropc.field_oauth_ropc_provider__write_uid +msgid "Last Updated by" +msgstr "Ultimo aggiornamento di" + +#. module: auth_oauth_ropc +#: model:ir.model.fields,field_description:auth_oauth_ropc.field_oauth_ropc_provider__write_date +msgid "Last Updated on" +msgstr "Ultimo aggiornamento il" + +#. module: auth_oauth_ropc +#: model:ir.model.fields,field_description:auth_oauth_ropc.field_oauth_ropc_provider__name +msgid "Name" +msgstr "Nome" + +#. module: auth_oauth_ropc +#: model:ir.model,name:auth_oauth_ropc.model_oauth_ropc_provider +msgid "OAuth ROPC Provider" +msgstr "Provider ROPC OAuth" + +#. module: auth_oauth_ropc +#: model:ir.model.fields,field_description:auth_oauth_ropc.field_oauth_ropc_provider__resource +msgid "Resource" +msgstr "Risorsa" + +#. module: auth_oauth_ropc +#: model:ir.model.fields,field_description:auth_oauth_ropc.field_oauth_ropc_provider__scope +msgid "Scope" +msgstr "Ambito" + +#. module: auth_oauth_ropc +#: model:ir.model,name:auth_oauth_ropc.model_res_users +msgid "User" +msgstr "Utente" + +#. module: auth_oauth_ropc +#. odoo-python +#: code:addons/auth_oauth_ropc/models/oauth_ropc_provider.py:0 +#, python-format +msgid "You can define only one active provider" +msgstr "Si può definire attivo un solo provider" + +#. module: auth_oauth_ropc +#: model:ir.actions.act_window,name:auth_oauth_ropc.oauth_ropc_provider_act_window +#: model:ir.ui.menu,name:auth_oauth_ropc.oauth_ropc_provider_menu +msgid "oauth ROPC Providers" +msgstr "Provider ROPC OAuth" diff --git a/auth_oauth_ropc/models/__init__.py b/auth_oauth_ropc/models/__init__.py new file mode 100644 index 0000000000..c136e1765e --- /dev/null +++ b/auth_oauth_ropc/models/__init__.py @@ -0,0 +1,2 @@ +from . import oauth_ropc_provider +from . import res_users diff --git a/auth_oauth_ropc/models/oauth_ropc_provider.py b/auth_oauth_ropc/models/oauth_ropc_provider.py new file mode 100644 index 0000000000..095c4abf3e --- /dev/null +++ b/auth_oauth_ropc/models/oauth_ropc_provider.py @@ -0,0 +1,44 @@ +# Copyright 2023 ACSONE SA/NV +# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl). + +import requests + +from odoo import _, api, fields, models +from odoo.exceptions import ValidationError + + +class OAuthRopcProvider(models.Model): + + _name = "oauth.ropc.provider" + _description = "OAuth ROPC Provider" + + name = fields.Char() + client_id = fields.Char(string="Client ID") + client_secret = fields.Char() + auth_endpoint = fields.Char(string="Authorization URL", required=True) + resource = fields.Char() + scope = fields.Char() + active = fields.Boolean(default=True) + + @api.constrains("active") + def _check_active(self): + records_to_check = self.filtered(lambda r: r.active) + for record in records_to_check: + if self.search([("id", "!=", record.id)]): + raise ValidationError(_("""You can define only one active provider""")) + + def _authenticate(self, login, password): + self.ensure_one() + data = { + "client_id": self.client_id, + "client_secret": self.client_secret, + "resource": self.resource, + "scope": self.scope, + "grant_type": "password", + "username": login, + "password": password, + } + r = requests.post(self.auth_endpoint, data=data, timeout=5) + if r.status_code == 200: + return True + return False diff --git a/auth_oauth_ropc/models/res_users.py b/auth_oauth_ropc/models/res_users.py new file mode 100644 index 0000000000..3bf8dff43d --- /dev/null +++ b/auth_oauth_ropc/models/res_users.py @@ -0,0 +1,23 @@ +# Copyright 2023 ACSONE SA/NV +# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl). + +from odoo import models +from odoo.exceptions import AccessDenied + + +class ResUsers(models.Model): + + _inherit = "res.users" + + def _check_credentials(self, password, env): + try: + return super(ResUsers, self)._check_credentials(password, env) + except AccessDenied: + passwd_allowed = ( + env["interactive"] or not self.env.user._rpc_api_keys_only() + ) + if passwd_allowed and self.env.user.active: + if ropc_provider := self.env["oauth.ropc.provider"].sudo().search([]): + if ropc_provider._authenticate(self.env.user.login, password): + return + raise diff --git a/auth_oauth_ropc/readme/CONFIGURE.rst b/auth_oauth_ropc/readme/CONFIGURE.rst new file mode 100644 index 0000000000..7ade86e028 --- /dev/null +++ b/auth_oauth_ropc/readme/CONFIGURE.rst @@ -0,0 +1,11 @@ +The configuration of this module is based with Microsoft Azure ad OAuth provider + +https://learn.microsoft.com/en-us/azure/active-directory/develop/v2-oauth-ropc + +To configure this module, you need to: + +#. Go to Settings/Users/OAuth ROPC providers and create a new one + +.. figure:: ../static/description/configuration.png + :alt: provider description + :width: 600 px diff --git a/auth_oauth_ropc/readme/CONTRIBUTORS.rst b/auth_oauth_ropc/readme/CONTRIBUTORS.rst new file mode 100644 index 0000000000..e2bc6777dc --- /dev/null +++ b/auth_oauth_ropc/readme/CONTRIBUTORS.rst @@ -0,0 +1 @@ +Adrien Peiffer diff --git a/auth_oauth_ropc/readme/DESCRIPTION.rst b/auth_oauth_ropc/readme/DESCRIPTION.rst new file mode 100644 index 0000000000..79a7b4ffb5 --- /dev/null +++ b/auth_oauth_ropc/readme/DESCRIPTION.rst @@ -0,0 +1,7 @@ +This module add the possibility to login with OAuth Resource Owner Password Credentials Grant + +https://datatracker.ietf.org/doc/html/rfc6749#section-4.3 + +In most scenarios, more secure alternatives are available and recommended. This flow requires a very high degree of trust in the application, and carries risks that are not present in other flows. You should only use this flow when other more secure flows aren't viable. + +This module is useful for the Odoo mobile application, which only supports user/password authentication. diff --git a/auth_oauth_ropc/readme/USAGE.rst b/auth_oauth_ropc/readme/USAGE.rst new file mode 100644 index 0000000000..2b8eb9cdaa --- /dev/null +++ b/auth_oauth_ropc/readme/USAGE.rst @@ -0,0 +1,5 @@ +To use this module, you need to: + +#. Go on the login screen +#. Fill your Odoo user name (must be the same in OAuth provider) +#. Fill your OAuth password diff --git a/auth_oauth_ropc/security/oauth_ropc_provider.xml b/auth_oauth_ropc/security/oauth_ropc_provider.xml new file mode 100644 index 0000000000..dfb9201231 --- /dev/null +++ b/auth_oauth_ropc/security/oauth_ropc_provider.xml @@ -0,0 +1,16 @@ + + + + + + oauth.ropc.provider access system + + + + + + + + + diff --git a/auth_oauth_ropc/static/description/configuration.png b/auth_oauth_ropc/static/description/configuration.png new file mode 100644 index 0000000000..370233cacd Binary files /dev/null and b/auth_oauth_ropc/static/description/configuration.png differ diff --git a/auth_oauth_ropc/static/description/icon.png b/auth_oauth_ropc/static/description/icon.png new file mode 100644 index 0000000000..3a0328b516 Binary files /dev/null and b/auth_oauth_ropc/static/description/icon.png differ diff --git a/auth_oauth_ropc/static/description/index.html b/auth_oauth_ropc/static/description/index.html new file mode 100644 index 0000000000..040d6ff7a6 --- /dev/null +++ b/auth_oauth_ropc/static/description/index.html @@ -0,0 +1,444 @@ + + + + + +Auth OAuth ROPC + + + +
+

Auth OAuth ROPC

+ + +

Beta License: AGPL-3 OCA/server-auth Translate me on Weblate Try me on Runboat

+

This module add the possibility to login with OAuth Resource Owner Password Credentials Grant

+

https://datatracker.ietf.org/doc/html/rfc6749#section-4.3

+

In most scenarios, more secure alternatives are available and recommended. This flow requires a very high degree of trust in the application, and carries risks that are not present in other flows. You should only use this flow when other more secure flows aren’t viable.

+

This module is useful for the Odoo mobile application, which only supports user/password authentication.

+

Table of contents

+ +
+

Configuration

+

The configuration of this module is based with Microsoft Azure ad OAuth provider

+

https://learn.microsoft.com/en-us/azure/active-directory/develop/v2-oauth-ropc

+

To configure this module, you need to:

+
    +
  1. Go to Settings/Users/OAuth ROPC providers and create a new one
  2. +
+
+provider description +
+
+
+

Usage

+

To use this module, you need to:

+
    +
  1. Go on the login screen
  2. +
  3. Fill your Odoo user name (must be the same in OAuth provider)
  4. +
  5. Fill your OAuth password
  6. +
+
+
+

Bug Tracker

+

Bugs are tracked on GitHub Issues. +In case of trouble, please check there if your issue has already been reported. +If you spotted it first, help us to smash it by providing a detailed and welcomed +feedback.

+

Do not contact contributors directly about support or help with technical issues.

+
+
+

Credits

+
+

Authors

+
    +
  • ACSONE SA/NV
  • +
+
+ +
+

Maintainers

+

This module is maintained by the OCA.

+Odoo Community Association +

OCA, or the Odoo Community Association, is a nonprofit organization whose +mission is to support the collaborative development of Odoo features and +promote its widespread use.

+

This module is part of the OCA/server-auth project on GitHub.

+

You are welcome to contribute. To learn how please visit https://odoo-community.org/page/Contribute.

+
+
+
+ + diff --git a/auth_oauth_ropc/views/oauth_ropc_provider.xml b/auth_oauth_ropc/views/oauth_ropc_provider.xml new file mode 100644 index 0000000000..ee69abb61b --- /dev/null +++ b/auth_oauth_ropc/views/oauth_ropc_provider.xml @@ -0,0 +1,53 @@ + + + + + + oauth.ropc.provider.form (in auth_oauth_ropc) + oauth.ropc.provider + +
+ + + + + + + + + + + +
+
+
+ + + + oauth.ropc.provider.tree (in auth_oauth_ropc) + oauth.ropc.provider + + + + + + + + + + oauth ROPC Providers + oauth.ropc.provider + tree,form + [] + {} + + + + oauth ROPC Providers + + + + + +
diff --git a/auth_oidc/i18n/it.po b/auth_oidc/i18n/it.po new file mode 100644 index 0000000000..e4f38a45a8 --- /dev/null +++ b/auth_oidc/i18n/it.po @@ -0,0 +1,127 @@ +# Translation of Odoo Server. +# This file contains the translation of the following modules: +# * auth_oidc +# +msgid "" +msgstr "" +"Project-Id-Version: Odoo Server 16.0\n" +"Report-Msgid-Bugs-To: \n" +"PO-Revision-Date: 2024-01-05 10:34+0000\n" +"Last-Translator: mymage \n" +"Language-Team: none\n" +"Language: it\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: \n" +"Plural-Forms: nplurals=2; plural=n != 1;\n" +"X-Generator: Weblate 4.17\n" + +#. module: auth_oidc +#: model:ir.model.fields,field_description:auth_oidc.field_auth_oauth_provider__flow +msgid "Auth Flow" +msgstr "Flusso atorizzazione" + +#. module: auth_oidc +#: model:ir.model.fields,field_description:auth_oidc.field_auth_oauth_provider__client_secret +msgid "Client Secret" +msgstr "Chiave segreta client" + +#. module: auth_oidc +#: model:ir.model.fields,field_description:auth_oidc.field_auth_oauth_provider__code_verifier +msgid "Code Verifier" +msgstr "Verificatore codice" + +#. module: auth_oidc +#: model:ir.model.fields,field_description:auth_oidc.field_auth_oauth_provider__jwks_uri +msgid "JWKS URL" +msgstr "URL JWKS" + +#. module: auth_oidc +#: model:auth.oauth.provider,body:auth_oidc.provider_azuread_multi +#: model:auth.oauth.provider,body:auth_oidc.provider_azuread_single +msgid "Log in with Microsoft" +msgstr "Accedi con Mcrosoft" + +#. module: auth_oidc +#: model:ir.model.fields.selection,name:auth_oidc.selection__auth_oauth_provider__flow__access_token +msgid "OAuth2" +msgstr "OAuth2" + +#. module: auth_oidc +#: model:ir.model,name:auth_oidc.model_auth_oauth_provider +msgid "OAuth2 provider" +msgstr "Provider OAuth2" + +#. module: auth_oidc +#: model:ir.model.fields.selection,name:auth_oidc.selection__auth_oauth_provider__flow__id_token_code +msgid "OpenID Connect (authorization code flow)" +msgstr "OpenID Connect (flusso codice autorizzazione)" + +#. module: auth_oidc +#: model:ir.model.fields.selection,name:auth_oidc.selection__auth_oauth_provider__flow__id_token +msgid "OpenID Connect (implicit flow, not recommended)" +msgstr "OpenID Connect (flusso implicito, non raccomandato)" + +#. module: auth_oidc +#: model:ir.model.fields,help:auth_oidc.field_auth_oauth_provider__token_endpoint +msgid "Required for OpenID Connect authorization code flow." +msgstr "Richiesto per flusso codice atorizzazione OpenID Connect." + +#. module: auth_oidc +#: model:ir.model.fields,help:auth_oidc.field_auth_oauth_provider__jwks_uri +msgid "Required for OpenID Connect." +msgstr "Richiesto per OpenID Connect." + +#. module: auth_oidc +#: model:ir.model.fields,help:auth_oidc.field_auth_oauth_provider__token_map +msgid "" +"Some Oauth providers don't map keys in their responses exactly as required." +" It is important to ensure user_id and email at least are mapped. For " +"OpenID Connect user_id is the sub key in the standard." +msgstr "" +"Alcuni Provider Oauth non mappano le chiavi nelle loro risposte esattamente " +"come richiesto. È importante assicurare che almeno user_id ed e-mail siano " +"mappati. Per OpenID Connect user_id è la sotto-chiave nello standard." + +#. module: auth_oidc +#: model:ir.model.fields,field_description:auth_oidc.field_auth_oauth_provider__token_map +msgid "Token Map" +msgstr "Mappa token" + +#. module: auth_oidc +#: model:ir.model.fields,field_description:auth_oidc.field_auth_oauth_provider__token_endpoint +msgid "Token URL" +msgstr "URL token" + +#. module: auth_oidc +#: model:ir.model.fields,help:auth_oidc.field_auth_oauth_provider__code_verifier +msgid "Used for PKCE." +msgstr "Utilizzato per PKCE." + +#. module: auth_oidc +#: model:ir.model.fields,help:auth_oidc.field_auth_oauth_provider__client_secret +msgid "" +"Used in OpenID Connect authorization code flow for confidential clients." +msgstr "" +"Utilizzato nel flusso codice autorizzazione OpenID Connect per client " +"riservati." + +#. module: auth_oidc +#: model:ir.model,name:auth_oidc.model_res_users +msgid "User" +msgstr "Utente" + +#. module: auth_oidc +#: model:ir.model.fields,field_description:auth_oidc.field_auth_oauth_provider__validation_endpoint +msgid "UserInfo URL" +msgstr "URL info utente" + +#. module: auth_oidc +#: model_terms:ir.ui.view,arch_db:auth_oidc.view_oidc_provider_form +msgid "e.g from:to upn:email sub:user_id" +msgstr "es. from:to upn:email sub:user_id" + +#. module: auth_oidc +#: model:auth.oauth.provider,body:auth_oidc.local_keycloak +msgid "keycloak:8080 on localhost" +msgstr "keycloak:8080 su localhost" diff --git a/auth_oidc_environment/i18n/it.po b/auth_oidc_environment/i18n/it.po new file mode 100644 index 0000000000..eea27c216c --- /dev/null +++ b/auth_oidc_environment/i18n/it.po @@ -0,0 +1,27 @@ +# Translation of Odoo Server. +# This file contains the translation of the following modules: +# * auth_oidc_environment +# +msgid "" +msgstr "" +"Project-Id-Version: Odoo Server 16.0\n" +"Report-Msgid-Bugs-To: \n" +"PO-Revision-Date: 2024-01-03 14:33+0000\n" +"Last-Translator: mymage \n" +"Language-Team: none\n" +"Language: it\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: \n" +"Plural-Forms: nplurals=2; plural=n != 1;\n" +"X-Generator: Weblate 4.17\n" + +#. module: auth_oidc_environment +#: model:ir.model,name:auth_oidc_environment.model_auth_oauth_provider +msgid "OAuth2 provider" +msgstr "Provider OAuth2" + +#. module: auth_oidc_environment +#: model:ir.model.fields,field_description:auth_oidc_environment.field_auth_oauth_provider__server_env_defaults +msgid "Server Env Defaults" +msgstr "Server ambiente predefinito" diff --git a/auth_saml/README.rst b/auth_saml/README.rst index 0278f10326..ea6b223ea1 100644 --- a/auth_saml/README.rst +++ b/auth_saml/README.rst @@ -7,7 +7,7 @@ SAML2 Authentication !! This file is generated by oca-gen-addon-readme !! !! changes will be overwritten. !! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! - !! source digest: sha256:d297addccec609ee677847489b8f99d0da3056d322226eef9cb790c6bbe9667a + !! source digest: sha256:3fcac74e9beda7cf4b033bd925615869ba6499576aabc948428f2cce34b6b790 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! .. |badge1| image:: https://img.shields.io/badge/maturity-Beta-yellow.png diff --git a/auth_saml/__manifest__.py b/auth_saml/__manifest__.py index a5d6eeede9..ef4f1bb564 100644 --- a/auth_saml/__manifest__.py +++ b/auth_saml/__manifest__.py @@ -4,7 +4,7 @@ { "name": "SAML2 Authentication", - "version": "16.0.1.0.5", + "version": "16.0.1.0.4", "category": "Tools", "author": "XCG Consulting, Odoo Community Association (OCA)", "maintainers": ["vincent-hatakeyama"], diff --git a/auth_saml/controllers/main.py b/auth_saml/controllers/main.py index 8f5bed2272..bfd201aad2 100644 --- a/auth_saml/controllers/main.py +++ b/auth_saml/controllers/main.py @@ -191,7 +191,7 @@ def signin(self, **kw): """ saml_response = kw.get("SAMLResponse") - if kw.get("RelayState") is None: + if not kw.get("RelayState"): # here we are in front of a client that went through # some routes that "lost" its relaystate... this can happen # if the client visited his IDP and successfully logged in diff --git a/auth_saml/i18n/it.po b/auth_saml/i18n/it.po new file mode 100644 index 0000000000..c371d8d389 --- /dev/null +++ b/auth_saml/i18n/it.po @@ -0,0 +1,567 @@ +# Translation of Odoo Server. +# This file contains the translation of the following modules: +# * auth_saml +# +msgid "" +msgstr "" +"Project-Id-Version: Odoo Server 16.0\n" +"Report-Msgid-Bugs-To: \n" +"PO-Revision-Date: 2024-01-05 10:34+0000\n" +"Last-Translator: mymage \n" +"Language-Team: none\n" +"Language: it\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: \n" +"Plural-Forms: nplurals=2; plural=n != 1;\n" +"X-Generator: Weblate 4.17\n" + +#. module: auth_saml +#: model_terms:ir.ui.view,arch_db:auth_saml.providers +msgid "- or -" +msgstr "- o -" + +#. module: auth_saml +#. odoo-python +#: code:addons/auth_saml/controllers/main.py:0 +#, python-format +msgid "Access Denied" +msgstr "Accesso negato" + +#. module: auth_saml +#: model:ir.model.fields,field_description:auth_saml.field_auth_saml_provider__active +msgid "Active" +msgstr "Attivo" + +#. module: auth_saml +#: model:ir.model.fields,help:auth_saml.field_auth_saml_provider__css_class +msgid "Add a CSS class that serves you to style the login button." +msgstr "Aggiungere una classe CSS utile a definire il pulsante di accesso." + +#. module: auth_saml +#: model_terms:ir.ui.view,arch_db:auth_saml.view_saml_provider_form +msgid "Algorithm used to sign requests." +msgstr "Algoritmo utilizzato per firmare le richieste." + +#. module: auth_saml +#: model:ir.model.fields,field_description:auth_saml.field_res_config_settings__allow_saml_uid_and_internal_password +msgid "" +"Allow SAML users to possess an Odoo password (warning: decreases security)" +msgstr "" +"Consente agli utenti SAML di avere una password Odoo (attenzione: diminuisce " +"la sicurezza)" + +#. module: auth_saml +#: model_terms:ir.ui.view,arch_db:auth_saml.auth_saml_provider_view_search +#: model_terms:ir.ui.view,arch_db:auth_saml.view_saml_provider_form +msgid "Archived" +msgstr "In archivio" + +#. module: auth_saml +#: model:ir.model.fields,field_description:auth_saml.field_auth_saml_provider__attribute_mapping_ids +msgid "Attribute Mapping" +msgstr "Mappatura attributo" + +#. module: auth_saml +#: model:ir.model.fields,help:auth_saml.field_auth_saml_provider__matching_attribute +msgid "" +"Attribute to look for in the returned IDP response to match against an Odoo " +"user." +msgstr "" +"Attributo da cercare nella risposta IDP restituita da corrispondere con un " +"utente Odoo." + +#. module: auth_saml +#: model_terms:ir.ui.view,arch_db:auth_saml.view_saml_provider_form +msgid "" +"Attribute to match the user in Odoo with against the IDP (Identity " +"Provider). You may use the special case \"subject.nameId\" to match against " +"the nameId in the IDP response." +msgstr "" +"Attributo per corrispondere l'utente in Odoo con quello dell'IDP (provider " +"di identità). Si può utilizzare l'opzione speciale \"subject.nameId\" per " +"corrispondere al nameId nella risposta IDP." + +#. module: auth_saml +#: model:ir.model.fields,field_description:auth_saml.field_auth_saml_provider__authn_requests_signed +msgid "Authn Requests Signed" +msgstr "Richieste atenticazione firmate" + +#. module: auth_saml +#: model:ir.model.fields,field_description:auth_saml.field_auth_saml_provider__autoredirect +msgid "Automatic Redirection" +msgstr "Inoltro automatico" + +#. module: auth_saml +#: model_terms:ir.ui.view,arch_db:auth_saml.view_saml_provider_form +msgid "" +"Available after first save. The URL will change if the provider is deleted " +"& recreated or the database is renamed." +msgstr "" +"Disponibile dopo il primo salvataggio. L'URL cambierà se il forntore è " +"cancellato e ricreato il database rinominato." + +#. module: auth_saml +#: model:ir.model.fields,help:auth_saml.field_auth_saml_provider__sp_baseurl +msgid "" +"Base URL sent to Odoo with this, rather than automatically\n" +" detecting from request or system parameter web.base.url" +msgstr "" +"URL base inviato a Odoo con questo, anziché rilevarlo \n" +" automaticamente dalla richiesta o parametro di sistema web.base.url" + +#. module: auth_saml +#: model:ir.model.fields,field_description:auth_saml.field_auth_saml_provider__css_class +msgid "Button Icon CSS class" +msgstr "Pulsante icona classe CSS" + +#. module: auth_saml +#: model:ir.model,name:auth_saml.model_res_config_settings +msgid "Config Settings" +msgstr "Impostazioni configurazione" + +#. module: auth_saml +#: model:ir.model.fields,help:auth_saml.field_auth_saml_provider__idp_metadata +msgid "" +"Configuration for this Identity Provider. Supplied by the provider, in XML " +"format." +msgstr "" +"Configurazione per questo provider di identità. Fornito dal provider, in " +"formato XML." + +#. module: auth_saml +#: model:ir.model.fields,field_description:auth_saml.field_auth_saml_attribute_mapping__create_uid +#: model:ir.model.fields,field_description:auth_saml.field_auth_saml_provider__create_uid +#: model:ir.model.fields,field_description:auth_saml.field_auth_saml_request__create_uid +#: model:ir.model.fields,field_description:auth_saml.field_res_users_saml__create_uid +msgid "Created by" +msgstr "Creato da" + +#. module: auth_saml +#: model:ir.model.fields,field_description:auth_saml.field_auth_saml_attribute_mapping__create_date +#: model:ir.model.fields,field_description:auth_saml.field_auth_saml_provider__create_date +#: model:ir.model.fields,field_description:auth_saml.field_auth_saml_request__create_date +#: model:ir.model.fields,field_description:auth_saml.field_res_users_saml__create_date +msgid "Created on" +msgstr "Creato il" + +#. module: auth_saml +#: model:ir.model.fields,field_description:auth_saml.field_auth_saml_request__saml_request_id +msgid "Current Request ID" +msgstr "ID richiesta attuale" + +#. module: auth_saml +#: model:ir.model.fields,field_description:auth_saml.field_res_users_saml__saml_access_token +msgid "Current SAML token for this user" +msgstr "Token SAML attuale per questo utente" + +#. module: auth_saml +#: model:ir.model.fields,field_description:auth_saml.field_auth_saml_attribute_mapping__display_name +#: model:ir.model.fields,field_description:auth_saml.field_auth_saml_provider__display_name +#: model:ir.model.fields,field_description:auth_saml.field_auth_saml_request__display_name +#: model:ir.model.fields,field_description:auth_saml.field_res_users_saml__display_name +msgid "Display Name" +msgstr "Nome visualizzato" + +#. module: auth_saml +#: model_terms:ir.ui.view,arch_db:auth_saml.view_saml_provider_form +msgid "Display Settings" +msgstr "Visualizza impostazioni" + +#. module: auth_saml +#: model:ir.model.fields,field_description:auth_saml.field_auth_saml_provider__entity_id +msgid "Entity ID" +msgstr "ID entità" + +#. module: auth_saml +#: model_terms:ir.ui.view,arch_db:auth_saml.view_saml_provider_form +msgid "" +"Entity Identifier sent to the IDP. Often this would be the metadata URL, but" +" it can be any string." +msgstr "" +"Identificatore entità inviato al IDP. Spesso è l'URL dei metadati, ma può " +"essere qualsiasi stringa." + +#. module: auth_saml +#: model:ir.model.fields,help:auth_saml.field_auth_saml_provider__entity_id +msgid "EntityID passed to IDP, used to identify the Odoo" +msgstr "EntityID passato all'IDP, utilizzato per identificate Odoo" + +#. module: auth_saml +#: model:ir.model.fields,help:auth_saml.field_auth_saml_provider__matching_attribute_to_lower +msgid "Force matching_attribute to lower case before passing back to Odoo." +msgstr "Forza matching_attribute a minuscolo prima di restituirlo ad Odoo." + +#. module: auth_saml +#: model:ir.model.fields,field_description:auth_saml.field_auth_saml_attribute_mapping__id +#: model:ir.model.fields,field_description:auth_saml.field_auth_saml_provider__id +#: model:ir.model.fields,field_description:auth_saml.field_auth_saml_request__id +#: model:ir.model.fields,field_description:auth_saml.field_res_users_saml__id +msgid "ID" +msgstr "ID" + +#. module: auth_saml +#: model:ir.model.fields,field_description:auth_saml.field_auth_saml_attribute_mapping__attribute_name +msgid "IDP Response Attribute" +msgstr "Attributo risposta IDP" + +#. module: auth_saml +#: model:ir.model.fields,field_description:auth_saml.field_auth_saml_provider__idp_metadata +msgid "Identity Provider Metadata" +msgstr "Metadati provider identità" + +#. module: auth_saml +#: model_terms:ir.ui.view,arch_db:auth_saml.view_saml_provider_form +msgid "Identity Provider Settings" +msgstr "Impostazioni provider identità" + +#. module: auth_saml +#: model:ir.model.fields,field_description:auth_saml.field_auth_saml_provider__matching_attribute +msgid "Identity Provider matching attribute" +msgstr "Attributo corrsipondenza provider identità" + +#. module: auth_saml +#: model:ir.model.fields,help:auth_saml.field_auth_saml_provider__authn_requests_signed +msgid "" +"Indicates if the Authentication Requests sent by this SP should be signed by" +" default." +msgstr "" +"ndica se la richiesta di atenticazione inviata da questo SP deve essere " +"firmata in modo predefinito." + +#. module: auth_saml +#: model:ir.model.fields,help:auth_saml.field_auth_saml_provider__want_assertions_signed +msgid "Indicates if this SP wants the IdP to send the assertions signed." +msgstr "Indica se questo SP richiede che l'IDP invii la conferma firmata." + +#. module: auth_saml +#: model:ir.model.fields,help:auth_saml.field_auth_saml_provider__logout_requests_signed +msgid "" +"Indicates if this entity will sign the Logout Requests originated from it." +msgstr "" +"Indica se questa entità firmerà la richiesta di uscita da esso generata." + +#. module: auth_saml +#: model:ir.model.fields,help:auth_saml.field_auth_saml_provider__want_response_signed +msgid "Indicates that Authentication Responses to this SP must be signed." +msgstr "" +"Indica che le risposte di autenticazione a questo SP devono essere firmate." + +#. module: auth_saml +#: model:ir.model.fields,help:auth_saml.field_auth_saml_provider__want_assertions_or_response_signed +msgid "" +"Indicates that either the Authentication Response or the assertions " +"contained within the response to this SP must be signed." +msgstr "" +"Indica che la risposta di autenticazione o le dichiarazioni contenute nelle " +"risposte a questo SP deve essere firmata." + +#. module: auth_saml +#: model:ir.model.fields,field_description:auth_saml.field_auth_saml_attribute_mapping____last_update +#: model:ir.model.fields,field_description:auth_saml.field_auth_saml_provider____last_update +#: model:ir.model.fields,field_description:auth_saml.field_auth_saml_request____last_update +#: model:ir.model.fields,field_description:auth_saml.field_res_users_saml____last_update +msgid "Last Modified on" +msgstr "Ultima modifica il" + +#. module: auth_saml +#: model:ir.model.fields,field_description:auth_saml.field_auth_saml_attribute_mapping__write_uid +#: model:ir.model.fields,field_description:auth_saml.field_auth_saml_provider__write_uid +#: model:ir.model.fields,field_description:auth_saml.field_auth_saml_request__write_uid +#: model:ir.model.fields,field_description:auth_saml.field_res_users_saml__write_uid +msgid "Last Updated by" +msgstr "Ultimo aggiornamento di" + +#. module: auth_saml +#: model:ir.model.fields,field_description:auth_saml.field_auth_saml_attribute_mapping__write_date +#: model:ir.model.fields,field_description:auth_saml.field_auth_saml_provider__write_date +#: model:ir.model.fields,field_description:auth_saml.field_auth_saml_request__write_date +#: model:ir.model.fields,field_description:auth_saml.field_res_users_saml__write_date +msgid "Last Updated on" +msgstr "Ultimo aggiornamento il" + +#. module: auth_saml +#: model:ir.model.fields,help:auth_saml.field_auth_saml_provider__body +msgid "Link text in Login Dialog" +msgstr "Collega il testo nella maschera di accesso" + +#. module: auth_saml +#: model:ir.model.fields,field_description:auth_saml.field_auth_saml_provider__body +msgid "Login button label" +msgstr "Etichetta pulsante accesso" + +#. module: auth_saml +#: model:ir.model.fields,field_description:auth_saml.field_auth_saml_provider__logout_requests_signed +msgid "Logout Requests Signed" +msgstr "Richiesta uscita firmata" + +#. module: auth_saml +#: model:ir.model.fields,field_description:auth_saml.field_auth_saml_provider__matching_attribute_to_lower +msgid "Lowercase IDP Matching Attribute" +msgstr "Attributo corrispondenza IDP minuscolo" + +#. module: auth_saml +#: model_terms:ir.ui.view,arch_db:auth_saml.view_saml_provider_form +msgid "" +"Mapped attributes are copied from the SAML response at every logon, if " +"available. If multiple values are returned (i.e. a list) then the first " +"value is used." +msgstr "" +"Gli attributi mappati sono copiati dalla risposta SAML ad ogni accesso, se " +"disponibile. Se vengono restituiti valori multipli (cioè una lista) allora " +"viene usato il primo valore." + +#. module: auth_saml +#: model:ir.model.fields,field_description:auth_saml.field_auth_saml_provider__sp_metadata_url +msgid "Metadata URL" +msgstr "URL metadati" + +#. module: auth_saml +#. odoo-python +#: code:addons/auth_saml/controllers/main.py:0 +#, python-format +msgid "Missing parameters" +msgstr "Parametri mancanti" + +#. module: auth_saml +#: model:ir.model.fields,field_description:auth_saml.field_auth_saml_attribute_mapping__field_name +msgid "Odoo Field" +msgstr "Campo Odoo" + +#. module: auth_saml +#: model:ir.model.fields,field_description:auth_saml.field_auth_saml_provider__sp_pem_private +msgid "Odoo Private Key" +msgstr "Chiave privata Odoo" + +#. module: auth_saml +#: model:ir.model.fields,field_description:auth_saml.field_auth_saml_provider__sp_pem_private_filename +msgid "Odoo Private Key File Name" +msgstr "Nome file chiave privata Odoo" + +#. module: auth_saml +#: model:ir.model.fields,field_description:auth_saml.field_auth_saml_provider__sp_pem_public +msgid "Odoo Public Certificate" +msgstr "Certificato pubblico Odoo" + +#. module: auth_saml +#: model:ir.model.fields,field_description:auth_saml.field_auth_saml_provider__sp_pem_public_filename +msgid "Odoo Public Certificate File Name" +msgstr "Nome file certificato pubblico Odoo" + +#. module: auth_saml +#: model_terms:ir.ui.view,arch_db:auth_saml.view_saml_provider_form +msgid "Odoo Settings" +msgstr "Impostazioni Odoo" + +#. module: auth_saml +#: model:ir.model.fields,help:auth_saml.field_auth_saml_provider__autoredirect +msgid "" +"Only the provider with the higher priority will be automatically redirected" +msgstr "" +"Solo il provider con la priorità maggiore verrà inoltrato automaticamente" + +#. module: auth_saml +#: model:ir.model.fields,field_description:auth_saml.field_auth_saml_provider__sp_baseurl +msgid "Override Base URL" +msgstr "Ignora URL base" + +#. module: auth_saml +#: model:ir.model.fields,field_description:auth_saml.field_auth_saml_attribute_mapping__provider_id +msgid "Provider" +msgstr "Provider" + +#. module: auth_saml +#: model:ir.model.fields,field_description:auth_saml.field_auth_saml_provider__name +msgid "Provider Name" +msgstr "Nome provider" + +#. module: auth_saml +#: model:ir.actions.act_window,name:auth_saml.action_saml_provider +#: model_terms:ir.ui.view,arch_db:auth_saml.auth_saml_provider_view_search +msgid "Providers" +msgstr "Provider" + +#. module: auth_saml +#: model_terms:ir.ui.view,arch_db:auth_saml.view_users_form +msgid "SAML" +msgstr "SAML" + +#. module: auth_saml +#: model:ir.model,name:auth_saml.model_auth_saml_request +msgid "SAML Outstanding Requests" +msgstr "Richiesta straordinaria SAML" + +#. module: auth_saml +#: model:ir.model.fields,field_description:auth_saml.field_res_users_saml__saml_provider_id +#: model_terms:ir.ui.view,arch_db:auth_saml.view_saml_provider_form +msgid "SAML Provider" +msgstr "Provider SAML" + +#. module: auth_saml +#: model:ir.model.fields,field_description:auth_saml.field_auth_saml_request__saml_provider_id +msgid "SAML Provider that issued the token" +msgstr "Provider SAML che ha emesso il token" + +#. module: auth_saml +#: model:ir.model.fields,help:auth_saml.field_res_users_saml__saml_uid +msgid "SAML Provider user_id" +msgstr "user_id provider SAML" + +#. module: auth_saml +#: model:ir.ui.menu,name:auth_saml.menu_saml_providers +msgid "SAML Providers" +msgstr "Provider SAML" + +#. module: auth_saml +#: model:ir.model.constraint,message:auth_saml.constraint_res_users_saml_uniq_users_saml_provider_saml_uid +msgid "SAML UID must be unique per provider" +msgstr "UID SAML deve essere univoco per provider" + +#. module: auth_saml +#: model:ir.model.fields,field_description:auth_saml.field_res_users_saml__saml_uid +msgid "SAML User ID" +msgstr "ID utente SAML" + +#. module: auth_saml +#: model:ir.model,name:auth_saml.model_auth_saml_provider +msgid "SAML2 Provider" +msgstr "Provider SAML2" + +#. module: auth_saml +#: model:ir.model,name:auth_saml.model_auth_saml_attribute_mapping +msgid "SAML2 attribute mapping" +msgstr "Mappatura attributo SAML2" + +#. module: auth_saml +#: model:ir.model.fields,field_description:auth_saml.field_res_users__saml_ids +msgid "Saml" +msgstr "SAML" + +#. module: auth_saml +#: model:ir.model.fields,field_description:auth_saml.field_auth_saml_provider__sequence +msgid "Sequence" +msgstr "Sequenza" + +#. module: auth_saml +#: model:ir.model.fields,field_description:auth_saml.field_auth_saml_provider__sign_authenticate_requests +msgid "Sign Authenticate Requests" +msgstr "Firma richieste autenticazione" + +#. module: auth_saml +#: model:ir.model.fields,field_description:auth_saml.field_auth_saml_provider__sign_metadata +msgid "Sign Metadata" +msgstr "Frma metadati" + +#. module: auth_saml +#. odoo-python +#: code:addons/auth_saml/controllers/main.py:0 +#, python-format +msgid "Sign up is not allowed on this database." +msgstr "Non è consentito iscriversi a questo database." + +#. module: auth_saml +#: model:ir.model.fields,field_description:auth_saml.field_auth_saml_provider__sig_alg +msgid "Signature Algorithm" +msgstr "Algoritmo firma" + +#. module: auth_saml +#: model:ir.model,name:auth_saml.model_ir_config_parameter +msgid "System Parameter" +msgstr "Parametro di sistema" + +#. module: auth_saml +#: model_terms:ir.ui.view,arch_db:auth_saml.view_saml_provider_form +msgid "" +"The URL configured for the ACS must exactly match what is sent. If you have " +"odoo responding on multiple URLs you can use this to force it to send a " +"specific address rather than rely on automatically detecting." +msgstr "" +"L'URL configurato per l'ACS deve corrispondere esattamente a quando inviato. " +"Se si ha Odoo che risponde da URL multipli si può utilizzare per forzarlo ad " +"inviare un indirizzo specifico invece che rispondere al rilevamento " +"automatico." + +#. module: auth_saml +#: model:ir.model.fields,help:auth_saml.field_res_users_saml__saml_access_token +msgid "The current SAML token in use" +msgstr "Token SAML attualmente in uso" + +#. module: auth_saml +#. odoo-python +#: code:addons/auth_saml/models/res_users.py:0 +#, python-format +msgid "" +"This database disallows users to have both passwords and SAML IDs. Error for" +" logins %s" +msgstr "" +"Questo database nn consente agli utenti di avere sia password che ID SAML. " +"Errore per accessi %s" + +#. module: auth_saml +#. odoo-python +#: code:addons/auth_saml/controllers/main.py:0 +#, python-format +msgid "Unknown provider" +msgstr "Provider sconosciuto" + +#. module: auth_saml +#: model_terms:ir.ui.view,arch_db:auth_saml.view_saml_provider_form +msgid "" +"Used to sign requests sent to the IDP. You can use openssl to generate a " +"certificate and key." +msgstr "" +"Usato per firmare le richieste inviate all'IDP. Si può utilizzare OpenSSL " +"per generare un certificato e una chiave." + +#. module: auth_saml +#: model:ir.model,name:auth_saml.model_res_users +#: model:ir.model.fields,field_description:auth_saml.field_res_users_saml__user_id +msgid "User" +msgstr "Utente" + +#. module: auth_saml +#: model:ir.model,name:auth_saml.model_res_users_saml +msgid "User to SAML Provider Mapping" +msgstr "Mappatura tra utente e provider SAML" + +#. module: auth_saml +#: model:ir.model.fields,field_description:auth_saml.field_auth_saml_provider__want_assertions_or_response_signed +msgid "Want Assertions Or Response Signed" +msgstr "Richiede conferma o risposta firmate" + +#. module: auth_saml +#: model:ir.model.fields,field_description:auth_saml.field_auth_saml_provider__want_assertions_signed +msgid "Want Assertions Signed" +msgstr "Richiede conferme firmate" + +#. module: auth_saml +#: model:ir.model.fields,field_description:auth_saml.field_auth_saml_provider__want_response_signed +msgid "Want Response Signed" +msgstr "Richiede risposta firmata" + +#. module: auth_saml +#: model:ir.model.fields,help:auth_saml.field_auth_saml_provider__sign_metadata +msgid "Whether metadata should be signed or not" +msgstr "Se i metadata devno essere firmati o meno" + +#. module: auth_saml +#: model:ir.model.fields,help:auth_saml.field_auth_saml_provider__sign_authenticate_requests +msgid "Whether the request should be signed or not" +msgstr "Se la richiesta deve essere firmata o meno" + +#. module: auth_saml +#. odoo-python +#: code:addons/auth_saml/controllers/main.py:0 +#, python-format +msgid "You do not have access to this database. Please contact support." +msgstr "Non si ha accesso a questo database. Contattare il supporto." + +#. module: auth_saml +#: model_terms:ir.ui.view,arch_db:auth_saml.view_saml_provider_form +msgid "Your ACS url will be base_url + /auth_saml/signin" +msgstr "Il suo URL ACS sarà base_url + /auth_saml/signin" + +#. module: auth_saml +#: model_terms:ir.ui.view,arch_db:auth_saml.view_saml_provider_form +msgid "Your provider will give you this XML once configured." +msgstr "Il suo provider fornirà questo XML una volta configurato." diff --git a/auth_saml/models/ir_config_parameter.py b/auth_saml/models/ir_config_parameter.py index ddf9e50a31..37fc39c3bf 100644 --- a/auth_saml/models/ir_config_parameter.py +++ b/auth_saml/models/ir_config_parameter.py @@ -26,3 +26,13 @@ def write(self, vals): if self.filtered(lambda param: param.key == ALLOW_SAML_UID_AND_PASSWORD): self.env["res.users"].allow_saml_and_password_changed() return result + + def unlink(self): + """Redefined to update users when our parameter is deleted.""" + param_saml = self.filtered( + lambda param: param.key == ALLOW_SAML_UID_AND_PASSWORD + ) + result = super().unlink() + if result and param_saml: + self.env["res.users"].allow_saml_and_password_changed() + return result diff --git a/auth_saml/tests/test_pysaml.py b/auth_saml/tests/test_pysaml.py index c05235b747..7549e2546f 100644 --- a/auth_saml/tests/test_pysaml.py +++ b/auth_saml/tests/test_pysaml.py @@ -198,7 +198,7 @@ def test_login_with_saml(self): # User should now be able to log in with the token self.authenticate(user="test@example.com", password=token) - def test_disallow_user_password_when_changing_setting(self): + def test_disallow_user_password_when_changing_ir_config_parameter(self): """Test that disabling users from having both a password and SAML ids remove users password.""" # change the option @@ -336,3 +336,26 @@ def test_redirect_after_login(self): self.base_url() + "/web#action=37&model=ir.module.module&view_type=kanban&menu_id=5", ) + + def test_disallow_user_password_when_changing_settings(self): + """Test that disabling the setting will remove passwords from related users""" + # We activate the settings to allow password login + self.env["res.config.settings"].create( + { + "allow_saml_uid_and_internal_password": True, + } + ).execute() + + # Test the user can login with the password + self.authenticate(user="user@example.com", password="NesTNSte9340D720te>/-A") + + self.env["res.config.settings"].create( + { + "allow_saml_uid_and_internal_password": False, + } + ).execute() + + with self.assertRaises(AccessDenied): + self.authenticate( + user="user@example.com", password="NesTNSte9340D720te>/-A" + ) diff --git a/auth_session_timeout/i18n/it.po b/auth_session_timeout/i18n/it.po index c193ce4ccf..7691d541ec 100644 --- a/auth_session_timeout/i18n/it.po +++ b/auth_session_timeout/i18n/it.po @@ -10,15 +10,15 @@ msgstr "" "Project-Id-Version: Odoo Server 10.0\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2018-01-06 02:24+0000\n" -"PO-Revision-Date: 2023-03-07 19:36+0000\n" -"Last-Translator: Francesco Foresti \n" +"PO-Revision-Date: 2024-01-03 14:33+0000\n" +"Last-Translator: mymage \n" "Language-Team: Italian (https://www.transifex.com/oca/teams/23907/it/)\n" "Language: it\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: \n" "Plural-Forms: nplurals=2; plural=n != 1;\n" -"X-Generator: Weblate 4.14.1\n" +"X-Generator: Weblate 4.17\n" #. module: auth_session_timeout #: model:ir.model,name:auth_session_timeout.model_ir_http @@ -33,7 +33,7 @@ msgstr "Parametro di sistema" #. module: auth_session_timeout #: model:ir.model,name:auth_session_timeout.model_res_users msgid "User" -msgstr "" +msgstr "Utente" #~ msgid "Users" #~ msgstr "Utenti" diff --git a/auth_signup_verify_email/i18n/it.po b/auth_signup_verify_email/i18n/it.po index 691201a879..78f1ba46f5 100644 --- a/auth_signup_verify_email/i18n/it.po +++ b/auth_signup_verify_email/i18n/it.po @@ -9,22 +9,23 @@ msgstr "" "Project-Id-Version: server-tools (9.0)\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2016-06-09 12:31+0000\n" -"PO-Revision-Date: 2016-05-31 14:47+0000\n" -"Last-Translator: OCA Transbot \n" +"PO-Revision-Date: 2024-01-03 14:33+0000\n" +"Last-Translator: mymage \n" "Language-Team: Italian (http://www.transifex.com/oca/OCA-server-tools-9-0/" "language/it/)\n" "Language: it\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: \n" -"Plural-Forms: nplurals=2; plural=(n != 1);\n" +"Plural-Forms: nplurals=2; plural=n != 1;\n" +"X-Generator: Weblate 4.17\n" #. module: auth_signup_verify_email #. odoo-python #: code:addons/auth_signup_verify_email/controllers/main.py:0 #, python-format msgid "Another user is already registered using this email address." -msgstr "" +msgstr "Un altro utente che usa questa e-mail è già registrato." #. module: auth_signup_verify_email #. odoo-python diff --git a/auth_user_case_insensitive/i18n/it.po b/auth_user_case_insensitive/i18n/it.po index 2f7bafd478..58bc2aeb1f 100644 --- a/auth_user_case_insensitive/i18n/it.po +++ b/auth_user_case_insensitive/i18n/it.po @@ -9,36 +9,37 @@ msgstr "" "Project-Id-Version: Odoo Server 10.0\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2017-05-17 21:08+0000\n" -"PO-Revision-Date: 2017-05-17 21:08+0000\n" -"Last-Translator: OCA Transbot , 2017\n" +"PO-Revision-Date: 2024-01-03 14:33+0000\n" +"Last-Translator: mymage \n" "Language-Team: Italian (https://www.transifex.com/oca/teams/23907/it/)\n" "Language: it\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: \n" -"Plural-Forms: nplurals=2; plural=(n != 1);\n" +"Plural-Forms: nplurals=2; plural=n != 1;\n" +"X-Generator: Weblate 4.17\n" #. module: auth_user_case_insensitive #. odoo-python #: code:addons/auth_user_case_insensitive/hooks.py:0 #, python-format msgid "Conflicting user logins exist for `%s`" -msgstr "" +msgstr "Esiste un conflitto di accessi per l'utente '%s'" #. module: auth_user_case_insensitive #: model:ir.model.fields,field_description:auth_user_case_insensitive.field_res_users__login msgid "Login" -msgstr "" +msgstr "Login" #. module: auth_user_case_insensitive #: model:ir.model.fields,help:auth_user_case_insensitive.field_res_users__login msgid "Used to log into the system. Case insensitive." -msgstr "" +msgstr "Utilizzato per l'accesso al sistema. Insensibile a maiuscole/minuscole." #. module: auth_user_case_insensitive #: model:ir.model,name:auth_user_case_insensitive.model_res_users msgid "User" -msgstr "" +msgstr "Utente" #~ msgid "Users" #~ msgstr "Utenti" diff --git a/base_user_show_email/i18n/it.po b/base_user_show_email/i18n/it.po new file mode 100644 index 0000000000..d9c1a7edbc --- /dev/null +++ b/base_user_show_email/i18n/it.po @@ -0,0 +1,28 @@ +# Translation of Odoo Server. +# This file contains the translation of the following modules: +# * base_user_show_email +# +msgid "" +msgstr "" +"Project-Id-Version: Odoo Server 16.0\n" +"Report-Msgid-Bugs-To: \n" +"PO-Revision-Date: 2024-01-03 14:33+0000\n" +"Last-Translator: mymage \n" +"Language-Team: none\n" +"Language: it\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: \n" +"Plural-Forms: nplurals=2; plural=n != 1;\n" +"X-Generator: Weblate 4.17\n" + +#. module: base_user_show_email +#: model_terms:ir.ui.view,arch_db:base_user_show_email.user_email_form +msgid "Email Address" +msgstr "Indirizzo e-mail" + +#. module: base_user_show_email +#: model_terms:ir.ui.view,arch_db:base_user_show_email.login +#: model_terms:ir.ui.view,arch_db:base_user_show_email.user_email_form +msgid "Login" +msgstr "Login" diff --git a/password_security/i18n/it.po b/password_security/i18n/it.po index c8edb3fcad..d636d76d1b 100644 --- a/password_security/i18n/it.po +++ b/password_security/i18n/it.po @@ -10,8 +10,8 @@ msgstr "" "Project-Id-Version: Odoo Server 10.0\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2016-12-23 02:01+0000\n" -"PO-Revision-Date: 2023-10-13 12:44+0000\n" -"Last-Translator: Francesco Foresti \n" +"PO-Revision-Date: 2024-01-04 17:34+0000\n" +"Last-Translator: mymage \n" "Language-Team: Italian (https://www.transifex.com/oca/teams/23907/it/)\n" "Language: it\n" "MIME-Version: 1.0\n" @@ -28,6 +28,8 @@ msgid "" "\n" "* Lowercase letter (at least %s characters)" msgstr "" +"\n" +"* Lettere minuscole (almeno %s caratteri)" #. module: password_security #. odoo-python @@ -37,6 +39,8 @@ msgid "" "\n" "* Numeric digit (at least %s characters)" msgstr "" +"\n" +"* Cifra numerica (almeno %s caratteri)" #. module: password_security #. odoo-python @@ -46,6 +50,8 @@ msgid "" "\n" "* Special character (at least %s characters)" msgstr "" +"\n" +"* Crattere speciale (almeno %s caratteri)" #. module: password_security #. odoo-python @@ -55,6 +61,8 @@ msgid "" "\n" "* Uppercase letter (at least %s characters)" msgstr "" +"\n" +"* Lettere maiuscole (almeno %s caratteri)" #. module: password_security #: model_terms:ir.ui.view,arch_db:password_security.res_config_settings_view_form @@ -63,19 +71,23 @@ msgid "" " Minimum number of characters\n" " " msgstr "" +"\n" +" Numero minimo di caratteri\n" +" " #. module: password_security #: model:ir.model.fields,help:password_security.field_res_company__password_minimum #: model:ir.model.fields,help:password_security.field_res_config_settings__password_minimum msgid "Amount of hours until a user may change password again" msgstr "" +"Numero di ore dopo le quali l'utente può cambiare nuovamente la password" #. module: password_security #. odoo-python #: code:addons/password_security/models/res_users.py:0 #, python-format msgid "Cannot use the most recent %d passwords" -msgstr "" +msgstr "Impossibile usare le %d password più recenti" #. module: password_security #: model:ir.model,name:password_security.model_res_company @@ -85,7 +97,7 @@ msgstr "Aziende" #. module: password_security #: model:ir.model,name:password_security.model_res_config_settings msgid "Config Settings" -msgstr "" +msgstr "Impostazioni configurazione" #. module: password_security #: model:ir.model.fields,field_description:password_security.field_res_users_pass_history__create_uid @@ -111,7 +123,7 @@ msgstr "Giorni" #. module: password_security #: model_terms:ir.ui.view,arch_db:password_security.res_config_settings_view_form msgid "Disallow reuse of" -msgstr "" +msgstr "Impedire riuso di" #. module: password_security #: model:ir.model.fields,help:password_security.field_res_company__password_history @@ -120,6 +132,8 @@ msgid "" "Disallow reuse of this many previous passwords - use negative number for " "infinite, or 0 to disable" msgstr "" +"Impedire il riutilizzo di questa quantità di password precedenti - usare un " +"numero negativo per infinito, o 0 per disabilitare" #. module: password_security #: model:ir.model.fields,field_description:password_security.field_res_users_pass_history__display_name @@ -129,7 +143,7 @@ msgstr "Nome visualizzato" #. module: password_security #: model:ir.model.fields,field_description:password_security.field_res_users_pass_history__password_crypt msgid "Encrypted Password" -msgstr "" +msgstr "Password criptata" #. module: password_security #: model:ir.model.fields,field_description:password_security.field_res_company__password_history @@ -141,7 +155,7 @@ msgstr "Cronologia" #: model:ir.model.fields,help:password_security.field_res_company__password_expiration #: model:ir.model.fields,help:password_security.field_res_config_settings__password_expiration msgid "How many days until passwords expire" -msgstr "" +msgstr "Quanti giorni prima che le password scadano" #. module: password_security #: model:ir.model.fields,field_description:password_security.field_res_users_pass_history__id @@ -166,74 +180,74 @@ msgstr "Ultimo aggiornamento il" #. module: password_security #: model:ir.model.fields,field_description:password_security.field_res_users__password_write_date msgid "Last password update" -msgstr "" +msgstr "Ultimo aggiornamento password" #. module: password_security #: model:ir.model.fields,field_description:password_security.field_res_company__password_lower #: model:ir.model.fields,field_description:password_security.field_res_config_settings__password_lower msgid "Lowercase" -msgstr "" +msgstr "Minuscole" #. module: password_security #: model:ir.model.fields,field_description:password_security.field_res_company__password_minimum #: model:ir.model.fields,field_description:password_security.field_res_config_settings__password_minimum msgid "Minimum Hours" -msgstr "" +msgstr "Ore minime" #. module: password_security #: model_terms:ir.ui.view,arch_db:password_security.res_config_settings_view_form msgid "Minimum number of lowercase characters" -msgstr "" +msgstr "Numero minimo di caratteri minuscoli" #. module: password_security #: model_terms:ir.ui.view,arch_db:password_security.res_config_settings_view_form msgid "Minimum number of numeric characters" -msgstr "" +msgstr "Numero minimo di caratteri numerici" #. module: password_security #: model_terms:ir.ui.view,arch_db:password_security.res_config_settings_view_form msgid "Minimum number of special characters" -msgstr "" +msgstr "Numero minimo di caratteri speciali" #. module: password_security #: model_terms:ir.ui.view,arch_db:password_security.res_config_settings_view_form msgid "Minimum number of uppercase characters" -msgstr "" +msgstr "Numero minimo di caratteri maiuscoli" #. module: password_security #. odoo-python #: code:addons/password_security/models/res_users.py:0 #, python-format msgid "Must contain the following:" -msgstr "" +msgstr "Deve contenere le seguenti:" #. module: password_security #: model:ir.model.fields,field_description:password_security.field_res_company__password_numeric #: model:ir.model.fields,field_description:password_security.field_res_config_settings__password_numeric msgid "Numeric" -msgstr "" +msgstr "Numerici" #. module: password_security #: model:ir.model.fields,field_description:password_security.field_res_users__password_history_ids msgid "Password History" -msgstr "" +msgstr "Storico password" #. module: password_security #: model_terms:ir.ui.view,arch_db:password_security.res_config_settings_view_form msgid "Password Policy" -msgstr "" +msgstr "Politica password" #. module: password_security #: model_terms:ir.ui.view,arch_db:password_security.res_config_settings_view_form msgid "Password expires in" -msgstr "" +msgstr "La password scade in" #. module: password_security #. odoo-python #: code:addons/password_security/models/res_users.py:0 #, python-format msgid "Password must be %d characters or more." -msgstr "" +msgstr "La password deve essere di %d o più caratteri." #. module: password_security #. odoo-python @@ -243,52 +257,54 @@ msgid "" "Passwords can only be reset every %d hour(s). Please contact an " "administrator for assistance." msgstr "" +"Le password possono essere reimpostate solamente ogni %d ore. Contattare un " +"amministratore per assistenza." #. module: password_security #: model:ir.model.fields,help:password_security.field_res_company__password_lower #: model:ir.model.fields,help:password_security.field_res_config_settings__password_lower msgid "Require number of lowercase letters" -msgstr "" +msgstr "Richiede un numero di lettere minuscole" #. module: password_security #: model:ir.model.fields,help:password_security.field_res_company__password_numeric #: model:ir.model.fields,help:password_security.field_res_config_settings__password_numeric msgid "Require number of numeric digits" -msgstr "" +msgstr "Richiede un numero di cifre numeriche" #. module: password_security #: model:ir.model.fields,help:password_security.field_res_company__password_special #: model:ir.model.fields,help:password_security.field_res_config_settings__password_special msgid "Require number of unique special characters" -msgstr "" +msgstr "Richiede un numero di caratteri speciali unici" #. module: password_security #: model:ir.model.fields,help:password_security.field_res_company__password_upper #: model:ir.model.fields,help:password_security.field_res_config_settings__password_upper msgid "Require number of uppercase letters" -msgstr "" +msgstr "Richiede un numero di lettere maiuscole" #. module: password_security #: model:ir.model,name:password_security.model_res_users_pass_history msgid "Res Users Password History" -msgstr "" +msgstr "Storico password utente res" #. module: password_security #: model:ir.model.fields,field_description:password_security.field_res_company__password_special #: model:ir.model.fields,field_description:password_security.field_res_config_settings__password_special msgid "Special" -msgstr "" +msgstr "Speciali" #. module: password_security #: model:ir.model.fields,field_description:password_security.field_res_company__password_upper #: model:ir.model.fields,field_description:password_security.field_res_config_settings__password_upper msgid "Uppercase" -msgstr "" +msgstr "Maiuscole" #. module: password_security #: model_terms:ir.ui.view,arch_db:password_security.res_config_settings_view_form msgid "Use negative number for infinite, or 0 to disable" -msgstr "" +msgstr "Usare un numero negativo per infinito o 0 per disabilitare" #. module: password_security #: model:ir.model,name:password_security.model_res_users @@ -299,22 +315,22 @@ msgstr "Utente" #. module: password_security #: model_terms:ir.ui.view,arch_db:password_security.res_config_settings_view_form msgid "User can change password in" -msgstr "" +msgstr "L'utente puà modificare la password in" #. module: password_security #: model_terms:ir.ui.view,arch_db:password_security.res_config_settings_view_form msgid "days." -msgstr "" +msgstr "giorni." #. module: password_security #: model_terms:ir.ui.view,arch_db:password_security.res_config_settings_view_form msgid "hours again." -msgstr "" +msgstr "ore nuovamente." #. module: password_security #: model_terms:ir.ui.view,arch_db:password_security.res_config_settings_view_form msgid "previous passwords." -msgstr "" +msgstr "password precedenti." #~ msgid "Characters" #~ msgstr "Caratteri" diff --git a/setup/_metapackage/VERSION.txt b/setup/_metapackage/VERSION.txt index 2a1abaf1c9..ef64b9af1c 100644 --- a/setup/_metapackage/VERSION.txt +++ b/setup/_metapackage/VERSION.txt @@ -1 +1 @@ -16.0.20231130.0 \ No newline at end of file +16.0.20240222.0 \ No newline at end of file diff --git a/setup/_metapackage/setup.py b/setup/_metapackage/setup.py index ddd7973cf8..e0acedec55 100644 --- a/setup/_metapackage/setup.py +++ b/setup/_metapackage/setup.py @@ -15,6 +15,7 @@ 'odoo-addon-auth_jwt_demo>=16.0dev,<16.1dev', 'odoo-addon-auth_jwt_server_env>=16.0dev,<16.1dev', 'odoo-addon-auth_ldaps>=16.0dev,<16.1dev', + 'odoo-addon-auth_oauth_ropc>=16.0dev,<16.1dev', 'odoo-addon-auth_oidc>=16.0dev,<16.1dev', 'odoo-addon-auth_oidc_environment>=16.0dev,<16.1dev', 'odoo-addon-auth_saml>=16.0dev,<16.1dev', @@ -27,6 +28,7 @@ 'odoo-addon-users_ldap_groups>=16.0dev,<16.1dev', 'odoo-addon-users_ldap_mail>=16.0dev,<16.1dev', 'odoo-addon-users_ldap_populate>=16.0dev,<16.1dev', + 'odoo-addon-vault>=16.0dev,<16.1dev', ], classifiers=[ 'Programming Language :: Python', diff --git a/setup/auth_oauth_ropc/odoo/addons/auth_oauth_ropc b/setup/auth_oauth_ropc/odoo/addons/auth_oauth_ropc new file mode 120000 index 0000000000..d5d7c3d385 --- /dev/null +++ b/setup/auth_oauth_ropc/odoo/addons/auth_oauth_ropc @@ -0,0 +1 @@ +../../../../auth_oauth_ropc \ No newline at end of file diff --git a/setup/auth_oauth_ropc/setup.py b/setup/auth_oauth_ropc/setup.py new file mode 100644 index 0000000000..28c57bb640 --- /dev/null +++ b/setup/auth_oauth_ropc/setup.py @@ -0,0 +1,6 @@ +import setuptools + +setuptools.setup( + setup_requires=['setuptools-odoo'], + odoo_addon=True, +) diff --git a/setup/vault/odoo/addons/vault b/setup/vault/odoo/addons/vault new file mode 120000 index 0000000000..4ead31e201 --- /dev/null +++ b/setup/vault/odoo/addons/vault @@ -0,0 +1 @@ +../../../../vault \ No newline at end of file diff --git a/setup/vault/setup.py b/setup/vault/setup.py new file mode 100644 index 0000000000..28c57bb640 --- /dev/null +++ b/setup/vault/setup.py @@ -0,0 +1,6 @@ +import setuptools + +setuptools.setup( + setup_requires=['setuptools-odoo'], + odoo_addon=True, +) diff --git a/user_log_view/i18n/it.po b/user_log_view/i18n/it.po new file mode 100644 index 0000000000..4719f62cbe --- /dev/null +++ b/user_log_view/i18n/it.po @@ -0,0 +1,38 @@ +# Translation of Odoo Server. +# This file contains the translation of the following modules: +# * user_log_view +# +msgid "" +msgstr "" +"Project-Id-Version: Odoo Server 16.0\n" +"Report-Msgid-Bugs-To: \n" +"PO-Revision-Date: 2024-01-03 14:33+0000\n" +"Last-Translator: mymage \n" +"Language-Team: none\n" +"Language: it\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: \n" +"Plural-Forms: nplurals=2; plural=n != 1;\n" +"X-Generator: Weblate 4.17\n" + +#. module: user_log_view +#: model:ir.actions.act_window,name:user_log_view.action_user_log +#: model_terms:ir.ui.view,arch_db:user_log_view.res_users_view_form +msgid "Authentication logs" +msgstr "Registri autenticazione" + +#. module: user_log_view +#: model_terms:ir.ui.view,arch_db:user_log_view.res_users_log_view_search +msgid "Date" +msgstr "Data" + +#. module: user_log_view +#: model_terms:ir.ui.view,arch_db:user_log_view.res_users_log_view_search +msgid "Group By" +msgstr "Raggruppa per" + +#. module: user_log_view +#: model_terms:ir.ui.view,arch_db:user_log_view.res_users_log_view_search +msgid "Test Search" +msgstr "Testa ricerca" diff --git a/users_ldap_groups/i18n/it.po b/users_ldap_groups/i18n/it.po index cec08af062..897502b939 100644 --- a/users_ldap_groups/i18n/it.po +++ b/users_ldap_groups/i18n/it.po @@ -6,15 +6,15 @@ msgid "" msgstr "" "Project-Id-Version: Odoo Server 14.0\n" "Report-Msgid-Bugs-To: \n" -"PO-Revision-Date: 2023-01-18 13:45+0000\n" -"Last-Translator: Francesco Foresti \n" +"PO-Revision-Date: 2024-01-03 14:33+0000\n" +"Last-Translator: mymage \n" "Language-Team: none\n" "Language: it\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: \n" "Plural-Forms: nplurals=2; plural=n != 1;\n" -"X-Generator: Weblate 4.14.1\n" +"X-Generator: Weblate 4.17\n" #. module: users_ldap_groups #: model:ir.model,name:users_ldap_groups.model_res_company_ldap @@ -163,7 +163,7 @@ msgstr "" #. module: users_ldap_groups #: model:ir.model,name:users_ldap_groups.model_res_users msgid "User" -msgstr "" +msgstr "Utente" #. module: users_ldap_groups #: model:ir.model.fields,field_description:users_ldap_groups.field_res_company_ldap_group_mapping__value diff --git a/users_ldap_mail/i18n/it.po b/users_ldap_mail/i18n/it.po new file mode 100644 index 0000000000..6f42d6e7e4 --- /dev/null +++ b/users_ldap_mail/i18n/it.po @@ -0,0 +1,46 @@ +# Translation of Odoo Server. +# This file contains the translation of the following modules: +# * users_ldap_mail +# +msgid "" +msgstr "" +"Project-Id-Version: Odoo Server 16.0\n" +"Report-Msgid-Bugs-To: \n" +"PO-Revision-Date: 2024-01-03 14:33+0000\n" +"Last-Translator: mymage \n" +"Language-Team: none\n" +"Language: it\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: \n" +"Plural-Forms: nplurals=2; plural=n != 1;\n" +"X-Generator: Weblate 4.17\n" + +#. module: users_ldap_mail +#: model:ir.model.fields,help:users_ldap_mail.field_res_company_ldap__name_attribute +msgid "" +"By default 'cn' is used. For ActiveDirectory you might use 'displayName' " +"instead." +msgstr "" +"In modo predefinito viene usato \"cn\". Per ActiveDirectory potrebbe invece " +"essere utilizzato \"displayName\"." + +#. module: users_ldap_mail +#: model:ir.model,name:users_ldap_mail.model_res_company_ldap +msgid "Company LDAP configuration" +msgstr "Configurazione LDAP azienda" + +#. module: users_ldap_mail +#: model:ir.model.fields,field_description:users_ldap_mail.field_res_company_ldap__mail_attribute +msgid "E-mail attribute" +msgstr "Attributo email" + +#. module: users_ldap_mail +#: model:ir.model.fields,help:users_ldap_mail.field_res_company_ldap__mail_attribute +msgid "LDAP attribute to use to retrieve e-mail address." +msgstr "Attributo LDAP da utilizzare per il recupero degli indirizzi e-mail." + +#. module: users_ldap_mail +#: model:ir.model.fields,field_description:users_ldap_mail.field_res_company_ldap__name_attribute +msgid "Name Attribute" +msgstr "Attributo del nome" diff --git a/users_ldap_populate/i18n/it.po b/users_ldap_populate/i18n/it.po index 5d143ada18..4d8f3c8ef9 100644 --- a/users_ldap_populate/i18n/it.po +++ b/users_ldap_populate/i18n/it.po @@ -10,7 +10,7 @@ msgstr "" "Project-Id-Version: Odoo Server 10.0\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2020-06-26 20:39+0000\n" -"PO-Revision-Date: 2023-04-17 16:35+0000\n" +"PO-Revision-Date: 2024-01-04 10:34+0000\n" "Last-Translator: mymage \n" "Language-Team: Italian (https://www.transifex.com/oca/teams/23907/it/)\n" "Language: it\n" @@ -18,17 +18,17 @@ msgstr "" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: \n" "Plural-Forms: nplurals=2; plural=n != 1;\n" -"X-Generator: Weblate 4.14.1\n" +"X-Generator: Weblate 4.17\n" #. module: users_ldap_populate #: model_terms:ir.ui.view,arch_db:users_ldap_populate.populate_wizard_view msgid "Add populate button to ldap view" -msgstr "" +msgstr "Aggiungi pulsante compilazione alla vista LDAP" #. module: users_ldap_populate #: model:ir.model,name:users_ldap_populate.model_res_company_ldap msgid "Company LDAP configuration" -msgstr "" +msgstr "Configurazione LDAP azienda" #. module: users_ldap_populate #: model:ir.model.fields,field_description:users_ldap_populate.field_res_company_ldap_populate_wizard__create_uid @@ -43,7 +43,7 @@ msgstr "Creato il" #. module: users_ldap_populate #: model:ir.model.fields,field_description:users_ldap_populate.field_res_company_ldap__deactivate_unknown_users msgid "Deactivate unknown users" -msgstr "" +msgstr "Disattiva utenti sconosciuti" #. module: users_ldap_populate #: model:ir.model.fields,field_description:users_ldap_populate.field_res_company_ldap_populate_wizard__display_name @@ -58,7 +58,7 @@ msgstr "ID" #. module: users_ldap_populate #: model:ir.model.fields,field_description:users_ldap_populate.field_res_company_ldap_populate_wizard__ldap_id msgid "LDAP Configuration" -msgstr "" +msgstr "Configurazione LDAP" #. module: users_ldap_populate #: model:ir.model.fields,field_description:users_ldap_populate.field_res_company_ldap_populate_wizard____last_update @@ -79,6 +79,8 @@ msgstr "Ultimo aggiornamento il" #: model:ir.model.fields,help:users_ldap_populate.field_res_company_ldap__no_deactivate_user_ids msgid "List users who never should be deactivated by the deactivation wizard" msgstr "" +"Elenco utenti che non devono essere disattivati dalla procedura guidata di " +"disattivazione" #. module: users_ldap_populate #: model:ir.model.fields,field_description:users_ldap_populate.field_res_company_ldap_populate_wizard__name @@ -92,48 +94,50 @@ msgstr "Nome" msgid "" "No login attribute found: Could not extract login attribute from filter %s" msgstr "" +"Nessun attributo di accesso trovato: impossibile estrarre attributo di " +"accesso dal filtro %s" #. module: users_ldap_populate #: model:ir.model.fields,field_description:users_ldap_populate.field_res_company_ldap_populate_wizard__users_created msgid "Number of users created" -msgstr "" +msgstr "Numero di utenti creati" #. module: users_ldap_populate #: model:ir.model.fields,field_description:users_ldap_populate.field_res_company_ldap_populate_wizard__users_deactivated msgid "Number of users deactivated" -msgstr "" +msgstr "Numero di utenti disattivati" #. module: users_ldap_populate #: model_terms:ir.ui.view,arch_db:users_ldap_populate.populate_wizard_view msgid "OK" -msgstr "" +msgstr "OK" #. module: users_ldap_populate #: model_terms:ir.ui.view,arch_db:users_ldap_populate.company_form_view msgid "Populate" -msgstr "" +msgstr "Compila" #. module: users_ldap_populate #: model_terms:ir.ui.view,arch_db:users_ldap_populate.company_form_view msgid "Populate user database" -msgstr "" +msgstr "Compila database utente" #. module: users_ldap_populate #: model:ir.model,name:users_ldap_populate.model_res_company_ldap_populate_wizard msgid "Populate users from LDAP" -msgstr "" +msgstr "Compila utenti da LDAP" #. module: users_ldap_populate #. odoo-python #: code:addons/users_ldap_populate/models/users_ldap.py:0 #, python-format msgid "Unable to process user with login %s" -msgstr "" +msgstr "Impossibile elaborare utente con accesso %s" #. module: users_ldap_populate #: model:ir.model.fields,field_description:users_ldap_populate.field_res_company_ldap__no_deactivate_user_ids msgid "Users never to deactivate" -msgstr "" +msgstr "Utenti da non disattivare" #~ msgid "res.company.ldap" #~ msgstr "res.company.ldap" diff --git a/vault/README.rst b/vault/README.rst new file mode 100644 index 0000000000..e58d1e5c71 --- /dev/null +++ b/vault/README.rst @@ -0,0 +1,100 @@ +===== +Vault +===== + +.. + !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + !! This file is generated by oca-gen-addon-readme !! + !! changes will be overwritten. !! + !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + !! source digest: sha256:12d8822aab453f4a6f00d8151ec6cdef4c66ec07c08d88e6528c85f3526d0818 + !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + +.. |badge1| image:: https://img.shields.io/badge/maturity-Beta-yellow.png + :target: https://odoo-community.org/page/development-status + :alt: Beta +.. |badge2| image:: https://img.shields.io/badge/licence-AGPL--3-blue.png + :target: http://www.gnu.org/licenses/agpl-3.0-standalone.html + :alt: License: AGPL-3 +.. |badge3| image:: https://img.shields.io/badge/github-OCA%2Fserver--auth-lightgray.png?logo=github + :target: https://github.com/OCA/server-auth/tree/16.0/vault + :alt: OCA/server-auth +.. |badge4| image:: https://img.shields.io/badge/weblate-Translate%20me-F47D42.png + :target: https://translation.odoo-community.org/projects/server-auth-16-0/server-auth-16-0-vault + :alt: Translate me on Weblate +.. |badge5| image:: https://img.shields.io/badge/runboat-Try%20me-875A7B.png + :target: https://runboat.odoo-community.org/builds?repo=OCA/server-auth&target_branch=16.0 + :alt: Try me on Runboat + +|badge1| |badge2| |badge3| |badge4| |badge5| + +This module implements a vault for secrets and files using end-to-end-encryption. The encryption and decryption happens in the browser using a vault specific shared master key. The master keys are encrypted using asymmetrically. For this the user has to enter a second password on the first login or if he needs to access data in a vault. The asymmetric keys are stored for a certain time in the browser storage. + +The server can never access the secrets with the information available. Only people registered in the vault can decrypt or encrypt values in a vault. The meta data isn't encrypted to be able to search/filter for entries more easily. + +This modules requires a secure context for the browser to work properly and therefore HTTPS support is required. + +The `vault-recovery `_ project focuses on disaster recovery in case of an incident to recover secrets from old database backups or old exports. + +**Table of contents** + +.. contents:: + :local: + +Known issues / Roadmap +====================== + +* Field and file history for restoration + +* Import improvement + + * Support challenge-response/FIDO2 + * Support for argon2 and kdbx v4 + +* When changing an entry from one vault to another existing vault, the values added on + this entry cannot be accessed, so the field vault is going to be readonly when it + is defined. + + If you want to move entries between vaults you can use the export -> import option. + +* HTTPS or localhost (secure browser context) is required for the client side encryption + +Bug Tracker +=========== + +Bugs are tracked on `GitHub Issues `_. +In case of trouble, please check there if your issue has already been reported. +If you spotted it first, help us to smash it by providing a detailed and welcomed +`feedback `_. + +Do not contact contributors directly about support or help with technical issues. + +Credits +======= + +Authors +~~~~~~~ + +* initOS GmbH + +Contributors +~~~~~~~~~~~~ + +* Florian Kantelberg + +Maintainers +~~~~~~~~~~~ + +This module is maintained by the OCA. + +.. image:: https://odoo-community.org/logo.png + :alt: Odoo Community Association + :target: https://odoo-community.org + +OCA, or the Odoo Community Association, is a nonprofit organization whose +mission is to support the collaborative development of Odoo features and +promote its widespread use. + +This module is part of the `OCA/server-auth `_ project on GitHub. + +You are welcome to contribute. To learn how please visit https://odoo-community.org/page/Contribute. diff --git a/vault/TECHNICAL.rst b/vault/TECHNICAL.rst new file mode 100644 index 0000000000..4a5456445d --- /dev/null +++ b/vault/TECHNICAL.rst @@ -0,0 +1,143 @@ +:: + + ┌───────┐ ┏━━━━━━━━━━━━━┓ ╔═══════════╗ + │ input │ ┃ unencrypted ┃ ║ encrypted ║ + └───────┘ ┗━━━━━━━━━━━━━┛ ╚═══════════╝ + +Vault +===== + +Each vault stores entries with enrypted fields and files in a tree like structure. The access is controlled per vault. Every added user can read the secrets of a vault. Otherwise the users can receive permission to share the vault with other users, to write secrets in the vault, or to delete entries of the vault. The databases stores the public and password protected private key of each user. The password used for the private key is derived from a password entered by the user and should be different than the password used for the login. Keep in mind that the meta information like field name or file names aren't encrypted. + +Shared-key encryption +===================== + +To be able to securely share sensitive data between all users a shared-key encryption is used. All users share a common secret for each vault. This secret is encrypted by the public key of each user to grant access to the user by using the private key to restore the secret. + +Encryption of master key +------------------------ + +:: + + . ┏━━━━━━━━━━━━┓ + ┃ Master key ┃ + ┗━━━━━━━━━━━━┛ + ┏━━━━━━━━━━━━━━━━━┓ ┃ + ┃ User ┃ ▼ + ┃ ┃ ┏━━━━━━━━━┓ + ┃ ┏━━━━━━━━━━━━━┓ ┃ ┃ encrypt ┃ ╔════════════╗ + ┃ ┃ Public key ┃━━━━▶┃ (RSA) ┃━━━━━▶║ Master key ║ + ┃ ┗━━━━━━━━━━━━━┛ ┃ ┗━━━━━━━━━┛ ╚════════════╝ + ┃ ╔═════════════╗ ┃ + ┃ ║ Private key ║ ┃ + ┃ ╚═════════════╝ ┃ + ┗━━━━━━━━━━━━━━━━━┛ + +Decryption of master key +------------------------ + +:: + + . ┌──────────┐ ┏━━━━━━━━━━┓ + │ Password │━━━━▶┃ derive ┃ + └──────────┘ ┃ (PBKDF2) ┃ + ┗━━━━━━━━━━┛ + ┃ + ┏━━━━━━━━━━━━━━━━━┓ ▼ ╔════════════╗ + ┃ User ┃ ┏━━━━━━━━━━┓ ║ Master key ║ + ┃ ┃ ┃ Password ┃ ╚════════════╝ + ┃ ┏━━━━━━━━━━━━━┓ ┃ ┗━━━━━━━━━━┛ ┃ + ┃ ┃ Public key ┃ ┃ ┃ ▼ + ┃ ┗━━━━━━━━━━━━━┛ ┃ ▼ ┏━━━━━━━━━┓ + ┃ ╔═════════════╗ ┃ ┏━━━━━━━━┓ ┏━━━━━━━━━━━━━┓ ┃ decrypt ┃ ┏━━━━━━━━━━━━┓ + ┃ ║ Private key ║━━━━━┃ unlock ┃━━▶┃ Private key ┃━━━▶┃ (RSA) ┃━━━━━▶┃ Master key ┃ + ┃ ╚═════════════╝ ┃ ┗━━━━━━━━┛ ┗━━━━━━━━━━━━━┛ ┗━━━━━━━━━┛ ┗━━━━━━━━━━━━┛ + ┗━━━━━━━━━━━━━━━━━┛ + +Symmetric encryption of the data +================================ + +The symmetric cipher AES is used with the common master key to encrypt/decrypt the secrets of the vaults. The encryption parameter and encrypted data is stored in the database while everything else happens in the browser. + +Encryption of data +------------------ + +:: + + . ┏━━━━━━━━━━━━┓ + ┃ Master key ┃ + ┗━━━━━━━━━━━━┛ + ┃ ┏━━━━━━━━━━━━━━━━━━┓ + ▼ ┃ Database ┃ + ┏━━━━━━━━━┓ ┃ ┃ + ┏━━━━━━━━━━━━┓ ┃ encrypt ┃ ┃╔════════════════╗┃ + ┃ Plain text ┃━━▶┃ (AES) ┃━━━▶║ Encrypted data ║┃ + ┗━━━━━━━━━━━━┛ ┗━━━━━━━━━┛ ┃╚════════════════╝┃ + ┃ ┃┏━━━━━━━━━━━━━━━━┓┃ + ┗━━━━━━━━▶┃ Parameters ┃┃ + ┃┗━━━━━━━━━━━━━━━━┛┃ + ┗━━━━━━━━━━━━━━━━━━┛ + +Decryption of data +------------------ + +:: + + . ┏━━━━━━━━━━━━┓ + ┃ Master key ┃ + ┗━━━━━━━━━━━━┛ + ┏━━━━━━━━━━━━━━━━━━┓ ┃ + ┃ Database ┃ ▼ + ┃ ┃ ┏━━━━━━━━━┓ + ┃╔════════════════╗┃ ┃ decrypt ┃ ┏━━━━━━━━━━━━┓ + ┃║ Encrypted data ║━━━▶┃ (AES) ┃━━▶┃ Plain text ┃ + ┃╚════════════════╝┃ ┗━━━━━━━━━┛ ┗━━━━━━━━━━━━┛ + ┃┏━━━━━━━━━━━━━━━━┓┃ ▲ + ┃┃ Parameters ┃━━━━━━━━┛ + ┃┗━━━━━━━━━━━━━━━━┛┃ + ┗━━━━━━━━━━━━━━━━━━┛ + +Inbox +===== + +This allows an user to receive encrypted secrets by external or internal Odoo users. External users have to use either the owner specific inbox link from his preferences or the link of an already created inbox. The value is symmetrically encrypted. The key for the encryption is wrapped with the public key of the user of the inbox to grant the user the access to the key. Internal users can directly send a secret from a vault entry to another user who has enabled this feature. If a direct link is used the access counter and expiration time can block an overwrite. + +Encryption of inbox +------------------- + +:: + + . ┏━━━━━━━━━━━━┓ + ┃ Plain data ┃ + ┗━━━━━━━━━━━━┛ + ┏━━━━━━━━━━━━━━━━━┓ ┃ + ┃ User ┃ ▼ + ┃ ┃ ┏━━━━━━━━━┓ + ┃ ┏━━━━━━━━━━━━━┓ ┃ ┃ encrypt ┃ ╔════════════════╗ + ┃ ┃ Public key ┃━━━━▶┃ (RSA) ┃━━━━━▶║ Encrypted data ║ + ┃ ┗━━━━━━━━━━━━━┛ ┃ ┗━━━━━━━━━┛ ╚════════════════╝ + ┃ ╔═════════════╗ ┃ + ┃ ║ Private key ║ ┃ + ┃ ╚═════════════╝ ┃ + ┗━━━━━━━━━━━━━━━━━┛ + +Decryption of inbox +------------------- + +:: + + . ┌──────────┐ ┏━━━━━━━━━━┓ + │ Password │━━━━▶┃ derive ┃ + └──────────┘ ┃ (PBKDF2) ┃ + ┗━━━━━━━━━━┛ + ┃ + ┏━━━━━━━━━━━━━━━━━┓ ▼ ╔════════════════╗ + ┃ User ┃ ┏━━━━━━━━━━┓ ║ Encrypted data ║ + ┃ ┃ ┃ Password ┃ ╚════════════════╝ + ┃ ┏━━━━━━━━━━━━━┓ ┃ ┗━━━━━━━━━━┛ ┃ + ┃ ┃ Public key ┃ ┃ ┃ ▼ + ┃ ┗━━━━━━━━━━━━━┛ ┃ ▼ ┏━━━━━━━━━┓ + ┃ ╔═════════════╗ ┃ ┏━━━━━━━━┓ ┏━━━━━━━━━━━━━┓ ┃ decrypt ┃ ┏━━━━━━━━━━━━┓ + ┃ ║ Private key ║━━━━━┃ unlock ┃━━▶┃ Private key ┃━━━▶┃ (RSA) ┃━━━━━▶┃ Plain data ┃ + ┃ ╚═════════════╝ ┃ ┗━━━━━━━━┛ ┗━━━━━━━━━━━━━┛ ┗━━━━━━━━━┛ ┗━━━━━━━━━━━━┛ + ┗━━━━━━━━━━━━━━━━━┛ diff --git a/vault/__init__.py b/vault/__init__.py new file mode 100644 index 0000000000..843ac90a95 --- /dev/null +++ b/vault/__init__.py @@ -0,0 +1,4 @@ +# © 2021 Florian Kantelberg - initOS GmbH +# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). + +from . import controllers, models, wizards diff --git a/vault/__manifest__.py b/vault/__manifest__.py new file mode 100644 index 0000000000..e3cfda3f64 --- /dev/null +++ b/vault/__manifest__.py @@ -0,0 +1,50 @@ +# © 2021 Florian Kantelberg - initOS GmbH +# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). + +{ + "name": "Vault", + "summary": "Password vault integration in Odoo", + "license": "AGPL-3", + "version": "16.0.1.0.0", + "website": "https://github.com/OCA/server-auth", + "application": True, + "author": "initOS GmbH, Odoo Community Association (OCA)", + "category": "Vault", + "depends": ["base_setup", "web"], + "data": [ + "security/ir.model.access.csv", + "security/ir_rule.xml", + "security/vault_security.xml", + "views/res_config_settings_views.xml", + "views/res_users_views.xml", + "views/vault_entry_views.xml", + "views/vault_field_views.xml", + "views/vault_file_views.xml", + "views/vault_log_views.xml", + "views/vault_inbox_views.xml", + "views/vault_right_views.xml", + "views/vault_views.xml", + "views/menuitems.xml", + "views/templates.xml", + "wizards/vault_export_wizard.xml", + "wizards/vault_import_wizard.xml", + "wizards/vault_send_wizard.xml", + "wizards/vault_store_wizard.xml", + ], + "assets": { + "vault.assets_frontend": [ + "vault/static/src/common/*.js", + "vault/static/src/frontend/*.js", + ], + "web.assets_backend": [ + "vault/static/lib/**/*.min.js", + "vault/static/src/**/*.xml", + "vault/static/src/common/*.js", + "vault/static/src/backend/*.scss", + "vault/static/src/backend/**/*.js", + ], + "web.tests_assets": [ + "vault/static/tests/**/*.js", + ], + }, +} diff --git a/vault/controllers/__init__.py b/vault/controllers/__init__.py new file mode 100644 index 0000000000..aabfa83edd --- /dev/null +++ b/vault/controllers/__init__.py @@ -0,0 +1,4 @@ +# © 2021 Florian Kantelberg - initOS GmbH +# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). + +from . import main diff --git a/vault/controllers/main.py b/vault/controllers/main.py new file mode 100644 index 0000000000..1ca361dda3 --- /dev/null +++ b/vault/controllers/main.py @@ -0,0 +1,152 @@ +# © 2021 Florian Kantelberg - initOS GmbH +# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). + +import logging + +from odoo import _, http +from odoo.exceptions import AccessDenied +from odoo.http import request + +_logger = logging.getLogger(__name__) + + +class Controller(http.Controller): + @http.route("/vault/inbox/", type="http", auth="public") + def vault_inbox(self, token): + ctx = {"disable_footer": True, "token": token} + # Find the right token + inbox = request.env["vault.inbox"].sudo().find_inbox(token) + user = request.env["res.users"].sudo().find_user_of_inbox(token) + if len(inbox) == 1 and inbox.accesses > 0: + ctx.update({"name": inbox.name, "public": inbox.user_id.active_key.public}) + elif len(inbox) == 0 and len(user) == 1: + ctx["public"] = user.active_key.public + + # A valid token would mean we found a public key + if not ctx.get("public"): + ctx["error"] = _("Invalid token") + return request.render("vault.inbox", ctx) + + # Just render if GET method + if request.httprequest.method != "POST": + return request.render("vault.inbox", ctx) + + # Check the param + name = request.params.get("name") + secret = request.params.get("encrypted") + secret_file = request.params.get("encrypted_file") + filename = request.params.get("filename") + iv = request.params.get("iv") + key = request.params.get("key") + if not name: + ctx["error"] = _("Please specify a name") + return request.render("vault.inbox", ctx) + + if not secret and not secret_file: + ctx["error"] = _("No secret found") + return request.render("vault.inbox", ctx) + + if secret_file and not filename: + ctx["error"] = _("Missing filename") + return request.render("vault.inbox", ctx) + + if not iv or not key: + ctx["error"] = _("Something went wrong with the encryption") + return request.render("vault.inbox", ctx) + + try: + inbox.store_in_inbox( + name, + secret, + secret_file, + iv, + key, + user, + filename, + ip=request.httprequest.remote_addr, + ) + except Exception as e: + _logger.exception(e) + ctx["error"] = _( + "An error occured. Please contact the user or administrator" + ) + return request.render("vault.inbox", ctx) + + ctx["message"] = _("Successfully stored") + return request.render("vault.inbox", ctx) + + @http.route("/vault/public", type="json") + def vault_public(self, user_id): + """Get the public key of a specific user""" + user = request.env["res.users"].sudo().browse(user_id).exists() + if not user or not user.keys: + return {} + + return {"public_key": user.active_key.public} + + @http.route("/vault/inbox/get", auth="user", type="json") + def vault_get_inbox(self): + inboxes = request.env.user.inbox_ids + return {inbox.token: inbox.key for inbox in inboxes} + + @http.route("/vault/inbox/store", auth="user", type="json") + def vault_store_inbox(self, keys): + if not isinstance(keys, dict): + return + + for inbox in request.env.user.inbox_ids: + key = keys.get(inbox.token) + + if isinstance(key, str): + inbox.key = key + + @http.route("/vault/keys/store", auth="user", type="json") + def vault_store_keys(self, **kwargs): + """Store the key pair for the current user""" + return request.env["res.users.key"].store(**kwargs) + + @http.route("/vault/keys/get", auth="user", type="json") + def vault_get_keys(self): + """Get the currently active key pair""" + return request.env.user.get_vault_keys() + + @http.route("/vault/rights/get", auth="user", type="json") + def vault_get_right_keys(self): + """Get the master keys from the vault.right records""" + rights = request.env.user.vault_right_ids + return {right.vault_id.uuid: right.key for right in rights} + + @http.route("/vault/rights/store", auth="user", type="json") + def vault_store_right_keys(self, keys): + """Store the master keys to the specific vault.right records""" + if not isinstance(keys, dict): + return + + for right in request.env.user.vault_right_ids: + master_key = keys.get(right.vault_id.uuid) + + if isinstance(master_key, str): + right.sudo().key = master_key + + @http.route("/vault/replace", auth="user", type="json") + def vault_replace(self, data): + """Replace the master keys and values within a single transaction""" + if not isinstance(data, list): + return + + vault = request.env["vault"].with_context(vault_skip_log=True) + for changes in data: + record = vault.env[changes["model"]].browse(changes["id"]) + if not record.vault_id.allowed_write: + raise AccessDenied() + + vault |= record.vault_id + if record._name in ("vault.field", "vault.file"): + record.write({k: v for k, v in changes.items() if k in ["iv", "value"]}) + elif record._name == "vault.right": + record.write({k: v for k, v in changes.items() if k in ["key"]}) + + for v in vault: + v._log_entry("Replaced the keys", "info") + + vault.sudo().write({"reencrypt_required": False}) diff --git a/vault/i18n/es.po b/vault/i18n/es.po new file mode 100644 index 0000000000..3358c5bda5 --- /dev/null +++ b/vault/i18n/es.po @@ -0,0 +1,1505 @@ +# Translation of Odoo Server. +# This file contains the translation of the following modules: +# * vault +# +msgid "" +msgstr "" +"Project-Id-Version: Odoo Server 14.0\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2022-06-06 06:57+0000\n" +"PO-Revision-Date: 2023-10-31 20:36+0000\n" +"Last-Translator: Ivorra78 \n" +"Language-Team: \n" +"Language: es\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=2; plural=n != 1;\n" +"X-Generator: Weblate 4.17\n" + +#. module: vault +#. odoo-python +#: code:addons/vault/models/vault_entry.py:0 +#, python-format +msgid "%(action)s entry %(name)s by %(user)s" +msgstr "%(action)s entrada %(name)s por %(user)s" + +#. module: vault +#. odoo-javascript +#: code:addons/vault/static/src/backend/controller.esm.js:0 +#, python-format +msgid "%s '%s' of entry '%s'" +msgstr "%s '%s' del registro '%s'" + +#. module: vault +#. odoo-python +#: code:addons/vault/models/vault_entry.py:0 +#, python-format +msgid "%s (copy)" +msgstr "%s (copia)" + +#. module: vault +#. odoo-javascript +#: code:addons/vault/static/src/backend/controller.esm.js:0 +#, python-format +msgid "" +"A secure browser context is required. Please switch to https or contact your " +"administrator" +msgstr "" + +#. module: vault +#. odoo-javascript +#: code:addons/vault/static/src/backend/templates.xml:0 +#, python-format +msgid "A-Z" +msgstr "A-Z" + +#. module: vault +#. odoo-python +#: code:addons/vault/models/abstract_vault_field.py:0 +#: model:ir.model,name:vault.model_vault_abstract_field +#, python-format +msgid "Abstract model to implement basic fields for encryption" +msgstr "Modelo abstracto para implementar los campos básicos de encriptación" + +#. module: vault +#. odoo-python +#: code:addons/vault/models/abstract_vault.py:0 +#: model:ir.model,name:vault.model_vault_abstract +#, python-format +msgid "Abstract model to implement general access rights" +msgstr "Modelo abstracto para aplicar los derechos de acceso generales" + +#. module: vault +#: model:ir.model.fields,field_description:vault.field_vault_inbox__accesses +msgid "Access counter" +msgstr "Contador de acceso" + +#. module: vault +#: model:ir.model.fields,field_description:vault.field_res_users__active_key +msgid "Active Key" +msgstr "Clave activa" + +#. module: vault +#: model:ir.actions.act_window,name:vault.action_vault_entry +#: model:ir.ui.menu,name:vault.menu_vault_entry +msgid "All Entries" +msgstr "Todos los registros" + +#. module: vault +#: model_terms:ir.ui.view,arch_db:vault.res_config_settings_view_form +msgid "Allow all users to export vaults accessible to them" +msgstr "Permitir que todos los usuarios exporten bóvedas accesibles para ellos" + +#. module: vault +#: model_terms:ir.ui.view,arch_db:vault.res_config_settings_view_form +msgid "Allow all users to import vaults accessible to them" +msgstr "Permitir que todos los usuarios importen bóvedas accesibles para ellos" + +#. module: vault +#: model_terms:ir.ui.view,arch_db:vault.res_config_settings_view_form +msgid "Allow the usage to share secrets with external users" +msgstr "Permitir el uso para compartir secretos con usuarios externos" + +#. module: vault +#: model:ir.model.fields,help:vault.field_vault_right__perm_create +msgid "Allow to create in the vault" +msgstr "Permitir crear en el vault" + +#. module: vault +#: model:ir.model.fields,help:vault.field_vault_right__perm_delete +msgid "Allow to delete a vault" +msgstr "Permitir borrar un vault" + +#. module: vault +#: model:res.groups,name:vault.group_vault_export +msgid "Allow to export vaults" +msgstr "Permitir exportar bóvedas" + +#. module: vault +#: model:res.groups,name:vault.group_vault_import +msgid "Allow to import vaults" +msgstr "Permitir importar bóvedas" + +#. module: vault +#: model:ir.model.fields,help:vault.field_vault_right__perm_share +msgid "Allow to share a vault with new users" +msgstr "Permitir compartir un vault con nuevos usuarios" + +#. module: vault +#: model:ir.model.fields,help:vault.field_vault_right__perm_write +msgid "Allow to write to the vault" +msgstr "Permitir escribir en un vault" + +#. module: vault +#: model:ir.model.fields,field_description:vault.field_vault__allowed_create +#: model:ir.model.fields,field_description:vault.field_vault_abstract_field__allowed_create +#: model:ir.model.fields,field_description:vault.field_vault_entry__allowed_create +#: model:ir.model.fields,field_description:vault.field_vault_field__allowed_create +#: model:ir.model.fields,field_description:vault.field_vault_file__allowed_create +#: model:ir.model.fields,field_description:vault.field_vault_right__allowed_create +msgid "Allowed Create" +msgstr "Permitido crear" + +#. module: vault +#: model:ir.model.fields,field_description:vault.field_vault__allowed_delete +#: model:ir.model.fields,field_description:vault.field_vault_abstract_field__allowed_delete +#: model:ir.model.fields,field_description:vault.field_vault_entry__allowed_delete +#: model:ir.model.fields,field_description:vault.field_vault_field__allowed_delete +#: model:ir.model.fields,field_description:vault.field_vault_file__allowed_delete +#: model:ir.model.fields,field_description:vault.field_vault_right__allowed_delete +msgid "Allowed Delete" +msgstr "Permitido borrar" + +#. module: vault +#: model:ir.model.fields,field_description:vault.field_vault__allowed_read +#: model:ir.model.fields,field_description:vault.field_vault_abstract_field__allowed_read +#: model:ir.model.fields,field_description:vault.field_vault_entry__allowed_read +#: model:ir.model.fields,field_description:vault.field_vault_field__allowed_read +#: model:ir.model.fields,field_description:vault.field_vault_file__allowed_read +#: model:ir.model.fields,field_description:vault.field_vault_right__allowed_read +msgid "Allowed Read" +msgstr "Permitido leer" + +#. module: vault +#: model:ir.model.fields,field_description:vault.field_vault__allowed_share +#: model:ir.model.fields,field_description:vault.field_vault_abstract_field__allowed_share +#: model:ir.model.fields,field_description:vault.field_vault_entry__allowed_share +#: model:ir.model.fields,field_description:vault.field_vault_field__allowed_share +#: model:ir.model.fields,field_description:vault.field_vault_file__allowed_share +#: model:ir.model.fields,field_description:vault.field_vault_right__allowed_share +msgid "Allowed Share" +msgstr "Permitido añadir usuarios" + +#. module: vault +#: model:ir.model.fields,field_description:vault.field_vault__allowed_write +#: model:ir.model.fields,field_description:vault.field_vault_abstract_field__allowed_write +#: model:ir.model.fields,field_description:vault.field_vault_entry__allowed_write +#: model:ir.model.fields,field_description:vault.field_vault_field__allowed_write +#: model:ir.model.fields,field_description:vault.field_vault_file__allowed_write +#: model:ir.model.fields,field_description:vault.field_vault_right__allowed_write +msgid "Allowed Write" +msgstr "Permitido escribir" + +#. module: vault +#. odoo-python +#: code:addons/vault/controllers/main.py:0 +#, python-format +msgid "An error occured. Please contact the user or administrator" +msgstr "" +"Se ha producido un error. Por favor, póngase en contacto con el usuario o el " +"administrador" + +#. module: vault +#: model_terms:ir.ui.view,arch_db:vault.view_vault_right_overview_search +msgid "By user" +msgstr "Por usuario" + +#. module: vault +#: model_terms:ir.ui.view,arch_db:vault.view_vault_right_overview_search +msgid "By vault" +msgstr "Por vault" + +#. module: vault +#. odoo-javascript +#: code:addons/vault/static/src/common/utils.esm.js:0 +#: model_terms:ir.ui.view,arch_db:vault.view_users_form_keys_modif +#: model_terms:ir.ui.view,arch_db:vault.view_vault_import_wizard +#: model_terms:ir.ui.view,arch_db:vault.view_vault_send_wizard +#: model_terms:ir.ui.view,arch_db:vault.view_vault_store_wizard +#, python-format +msgid "Cancel" +msgstr "Cancelar" + +#. module: vault +#. odoo-javascript +#: code:addons/vault/static/src/common/utils.esm.js:0 +#, python-format +msgid "Cancelled" +msgstr "Cancelado" + +#. module: vault +#. odoo-javascript +#: code:addons/vault/static/src/backend/templates.xml:0 +#, python-format +msgid "Characters:" +msgstr "Caracteres:" + +#. module: vault +#: model:ir.model.fields,field_description:vault.field_vault_entry__child_ids +msgid "Child" +msgstr "Hijo" + +#. module: vault +#: model_terms:ir.ui.view,arch_db:vault.view_vault_entry_form +msgid "Childs" +msgstr "Hijos" + +#. module: vault +#: model_terms:ir.ui.view,arch_db:vault.view_vault_export_wizard +msgid "Close" +msgstr "Cerrar" + +#. module: vault +#: model:ir.model.fields,field_description:vault.field_vault_abstract_field__entry_name +#: model:ir.model.fields,field_description:vault.field_vault_entry__complete_name +#: model:ir.model.fields,field_description:vault.field_vault_field__entry_name +#: model:ir.model.fields,field_description:vault.field_vault_file__entry_name +msgid "Complete Name" +msgstr "Nombre completo" + +#. module: vault +#: model:ir.model,name:vault.model_res_config_settings +msgid "Config Settings" +msgstr "Opciones de Configuración" + +#. module: vault +#. odoo-javascript +#: code:addons/vault/static/src/backend/templates.xml:0 +#, python-format +msgid "Confirm your password:" +msgstr "Confirma tu contraseña:" + +#. module: vault +#: model_terms:ir.ui.view,arch_db:vault.view_vault_entry_form +msgid "Content" +msgstr "Contenido" + +#. module: vault +#. odoo-javascript +#: code:addons/vault/static/src/backend/fields/templates.xml:0 +#, python-format +msgid "Copy to clipboard" +msgstr "Copiar al portapapeles" + +#. module: vault +#: model:ir.model.fields,field_description:vault.field_vault_right__perm_create +msgid "Create" +msgstr "Crear" + +#. module: vault +#: model:ir.model.fields,field_description:vault.field_res_users_key__create_uid +#: model:ir.model.fields,field_description:vault.field_vault__create_uid +#: model:ir.model.fields,field_description:vault.field_vault_entry__create_uid +#: model:ir.model.fields,field_description:vault.field_vault_export_wizard__create_uid +#: model:ir.model.fields,field_description:vault.field_vault_field__create_uid +#: model:ir.model.fields,field_description:vault.field_vault_file__create_uid +#: model:ir.model.fields,field_description:vault.field_vault_import_wizard__create_uid +#: model:ir.model.fields,field_description:vault.field_vault_import_wizard_path__create_uid +#: model:ir.model.fields,field_description:vault.field_vault_inbox__create_uid +#: model:ir.model.fields,field_description:vault.field_vault_inbox_log__create_uid +#: model:ir.model.fields,field_description:vault.field_vault_log__create_uid +#: model:ir.model.fields,field_description:vault.field_vault_right__create_uid +#: model:ir.model.fields,field_description:vault.field_vault_send_wizard__create_uid +#: model:ir.model.fields,field_description:vault.field_vault_store_wizard__create_uid +#: model:ir.model.fields,field_description:vault.field_vault_tag__create_uid +msgid "Created by" +msgstr "Creado por" + +#. module: vault +#. odoo-python +#: code:addons/vault/models/vault_inbox.py:0 +#, python-format +msgid "Created by %(name)s via %(ip)s" +msgstr "Creado por %(name)s a través de %(ip)s" + +#. module: vault +#. odoo-python +#: code:addons/vault/wizards/vault_send_wizard.py:0 +#, python-format +msgid "Created by %s" +msgstr "Creado por %s" + +#. module: vault +#: model:ir.model.fields,field_description:vault.field_res_users_key__create_date +#: model:ir.model.fields,field_description:vault.field_vault__create_date +#: model:ir.model.fields,field_description:vault.field_vault_entry__create_date +#: model:ir.model.fields,field_description:vault.field_vault_export_wizard__create_date +#: model:ir.model.fields,field_description:vault.field_vault_field__create_date +#: model:ir.model.fields,field_description:vault.field_vault_file__create_date +#: model:ir.model.fields,field_description:vault.field_vault_import_wizard__create_date +#: model:ir.model.fields,field_description:vault.field_vault_import_wizard_path__create_date +#: model:ir.model.fields,field_description:vault.field_vault_inbox__create_date +#: model:ir.model.fields,field_description:vault.field_vault_inbox_log__create_date +#: model:ir.model.fields,field_description:vault.field_vault_log__create_date +#: model:ir.model.fields,field_description:vault.field_vault_right__create_date +#: model:ir.model.fields,field_description:vault.field_vault_send_wizard__create_date +#: model:ir.model.fields,field_description:vault.field_vault_store_wizard__create_date +#: model:ir.model.fields,field_description:vault.field_vault_tag__create_date +msgid "Created on" +msgstr "Creado el" + +#. module: vault +#: model:ir.model.fields,field_description:vault.field_vault_import_wizard__crypted_content +msgid "Crypted Content" +msgstr "Contenido encriptado" + +#. module: vault +#: model:ir.model.fields,field_description:vault.field_res_users_key__current +msgid "Current" +msgstr "Actual" + +#. module: vault +#: model_terms:ir.ui.view,arch_db:vault.view_vault_import_wizard +msgid "Custom JSON format .json" +msgstr "Formato JSON personalizado .json" + +#. module: vault +#: model:ir.model.fields,field_description:vault.field_vault_import_wizard__content +msgid "Database" +msgstr "Base de datos" + +#. module: vault +#: model:ir.model.fields,field_description:vault.field_vault_right__perm_delete +msgid "Delete" +msgstr "Borrar" + +#. module: vault +#: model:ir.model.fields,field_description:vault.field_res_users_key__display_name +#: model:ir.model.fields,field_description:vault.field_vault__display_name +#: model:ir.model.fields,field_description:vault.field_vault_entry__display_name +#: model:ir.model.fields,field_description:vault.field_vault_export_wizard__display_name +#: model:ir.model.fields,field_description:vault.field_vault_field__display_name +#: model:ir.model.fields,field_description:vault.field_vault_file__display_name +#: model:ir.model.fields,field_description:vault.field_vault_import_wizard__display_name +#: model:ir.model.fields,field_description:vault.field_vault_import_wizard_path__display_name +#: model:ir.model.fields,field_description:vault.field_vault_inbox__display_name +#: model:ir.model.fields,field_description:vault.field_vault_inbox_log__display_name +#: model:ir.model.fields,field_description:vault.field_vault_log__display_name +#: model:ir.model.fields,field_description:vault.field_vault_right__display_name +#: model:ir.model.fields,field_description:vault.field_vault_send_wizard__display_name +#: model:ir.model.fields,field_description:vault.field_vault_store_wizard__display_name +#: model:ir.model.fields,field_description:vault.field_vault_tag__display_name +msgid "Display Name" +msgstr "Nombre a mostrar" + +#. module: vault +#. odoo-javascript +#: code:addons/vault/static/src/backend/controller.esm.js:0 +#, python-format +msgid "Do you really want to create a new key pair and set it active?" +msgstr "¿Realmente quiere crear un nuevo par de claves y activarlo?" + +#. module: vault +#: model:ir.model.fields,field_description:vault.field_vault_export_wizard__content +msgid "Download" +msgstr "Descargar" + +#. module: vault +#. odoo-javascript +#: code:addons/vault/static/src/common/utils.esm.js:0 +#, python-format +msgid "Enter" +msgstr "Ingrese a" + +#. module: vault +#. odoo-javascript +#: code:addons/vault/static/src/backend/templates.xml:0 +#, python-format +msgid "Enter your password:" +msgstr "Ingrese su contraseña:" + +#. module: vault +#: model:ir.actions.act_window,name:vault.action_open_entries +#: model:ir.model.fields,field_description:vault.field_vault__entry_ids +#: model:ir.model.fields,field_description:vault.field_vault_export_wizard__entry_id +#: model_terms:ir.ui.view,arch_db:vault.view_vault_entry_search +#: model_terms:ir.ui.view,arch_db:vault.view_vault_form +msgid "Entries" +msgstr "Registros" + +#. module: vault +#: model:ir.model.fields,field_description:vault.field_vault_abstract_field__entry_id +#: model:ir.model.fields,field_description:vault.field_vault_field__entry_id +#: model:ir.model.fields,field_description:vault.field_vault_file__entry_id +#: model:ir.model.fields,field_description:vault.field_vault_log__entry_id +#: model:ir.model.fields,field_description:vault.field_vault_store_wizard__entry_id +msgid "Entry" +msgstr "Registro" + +#. module: vault +#. odoo-python +#: code:addons/vault/models/vault_entry.py:0 +#: model:ir.model,name:vault.model_vault_entry +#, python-format +msgid "Entry inside a vault" +msgstr "Entrar al interior de un vault" + +#. module: vault +#. odoo-python +#: code:addons/vault/models/vault_log.py:0 +#, python-format +msgid "Error" +msgstr "Error" + +#. module: vault +#: model:ir.model.fields,field_description:vault.field_vault_inbox__expiration +msgid "Expiration" +msgstr "Expiración" + +#. module: vault +#: model:ir.model.fields,field_description:vault.field_vault_entry__expired +#: model_terms:ir.ui.view,arch_db:vault.view_vault_entry_search +msgid "Expired" +msgstr "Expirado" + +#. module: vault +#: model:ir.model.fields,field_description:vault.field_vault_entry__expire_date +msgid "Expires on" +msgstr "Expira en" + +#. module: vault +#: model:ir.model.fields,field_description:vault.field_res_config_settings__group_vault_export +msgid "Export Vaults" +msgstr "Exportar bóvedas" + +#. module: vault +#. odoo-python +#: code:addons/vault/models/vault.py:0 +#: code:addons/vault/models/vault_entry.py:0 +#: model_terms:ir.ui.view,arch_db:vault.view_vault_entry_form +#: model_terms:ir.ui.view,arch_db:vault.view_vault_form +#, python-format +msgid "Export to file" +msgstr "Exportar a fichero" + +#. module: vault +#. odoo-python +#: code:addons/vault/wizards/vault_export_wizard.py:0 +#: model:ir.model,name:vault.model_vault_export_wizard +#, python-format +msgid "Export wizard for vaults" +msgstr "Asistente de exportación para vaults" + +#. module: vault +#. odoo-javascript +#: code:addons/vault/static/src/backend/vault.esm.js:0 +#, python-format +msgid "Failed to export keys to object store" +msgstr "Fallo en la exportación de claves al almacén de objetos" + +#. module: vault +#. odoo-javascript +#: code:addons/vault/static/src/backend/vault.esm.js:0 +#, python-format +msgid "Failed to export the keys to the database" +msgstr "Fallo en la exportación de claves a la base de datos" + +#. module: vault +#. odoo-javascript +#: code:addons/vault/static/src/backend/vault.esm.js:0 +#, python-format +msgid "Failed to import keys from database" +msgstr "Fallo en la importación de claves desde la base de datos" + +#. module: vault +#. odoo-python +#: code:addons/vault/models/vault_field.py:0 +#: model:ir.model,name:vault.model_vault_field +#, python-format +msgid "Field of a vault" +msgstr "Campo de un vault" + +#. module: vault +#: model:ir.model.fields,field_description:vault.field_vault__field_ids +#: model:ir.model.fields,field_description:vault.field_vault_entry__field_ids +msgid "Fields" +msgstr "Campos" + +#. module: vault +#. odoo-python +#: code:addons/vault/models/vault_file.py:0 +#: model:ir.model,name:vault.model_vault_file +#, python-format +msgid "File of a vault" +msgstr "Fichero de un vault" + +#. module: vault +#: model_terms:ir.ui.view,arch_db:vault.inbox +msgid "File to share:" +msgstr "Fichero a compartir:" + +#. module: vault +#: model:ir.model.fields,field_description:vault.field_vault_inbox__filename +#: model:ir.model.fields,field_description:vault.field_vault_send_wizard__filename +msgid "Filename" +msgstr "Nombre del fichero" + +#. module: vault +#: model:ir.model.fields,field_description:vault.field_vault__file_ids +#: model:ir.model.fields,field_description:vault.field_vault_entry__file_ids +msgid "Files" +msgstr "Ficheros" + +#. module: vault +#: model:ir.model.fields,field_description:vault.field_res_users_key__fingerprint +msgid "Fingerprint" +msgstr "Huella digital" + +#. module: vault +#. odoo-javascript +#: code:addons/vault/static/src/backend/fields/templates.xml:0 +#, python-format +msgid "Generate" +msgstr "Generar" + +#. module: vault +#. odoo-javascript +#: code:addons/vault/static/src/backend/templates.xml:0 +#, python-format +msgid "Generate a new secret:" +msgstr "Generar nuevo secreto:" + +#. module: vault +#: model_terms:ir.ui.view,arch_db:vault.view_vault_right_overview_search +msgid "Grouped" +msgstr "Agrupado" + +#. module: vault +#. odoo-javascript +#: code:addons/vault/static/src/backend/fields/templates.xml:0 +#, python-format +msgid "Hide" +msgstr "Ocultar" + +#. module: vault +#: model:ir.model.fields,field_description:vault.field_res_users_key__id +#: model:ir.model.fields,field_description:vault.field_vault__id +#: model:ir.model.fields,field_description:vault.field_vault_entry__id +#: model:ir.model.fields,field_description:vault.field_vault_export_wizard__id +#: model:ir.model.fields,field_description:vault.field_vault_field__id +#: model:ir.model.fields,field_description:vault.field_vault_file__id +#: model:ir.model.fields,field_description:vault.field_vault_import_wizard__id +#: model:ir.model.fields,field_description:vault.field_vault_import_wizard_path__id +#: model:ir.model.fields,field_description:vault.field_vault_inbox__id +#: model:ir.model.fields,field_description:vault.field_vault_inbox_log__id +#: model:ir.model.fields,field_description:vault.field_vault_log__id +#: model:ir.model.fields,field_description:vault.field_vault_right__id +#: model:ir.model.fields,field_description:vault.field_vault_send_wizard__id +#: model:ir.model.fields,field_description:vault.field_vault_store_wizard__id +#: model:ir.model.fields,field_description:vault.field_vault_tag__id +msgid "ID" +msgstr "ID" + +#. module: vault +#: model:ir.model.fields,help:vault.field_vault_inbox__expiration +msgid "If expired the inbox can't be written using the link" +msgstr "" +"Si ha caducado, la bandeja de entrada no puede escribirse utilizando el " +"enlace" + +#. module: vault +#: model:ir.model.fields,help:vault.field_vault_inbox__accesses +msgid "If this is 0 the inbox can't be written using the link" +msgstr "" +"Si esto es 0 la bandeja de entrada no puede ser escrita usando el enlace" + +#. module: vault +#: model_terms:ir.ui.view,arch_db:vault.view_vault_import_wizard +msgid "Import" +msgstr "Importar" + +#. module: vault +#: model:ir.model.fields,field_description:vault.field_res_config_settings__group_vault_import +msgid "Import Vaults" +msgstr "Importar bóvedas" + +#. module: vault +#. odoo-python +#: code:addons/vault/models/vault.py:0 +#: code:addons/vault/models/vault_entry.py:0 +#: model_terms:ir.ui.view,arch_db:vault.view_vault_entry_form +#: model_terms:ir.ui.view,arch_db:vault.view_vault_form +#, python-format +msgid "Import from file" +msgstr "Importar desde archivo" + +#. module: vault +#. odoo-python +#: code:addons/vault/wizards/vault_import_wizard.py:0 +#: model:ir.model,name:vault.model_vault_import_wizard +#, python-format +msgid "Import wizard for vaults" +msgstr "Asistente de importación para vaults" + +#. module: vault +#. odoo-python +#: code:addons/vault/wizards/vault_import_wizard.py:0 +#: model:ir.model,name:vault.model_vault_import_wizard_path +#, python-format +msgid "Import wizard path for vaults" +msgstr "Ruta del asistente de importación para vaults" + +#. module: vault +#: model:ir.actions.act_window,name:vault.action_vault_inbox +#: model:ir.model.fields,field_description:vault.field_res_users__inbox_ids +#: model:ir.model.fields,field_description:vault.field_vault_inbox_log__inbox_id +#: model:ir.ui.menu,name:vault.menu_vault_inbox +msgid "Inbox" +msgstr "Bandeja de entrada" + +#. module: vault +#: model:ir.model.fields,field_description:vault.field_res_users__inbox_enabled +msgid "Inbox Enabled" +msgstr "Bandeja de entrada habilitada" + +#. module: vault +#: model:ir.model.fields,field_description:vault.field_res_users__inbox_link +#: model:ir.model.fields,field_description:vault.field_vault_inbox__inbox_link +msgid "Inbox Link" +msgstr "Enlace de la bandeja de entrada" + +#. module: vault +#: model:ir.model.fields,field_description:vault.field_res_users__inbox_token +msgid "Inbox Token" +msgstr "Token bandeja de entrada" + +#. module: vault +#: model:ir.model.fields,field_description:vault.field_vault_export_wizard__include_childs +msgid "Include Childs" +msgstr "Incluir hijos" + +#. module: vault +#. odoo-python +#: code:addons/vault/models/vault_log.py:0 +#, python-format +msgid "Information" +msgstr "Información" + +#. module: vault +#. odoo-python +#: code:addons/vault/wizards/vault_import_wizard.py:0 +#, python-format +msgid "Invalid file to import from" +msgstr "Archivo inválido para importar" + +#. module: vault +#. odoo-python +#: code:addons/vault/models/res_users_key.py:0 +#, python-format +msgid "Invalid parameter" +msgstr "Parámetro no válido" + +#. module: vault +#. odoo-python +#: code:addons/vault/controllers/main.py:0 +#, python-format +msgid "Invalid token" +msgstr "Token inválido" + +#. module: vault +#: model_terms:ir.ui.view,arch_db:vault.view_users_form_keys_modif +msgid "Invalidate private key" +msgstr "Invalidar clave privada" + +#. module: vault +#: model:ir.model.fields,field_description:vault.field_res_users_key__iterations +msgid "Iterations" +msgstr "Iteraciones" + +#. module: vault +#: model:ir.model.fields,field_description:vault.field_res_users_key__iv +#: model:ir.model.fields,field_description:vault.field_vault_abstract_field__iv +#: model:ir.model.fields,field_description:vault.field_vault_field__iv +#: model:ir.model.fields,field_description:vault.field_vault_file__iv +#: model:ir.model.fields,field_description:vault.field_vault_inbox__iv +#: model:ir.model.fields,field_description:vault.field_vault_send_wizard__iv +#: model:ir.model.fields,field_description:vault.field_vault_store_wizard__iv +msgid "Iv" +msgstr "Iv" + +#. module: vault +#: model_terms:ir.ui.view,arch_db:vault.view_vault_import_wizard +msgid "Keepass Database .kdbx" +msgstr "Base de datos keepass .kdbx" + +#. module: vault +#: model:ir.model.fields,field_description:vault.field_vault_inbox__key +#: model:ir.model.fields,field_description:vault.field_vault_right__key +#: model:ir.model.fields,field_description:vault.field_vault_send_wizard__key +#: model:ir.model.fields,field_description:vault.field_vault_store_wizard__key +msgid "Key" +msgstr "Clave" + +#. module: vault +#. odoo-javascript +#: code:addons/vault/static/src/backend/user_menu.esm.js:0 +#, python-format +msgid "Key Management" +msgstr "Gestión de claves" + +#. module: vault +#: model:ir.model.fields,field_description:vault.field_vault_send_wizard__key_user +msgid "Key User" +msgstr "Clave de usuario" + +#. module: vault +#. odoo-javascript +#: code:addons/vault/static/src/backend/templates.xml:0 +#, python-format +msgid "Keyfile:" +msgstr "Archivo de llaves:" + +#. module: vault +#: model:ir.model.fields,field_description:vault.field_res_users__keys +msgid "Keys" +msgstr "Claves" + +#. module: vault +#: model:ir.model.fields,field_description:vault.field_res_users_key____last_update +#: model:ir.model.fields,field_description:vault.field_vault____last_update +#: model:ir.model.fields,field_description:vault.field_vault_entry____last_update +#: model:ir.model.fields,field_description:vault.field_vault_export_wizard____last_update +#: model:ir.model.fields,field_description:vault.field_vault_field____last_update +#: model:ir.model.fields,field_description:vault.field_vault_file____last_update +#: model:ir.model.fields,field_description:vault.field_vault_import_wizard____last_update +#: model:ir.model.fields,field_description:vault.field_vault_import_wizard_path____last_update +#: model:ir.model.fields,field_description:vault.field_vault_inbox____last_update +#: model:ir.model.fields,field_description:vault.field_vault_inbox_log____last_update +#: model:ir.model.fields,field_description:vault.field_vault_log____last_update +#: model:ir.model.fields,field_description:vault.field_vault_right____last_update +#: model:ir.model.fields,field_description:vault.field_vault_send_wizard____last_update +#: model:ir.model.fields,field_description:vault.field_vault_store_wizard____last_update +#: model:ir.model.fields,field_description:vault.field_vault_tag____last_update +msgid "Last Modified on" +msgstr "Última modificación el" + +#. module: vault +#: model:ir.model.fields,field_description:vault.field_res_users_key__write_uid +#: model:ir.model.fields,field_description:vault.field_vault__write_uid +#: model:ir.model.fields,field_description:vault.field_vault_entry__write_uid +#: model:ir.model.fields,field_description:vault.field_vault_export_wizard__write_uid +#: model:ir.model.fields,field_description:vault.field_vault_field__write_uid +#: model:ir.model.fields,field_description:vault.field_vault_file__write_uid +#: model:ir.model.fields,field_description:vault.field_vault_import_wizard__write_uid +#: model:ir.model.fields,field_description:vault.field_vault_import_wizard_path__write_uid +#: model:ir.model.fields,field_description:vault.field_vault_inbox__write_uid +#: model:ir.model.fields,field_description:vault.field_vault_inbox_log__write_uid +#: model:ir.model.fields,field_description:vault.field_vault_log__write_uid +#: model:ir.model.fields,field_description:vault.field_vault_right__write_uid +#: model:ir.model.fields,field_description:vault.field_vault_send_wizard__write_uid +#: model:ir.model.fields,field_description:vault.field_vault_store_wizard__write_uid +#: model:ir.model.fields,field_description:vault.field_vault_tag__write_uid +msgid "Last Updated by" +msgstr "Última modificación por" + +#. module: vault +#: model:ir.model.fields,field_description:vault.field_res_users_key__write_date +#: model:ir.model.fields,field_description:vault.field_vault__write_date +#: model:ir.model.fields,field_description:vault.field_vault_entry__write_date +#: model:ir.model.fields,field_description:vault.field_vault_export_wizard__write_date +#: model:ir.model.fields,field_description:vault.field_vault_field__write_date +#: model:ir.model.fields,field_description:vault.field_vault_file__write_date +#: model:ir.model.fields,field_description:vault.field_vault_import_wizard__write_date +#: model:ir.model.fields,field_description:vault.field_vault_import_wizard_path__write_date +#: model:ir.model.fields,field_description:vault.field_vault_inbox__write_date +#: model:ir.model.fields,field_description:vault.field_vault_inbox_log__write_date +#: model:ir.model.fields,field_description:vault.field_vault_log__write_date +#: model:ir.model.fields,field_description:vault.field_vault_right__write_date +#: model:ir.model.fields,field_description:vault.field_vault_send_wizard__write_date +#: model:ir.model.fields,field_description:vault.field_vault_store_wizard__write_date +#: model:ir.model.fields,field_description:vault.field_vault_tag__write_date +msgid "Last Updated on" +msgstr "Última actualización en" + +#. module: vault +#. odoo-javascript +#: code:addons/vault/static/src/backend/templates.xml:0 +#, python-format +msgid "Length:" +msgstr "Longitud:" + +#. module: vault +#: model:ir.model.fields,field_description:vault.field_vault__log_ids +#: model:ir.model.fields,field_description:vault.field_vault_entry__log_ids +#: model:ir.model.fields,field_description:vault.field_vault_inbox__log_ids +#: model_terms:ir.ui.view,arch_db:vault.view_vault_entry_form +#: model_terms:ir.ui.view,arch_db:vault.view_vault_form +msgid "Log" +msgstr "Registro" + +#. module: vault +#. odoo-python +#: code:addons/vault/models/vault_log.py:0 +#: model:ir.model,name:vault.model_vault_log +#, python-format +msgid "Log entry of a vault" +msgstr "Registro de entrada de un vault" + +#. module: vault +#: model:ir.actions.act_window,name:vault.action_res_users_keys +msgid "Manage my keys" +msgstr "Gestionar mis claves" + +#. module: vault +#: model:ir.model.fields,field_description:vault.field_vault__master_key +#: model:ir.model.fields,field_description:vault.field_vault_abstract_field__master_key +#: model:ir.model.fields,field_description:vault.field_vault_export_wizard__master_key +#: model:ir.model.fields,field_description:vault.field_vault_field__master_key +#: model:ir.model.fields,field_description:vault.field_vault_file__master_key +#: model:ir.model.fields,field_description:vault.field_vault_import_wizard__master_key +#: model:ir.model.fields,field_description:vault.field_vault_right__master_key +#: model:ir.model.fields,field_description:vault.field_vault_store_wizard__master_key +msgid "Master Key" +msgstr "Clave maestra" + +#. module: vault +#: model:ir.model.fields,field_description:vault.field_vault_log__message +msgid "Message" +msgstr "Mensaje" + +#. module: vault +#. odoo-python +#: code:addons/vault/controllers/main.py:0 +#, python-format +msgid "Missing filename" +msgstr "Falta el nombre del fichero" + +#. module: vault +#. odoo-javascript +#: code:addons/vault/static/src/common/utils.esm.js:0 +#, python-format +msgid "Missing password" +msgstr "Falta la contraseña" + +#. module: vault +#: model:ir.model.fields,field_description:vault.field_vault_store_wizard__model +msgid "Model" +msgstr "Modelo" + +#. module: vault +#: model:ir.model.fields,field_description:vault.field_res_config_settings__module_vault_share +msgid "Module Vault Share" +msgstr "Módulo Vault Share" + +#. module: vault +#: model:ir.model.fields,field_description:vault.field_vault__name +#: model:ir.model.fields,field_description:vault.field_vault_abstract_field__name +#: model:ir.model.fields,field_description:vault.field_vault_entry__name +#: model:ir.model.fields,field_description:vault.field_vault_export_wizard__name +#: model:ir.model.fields,field_description:vault.field_vault_field__name +#: model:ir.model.fields,field_description:vault.field_vault_file__name +#: model:ir.model.fields,field_description:vault.field_vault_import_wizard__name +#: model:ir.model.fields,field_description:vault.field_vault_import_wizard_path__name +#: model:ir.model.fields,field_description:vault.field_vault_inbox__name +#: model:ir.model.fields,field_description:vault.field_vault_inbox_log__name +#: model:ir.model.fields,field_description:vault.field_vault_send_wizard__name +#: model:ir.model.fields,field_description:vault.field_vault_store_wizard__name +#: model:ir.model.fields,field_description:vault.field_vault_tag__name +msgid "Name" +msgstr "Nombre" + +#. module: vault +#: model_terms:ir.ui.view,arch_db:vault.inbox +msgid "Name of your secret:" +msgstr "Nombre de tu secreto:" + +#. module: vault +#. odoo-python +#: code:addons/vault/wizards/vault_send_wizard.py:0 +#, python-format +msgid "Neither a secret nor file was given" +msgstr "" + +#. module: vault +#: model_terms:ir.ui.view,arch_db:vault.view_users_form_keys_modif +msgid "New inbox link" +msgstr "Nuevo enlace de la bandeja de entrada" + +#. module: vault +#: model_terms:ir.ui.view,arch_db:vault.view_users_form_keys_modif +msgid "New private key" +msgstr "Nueva clave privada" + +#. module: vault +#. odoo-python +#: code:addons/vault/controllers/main.py:0 +#, python-format +msgid "No secret found" +msgstr "No se ha encontrado ningún secreto" + +#. module: vault +#. odoo-python +#: code:addons/vault/models/vault_inbox.py:0 +#: code:addons/vault/wizards/vault_send_wizard.py:0 +#: model:ir.model.constraint,message:vault.constraint_vault_inbox_value_check +#: model:ir.model.constraint,message:vault.constraint_vault_send_wizard_value_check +#, python-format +msgid "No value found" +msgstr "No se ha encontrado ningún valor" + +#. module: vault +#: model_terms:ir.ui.view,arch_db:vault.view_vault_entry_search +msgid "Not Expired" +msgstr "No ha caducado" + +#. module: vault +#: model:ir.model.fields,field_description:vault.field_vault__note +#: model:ir.model.fields,field_description:vault.field_vault_entry__note +#: model_terms:ir.ui.view,arch_db:vault.view_vault_entry_form +msgid "Note" +msgstr "Nota" + +#. module: vault +#: model:ir.model.fields,field_description:vault.field_vault__user_id +#: model:ir.model.fields,field_description:vault.field_vault_entry__user_id +msgid "Owner" +msgstr "Propietario" + +#. module: vault +#: model:ir.model.fields,field_description:vault.field_vault_entry__parent_id +msgid "Parent" +msgstr "Padre" + +#. module: vault +#: model:ir.model.fields,field_description:vault.field_vault_import_wizard__parent_id +msgid "Parent Entry" +msgstr "Registro padre" + +#. module: vault +#. odoo-javascript +#: code:addons/vault/static/src/backend/templates.xml:0 +#, python-format +msgid "Password:" +msgstr "Contraseña:" + +#. module: vault +#: model:ir.model.fields,field_description:vault.field_vault_import_wizard__path +msgid "Path to import" +msgstr "Ruta de importación" + +#. module: vault +#: model:ir.model.fields,field_description:vault.field_vault__perm_user +#: model:ir.model.fields,field_description:vault.field_vault_abstract_field__perm_user +#: model:ir.model.fields,field_description:vault.field_vault_entry__perm_user +#: model:ir.model.fields,field_description:vault.field_vault_field__perm_user +#: model:ir.model.fields,field_description:vault.field_vault_file__perm_user +#: model:ir.model.fields,field_description:vault.field_vault_right__perm_user +msgid "Perm User" +msgstr "Usuario permanente" + +#. module: vault +#. odoo-javascript +#: code:addons/vault/static/src/backend/export.esm.js:0 +#: code:addons/vault/static/src/backend/import.esm.js:0 +#, python-format +msgid "Please enter the password for the database" +msgstr "Por favor, introduzca la contraseña de la base de datos" + +#. module: vault +#. odoo-javascript +#: code:addons/vault/static/src/backend/import.esm.js:0 +#, python-format +msgid "Please enter the password for the keepass database" +msgstr "Por favor, introduzca la contraseña de la base de datos keepass" + +#. module: vault +#. odoo-javascript +#: code:addons/vault/static/src/backend/vault.esm.js:0 +#, python-format +msgid "Please enter the password for your private key" +msgstr "Por favor, introduzca la contraseña de su clave privada" + +#. module: vault +#. odoo-javascript +#: code:addons/vault/static/src/backend/templates.xml:0 +#, python-format +msgid "Please enter your password or upload a keyfile:" +msgstr "Por favor, introduzca su contraseña o cargue un archivo de claves:" + +#. module: vault +#. odoo-python +#: code:addons/vault/controllers/main.py:0 +#, python-format +msgid "Please specify a name" +msgstr "Por favor, especifique un nombre" + +#. module: vault +#: model:ir.model.fields,field_description:vault.field_res_users_key__private +msgid "Private" +msgstr "Privado" + +#. module: vault +#: model:ir.model.fields,field_description:vault.field_res_users_key__public +#: model:ir.model.fields,field_description:vault.field_vault_send_wizard__public +msgid "Public" +msgstr "Público" + +#. module: vault +#: model:ir.model.fields,field_description:vault.field_vault_right__public_key +msgid "Public Key" +msgstr "Clave pública" + +#. module: vault +#: model_terms:ir.ui.view,arch_db:vault.view_vault_form +msgid "Re-encrypt" +msgstr "Reencriptar" + +#. module: vault +#: model:ir.model.fields,field_description:vault.field_vault__reencrypt_required +msgid "Reencrypt Required" +msgstr "Necesita reencriptarse" + +#. module: vault +#: model:ir.actions.act_window,name:vault.action_vault_right +#: model:ir.model.fields,field_description:vault.field_vault__right_ids +#: model:ir.ui.menu,name:vault.menu_vault_right +#: model_terms:ir.ui.view,arch_db:vault.view_vault_form +msgid "Rights" +msgstr "Derechos" + +#. module: vault +#: model:ir.model.fields,field_description:vault.field_res_users_key__salt +msgid "Salt" +msgstr "Sal" + +#. module: vault +#. odoo-javascript +#: code:addons/vault/static/src/backend/fields/vault_export_file.esm.js:0 +#: code:addons/vault/static/src/backend/fields/vault_file.esm.js:0 +#, python-format +msgid "Save As..." +msgstr "Guardar como..." + +#. module: vault +#. odoo-javascript +#: code:addons/vault/static/src/backend/fields/templates.xml:0 +#, python-format +msgid "Save in a vault" +msgstr "Guardar en un vault" + +#. module: vault +#: model:ir.model.fields,field_description:vault.field_vault_inbox__secret +#: model:ir.model.fields,field_description:vault.field_vault_send_wizard__secret +#: model:ir.model.fields,field_description:vault.field_vault_store_wizard__secret +#: model_terms:ir.ui.view,arch_db:vault.inbox +msgid "Secret" +msgstr "Secreto" + +#. module: vault +#: model:ir.model.fields,field_description:vault.field_vault_inbox__secret_file +#: model:ir.model.fields,field_description:vault.field_vault_send_wizard__secret_file +msgid "Secret File" +msgstr "Archivo de secretos" + +#. module: vault +#: model:ir.model.fields,field_description:vault.field_vault_store_wizard__secret_temporary +msgid "Secret Temporary" +msgstr "Secreto temporal" + +#. module: vault +#: model_terms:ir.ui.view,arch_db:vault.inbox +msgid "Secret to share:" +msgstr "Secreto a compartir:" + +#. module: vault +#: model_terms:ir.ui.view,arch_db:vault.view_vault_send_wizard +msgid "Send" +msgstr "Enviar" + +#. module: vault +#. odoo-javascript +#: code:addons/vault/static/src/backend/fields/templates.xml:0 +#, python-format +msgid "Send the secret to an user" +msgstr "Enviar secreto a un usuario" + +#. module: vault +#. odoo-javascript +#: code:addons/vault/static/src/backend/fields/vault_mixin.esm.js:0 +#, python-format +msgid "Send the secret to another user" +msgstr "Enviar secreto a otro usuario" + +#. module: vault +#: model:ir.model.fields,field_description:vault.field_vault_right__perm_share +msgid "Share" +msgstr "Compartir" + +#. module: vault +#. odoo-javascript +#: code:addons/vault/static/src/backend/fields/templates.xml:0 +#, python-format +msgid "Show" +msgstr "Mostrar" + +#. module: vault +#. odoo-python +#: code:addons/vault/controllers/main.py:0 +#, python-format +msgid "Something went wrong with the encryption" +msgstr "Algo ha ido mal en el encriptado" + +#. module: vault +#. odoo-javascript +#: code:addons/vault/static/src/backend/templates.xml:0 +#, python-format +msgid "Special" +msgstr "Especial" + +#. module: vault +#: model:ir.model.fields,field_description:vault.field_vault_log__state +msgid "State" +msgstr "Estado" + +#. module: vault +#: model_terms:ir.ui.view,arch_db:vault.view_vault_store_wizard +msgid "Store" +msgstr "Tienda" + +#. module: vault +#. odoo-javascript +#: code:addons/vault/static/src/backend/fields/vault_inbox_mixin.esm.js:0 +#, python-format +msgid "Store the secret in a vault" +msgstr "Guarda el secreto en un vault" + +#. module: vault +#: model_terms:ir.ui.view,arch_db:vault.inbox +msgid "Submit secret" +msgstr "Enviar secreto" + +#. module: vault +#. odoo-python +#: code:addons/vault/controllers/main.py:0 +#, python-format +msgid "Successfully stored" +msgstr "Guardado correctamente" + +#. module: vault +#: model:ir.model.fields,field_description:vault.field_vault_entry__tags +msgid "Tags" +msgstr "Etiquetas" + +#. module: vault +#. odoo-python +#: code:addons/vault/models/vault.py:0 +#: code:addons/vault/models/vault_entry.py:0 +#: model:ir.model.constraint,message:vault.constraint_vault_entry_vault_uuid_uniq +#: model:ir.model.constraint,message:vault.constraint_vault_uuid_uniq +#, python-format +msgid "The UUID must be unique." +msgstr "El UUID debe ser único." + +#. module: vault +#. odoo-javascript +#: code:addons/vault/static/src/backend/fields/vault_export_file.esm.js:0 +#: code:addons/vault/static/src/backend/fields/vault_file.esm.js:0 +#, python-format +msgid "The field is empty, there's nothing to save!" +msgstr "El campo está vacío, ¡no hay nada que guardar!" + +#. module: vault +#: model_terms:ir.ui.view,arch_db:vault.view_vault_import_wizard +msgid "The files must end on one of the supported file type:" +msgstr "Los archivos deben terminar en uno de los tipos de archivo admitidos:" + +#. module: vault +#. odoo-javascript +#: code:addons/vault/static/src/backend/controller.esm.js:0 +#, python-format +msgid "The following entries are broken:" +msgstr "Los siguientes registros están rotos:" + +#. module: vault +#. odoo-javascript +#: code:addons/vault/static/src/common/utils.esm.js:0 +#, python-format +msgid "The passwords aren't matching" +msgstr "Las contraseñas no coinciden" + +#. module: vault +#. odoo-python +#: code:addons/vault/models/abstract_vault.py:0 +#, python-format +msgid "" +"The requested operation can not be completed due to security restrictions." +msgstr "" +"La operación solicitada no puede completarse debido a restricciones de " +"seguridad." + +#. module: vault +#. odoo-python +#: code:addons/vault/models/vault_tag.py:0 +#: model:ir.model.constraint,message:vault.constraint_vault_tag_name_uniq +#, python-format +msgid "The tag must be unique!" +msgstr "¡La etiqueta debe ser única!" + +#. module: vault +#. odoo-python +#: code:addons/vault/models/vault_right.py:0 +#: model:ir.model.constraint,message:vault.constraint_vault_right_user_uniq +#, python-format +msgid "The user must be unique" +msgstr "El usuario debe ser único" + +#. module: vault +#: model:ir.model.fields,field_description:vault.field_vault_inbox__token +msgid "Token" +msgstr "Token" + +#. module: vault +#. odoo-javascript +#: code:addons/vault/static/src/backend/import.esm.js:0 +#, python-format +msgid "Unsupported file to import" +msgstr "Archivo no compatible para importar" + +#. module: vault +#: model:ir.model.fields,field_description:vault.field_vault_entry__url +msgid "Url" +msgstr "Url" + +#. module: vault +#: model:ir.model,name:vault.model_res_users +#: model:ir.model.fields,field_description:vault.field_res_users_key__user_id +#: model:ir.model.fields,field_description:vault.field_vault_log__user_id +#: model:ir.model.fields,field_description:vault.field_vault_right__user_id +#: model:ir.model.fields,field_description:vault.field_vault_send_wizard__user_id +msgid "User" +msgstr "Usuario" + +#. module: vault +#. odoo-python +#: code:addons/vault/models/res_users_key.py:0 +#: model:ir.model,name:vault.model_res_users_key +#, python-format +msgid "User data of a vault" +msgstr "Datos de usuario de un vault" + +#. module: vault +#: model:ir.model.fields,help:vault.field_vault_inbox__inbox_link +msgid "" +"Using this link you can write to the current inbox. If you want people to " +"create new inboxes you should give them your inbox link from your key " +"management." +msgstr "" +"Con este enlace puedes escribir en la bandeja de entrada actual. Si quieres " +"que la gente cree nuevas bandejas de entrada, deberás darles el enlace de tu " +"bandeja de entrada desde tu gestor de claves." + +#. module: vault +#: model:ir.model.fields,field_description:vault.field_res_users_key__uuid +#: model:ir.model.fields,field_description:vault.field_vault__uuid +#: model:ir.model.fields,field_description:vault.field_vault_entry__uuid +#: model:ir.model.fields,field_description:vault.field_vault_import_wizard__uuid +#: model:ir.model.fields,field_description:vault.field_vault_import_wizard_path__uuid +msgid "Uuid" +msgstr "Uuid" + +#. module: vault +#: model:ir.model.fields,field_description:vault.field_vault_field__value +#: model:ir.model.fields,field_description:vault.field_vault_file__value +msgid "Value" +msgstr "Valor" + +#. module: vault +#. odoo-python +#: code:addons/vault/models/vault.py:0 +#: model:ir.actions.act_window,name:vault.action_vault +#: model:ir.model,name:vault.model_vault +#: model:ir.model.fields,field_description:vault.field_vault_abstract_field__vault_id +#: model:ir.model.fields,field_description:vault.field_vault_entry__vault_id +#: model:ir.model.fields,field_description:vault.field_vault_export_wizard__vault_id +#: model:ir.model.fields,field_description:vault.field_vault_field__vault_id +#: model:ir.model.fields,field_description:vault.field_vault_file__vault_id +#: model:ir.model.fields,field_description:vault.field_vault_import_wizard__vault_id +#: model:ir.model.fields,field_description:vault.field_vault_inbox__user_id +#: model:ir.model.fields,field_description:vault.field_vault_log__vault_id +#: model:ir.model.fields,field_description:vault.field_vault_right__vault_id +#: model:ir.model.fields,field_description:vault.field_vault_store_wizard__vault_id +#: model:ir.ui.menu,name:vault.menu_vault +#: model_terms:ir.ui.view,arch_db:vault.res_config_settings_view_form +#: model_terms:ir.ui.view,arch_db:vault.view_vault_entry_search +#, python-format +msgid "Vault" +msgstr "Bóveda" + +#. module: vault +#. odoo-javascript +#: code:addons/vault/static/src/backend/fields/vault_field.esm.js:0 +#, python-format +msgid "Vault Field" +msgstr "" + +#. module: vault +#. odoo-javascript +#: code:addons/vault/static/src/backend/fields/vault_file.esm.js:0 +#, python-format +msgid "Vault File" +msgstr "" + +#. module: vault +#. odoo-javascript +#: code:addons/vault/static/src/backend/fields/vault_inbox_field.esm.js:0 +#, python-format +msgid "Vault Inbox Field" +msgstr "" + +#. module: vault +#. odoo-javascript +#: code:addons/vault/static/src/backend/fields/vault_inbox_file.esm.js:0 +#, python-format +msgid "Vault Inbox File" +msgstr "" + +#. module: vault +#: model:ir.model.fields,field_description:vault.field_res_users__vault_right_ids +msgid "Vault Right" +msgstr "Permiso de vault" + +#. module: vault +#: model_terms:ir.ui.view,arch_db:vault.res_config_settings_view_form +msgid "Vault Share" +msgstr "Compartir vault" + +#. module: vault +#. odoo-python +#: code:addons/vault/models/vault_inbox_log.py:0 +#: model:ir.model,name:vault.model_vault_inbox_log +#, python-format +msgid "Vault inbox log" +msgstr "Registro de bandeja de entrada de vault" + +#. module: vault +#. odoo-javascript +#: code:addons/vault/static/src/backend/controller.esm.js:0 +#, python-format +msgid "Vault is not supported" +msgstr "" + +#. module: vault +#. odoo-python +#: code:addons/vault/models/vault_right.py:0 +#: model:ir.model,name:vault.model_vault_right +#, python-format +msgid "Vault rights" +msgstr "Permisos de vault" + +#. module: vault +#. odoo-python +#: code:addons/vault/models/vault_inbox.py:0 +#: model:ir.model,name:vault.model_vault_inbox +#, python-format +msgid "Vault share incoming secrets" +msgstr "Compartir los secretos de entrada de vault" + +#. module: vault +#. odoo-python +#: code:addons/vault/models/vault_tag.py:0 +#: model:ir.model,name:vault.model_vault_tag +#, python-format +msgid "Vault tag" +msgstr "Etiqueta de vault" + +#. module: vault +#: model_terms:ir.ui.view,arch_db:vault.view_vault_entry_search +msgid "Vaults" +msgstr "Bóvedas" + +#. module: vault +#: model_terms:ir.ui.view,arch_db:vault.view_vault_form +msgid "Verify" +msgstr "Verificar" + +#. module: vault +#: model:ir.model.fields,field_description:vault.field_res_users_key__version +msgid "Version" +msgstr "Versión" + +#. module: vault +#. odoo-python +#: code:addons/vault/models/vault_log.py:0 +#, python-format +msgid "Warning" +msgstr "Advertencia" + +#. module: vault +#. odoo-python +#: code:addons/vault/wizards/vault_store_wizard.py:0 +#: model:ir.model,name:vault.model_vault_store_wizard +#, python-format +msgid "Wizard store a shared secret in a vault" +msgstr "Asistente de almacenado de secreto compartido en un vault" + +#. module: vault +#. odoo-python +#: code:addons/vault/wizards/vault_send_wizard.py:0 +#: model:ir.model,name:vault.model_vault_send_wizard +#, python-format +msgid "Wizard to send another user a secret" +msgstr "Asistente para enviar un secreto a otro usuario" + +#. module: vault +#: model:ir.model.fields,field_description:vault.field_vault_right__perm_write +msgid "Write" +msgstr "Escribir" + +#. module: vault +#. odoo-python +#: code:addons/vault/models/vault_inbox.py:0 +#, python-format +msgid "Written by %(name)s via %(ip)s" +msgstr "Escrito por %(name)s vía %(ip)s" + +#. module: vault +#. odoo-python +#: code:addons/vault/models/vault_entry.py:0 +#, python-format +msgid "You can not create recursive entries." +msgstr "No puedes crear registros recrsivos." + +#. module: vault +#: model_terms:ir.ui.view,arch_db:vault.view_vault_send_wizard +msgid "" +"You can only send the secret to the user who has generated a key-pair.\n" +" If an user is not showing please ask him to generate " +"these." +msgstr "" +"Sólo se puede enviar el secreto al usuario que ha generado un par de " +"claves.\n" +" Si un usuario no aparece, por favor, pídale que los " +"genere." + +#. module: vault +#: model_terms:ir.ui.view,arch_db:vault.view_users_form_keys_modif +msgid "" +"You will loose access to all vaults and your inbox. Do you want to continue?" +msgstr "" +"Perderá el acceso a todos sus vaults y a su bandeja de entrada. ¿Desea " +"continuar?" + +#. module: vault +#. odoo-javascript +#: code:addons/vault/static/src/backend/templates.xml:0 +#, python-format +msgid "a-z" +msgstr "a-z" + +#. module: vault +#: model_terms:ir.ui.view,arch_db:vault.view_vault_import_wizard +#: model_terms:ir.ui.view,arch_db:vault.view_vault_send_wizard +#: model_terms:ir.ui.view,arch_db:vault.view_vault_store_wizard +msgid "or" +msgstr "o" + +#~ msgid "Users" +#~ msgstr "Usuarios" + +#, python-format +#~ msgid "" +#~ "This will re-encrypt everything in the vault. Do you want to proceed?" +#~ msgstr "Esto volverá a encriptar todo en el vault. ¿Quieres proceder?" + +#, python-format +#~ msgid "%s entry %s by %s" +#~ msgstr "%s registrado %s por %s" + +#, python-format +#~ msgid "Created by %s via %s" +#~ msgstr "Creado por %s via %s" + +#, python-format +#~ msgid "Written by %s via %s" +#~ msgstr "Escrito por %s via %s" diff --git a/vault/i18n/it.po b/vault/i18n/it.po new file mode 100644 index 0000000000..b19101f30f --- /dev/null +++ b/vault/i18n/it.po @@ -0,0 +1,1479 @@ +# Translation of Odoo Server. +# This file contains the translation of the following modules: +# * vault +# +msgid "" +msgstr "" +"Project-Id-Version: Odoo Server 16.0\n" +"Report-Msgid-Bugs-To: \n" +"Last-Translator: Automatically generated\n" +"Language-Team: none\n" +"Language: it\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: \n" +"Plural-Forms: nplurals=2; plural=n != 1;\n" + +#. module: vault +#. odoo-python +#: code:addons/vault/models/vault_entry.py:0 +#, python-format +msgid "%(action)s entry %(name)s by %(user)s" +msgstr "" + +#. module: vault +#. odoo-javascript +#: code:addons/vault/static/src/backend/controller.esm.js:0 +#, python-format +msgid "%s '%s' of entry '%s'" +msgstr "" + +#. module: vault +#. odoo-python +#: code:addons/vault/models/vault_entry.py:0 +#, python-format +msgid "%s (copy)" +msgstr "" + +#. module: vault +#. odoo-javascript +#: code:addons/vault/static/src/backend/controller.esm.js:0 +#, python-format +msgid "" +"A secure browser context is required. Please switch to https or contact your" +" administrator" +msgstr "" + +#. module: vault +#. odoo-javascript +#: code:addons/vault/static/src/backend/templates.xml:0 +#, python-format +msgid "A-Z" +msgstr "" + +#. module: vault +#. odoo-python +#: code:addons/vault/models/abstract_vault_field.py:0 +#: model:ir.model,name:vault.model_vault_abstract_field +#, python-format +msgid "Abstract model to implement basic fields for encryption" +msgstr "" + +#. module: vault +#. odoo-python +#: code:addons/vault/models/abstract_vault.py:0 +#: model:ir.model,name:vault.model_vault_abstract +#, python-format +msgid "Abstract model to implement general access rights" +msgstr "" + +#. module: vault +#: model:ir.model.fields,field_description:vault.field_vault_inbox__accesses +msgid "Access counter" +msgstr "" + +#. module: vault +#: model:ir.model.fields,field_description:vault.field_res_users__active_key +msgid "Active Key" +msgstr "" + +#. module: vault +#: model:ir.actions.act_window,name:vault.action_vault_entry +#: model:ir.ui.menu,name:vault.menu_vault_entry +msgid "All Entries" +msgstr "" + +#. module: vault +#: model_terms:ir.ui.view,arch_db:vault.res_config_settings_view_form +msgid "Allow all users to export vaults accessible to them" +msgstr "" + +#. module: vault +#: model_terms:ir.ui.view,arch_db:vault.res_config_settings_view_form +msgid "Allow all users to import vaults accessible to them" +msgstr "" + +#. module: vault +#: model_terms:ir.ui.view,arch_db:vault.res_config_settings_view_form +msgid "Allow the usage to share secrets with external users" +msgstr "" + +#. module: vault +#: model:ir.model.fields,help:vault.field_vault_right__perm_create +msgid "Allow to create in the vault" +msgstr "" + +#. module: vault +#: model:ir.model.fields,help:vault.field_vault_right__perm_delete +msgid "Allow to delete a vault" +msgstr "" + +#. module: vault +#: model:res.groups,name:vault.group_vault_export +msgid "Allow to export vaults" +msgstr "" + +#. module: vault +#: model:res.groups,name:vault.group_vault_import +msgid "Allow to import vaults" +msgstr "" + +#. module: vault +#: model:ir.model.fields,help:vault.field_vault_right__perm_share +msgid "Allow to share a vault with new users" +msgstr "" + +#. module: vault +#: model:ir.model.fields,help:vault.field_vault_right__perm_write +msgid "Allow to write to the vault" +msgstr "" + +#. module: vault +#: model:ir.model.fields,field_description:vault.field_vault__allowed_create +#: model:ir.model.fields,field_description:vault.field_vault_abstract_field__allowed_create +#: model:ir.model.fields,field_description:vault.field_vault_entry__allowed_create +#: model:ir.model.fields,field_description:vault.field_vault_field__allowed_create +#: model:ir.model.fields,field_description:vault.field_vault_file__allowed_create +#: model:ir.model.fields,field_description:vault.field_vault_right__allowed_create +msgid "Allowed Create" +msgstr "" + +#. module: vault +#: model:ir.model.fields,field_description:vault.field_vault__allowed_delete +#: model:ir.model.fields,field_description:vault.field_vault_abstract_field__allowed_delete +#: model:ir.model.fields,field_description:vault.field_vault_entry__allowed_delete +#: model:ir.model.fields,field_description:vault.field_vault_field__allowed_delete +#: model:ir.model.fields,field_description:vault.field_vault_file__allowed_delete +#: model:ir.model.fields,field_description:vault.field_vault_right__allowed_delete +msgid "Allowed Delete" +msgstr "" + +#. module: vault +#: model:ir.model.fields,field_description:vault.field_vault__allowed_read +#: model:ir.model.fields,field_description:vault.field_vault_abstract_field__allowed_read +#: model:ir.model.fields,field_description:vault.field_vault_entry__allowed_read +#: model:ir.model.fields,field_description:vault.field_vault_field__allowed_read +#: model:ir.model.fields,field_description:vault.field_vault_file__allowed_read +#: model:ir.model.fields,field_description:vault.field_vault_right__allowed_read +msgid "Allowed Read" +msgstr "" + +#. module: vault +#: model:ir.model.fields,field_description:vault.field_vault__allowed_share +#: model:ir.model.fields,field_description:vault.field_vault_abstract_field__allowed_share +#: model:ir.model.fields,field_description:vault.field_vault_entry__allowed_share +#: model:ir.model.fields,field_description:vault.field_vault_field__allowed_share +#: model:ir.model.fields,field_description:vault.field_vault_file__allowed_share +#: model:ir.model.fields,field_description:vault.field_vault_right__allowed_share +msgid "Allowed Share" +msgstr "" + +#. module: vault +#: model:ir.model.fields,field_description:vault.field_vault__allowed_write +#: model:ir.model.fields,field_description:vault.field_vault_abstract_field__allowed_write +#: model:ir.model.fields,field_description:vault.field_vault_entry__allowed_write +#: model:ir.model.fields,field_description:vault.field_vault_field__allowed_write +#: model:ir.model.fields,field_description:vault.field_vault_file__allowed_write +#: model:ir.model.fields,field_description:vault.field_vault_right__allowed_write +msgid "Allowed Write" +msgstr "" + +#. module: vault +#. odoo-python +#: code:addons/vault/controllers/main.py:0 +#, python-format +msgid "An error occured. Please contact the user or administrator" +msgstr "" + +#. module: vault +#: model_terms:ir.ui.view,arch_db:vault.view_vault_right_overview_search +msgid "By user" +msgstr "" + +#. module: vault +#: model_terms:ir.ui.view,arch_db:vault.view_vault_right_overview_search +msgid "By vault" +msgstr "" + +#. module: vault +#. odoo-javascript +#: code:addons/vault/static/src/common/utils.esm.js:0 +#: code:addons/vault/static/src/common/utils.esm.js:0 +#: model_terms:ir.ui.view,arch_db:vault.view_users_form_keys_modif +#: model_terms:ir.ui.view,arch_db:vault.view_vault_import_wizard +#: model_terms:ir.ui.view,arch_db:vault.view_vault_send_wizard +#: model_terms:ir.ui.view,arch_db:vault.view_vault_store_wizard +#, python-format +msgid "Cancel" +msgstr "" + +#. module: vault +#. odoo-javascript +#: code:addons/vault/static/src/common/utils.esm.js:0 +#: code:addons/vault/static/src/common/utils.esm.js:0 +#, python-format +msgid "Cancelled" +msgstr "" + +#. module: vault +#. odoo-javascript +#: code:addons/vault/static/src/backend/templates.xml:0 +#, python-format +msgid "Characters:" +msgstr "" + +#. module: vault +#: model:ir.model.fields,field_description:vault.field_vault_entry__child_ids +msgid "Child" +msgstr "" + +#. module: vault +#: model_terms:ir.ui.view,arch_db:vault.view_vault_entry_form +msgid "Childs" +msgstr "" + +#. module: vault +#: model_terms:ir.ui.view,arch_db:vault.view_vault_export_wizard +msgid "Close" +msgstr "" + +#. module: vault +#: model:ir.model.fields,field_description:vault.field_vault_abstract_field__entry_name +#: model:ir.model.fields,field_description:vault.field_vault_entry__complete_name +#: model:ir.model.fields,field_description:vault.field_vault_field__entry_name +#: model:ir.model.fields,field_description:vault.field_vault_file__entry_name +msgid "Complete Name" +msgstr "" + +#. module: vault +#: model:ir.model,name:vault.model_res_config_settings +msgid "Config Settings" +msgstr "" + +#. module: vault +#. odoo-javascript +#: code:addons/vault/static/src/backend/templates.xml:0 +#, python-format +msgid "Confirm your password:" +msgstr "" + +#. module: vault +#: model_terms:ir.ui.view,arch_db:vault.view_vault_entry_form +msgid "Content" +msgstr "" + +#. module: vault +#. odoo-javascript +#: code:addons/vault/static/src/backend/fields/templates.xml:0 +#: code:addons/vault/static/src/backend/fields/templates.xml:0 +#, python-format +msgid "Copy to clipboard" +msgstr "" + +#. module: vault +#: model:ir.model.fields,field_description:vault.field_vault_right__perm_create +msgid "Create" +msgstr "" + +#. module: vault +#: model:ir.model.fields,field_description:vault.field_res_users_key__create_uid +#: model:ir.model.fields,field_description:vault.field_vault__create_uid +#: model:ir.model.fields,field_description:vault.field_vault_entry__create_uid +#: model:ir.model.fields,field_description:vault.field_vault_export_wizard__create_uid +#: model:ir.model.fields,field_description:vault.field_vault_field__create_uid +#: model:ir.model.fields,field_description:vault.field_vault_file__create_uid +#: model:ir.model.fields,field_description:vault.field_vault_import_wizard__create_uid +#: model:ir.model.fields,field_description:vault.field_vault_import_wizard_path__create_uid +#: model:ir.model.fields,field_description:vault.field_vault_inbox__create_uid +#: model:ir.model.fields,field_description:vault.field_vault_inbox_log__create_uid +#: model:ir.model.fields,field_description:vault.field_vault_log__create_uid +#: model:ir.model.fields,field_description:vault.field_vault_right__create_uid +#: model:ir.model.fields,field_description:vault.field_vault_send_wizard__create_uid +#: model:ir.model.fields,field_description:vault.field_vault_store_wizard__create_uid +#: model:ir.model.fields,field_description:vault.field_vault_tag__create_uid +msgid "Created by" +msgstr "" + +#. module: vault +#. odoo-python +#: code:addons/vault/models/vault_inbox.py:0 +#, python-format +msgid "Created by %(name)s via %(ip)s" +msgstr "" + +#. module: vault +#. odoo-python +#: code:addons/vault/wizards/vault_send_wizard.py:0 +#, python-format +msgid "Created by %s" +msgstr "" + +#. module: vault +#: model:ir.model.fields,field_description:vault.field_res_users_key__create_date +#: model:ir.model.fields,field_description:vault.field_vault__create_date +#: model:ir.model.fields,field_description:vault.field_vault_entry__create_date +#: model:ir.model.fields,field_description:vault.field_vault_export_wizard__create_date +#: model:ir.model.fields,field_description:vault.field_vault_field__create_date +#: model:ir.model.fields,field_description:vault.field_vault_file__create_date +#: model:ir.model.fields,field_description:vault.field_vault_import_wizard__create_date +#: model:ir.model.fields,field_description:vault.field_vault_import_wizard_path__create_date +#: model:ir.model.fields,field_description:vault.field_vault_inbox__create_date +#: model:ir.model.fields,field_description:vault.field_vault_inbox_log__create_date +#: model:ir.model.fields,field_description:vault.field_vault_log__create_date +#: model:ir.model.fields,field_description:vault.field_vault_right__create_date +#: model:ir.model.fields,field_description:vault.field_vault_send_wizard__create_date +#: model:ir.model.fields,field_description:vault.field_vault_store_wizard__create_date +#: model:ir.model.fields,field_description:vault.field_vault_tag__create_date +msgid "Created on" +msgstr "" + +#. module: vault +#: model:ir.model.fields,field_description:vault.field_vault_import_wizard__crypted_content +msgid "Crypted Content" +msgstr "" + +#. module: vault +#: model:ir.model.fields,field_description:vault.field_res_users_key__current +msgid "Current" +msgstr "" + +#. module: vault +#: model_terms:ir.ui.view,arch_db:vault.view_vault_import_wizard +msgid "Custom JSON format .json" +msgstr "" + +#. module: vault +#: model:ir.model.fields,field_description:vault.field_vault_import_wizard__content +msgid "Database" +msgstr "" + +#. module: vault +#: model:ir.model.fields,field_description:vault.field_vault_right__perm_delete +msgid "Delete" +msgstr "" + +#. module: vault +#: model:ir.model.fields,field_description:vault.field_res_users_key__display_name +#: model:ir.model.fields,field_description:vault.field_vault__display_name +#: model:ir.model.fields,field_description:vault.field_vault_entry__display_name +#: model:ir.model.fields,field_description:vault.field_vault_export_wizard__display_name +#: model:ir.model.fields,field_description:vault.field_vault_field__display_name +#: model:ir.model.fields,field_description:vault.field_vault_file__display_name +#: model:ir.model.fields,field_description:vault.field_vault_import_wizard__display_name +#: model:ir.model.fields,field_description:vault.field_vault_import_wizard_path__display_name +#: model:ir.model.fields,field_description:vault.field_vault_inbox__display_name +#: model:ir.model.fields,field_description:vault.field_vault_inbox_log__display_name +#: model:ir.model.fields,field_description:vault.field_vault_log__display_name +#: model:ir.model.fields,field_description:vault.field_vault_right__display_name +#: model:ir.model.fields,field_description:vault.field_vault_send_wizard__display_name +#: model:ir.model.fields,field_description:vault.field_vault_store_wizard__display_name +#: model:ir.model.fields,field_description:vault.field_vault_tag__display_name +msgid "Display Name" +msgstr "" + +#. module: vault +#. odoo-javascript +#: code:addons/vault/static/src/backend/controller.esm.js:0 +#, python-format +msgid "Do you really want to create a new key pair and set it active?" +msgstr "" + +#. module: vault +#: model:ir.model.fields,field_description:vault.field_vault_export_wizard__content +msgid "Download" +msgstr "" + +#. module: vault +#. odoo-javascript +#: code:addons/vault/static/src/common/utils.esm.js:0 +#: code:addons/vault/static/src/common/utils.esm.js:0 +#, python-format +msgid "Enter" +msgstr "" + +#. module: vault +#. odoo-javascript +#: code:addons/vault/static/src/backend/templates.xml:0 +#, python-format +msgid "Enter your password:" +msgstr "" + +#. module: vault +#: model:ir.actions.act_window,name:vault.action_open_entries +#: model:ir.model.fields,field_description:vault.field_vault__entry_ids +#: model:ir.model.fields,field_description:vault.field_vault_export_wizard__entry_id +#: model_terms:ir.ui.view,arch_db:vault.view_vault_entry_search +#: model_terms:ir.ui.view,arch_db:vault.view_vault_form +msgid "Entries" +msgstr "" + +#. module: vault +#: model:ir.model.fields,field_description:vault.field_vault_abstract_field__entry_id +#: model:ir.model.fields,field_description:vault.field_vault_field__entry_id +#: model:ir.model.fields,field_description:vault.field_vault_file__entry_id +#: model:ir.model.fields,field_description:vault.field_vault_log__entry_id +#: model:ir.model.fields,field_description:vault.field_vault_store_wizard__entry_id +msgid "Entry" +msgstr "" + +#. module: vault +#. odoo-python +#: code:addons/vault/models/vault_entry.py:0 +#: model:ir.model,name:vault.model_vault_entry +#, python-format +msgid "Entry inside a vault" +msgstr "" + +#. module: vault +#. odoo-python +#: code:addons/vault/models/vault_log.py:0 +#, python-format +msgid "Error" +msgstr "" + +#. module: vault +#: model:ir.model.fields,field_description:vault.field_vault_inbox__expiration +msgid "Expiration" +msgstr "" + +#. module: vault +#: model:ir.model.fields,field_description:vault.field_vault_entry__expired +#: model_terms:ir.ui.view,arch_db:vault.view_vault_entry_search +msgid "Expired" +msgstr "" + +#. module: vault +#: model:ir.model.fields,field_description:vault.field_vault_entry__expire_date +msgid "Expires on" +msgstr "" + +#. module: vault +#: model:ir.model.fields,field_description:vault.field_res_config_settings__group_vault_export +msgid "Export Vaults" +msgstr "" + +#. module: vault +#. odoo-python +#: code:addons/vault/models/vault.py:0 +#: code:addons/vault/models/vault_entry.py:0 +#: model_terms:ir.ui.view,arch_db:vault.view_vault_entry_form +#: model_terms:ir.ui.view,arch_db:vault.view_vault_form +#, python-format +msgid "Export to file" +msgstr "" + +#. module: vault +#. odoo-python +#: code:addons/vault/wizards/vault_export_wizard.py:0 +#: model:ir.model,name:vault.model_vault_export_wizard +#, python-format +msgid "Export wizard for vaults" +msgstr "" + +#. module: vault +#. odoo-javascript +#: code:addons/vault/static/src/backend/vault.esm.js:0 +#, python-format +msgid "Failed to export keys to object store" +msgstr "" + +#. module: vault +#. odoo-javascript +#: code:addons/vault/static/src/backend/vault.esm.js:0 +#, python-format +msgid "Failed to export the keys to the database" +msgstr "" + +#. module: vault +#. odoo-javascript +#: code:addons/vault/static/src/backend/vault.esm.js:0 +#, python-format +msgid "Failed to import keys from database" +msgstr "" + +#. module: vault +#. odoo-python +#: code:addons/vault/models/vault_field.py:0 +#: model:ir.model,name:vault.model_vault_field +#, python-format +msgid "Field of a vault" +msgstr "" + +#. module: vault +#: model:ir.model.fields,field_description:vault.field_vault__field_ids +#: model:ir.model.fields,field_description:vault.field_vault_entry__field_ids +msgid "Fields" +msgstr "" + +#. module: vault +#. odoo-python +#: code:addons/vault/models/vault_file.py:0 +#: model:ir.model,name:vault.model_vault_file +#, python-format +msgid "File of a vault" +msgstr "" + +#. module: vault +#: model_terms:ir.ui.view,arch_db:vault.inbox +msgid "File to share:" +msgstr "" + +#. module: vault +#: model:ir.model.fields,field_description:vault.field_vault_inbox__filename +#: model:ir.model.fields,field_description:vault.field_vault_send_wizard__filename +msgid "Filename" +msgstr "" + +#. module: vault +#: model:ir.model.fields,field_description:vault.field_vault__file_ids +#: model:ir.model.fields,field_description:vault.field_vault_entry__file_ids +msgid "Files" +msgstr "" + +#. module: vault +#: model:ir.model.fields,field_description:vault.field_res_users_key__fingerprint +msgid "Fingerprint" +msgstr "" + +#. module: vault +#. odoo-javascript +#: code:addons/vault/static/src/backend/fields/templates.xml:0 +#: code:addons/vault/static/src/backend/fields/templates.xml:0 +#, python-format +msgid "Generate" +msgstr "" + +#. module: vault +#. odoo-javascript +#: code:addons/vault/static/src/backend/templates.xml:0 +#, python-format +msgid "Generate a new secret:" +msgstr "" + +#. module: vault +#: model_terms:ir.ui.view,arch_db:vault.view_vault_right_overview_search +msgid "Grouped" +msgstr "" + +#. module: vault +#. odoo-javascript +#: code:addons/vault/static/src/backend/fields/templates.xml:0 +#: code:addons/vault/static/src/backend/fields/templates.xml:0 +#, python-format +msgid "Hide" +msgstr "" + +#. module: vault +#: model:ir.model.fields,field_description:vault.field_res_users_key__id +#: model:ir.model.fields,field_description:vault.field_vault__id +#: model:ir.model.fields,field_description:vault.field_vault_entry__id +#: model:ir.model.fields,field_description:vault.field_vault_export_wizard__id +#: model:ir.model.fields,field_description:vault.field_vault_field__id +#: model:ir.model.fields,field_description:vault.field_vault_file__id +#: model:ir.model.fields,field_description:vault.field_vault_import_wizard__id +#: model:ir.model.fields,field_description:vault.field_vault_import_wizard_path__id +#: model:ir.model.fields,field_description:vault.field_vault_inbox__id +#: model:ir.model.fields,field_description:vault.field_vault_inbox_log__id +#: model:ir.model.fields,field_description:vault.field_vault_log__id +#: model:ir.model.fields,field_description:vault.field_vault_right__id +#: model:ir.model.fields,field_description:vault.field_vault_send_wizard__id +#: model:ir.model.fields,field_description:vault.field_vault_store_wizard__id +#: model:ir.model.fields,field_description:vault.field_vault_tag__id +msgid "ID" +msgstr "" + +#. module: vault +#: model:ir.model.fields,help:vault.field_vault_inbox__expiration +msgid "If expired the inbox can't be written using the link" +msgstr "" + +#. module: vault +#: model:ir.model.fields,help:vault.field_vault_inbox__accesses +msgid "If this is 0 the inbox can't be written using the link" +msgstr "" + +#. module: vault +#: model_terms:ir.ui.view,arch_db:vault.view_vault_import_wizard +msgid "Import" +msgstr "" + +#. module: vault +#: model:ir.model.fields,field_description:vault.field_res_config_settings__group_vault_import +msgid "Import Vaults" +msgstr "" + +#. module: vault +#. odoo-python +#: code:addons/vault/models/vault.py:0 +#: code:addons/vault/models/vault_entry.py:0 +#: model_terms:ir.ui.view,arch_db:vault.view_vault_entry_form +#: model_terms:ir.ui.view,arch_db:vault.view_vault_form +#, python-format +msgid "Import from file" +msgstr "" + +#. module: vault +#. odoo-python +#: code:addons/vault/wizards/vault_import_wizard.py:0 +#: model:ir.model,name:vault.model_vault_import_wizard +#, python-format +msgid "Import wizard for vaults" +msgstr "" + +#. module: vault +#. odoo-python +#: code:addons/vault/wizards/vault_import_wizard.py:0 +#: model:ir.model,name:vault.model_vault_import_wizard_path +#, python-format +msgid "Import wizard path for vaults" +msgstr "" + +#. module: vault +#: model:ir.actions.act_window,name:vault.action_vault_inbox +#: model:ir.model.fields,field_description:vault.field_res_users__inbox_ids +#: model:ir.model.fields,field_description:vault.field_vault_inbox_log__inbox_id +#: model:ir.ui.menu,name:vault.menu_vault_inbox +msgid "Inbox" +msgstr "" + +#. module: vault +#: model:ir.model.fields,field_description:vault.field_res_users__inbox_enabled +msgid "Inbox Enabled" +msgstr "" + +#. module: vault +#: model:ir.model.fields,field_description:vault.field_res_users__inbox_link +#: model:ir.model.fields,field_description:vault.field_vault_inbox__inbox_link +msgid "Inbox Link" +msgstr "" + +#. module: vault +#: model:ir.model.fields,field_description:vault.field_res_users__inbox_token +msgid "Inbox Token" +msgstr "" + +#. module: vault +#: model:ir.model.fields,field_description:vault.field_vault_export_wizard__include_childs +msgid "Include Childs" +msgstr "" + +#. module: vault +#. odoo-python +#: code:addons/vault/models/vault_log.py:0 +#, python-format +msgid "Information" +msgstr "" + +#. module: vault +#. odoo-python +#: code:addons/vault/wizards/vault_import_wizard.py:0 +#, python-format +msgid "Invalid file to import from" +msgstr "" + +#. module: vault +#. odoo-python +#: code:addons/vault/models/res_users_key.py:0 +#: code:addons/vault/models/res_users_key.py:0 +#: code:addons/vault/models/res_users_key.py:0 +#, python-format +msgid "Invalid parameter" +msgstr "" + +#. module: vault +#. odoo-python +#: code:addons/vault/controllers/main.py:0 +#, python-format +msgid "Invalid token" +msgstr "" + +#. module: vault +#: model_terms:ir.ui.view,arch_db:vault.view_users_form_keys_modif +msgid "Invalidate private key" +msgstr "" + +#. module: vault +#: model:ir.model.fields,field_description:vault.field_res_users_key__iterations +msgid "Iterations" +msgstr "" + +#. module: vault +#: model:ir.model.fields,field_description:vault.field_res_users_key__iv +#: model:ir.model.fields,field_description:vault.field_vault_abstract_field__iv +#: model:ir.model.fields,field_description:vault.field_vault_field__iv +#: model:ir.model.fields,field_description:vault.field_vault_file__iv +#: model:ir.model.fields,field_description:vault.field_vault_inbox__iv +#: model:ir.model.fields,field_description:vault.field_vault_send_wizard__iv +#: model:ir.model.fields,field_description:vault.field_vault_store_wizard__iv +msgid "Iv" +msgstr "" + +#. module: vault +#: model_terms:ir.ui.view,arch_db:vault.view_vault_import_wizard +msgid "Keepass Database .kdbx" +msgstr "" + +#. module: vault +#: model:ir.model.fields,field_description:vault.field_vault_inbox__key +#: model:ir.model.fields,field_description:vault.field_vault_right__key +#: model:ir.model.fields,field_description:vault.field_vault_send_wizard__key +#: model:ir.model.fields,field_description:vault.field_vault_store_wizard__key +msgid "Key" +msgstr "" + +#. module: vault +#. odoo-javascript +#: code:addons/vault/static/src/backend/user_menu.esm.js:0 +#, python-format +msgid "Key Management" +msgstr "" + +#. module: vault +#: model:ir.model.fields,field_description:vault.field_vault_send_wizard__key_user +msgid "Key User" +msgstr "" + +#. module: vault +#. odoo-javascript +#: code:addons/vault/static/src/backend/templates.xml:0 +#, python-format +msgid "Keyfile:" +msgstr "" + +#. module: vault +#: model:ir.model.fields,field_description:vault.field_res_users__keys +msgid "Keys" +msgstr "" + +#. module: vault +#: model:ir.model.fields,field_description:vault.field_res_users_key____last_update +#: model:ir.model.fields,field_description:vault.field_vault____last_update +#: model:ir.model.fields,field_description:vault.field_vault_entry____last_update +#: model:ir.model.fields,field_description:vault.field_vault_export_wizard____last_update +#: model:ir.model.fields,field_description:vault.field_vault_field____last_update +#: model:ir.model.fields,field_description:vault.field_vault_file____last_update +#: model:ir.model.fields,field_description:vault.field_vault_import_wizard____last_update +#: model:ir.model.fields,field_description:vault.field_vault_import_wizard_path____last_update +#: model:ir.model.fields,field_description:vault.field_vault_inbox____last_update +#: model:ir.model.fields,field_description:vault.field_vault_inbox_log____last_update +#: model:ir.model.fields,field_description:vault.field_vault_log____last_update +#: model:ir.model.fields,field_description:vault.field_vault_right____last_update +#: model:ir.model.fields,field_description:vault.field_vault_send_wizard____last_update +#: model:ir.model.fields,field_description:vault.field_vault_store_wizard____last_update +#: model:ir.model.fields,field_description:vault.field_vault_tag____last_update +msgid "Last Modified on" +msgstr "" + +#. module: vault +#: model:ir.model.fields,field_description:vault.field_res_users_key__write_uid +#: model:ir.model.fields,field_description:vault.field_vault__write_uid +#: model:ir.model.fields,field_description:vault.field_vault_entry__write_uid +#: model:ir.model.fields,field_description:vault.field_vault_export_wizard__write_uid +#: model:ir.model.fields,field_description:vault.field_vault_field__write_uid +#: model:ir.model.fields,field_description:vault.field_vault_file__write_uid +#: model:ir.model.fields,field_description:vault.field_vault_import_wizard__write_uid +#: model:ir.model.fields,field_description:vault.field_vault_import_wizard_path__write_uid +#: model:ir.model.fields,field_description:vault.field_vault_inbox__write_uid +#: model:ir.model.fields,field_description:vault.field_vault_inbox_log__write_uid +#: model:ir.model.fields,field_description:vault.field_vault_log__write_uid +#: model:ir.model.fields,field_description:vault.field_vault_right__write_uid +#: model:ir.model.fields,field_description:vault.field_vault_send_wizard__write_uid +#: model:ir.model.fields,field_description:vault.field_vault_store_wizard__write_uid +#: model:ir.model.fields,field_description:vault.field_vault_tag__write_uid +msgid "Last Updated by" +msgstr "" + +#. module: vault +#: model:ir.model.fields,field_description:vault.field_res_users_key__write_date +#: model:ir.model.fields,field_description:vault.field_vault__write_date +#: model:ir.model.fields,field_description:vault.field_vault_entry__write_date +#: model:ir.model.fields,field_description:vault.field_vault_export_wizard__write_date +#: model:ir.model.fields,field_description:vault.field_vault_field__write_date +#: model:ir.model.fields,field_description:vault.field_vault_file__write_date +#: model:ir.model.fields,field_description:vault.field_vault_import_wizard__write_date +#: model:ir.model.fields,field_description:vault.field_vault_import_wizard_path__write_date +#: model:ir.model.fields,field_description:vault.field_vault_inbox__write_date +#: model:ir.model.fields,field_description:vault.field_vault_inbox_log__write_date +#: model:ir.model.fields,field_description:vault.field_vault_log__write_date +#: model:ir.model.fields,field_description:vault.field_vault_right__write_date +#: model:ir.model.fields,field_description:vault.field_vault_send_wizard__write_date +#: model:ir.model.fields,field_description:vault.field_vault_store_wizard__write_date +#: model:ir.model.fields,field_description:vault.field_vault_tag__write_date +msgid "Last Updated on" +msgstr "" + +#. module: vault +#. odoo-javascript +#: code:addons/vault/static/src/backend/templates.xml:0 +#, python-format +msgid "Length:" +msgstr "" + +#. module: vault +#: model:ir.model.fields,field_description:vault.field_vault__log_ids +#: model:ir.model.fields,field_description:vault.field_vault_entry__log_ids +#: model:ir.model.fields,field_description:vault.field_vault_inbox__log_ids +#: model_terms:ir.ui.view,arch_db:vault.view_vault_entry_form +#: model_terms:ir.ui.view,arch_db:vault.view_vault_form +msgid "Log" +msgstr "" + +#. module: vault +#. odoo-python +#: code:addons/vault/models/vault_log.py:0 +#: model:ir.model,name:vault.model_vault_log +#, python-format +msgid "Log entry of a vault" +msgstr "" + +#. module: vault +#: model:ir.actions.act_window,name:vault.action_res_users_keys +msgid "Manage my keys" +msgstr "" + +#. module: vault +#: model:ir.model.fields,field_description:vault.field_vault__master_key +#: model:ir.model.fields,field_description:vault.field_vault_abstract_field__master_key +#: model:ir.model.fields,field_description:vault.field_vault_export_wizard__master_key +#: model:ir.model.fields,field_description:vault.field_vault_field__master_key +#: model:ir.model.fields,field_description:vault.field_vault_file__master_key +#: model:ir.model.fields,field_description:vault.field_vault_import_wizard__master_key +#: model:ir.model.fields,field_description:vault.field_vault_right__master_key +#: model:ir.model.fields,field_description:vault.field_vault_store_wizard__master_key +msgid "Master Key" +msgstr "" + +#. module: vault +#: model:ir.model.fields,field_description:vault.field_vault_log__message +msgid "Message" +msgstr "" + +#. module: vault +#. odoo-python +#: code:addons/vault/controllers/main.py:0 +#, python-format +msgid "Missing filename" +msgstr "" + +#. module: vault +#. odoo-javascript +#: code:addons/vault/static/src/common/utils.esm.js:0 +#: code:addons/vault/static/src/common/utils.esm.js:0 +#, python-format +msgid "Missing password" +msgstr "" + +#. module: vault +#: model:ir.model.fields,field_description:vault.field_vault_store_wizard__model +msgid "Model" +msgstr "" + +#. module: vault +#: model:ir.model.fields,field_description:vault.field_res_config_settings__module_vault_share +msgid "Module Vault Share" +msgstr "" + +#. module: vault +#: model:ir.model.fields,field_description:vault.field_vault__name +#: model:ir.model.fields,field_description:vault.field_vault_abstract_field__name +#: model:ir.model.fields,field_description:vault.field_vault_entry__name +#: model:ir.model.fields,field_description:vault.field_vault_export_wizard__name +#: model:ir.model.fields,field_description:vault.field_vault_field__name +#: model:ir.model.fields,field_description:vault.field_vault_file__name +#: model:ir.model.fields,field_description:vault.field_vault_import_wizard__name +#: model:ir.model.fields,field_description:vault.field_vault_import_wizard_path__name +#: model:ir.model.fields,field_description:vault.field_vault_inbox__name +#: model:ir.model.fields,field_description:vault.field_vault_inbox_log__name +#: model:ir.model.fields,field_description:vault.field_vault_send_wizard__name +#: model:ir.model.fields,field_description:vault.field_vault_store_wizard__name +#: model:ir.model.fields,field_description:vault.field_vault_tag__name +msgid "Name" +msgstr "" + +#. module: vault +#: model_terms:ir.ui.view,arch_db:vault.inbox +msgid "Name of your secret:" +msgstr "" + +#. module: vault +#. odoo-python +#: code:addons/vault/wizards/vault_send_wizard.py:0 +#, python-format +msgid "Neither a secret nor file was given" +msgstr "" + +#. module: vault +#: model_terms:ir.ui.view,arch_db:vault.view_users_form_keys_modif +msgid "New inbox link" +msgstr "" + +#. module: vault +#: model_terms:ir.ui.view,arch_db:vault.view_users_form_keys_modif +msgid "New private key" +msgstr "" + +#. module: vault +#. odoo-python +#: code:addons/vault/controllers/main.py:0 +#, python-format +msgid "No secret found" +msgstr "" + +#. module: vault +#. odoo-python +#: code:addons/vault/models/vault_inbox.py:0 +#: code:addons/vault/wizards/vault_send_wizard.py:0 +#: model:ir.model.constraint,message:vault.constraint_vault_inbox_value_check +#: model:ir.model.constraint,message:vault.constraint_vault_send_wizard_value_check +#, python-format +msgid "No value found" +msgstr "" + +#. module: vault +#: model_terms:ir.ui.view,arch_db:vault.view_vault_entry_search +msgid "Not Expired" +msgstr "" + +#. module: vault +#: model:ir.model.fields,field_description:vault.field_vault__note +#: model:ir.model.fields,field_description:vault.field_vault_entry__note +#: model_terms:ir.ui.view,arch_db:vault.view_vault_entry_form +msgid "Note" +msgstr "" + +#. module: vault +#: model:ir.model.fields,field_description:vault.field_vault__user_id +#: model:ir.model.fields,field_description:vault.field_vault_entry__user_id +msgid "Owner" +msgstr "" + +#. module: vault +#: model:ir.model.fields,field_description:vault.field_vault_entry__parent_id +msgid "Parent" +msgstr "" + +#. module: vault +#: model:ir.model.fields,field_description:vault.field_vault_import_wizard__parent_id +msgid "Parent Entry" +msgstr "" + +#. module: vault +#. odoo-javascript +#: code:addons/vault/static/src/backend/templates.xml:0 +#, python-format +msgid "Password:" +msgstr "" + +#. module: vault +#: model:ir.model.fields,field_description:vault.field_vault_import_wizard__path +msgid "Path to import" +msgstr "" + +#. module: vault +#: model:ir.model.fields,field_description:vault.field_vault__perm_user +#: model:ir.model.fields,field_description:vault.field_vault_abstract_field__perm_user +#: model:ir.model.fields,field_description:vault.field_vault_entry__perm_user +#: model:ir.model.fields,field_description:vault.field_vault_field__perm_user +#: model:ir.model.fields,field_description:vault.field_vault_file__perm_user +#: model:ir.model.fields,field_description:vault.field_vault_right__perm_user +msgid "Perm User" +msgstr "" + +#. module: vault +#. odoo-javascript +#: code:addons/vault/static/src/backend/export.esm.js:0 +#: code:addons/vault/static/src/backend/import.esm.js:0 +#, python-format +msgid "Please enter the password for the database" +msgstr "" + +#. module: vault +#. odoo-javascript +#: code:addons/vault/static/src/backend/import.esm.js:0 +#, python-format +msgid "Please enter the password for the keepass database" +msgstr "" + +#. module: vault +#. odoo-javascript +#: code:addons/vault/static/src/backend/vault.esm.js:0 +#, python-format +msgid "Please enter the password for your private key" +msgstr "" + +#. module: vault +#. odoo-javascript +#: code:addons/vault/static/src/backend/templates.xml:0 +#, python-format +msgid "Please enter your password or upload a keyfile:" +msgstr "" + +#. module: vault +#. odoo-python +#: code:addons/vault/controllers/main.py:0 +#, python-format +msgid "Please specify a name" +msgstr "" + +#. module: vault +#: model:ir.model.fields,field_description:vault.field_res_users_key__private +msgid "Private" +msgstr "" + +#. module: vault +#: model:ir.model.fields,field_description:vault.field_res_users_key__public +#: model:ir.model.fields,field_description:vault.field_vault_send_wizard__public +msgid "Public" +msgstr "" + +#. module: vault +#: model:ir.model.fields,field_description:vault.field_vault_right__public_key +msgid "Public Key" +msgstr "" + +#. module: vault +#: model_terms:ir.ui.view,arch_db:vault.view_vault_form +msgid "Re-encrypt" +msgstr "" + +#. module: vault +#: model:ir.model.fields,field_description:vault.field_vault__reencrypt_required +msgid "Reencrypt Required" +msgstr "" + +#. module: vault +#: model:ir.actions.act_window,name:vault.action_vault_right +#: model:ir.model.fields,field_description:vault.field_vault__right_ids +#: model:ir.ui.menu,name:vault.menu_vault_right +#: model_terms:ir.ui.view,arch_db:vault.view_vault_form +msgid "Rights" +msgstr "" + +#. module: vault +#: model:ir.model.fields,field_description:vault.field_res_users_key__salt +msgid "Salt" +msgstr "" + +#. module: vault +#. odoo-javascript +#: code:addons/vault/static/src/backend/fields/vault_export_file.esm.js:0 +#: code:addons/vault/static/src/backend/fields/vault_file.esm.js:0 +#, python-format +msgid "Save As..." +msgstr "" + +#. module: vault +#. odoo-javascript +#: code:addons/vault/static/src/backend/fields/templates.xml:0 +#: code:addons/vault/static/src/backend/fields/templates.xml:0 +#: code:addons/vault/static/src/backend/fields/templates.xml:0 +#: code:addons/vault/static/src/backend/fields/templates.xml:0 +#, python-format +msgid "Save in a vault" +msgstr "" + +#. module: vault +#: model:ir.model.fields,field_description:vault.field_vault_inbox__secret +#: model:ir.model.fields,field_description:vault.field_vault_send_wizard__secret +#: model:ir.model.fields,field_description:vault.field_vault_store_wizard__secret +#: model_terms:ir.ui.view,arch_db:vault.inbox +msgid "Secret" +msgstr "" + +#. module: vault +#: model:ir.model.fields,field_description:vault.field_vault_inbox__secret_file +#: model:ir.model.fields,field_description:vault.field_vault_send_wizard__secret_file +msgid "Secret File" +msgstr "" + +#. module: vault +#: model:ir.model.fields,field_description:vault.field_vault_store_wizard__secret_temporary +msgid "Secret Temporary" +msgstr "" + +#. module: vault +#: model_terms:ir.ui.view,arch_db:vault.inbox +msgid "Secret to share:" +msgstr "" + +#. module: vault +#: model_terms:ir.ui.view,arch_db:vault.view_vault_send_wizard +msgid "Send" +msgstr "" + +#. module: vault +#. odoo-javascript +#: code:addons/vault/static/src/backend/fields/templates.xml:0 +#: code:addons/vault/static/src/backend/fields/templates.xml:0 +#, python-format +msgid "Send the secret to an user" +msgstr "" + +#. module: vault +#. odoo-javascript +#: code:addons/vault/static/src/backend/fields/vault_mixin.esm.js:0 +#, python-format +msgid "Send the secret to another user" +msgstr "" + +#. module: vault +#: model:ir.model.fields,field_description:vault.field_vault_right__perm_share +msgid "Share" +msgstr "" + +#. module: vault +#. odoo-javascript +#: code:addons/vault/static/src/backend/fields/templates.xml:0 +#: code:addons/vault/static/src/backend/fields/templates.xml:0 +#, python-format +msgid "Show" +msgstr "" + +#. module: vault +#. odoo-python +#: code:addons/vault/controllers/main.py:0 +#, python-format +msgid "Something went wrong with the encryption" +msgstr "" + +#. module: vault +#. odoo-javascript +#: code:addons/vault/static/src/backend/templates.xml:0 +#, python-format +msgid "Special" +msgstr "" + +#. module: vault +#: model:ir.model.fields,field_description:vault.field_vault_log__state +msgid "State" +msgstr "" + +#. module: vault +#: model_terms:ir.ui.view,arch_db:vault.view_vault_store_wizard +msgid "Store" +msgstr "" + +#. module: vault +#. odoo-javascript +#: code:addons/vault/static/src/backend/fields/vault_inbox_mixin.esm.js:0 +#, python-format +msgid "Store the secret in a vault" +msgstr "" + +#. module: vault +#: model_terms:ir.ui.view,arch_db:vault.inbox +msgid "Submit secret" +msgstr "" + +#. module: vault +#. odoo-python +#: code:addons/vault/controllers/main.py:0 +#, python-format +msgid "Successfully stored" +msgstr "" + +#. module: vault +#: model:ir.model.fields,field_description:vault.field_vault_entry__tags +msgid "Tags" +msgstr "" + +#. module: vault +#. odoo-python +#: code:addons/vault/models/vault.py:0 +#: code:addons/vault/models/vault_entry.py:0 +#: model:ir.model.constraint,message:vault.constraint_vault_entry_vault_uuid_uniq +#: model:ir.model.constraint,message:vault.constraint_vault_uuid_uniq +#, python-format +msgid "The UUID must be unique." +msgstr "" + +#. module: vault +#. odoo-javascript +#: code:addons/vault/static/src/backend/fields/vault_export_file.esm.js:0 +#: code:addons/vault/static/src/backend/fields/vault_file.esm.js:0 +#, python-format +msgid "The field is empty, there's nothing to save!" +msgstr "" + +#. module: vault +#: model_terms:ir.ui.view,arch_db:vault.view_vault_import_wizard +msgid "The files must end on one of the supported file type:" +msgstr "" + +#. module: vault +#. odoo-javascript +#: code:addons/vault/static/src/backend/controller.esm.js:0 +#, python-format +msgid "The following entries are broken:" +msgstr "" + +#. module: vault +#. odoo-javascript +#: code:addons/vault/static/src/common/utils.esm.js:0 +#, python-format +msgid "The passwords aren't matching" +msgstr "" + +#. module: vault +#. odoo-python +#: code:addons/vault/models/abstract_vault.py:0 +#, python-format +msgid "" +"The requested operation can not be completed due to security restrictions." +msgstr "" + +#. module: vault +#. odoo-python +#: code:addons/vault/models/vault_tag.py:0 +#: model:ir.model.constraint,message:vault.constraint_vault_tag_name_uniq +#, python-format +msgid "The tag must be unique!" +msgstr "" + +#. module: vault +#. odoo-python +#: code:addons/vault/models/vault_right.py:0 +#: model:ir.model.constraint,message:vault.constraint_vault_right_user_uniq +#, python-format +msgid "The user must be unique" +msgstr "" + +#. module: vault +#: model:ir.model.fields,field_description:vault.field_vault_inbox__token +msgid "Token" +msgstr "" + +#. module: vault +#. odoo-javascript +#: code:addons/vault/static/src/backend/import.esm.js:0 +#, python-format +msgid "Unsupported file to import" +msgstr "" + +#. module: vault +#: model:ir.model.fields,field_description:vault.field_vault_entry__url +msgid "Url" +msgstr "" + +#. module: vault +#: model:ir.model,name:vault.model_res_users +#: model:ir.model.fields,field_description:vault.field_res_users_key__user_id +#: model:ir.model.fields,field_description:vault.field_vault_log__user_id +#: model:ir.model.fields,field_description:vault.field_vault_right__user_id +#: model:ir.model.fields,field_description:vault.field_vault_send_wizard__user_id +msgid "User" +msgstr "" + +#. module: vault +#. odoo-python +#: code:addons/vault/models/res_users_key.py:0 +#: model:ir.model,name:vault.model_res_users_key +#, python-format +msgid "User data of a vault" +msgstr "" + +#. module: vault +#: model:ir.model.fields,help:vault.field_vault_inbox__inbox_link +msgid "" +"Using this link you can write to the current inbox. If you want people to " +"create new inboxes you should give them your inbox link from your key " +"management." +msgstr "" + +#. module: vault +#: model:ir.model.fields,field_description:vault.field_res_users_key__uuid +#: model:ir.model.fields,field_description:vault.field_vault__uuid +#: model:ir.model.fields,field_description:vault.field_vault_entry__uuid +#: model:ir.model.fields,field_description:vault.field_vault_import_wizard__uuid +#: model:ir.model.fields,field_description:vault.field_vault_import_wizard_path__uuid +msgid "Uuid" +msgstr "" + +#. module: vault +#: model:ir.model.fields,field_description:vault.field_vault_field__value +#: model:ir.model.fields,field_description:vault.field_vault_file__value +msgid "Value" +msgstr "" + +#. module: vault +#. odoo-python +#: code:addons/vault/models/vault.py:0 +#: model:ir.actions.act_window,name:vault.action_vault +#: model:ir.model,name:vault.model_vault +#: model:ir.model.fields,field_description:vault.field_vault_abstract_field__vault_id +#: model:ir.model.fields,field_description:vault.field_vault_entry__vault_id +#: model:ir.model.fields,field_description:vault.field_vault_export_wizard__vault_id +#: model:ir.model.fields,field_description:vault.field_vault_field__vault_id +#: model:ir.model.fields,field_description:vault.field_vault_file__vault_id +#: model:ir.model.fields,field_description:vault.field_vault_import_wizard__vault_id +#: model:ir.model.fields,field_description:vault.field_vault_inbox__user_id +#: model:ir.model.fields,field_description:vault.field_vault_log__vault_id +#: model:ir.model.fields,field_description:vault.field_vault_right__vault_id +#: model:ir.model.fields,field_description:vault.field_vault_store_wizard__vault_id +#: model:ir.ui.menu,name:vault.menu_vault +#: model_terms:ir.ui.view,arch_db:vault.res_config_settings_view_form +#: model_terms:ir.ui.view,arch_db:vault.view_vault_entry_search +#, python-format +msgid "Vault" +msgstr "" + +#. module: vault +#. odoo-javascript +#: code:addons/vault/static/src/backend/fields/vault_field.esm.js:0 +#, python-format +msgid "Vault Field" +msgstr "" + +#. module: vault +#. odoo-javascript +#: code:addons/vault/static/src/backend/fields/vault_file.esm.js:0 +#, python-format +msgid "Vault File" +msgstr "" + +#. module: vault +#. odoo-javascript +#: code:addons/vault/static/src/backend/fields/vault_inbox_field.esm.js:0 +#, python-format +msgid "Vault Inbox Field" +msgstr "" + +#. module: vault +#. odoo-javascript +#: code:addons/vault/static/src/backend/fields/vault_inbox_file.esm.js:0 +#, python-format +msgid "Vault Inbox File" +msgstr "" + +#. module: vault +#: model:ir.model.fields,field_description:vault.field_res_users__vault_right_ids +msgid "Vault Right" +msgstr "" + +#. module: vault +#: model_terms:ir.ui.view,arch_db:vault.res_config_settings_view_form +msgid "Vault Share" +msgstr "" + +#. module: vault +#. odoo-python +#: code:addons/vault/models/vault_inbox_log.py:0 +#: model:ir.model,name:vault.model_vault_inbox_log +#, python-format +msgid "Vault inbox log" +msgstr "" + +#. module: vault +#. odoo-javascript +#: code:addons/vault/static/src/backend/controller.esm.js:0 +#, python-format +msgid "Vault is not supported" +msgstr "" + +#. module: vault +#. odoo-python +#: code:addons/vault/models/vault_right.py:0 +#: model:ir.model,name:vault.model_vault_right +#, python-format +msgid "Vault rights" +msgstr "" + +#. module: vault +#. odoo-python +#: code:addons/vault/models/vault_inbox.py:0 +#: model:ir.model,name:vault.model_vault_inbox +#, python-format +msgid "Vault share incoming secrets" +msgstr "" + +#. module: vault +#. odoo-python +#: code:addons/vault/models/vault_tag.py:0 +#: model:ir.model,name:vault.model_vault_tag +#, python-format +msgid "Vault tag" +msgstr "" + +#. module: vault +#: model_terms:ir.ui.view,arch_db:vault.view_vault_entry_search +msgid "Vaults" +msgstr "" + +#. module: vault +#: model_terms:ir.ui.view,arch_db:vault.view_vault_form +msgid "Verify" +msgstr "" + +#. module: vault +#: model:ir.model.fields,field_description:vault.field_res_users_key__version +msgid "Version" +msgstr "" + +#. module: vault +#. odoo-python +#: code:addons/vault/models/vault_log.py:0 +#, python-format +msgid "Warning" +msgstr "" + +#. module: vault +#. odoo-python +#: code:addons/vault/wizards/vault_store_wizard.py:0 +#: model:ir.model,name:vault.model_vault_store_wizard +#, python-format +msgid "Wizard store a shared secret in a vault" +msgstr "" + +#. module: vault +#. odoo-python +#: code:addons/vault/wizards/vault_send_wizard.py:0 +#: model:ir.model,name:vault.model_vault_send_wizard +#, python-format +msgid "Wizard to send another user a secret" +msgstr "" + +#. module: vault +#: model:ir.model.fields,field_description:vault.field_vault_right__perm_write +msgid "Write" +msgstr "" + +#. module: vault +#. odoo-python +#: code:addons/vault/models/vault_inbox.py:0 +#, python-format +msgid "Written by %(name)s via %(ip)s" +msgstr "" + +#. module: vault +#. odoo-python +#: code:addons/vault/models/vault_entry.py:0 +#, python-format +msgid "You can not create recursive entries." +msgstr "" + +#. module: vault +#: model_terms:ir.ui.view,arch_db:vault.view_vault_send_wizard +msgid "" +"You can only send the secret to the user who has generated a key-pair.\n" +" If an user is not showing please ask him to generate these." +msgstr "" + +#. module: vault +#: model_terms:ir.ui.view,arch_db:vault.view_users_form_keys_modif +msgid "" +"You will loose access to all vaults and your inbox. Do you want to continue?" +msgstr "" + +#. module: vault +#. odoo-javascript +#: code:addons/vault/static/src/backend/templates.xml:0 +#, python-format +msgid "a-z" +msgstr "" + +#. module: vault +#: model_terms:ir.ui.view,arch_db:vault.view_vault_import_wizard +#: model_terms:ir.ui.view,arch_db:vault.view_vault_send_wizard +#: model_terms:ir.ui.view,arch_db:vault.view_vault_store_wizard +msgid "or" +msgstr "" diff --git a/vault/i18n/nl.po b/vault/i18n/nl.po new file mode 100644 index 0000000000..eeb7fc93f9 --- /dev/null +++ b/vault/i18n/nl.po @@ -0,0 +1,1477 @@ +# Translation of Odoo Server. +# This file contains the translation of the following modules: +# * vault +# +msgid "" +msgstr "" +"Project-Id-Version: Odoo Server 15.0\n" +"Report-Msgid-Bugs-To: \n" +"PO-Revision-Date: 2023-05-05 10:45+0000\n" +"Last-Translator: Bosd \n" +"Language-Team: none\n" +"Language: nl\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: \n" +"Plural-Forms: nplurals=2; plural=n != 1;\n" +"X-Generator: Weblate 4.14.1\n" + +#. module: vault +#. odoo-python +#: code:addons/vault/models/vault_entry.py:0 +#, python-format +msgid "%(action)s entry %(name)s by %(user)s" +msgstr "%(action)s toegang %(name)s door %(user)s" + +#. module: vault +#. odoo-javascript +#: code:addons/vault/static/src/backend/controller.esm.js:0 +#, python-format +msgid "%s '%s' of entry '%s'" +msgstr "" + +#. module: vault +#. odoo-python +#: code:addons/vault/models/vault_entry.py:0 +#, python-format +msgid "%s (copy)" +msgstr "" + +#. module: vault +#. odoo-javascript +#: code:addons/vault/static/src/backend/controller.esm.js:0 +#, python-format +msgid "" +"A secure browser context is required. Please switch to https or contact your " +"administrator" +msgstr "" + +#. module: vault +#. odoo-javascript +#: code:addons/vault/static/src/backend/templates.xml:0 +#, python-format +msgid "A-Z" +msgstr "A-Z" + +#. module: vault +#. odoo-python +#: code:addons/vault/models/abstract_vault_field.py:0 +#: model:ir.model,name:vault.model_vault_abstract_field +#, python-format +msgid "Abstract model to implement basic fields for encryption" +msgstr "Abstract model om basisvelden voor encryptie te implementeren" + +#. module: vault +#. odoo-python +#: code:addons/vault/models/abstract_vault.py:0 +#: model:ir.model,name:vault.model_vault_abstract +#, python-format +msgid "Abstract model to implement general access rights" +msgstr "Abstract model om algemene toegangsrechten te implementeren" + +#. module: vault +#: model:ir.model.fields,field_description:vault.field_vault_inbox__accesses +msgid "Access counter" +msgstr "Toegangsteller" + +#. module: vault +#: model:ir.model.fields,field_description:vault.field_res_users__active_key +msgid "Active Key" +msgstr "Actieve sleutel" + +#. module: vault +#: model:ir.actions.act_window,name:vault.action_vault_entry +#: model:ir.ui.menu,name:vault.menu_vault_entry +msgid "All Entries" +msgstr "Alle invoeren" + +#. module: vault +#: model_terms:ir.ui.view,arch_db:vault.res_config_settings_view_form +msgid "Allow all users to export vaults accessible to them" +msgstr "" + +#. module: vault +#: model_terms:ir.ui.view,arch_db:vault.res_config_settings_view_form +msgid "Allow all users to import vaults accessible to them" +msgstr "" + +#. module: vault +#: model_terms:ir.ui.view,arch_db:vault.res_config_settings_view_form +msgid "Allow the usage to share secrets with external users" +msgstr "" + +#. module: vault +#: model:ir.model.fields,help:vault.field_vault_right__perm_create +msgid "Allow to create in the vault" +msgstr "" + +#. module: vault +#: model:ir.model.fields,help:vault.field_vault_right__perm_delete +msgid "Allow to delete a vault" +msgstr "" + +#. module: vault +#: model:res.groups,name:vault.group_vault_export +msgid "Allow to export vaults" +msgstr "" + +#. module: vault +#: model:res.groups,name:vault.group_vault_import +msgid "Allow to import vaults" +msgstr "" + +#. module: vault +#: model:ir.model.fields,help:vault.field_vault_right__perm_share +msgid "Allow to share a vault with new users" +msgstr "" + +#. module: vault +#: model:ir.model.fields,help:vault.field_vault_right__perm_write +msgid "Allow to write to the vault" +msgstr "" + +#. module: vault +#: model:ir.model.fields,field_description:vault.field_vault__allowed_create +#: model:ir.model.fields,field_description:vault.field_vault_abstract_field__allowed_create +#: model:ir.model.fields,field_description:vault.field_vault_entry__allowed_create +#: model:ir.model.fields,field_description:vault.field_vault_field__allowed_create +#: model:ir.model.fields,field_description:vault.field_vault_file__allowed_create +#: model:ir.model.fields,field_description:vault.field_vault_right__allowed_create +msgid "Allowed Create" +msgstr "" + +#. module: vault +#: model:ir.model.fields,field_description:vault.field_vault__allowed_delete +#: model:ir.model.fields,field_description:vault.field_vault_abstract_field__allowed_delete +#: model:ir.model.fields,field_description:vault.field_vault_entry__allowed_delete +#: model:ir.model.fields,field_description:vault.field_vault_field__allowed_delete +#: model:ir.model.fields,field_description:vault.field_vault_file__allowed_delete +#: model:ir.model.fields,field_description:vault.field_vault_right__allowed_delete +msgid "Allowed Delete" +msgstr "" + +#. module: vault +#: model:ir.model.fields,field_description:vault.field_vault__allowed_read +#: model:ir.model.fields,field_description:vault.field_vault_abstract_field__allowed_read +#: model:ir.model.fields,field_description:vault.field_vault_entry__allowed_read +#: model:ir.model.fields,field_description:vault.field_vault_field__allowed_read +#: model:ir.model.fields,field_description:vault.field_vault_file__allowed_read +#: model:ir.model.fields,field_description:vault.field_vault_right__allowed_read +msgid "Allowed Read" +msgstr "" + +#. module: vault +#: model:ir.model.fields,field_description:vault.field_vault__allowed_share +#: model:ir.model.fields,field_description:vault.field_vault_abstract_field__allowed_share +#: model:ir.model.fields,field_description:vault.field_vault_entry__allowed_share +#: model:ir.model.fields,field_description:vault.field_vault_field__allowed_share +#: model:ir.model.fields,field_description:vault.field_vault_file__allowed_share +#: model:ir.model.fields,field_description:vault.field_vault_right__allowed_share +msgid "Allowed Share" +msgstr "" + +#. module: vault +#: model:ir.model.fields,field_description:vault.field_vault__allowed_write +#: model:ir.model.fields,field_description:vault.field_vault_abstract_field__allowed_write +#: model:ir.model.fields,field_description:vault.field_vault_entry__allowed_write +#: model:ir.model.fields,field_description:vault.field_vault_field__allowed_write +#: model:ir.model.fields,field_description:vault.field_vault_file__allowed_write +#: model:ir.model.fields,field_description:vault.field_vault_right__allowed_write +msgid "Allowed Write" +msgstr "" + +#. module: vault +#. odoo-python +#: code:addons/vault/controllers/main.py:0 +#, python-format +msgid "An error occured. Please contact the user or administrator" +msgstr "" +"Er is een fout opgetreden. Neem contact op met de gebruiker of beheerder" + +#. module: vault +#: model_terms:ir.ui.view,arch_db:vault.view_vault_right_overview_search +msgid "By user" +msgstr "Door gebruiker" + +#. module: vault +#: model_terms:ir.ui.view,arch_db:vault.view_vault_right_overview_search +msgid "By vault" +msgstr "" + +#. module: vault +#. odoo-javascript +#: code:addons/vault/static/src/common/utils.esm.js:0 +#: model_terms:ir.ui.view,arch_db:vault.view_users_form_keys_modif +#: model_terms:ir.ui.view,arch_db:vault.view_vault_import_wizard +#: model_terms:ir.ui.view,arch_db:vault.view_vault_send_wizard +#: model_terms:ir.ui.view,arch_db:vault.view_vault_store_wizard +#, python-format +msgid "Cancel" +msgstr "Annuleer" + +#. module: vault +#. odoo-javascript +#: code:addons/vault/static/src/common/utils.esm.js:0 +#, python-format +msgid "Cancelled" +msgstr "Geannuleerd" + +#. module: vault +#. odoo-javascript +#: code:addons/vault/static/src/backend/templates.xml:0 +#, python-format +msgid "Characters:" +msgstr "Karakters:" + +#. module: vault +#: model:ir.model.fields,field_description:vault.field_vault_entry__child_ids +msgid "Child" +msgstr "" + +#. module: vault +#: model_terms:ir.ui.view,arch_db:vault.view_vault_entry_form +msgid "Childs" +msgstr "" + +#. module: vault +#: model_terms:ir.ui.view,arch_db:vault.view_vault_export_wizard +msgid "Close" +msgstr "Sluiten" + +#. module: vault +#: model:ir.model.fields,field_description:vault.field_vault_abstract_field__entry_name +#: model:ir.model.fields,field_description:vault.field_vault_entry__complete_name +#: model:ir.model.fields,field_description:vault.field_vault_field__entry_name +#: model:ir.model.fields,field_description:vault.field_vault_file__entry_name +msgid "Complete Name" +msgstr "Volledige naam" + +#. module: vault +#: model:ir.model,name:vault.model_res_config_settings +msgid "Config Settings" +msgstr "Configuratie-instellingen" + +#. module: vault +#. odoo-javascript +#: code:addons/vault/static/src/backend/templates.xml:0 +#, python-format +msgid "Confirm your password:" +msgstr "Bevestig uw wachtwoord:" + +#. module: vault +#: model_terms:ir.ui.view,arch_db:vault.view_vault_entry_form +msgid "Content" +msgstr "Inhoud" + +#. module: vault +#. odoo-javascript +#: code:addons/vault/static/src/backend/fields/templates.xml:0 +#, python-format +msgid "Copy to clipboard" +msgstr "Kopiëren naar klembord" + +#. module: vault +#: model:ir.model.fields,field_description:vault.field_vault_right__perm_create +msgid "Create" +msgstr "Aanmaken" + +#. module: vault +#: model:ir.model.fields,field_description:vault.field_res_users_key__create_uid +#: model:ir.model.fields,field_description:vault.field_vault__create_uid +#: model:ir.model.fields,field_description:vault.field_vault_entry__create_uid +#: model:ir.model.fields,field_description:vault.field_vault_export_wizard__create_uid +#: model:ir.model.fields,field_description:vault.field_vault_field__create_uid +#: model:ir.model.fields,field_description:vault.field_vault_file__create_uid +#: model:ir.model.fields,field_description:vault.field_vault_import_wizard__create_uid +#: model:ir.model.fields,field_description:vault.field_vault_import_wizard_path__create_uid +#: model:ir.model.fields,field_description:vault.field_vault_inbox__create_uid +#: model:ir.model.fields,field_description:vault.field_vault_inbox_log__create_uid +#: model:ir.model.fields,field_description:vault.field_vault_log__create_uid +#: model:ir.model.fields,field_description:vault.field_vault_right__create_uid +#: model:ir.model.fields,field_description:vault.field_vault_send_wizard__create_uid +#: model:ir.model.fields,field_description:vault.field_vault_store_wizard__create_uid +#: model:ir.model.fields,field_description:vault.field_vault_tag__create_uid +msgid "Created by" +msgstr "Aangemaakt door" + +#. module: vault +#. odoo-python +#: code:addons/vault/models/vault_inbox.py:0 +#, python-format +msgid "Created by %(name)s via %(ip)s" +msgstr "" + +#. module: vault +#. odoo-python +#: code:addons/vault/wizards/vault_send_wizard.py:0 +#, python-format +msgid "Created by %s" +msgstr "Aangemaakt door %s" + +#. module: vault +#: model:ir.model.fields,field_description:vault.field_res_users_key__create_date +#: model:ir.model.fields,field_description:vault.field_vault__create_date +#: model:ir.model.fields,field_description:vault.field_vault_entry__create_date +#: model:ir.model.fields,field_description:vault.field_vault_export_wizard__create_date +#: model:ir.model.fields,field_description:vault.field_vault_field__create_date +#: model:ir.model.fields,field_description:vault.field_vault_file__create_date +#: model:ir.model.fields,field_description:vault.field_vault_import_wizard__create_date +#: model:ir.model.fields,field_description:vault.field_vault_import_wizard_path__create_date +#: model:ir.model.fields,field_description:vault.field_vault_inbox__create_date +#: model:ir.model.fields,field_description:vault.field_vault_inbox_log__create_date +#: model:ir.model.fields,field_description:vault.field_vault_log__create_date +#: model:ir.model.fields,field_description:vault.field_vault_right__create_date +#: model:ir.model.fields,field_description:vault.field_vault_send_wizard__create_date +#: model:ir.model.fields,field_description:vault.field_vault_store_wizard__create_date +#: model:ir.model.fields,field_description:vault.field_vault_tag__create_date +msgid "Created on" +msgstr "Aangemaakt op" + +#. module: vault +#: model:ir.model.fields,field_description:vault.field_vault_import_wizard__crypted_content +msgid "Crypted Content" +msgstr "Versleutelde inhoud" + +#. module: vault +#: model:ir.model.fields,field_description:vault.field_res_users_key__current +msgid "Current" +msgstr "Huidig" + +#. module: vault +#: model_terms:ir.ui.view,arch_db:vault.view_vault_import_wizard +msgid "Custom JSON format .json" +msgstr "" + +#. module: vault +#: model:ir.model.fields,field_description:vault.field_vault_import_wizard__content +msgid "Database" +msgstr "Database" + +#. module: vault +#: model:ir.model.fields,field_description:vault.field_vault_right__perm_delete +msgid "Delete" +msgstr "Verwijder" + +#. module: vault +#: model:ir.model.fields,field_description:vault.field_res_users_key__display_name +#: model:ir.model.fields,field_description:vault.field_vault__display_name +#: model:ir.model.fields,field_description:vault.field_vault_entry__display_name +#: model:ir.model.fields,field_description:vault.field_vault_export_wizard__display_name +#: model:ir.model.fields,field_description:vault.field_vault_field__display_name +#: model:ir.model.fields,field_description:vault.field_vault_file__display_name +#: model:ir.model.fields,field_description:vault.field_vault_import_wizard__display_name +#: model:ir.model.fields,field_description:vault.field_vault_import_wizard_path__display_name +#: model:ir.model.fields,field_description:vault.field_vault_inbox__display_name +#: model:ir.model.fields,field_description:vault.field_vault_inbox_log__display_name +#: model:ir.model.fields,field_description:vault.field_vault_log__display_name +#: model:ir.model.fields,field_description:vault.field_vault_right__display_name +#: model:ir.model.fields,field_description:vault.field_vault_send_wizard__display_name +#: model:ir.model.fields,field_description:vault.field_vault_store_wizard__display_name +#: model:ir.model.fields,field_description:vault.field_vault_tag__display_name +msgid "Display Name" +msgstr "Schermnaam" + +#. module: vault +#. odoo-javascript +#: code:addons/vault/static/src/backend/controller.esm.js:0 +#, python-format +msgid "Do you really want to create a new key pair and set it active?" +msgstr "Wilt u echt een nieuw sleutelpaar aanmaken en activeren?" + +#. module: vault +#: model:ir.model.fields,field_description:vault.field_vault_export_wizard__content +msgid "Download" +msgstr "Download" + +#. module: vault +#. odoo-javascript +#: code:addons/vault/static/src/common/utils.esm.js:0 +#, python-format +msgid "Enter" +msgstr "" + +#. module: vault +#. odoo-javascript +#: code:addons/vault/static/src/backend/templates.xml:0 +#, python-format +msgid "Enter your password:" +msgstr "Voer uw wachtwoord in:" + +#. module: vault +#: model:ir.actions.act_window,name:vault.action_open_entries +#: model:ir.model.fields,field_description:vault.field_vault__entry_ids +#: model:ir.model.fields,field_description:vault.field_vault_export_wizard__entry_id +#: model_terms:ir.ui.view,arch_db:vault.view_vault_entry_search +#: model_terms:ir.ui.view,arch_db:vault.view_vault_form +msgid "Entries" +msgstr "Boekingen" + +#. module: vault +#: model:ir.model.fields,field_description:vault.field_vault_abstract_field__entry_id +#: model:ir.model.fields,field_description:vault.field_vault_field__entry_id +#: model:ir.model.fields,field_description:vault.field_vault_file__entry_id +#: model:ir.model.fields,field_description:vault.field_vault_log__entry_id +#: model:ir.model.fields,field_description:vault.field_vault_store_wizard__entry_id +msgid "Entry" +msgstr "" + +#. module: vault +#. odoo-python +#: code:addons/vault/models/vault_entry.py:0 +#: model:ir.model,name:vault.model_vault_entry +#, python-format +msgid "Entry inside a vault" +msgstr "" + +#. module: vault +#. odoo-python +#: code:addons/vault/models/vault_log.py:0 +#, python-format +msgid "Error" +msgstr "Fout" + +#. module: vault +#: model:ir.model.fields,field_description:vault.field_vault_inbox__expiration +msgid "Expiration" +msgstr "Vervaldatum" + +#. module: vault +#: model:ir.model.fields,field_description:vault.field_vault_entry__expired +#: model_terms:ir.ui.view,arch_db:vault.view_vault_entry_search +msgid "Expired" +msgstr "Verlopen" + +#. module: vault +#: model:ir.model.fields,field_description:vault.field_vault_entry__expire_date +msgid "Expires on" +msgstr "Verloopt op" + +#. module: vault +#: model:ir.model.fields,field_description:vault.field_res_config_settings__group_vault_export +msgid "Export Vaults" +msgstr "" + +#. module: vault +#. odoo-python +#: code:addons/vault/models/vault.py:0 +#: code:addons/vault/models/vault_entry.py:0 +#: model_terms:ir.ui.view,arch_db:vault.view_vault_entry_form +#: model_terms:ir.ui.view,arch_db:vault.view_vault_form +#, python-format +msgid "Export to file" +msgstr "Export naar bestand" + +#. module: vault +#. odoo-python +#: code:addons/vault/wizards/vault_export_wizard.py:0 +#: model:ir.model,name:vault.model_vault_export_wizard +#, python-format +msgid "Export wizard for vaults" +msgstr "" + +#. module: vault +#. odoo-javascript +#: code:addons/vault/static/src/backend/vault.esm.js:0 +#, python-format +msgid "Failed to export keys to object store" +msgstr "" + +#. module: vault +#. odoo-javascript +#: code:addons/vault/static/src/backend/vault.esm.js:0 +#, python-format +msgid "Failed to export the keys to the database" +msgstr "" + +#. module: vault +#. odoo-javascript +#: code:addons/vault/static/src/backend/vault.esm.js:0 +#, python-format +msgid "Failed to import keys from database" +msgstr "Kan geen sleutels uit database importeren" + +#. module: vault +#. odoo-python +#: code:addons/vault/models/vault_field.py:0 +#: model:ir.model,name:vault.model_vault_field +#, python-format +msgid "Field of a vault" +msgstr "" + +#. module: vault +#: model:ir.model.fields,field_description:vault.field_vault__field_ids +#: model:ir.model.fields,field_description:vault.field_vault_entry__field_ids +msgid "Fields" +msgstr "Velden" + +#. module: vault +#. odoo-python +#: code:addons/vault/models/vault_file.py:0 +#: model:ir.model,name:vault.model_vault_file +#, python-format +msgid "File of a vault" +msgstr "" + +#. module: vault +#: model_terms:ir.ui.view,arch_db:vault.inbox +msgid "File to share:" +msgstr "" + +#. module: vault +#: model:ir.model.fields,field_description:vault.field_vault_inbox__filename +#: model:ir.model.fields,field_description:vault.field_vault_send_wizard__filename +msgid "Filename" +msgstr "Bestandsnaam" + +#. module: vault +#: model:ir.model.fields,field_description:vault.field_vault__file_ids +#: model:ir.model.fields,field_description:vault.field_vault_entry__file_ids +msgid "Files" +msgstr "Bestanden" + +#. module: vault +#: model:ir.model.fields,field_description:vault.field_res_users_key__fingerprint +msgid "Fingerprint" +msgstr "Fingerprint" + +#. module: vault +#. odoo-javascript +#: code:addons/vault/static/src/backend/fields/templates.xml:0 +#, python-format +msgid "Generate" +msgstr "Genereer" + +#. module: vault +#. odoo-javascript +#: code:addons/vault/static/src/backend/templates.xml:0 +#, python-format +msgid "Generate a new secret:" +msgstr "Genereer een nieuw geheim:" + +#. module: vault +#: model_terms:ir.ui.view,arch_db:vault.view_vault_right_overview_search +msgid "Grouped" +msgstr "Gegroepeerd" + +#. module: vault +#. odoo-javascript +#: code:addons/vault/static/src/backend/fields/templates.xml:0 +#, python-format +msgid "Hide" +msgstr "Verbergen" + +#. module: vault +#: model:ir.model.fields,field_description:vault.field_res_users_key__id +#: model:ir.model.fields,field_description:vault.field_vault__id +#: model:ir.model.fields,field_description:vault.field_vault_entry__id +#: model:ir.model.fields,field_description:vault.field_vault_export_wizard__id +#: model:ir.model.fields,field_description:vault.field_vault_field__id +#: model:ir.model.fields,field_description:vault.field_vault_file__id +#: model:ir.model.fields,field_description:vault.field_vault_import_wizard__id +#: model:ir.model.fields,field_description:vault.field_vault_import_wizard_path__id +#: model:ir.model.fields,field_description:vault.field_vault_inbox__id +#: model:ir.model.fields,field_description:vault.field_vault_inbox_log__id +#: model:ir.model.fields,field_description:vault.field_vault_log__id +#: model:ir.model.fields,field_description:vault.field_vault_right__id +#: model:ir.model.fields,field_description:vault.field_vault_send_wizard__id +#: model:ir.model.fields,field_description:vault.field_vault_store_wizard__id +#: model:ir.model.fields,field_description:vault.field_vault_tag__id +msgid "ID" +msgstr "ID" + +#. module: vault +#: model:ir.model.fields,help:vault.field_vault_inbox__expiration +msgid "If expired the inbox can't be written using the link" +msgstr "" + +#. module: vault +#: model:ir.model.fields,help:vault.field_vault_inbox__accesses +msgid "If this is 0 the inbox can't be written using the link" +msgstr "" + +#. module: vault +#: model_terms:ir.ui.view,arch_db:vault.view_vault_import_wizard +msgid "Import" +msgstr "Import" + +#. module: vault +#: model:ir.model.fields,field_description:vault.field_res_config_settings__group_vault_import +msgid "Import Vaults" +msgstr "" + +#. module: vault +#. odoo-python +#: code:addons/vault/models/vault.py:0 +#: code:addons/vault/models/vault_entry.py:0 +#: model_terms:ir.ui.view,arch_db:vault.view_vault_entry_form +#: model_terms:ir.ui.view,arch_db:vault.view_vault_form +#, python-format +msgid "Import from file" +msgstr "Importeren uit bestand" + +#. module: vault +#. odoo-python +#: code:addons/vault/wizards/vault_import_wizard.py:0 +#: model:ir.model,name:vault.model_vault_import_wizard +#, python-format +msgid "Import wizard for vaults" +msgstr "Wizard voor het importeren van kluizen" + +#. module: vault +#. odoo-python +#: code:addons/vault/wizards/vault_import_wizard.py:0 +#: model:ir.model,name:vault.model_vault_import_wizard_path +#, python-format +msgid "Import wizard path for vaults" +msgstr "" + +#. module: vault +#: model:ir.actions.act_window,name:vault.action_vault_inbox +#: model:ir.model.fields,field_description:vault.field_res_users__inbox_ids +#: model:ir.model.fields,field_description:vault.field_vault_inbox_log__inbox_id +#: model:ir.ui.menu,name:vault.menu_vault_inbox +msgid "Inbox" +msgstr "Inbox" + +#. module: vault +#: model:ir.model.fields,field_description:vault.field_res_users__inbox_enabled +msgid "Inbox Enabled" +msgstr "" + +#. module: vault +#: model:ir.model.fields,field_description:vault.field_res_users__inbox_link +#: model:ir.model.fields,field_description:vault.field_vault_inbox__inbox_link +msgid "Inbox Link" +msgstr "" + +#. module: vault +#: model:ir.model.fields,field_description:vault.field_res_users__inbox_token +msgid "Inbox Token" +msgstr "Inbox Token" + +#. module: vault +#: model:ir.model.fields,field_description:vault.field_vault_export_wizard__include_childs +msgid "Include Childs" +msgstr "" + +#. module: vault +#. odoo-python +#: code:addons/vault/models/vault_log.py:0 +#, python-format +msgid "Information" +msgstr "Informatie" + +#. module: vault +#. odoo-python +#: code:addons/vault/wizards/vault_import_wizard.py:0 +#, python-format +msgid "Invalid file to import from" +msgstr "" + +#. module: vault +#. odoo-python +#: code:addons/vault/models/res_users_key.py:0 +#, python-format +msgid "Invalid parameter" +msgstr "Ongeldige parameter" + +#. module: vault +#. odoo-python +#: code:addons/vault/controllers/main.py:0 +#, python-format +msgid "Invalid token" +msgstr "Ongeldige token" + +#. module: vault +#: model_terms:ir.ui.view,arch_db:vault.view_users_form_keys_modif +msgid "Invalidate private key" +msgstr "" + +#. module: vault +#: model:ir.model.fields,field_description:vault.field_res_users_key__iterations +msgid "Iterations" +msgstr "Iteraties" + +#. module: vault +#: model:ir.model.fields,field_description:vault.field_res_users_key__iv +#: model:ir.model.fields,field_description:vault.field_vault_abstract_field__iv +#: model:ir.model.fields,field_description:vault.field_vault_field__iv +#: model:ir.model.fields,field_description:vault.field_vault_file__iv +#: model:ir.model.fields,field_description:vault.field_vault_inbox__iv +#: model:ir.model.fields,field_description:vault.field_vault_send_wizard__iv +#: model:ir.model.fields,field_description:vault.field_vault_store_wizard__iv +msgid "Iv" +msgstr "" + +#. module: vault +#: model_terms:ir.ui.view,arch_db:vault.view_vault_import_wizard +msgid "Keepass Database .kdbx" +msgstr "Keepass Database .kdbx" + +#. module: vault +#: model:ir.model.fields,field_description:vault.field_vault_inbox__key +#: model:ir.model.fields,field_description:vault.field_vault_right__key +#: model:ir.model.fields,field_description:vault.field_vault_send_wizard__key +#: model:ir.model.fields,field_description:vault.field_vault_store_wizard__key +msgid "Key" +msgstr "Sleutel" + +#. module: vault +#. odoo-javascript +#: code:addons/vault/static/src/backend/user_menu.esm.js:0 +#, python-format +msgid "Key Management" +msgstr "" + +#. module: vault +#: model:ir.model.fields,field_description:vault.field_vault_send_wizard__key_user +msgid "Key User" +msgstr "" + +#. module: vault +#. odoo-javascript +#: code:addons/vault/static/src/backend/templates.xml:0 +#, python-format +msgid "Keyfile:" +msgstr "Keyfile:" + +#. module: vault +#: model:ir.model.fields,field_description:vault.field_res_users__keys +msgid "Keys" +msgstr "Keys" + +#. module: vault +#: model:ir.model.fields,field_description:vault.field_res_users_key____last_update +#: model:ir.model.fields,field_description:vault.field_vault____last_update +#: model:ir.model.fields,field_description:vault.field_vault_entry____last_update +#: model:ir.model.fields,field_description:vault.field_vault_export_wizard____last_update +#: model:ir.model.fields,field_description:vault.field_vault_field____last_update +#: model:ir.model.fields,field_description:vault.field_vault_file____last_update +#: model:ir.model.fields,field_description:vault.field_vault_import_wizard____last_update +#: model:ir.model.fields,field_description:vault.field_vault_import_wizard_path____last_update +#: model:ir.model.fields,field_description:vault.field_vault_inbox____last_update +#: model:ir.model.fields,field_description:vault.field_vault_inbox_log____last_update +#: model:ir.model.fields,field_description:vault.field_vault_log____last_update +#: model:ir.model.fields,field_description:vault.field_vault_right____last_update +#: model:ir.model.fields,field_description:vault.field_vault_send_wizard____last_update +#: model:ir.model.fields,field_description:vault.field_vault_store_wizard____last_update +#: model:ir.model.fields,field_description:vault.field_vault_tag____last_update +msgid "Last Modified on" +msgstr "Laatst gewijzigd op" + +#. module: vault +#: model:ir.model.fields,field_description:vault.field_res_users_key__write_uid +#: model:ir.model.fields,field_description:vault.field_vault__write_uid +#: model:ir.model.fields,field_description:vault.field_vault_entry__write_uid +#: model:ir.model.fields,field_description:vault.field_vault_export_wizard__write_uid +#: model:ir.model.fields,field_description:vault.field_vault_field__write_uid +#: model:ir.model.fields,field_description:vault.field_vault_file__write_uid +#: model:ir.model.fields,field_description:vault.field_vault_import_wizard__write_uid +#: model:ir.model.fields,field_description:vault.field_vault_import_wizard_path__write_uid +#: model:ir.model.fields,field_description:vault.field_vault_inbox__write_uid +#: model:ir.model.fields,field_description:vault.field_vault_inbox_log__write_uid +#: model:ir.model.fields,field_description:vault.field_vault_log__write_uid +#: model:ir.model.fields,field_description:vault.field_vault_right__write_uid +#: model:ir.model.fields,field_description:vault.field_vault_send_wizard__write_uid +#: model:ir.model.fields,field_description:vault.field_vault_store_wizard__write_uid +#: model:ir.model.fields,field_description:vault.field_vault_tag__write_uid +msgid "Last Updated by" +msgstr "Laatst bijgewerkt door" + +#. module: vault +#: model:ir.model.fields,field_description:vault.field_res_users_key__write_date +#: model:ir.model.fields,field_description:vault.field_vault__write_date +#: model:ir.model.fields,field_description:vault.field_vault_entry__write_date +#: model:ir.model.fields,field_description:vault.field_vault_export_wizard__write_date +#: model:ir.model.fields,field_description:vault.field_vault_field__write_date +#: model:ir.model.fields,field_description:vault.field_vault_file__write_date +#: model:ir.model.fields,field_description:vault.field_vault_import_wizard__write_date +#: model:ir.model.fields,field_description:vault.field_vault_import_wizard_path__write_date +#: model:ir.model.fields,field_description:vault.field_vault_inbox__write_date +#: model:ir.model.fields,field_description:vault.field_vault_inbox_log__write_date +#: model:ir.model.fields,field_description:vault.field_vault_log__write_date +#: model:ir.model.fields,field_description:vault.field_vault_right__write_date +#: model:ir.model.fields,field_description:vault.field_vault_send_wizard__write_date +#: model:ir.model.fields,field_description:vault.field_vault_store_wizard__write_date +#: model:ir.model.fields,field_description:vault.field_vault_tag__write_date +msgid "Last Updated on" +msgstr "Laatst bijgewerkt op" + +#. module: vault +#. odoo-javascript +#: code:addons/vault/static/src/backend/templates.xml:0 +#, python-format +msgid "Length:" +msgstr "Lengte:" + +#. module: vault +#: model:ir.model.fields,field_description:vault.field_vault__log_ids +#: model:ir.model.fields,field_description:vault.field_vault_entry__log_ids +#: model:ir.model.fields,field_description:vault.field_vault_inbox__log_ids +#: model_terms:ir.ui.view,arch_db:vault.view_vault_entry_form +#: model_terms:ir.ui.view,arch_db:vault.view_vault_form +msgid "Log" +msgstr "Log" + +#. module: vault +#. odoo-python +#: code:addons/vault/models/vault_log.py:0 +#: model:ir.model,name:vault.model_vault_log +#, python-format +msgid "Log entry of a vault" +msgstr "Logboekvermelding van een kluis" + +#. module: vault +#: model:ir.actions.act_window,name:vault.action_res_users_keys +msgid "Manage my keys" +msgstr "Beheer mijn sleutels" + +#. module: vault +#: model:ir.model.fields,field_description:vault.field_vault__master_key +#: model:ir.model.fields,field_description:vault.field_vault_abstract_field__master_key +#: model:ir.model.fields,field_description:vault.field_vault_export_wizard__master_key +#: model:ir.model.fields,field_description:vault.field_vault_field__master_key +#: model:ir.model.fields,field_description:vault.field_vault_file__master_key +#: model:ir.model.fields,field_description:vault.field_vault_import_wizard__master_key +#: model:ir.model.fields,field_description:vault.field_vault_right__master_key +#: model:ir.model.fields,field_description:vault.field_vault_store_wizard__master_key +msgid "Master Key" +msgstr "Hoofdsleutel" + +#. module: vault +#: model:ir.model.fields,field_description:vault.field_vault_log__message +msgid "Message" +msgstr "Bericht" + +#. module: vault +#. odoo-python +#: code:addons/vault/controllers/main.py:0 +#, python-format +msgid "Missing filename" +msgstr "Ontbrekende bestandsnaam" + +#. module: vault +#. odoo-javascript +#: code:addons/vault/static/src/common/utils.esm.js:0 +#, python-format +msgid "Missing password" +msgstr "Ontbrekend wachtwoord" + +#. module: vault +#: model:ir.model.fields,field_description:vault.field_vault_store_wizard__model +msgid "Model" +msgstr "Type" + +#. module: vault +#: model:ir.model.fields,field_description:vault.field_res_config_settings__module_vault_share +msgid "Module Vault Share" +msgstr "" + +#. module: vault +#: model:ir.model.fields,field_description:vault.field_vault__name +#: model:ir.model.fields,field_description:vault.field_vault_abstract_field__name +#: model:ir.model.fields,field_description:vault.field_vault_entry__name +#: model:ir.model.fields,field_description:vault.field_vault_export_wizard__name +#: model:ir.model.fields,field_description:vault.field_vault_field__name +#: model:ir.model.fields,field_description:vault.field_vault_file__name +#: model:ir.model.fields,field_description:vault.field_vault_import_wizard__name +#: model:ir.model.fields,field_description:vault.field_vault_import_wizard_path__name +#: model:ir.model.fields,field_description:vault.field_vault_inbox__name +#: model:ir.model.fields,field_description:vault.field_vault_inbox_log__name +#: model:ir.model.fields,field_description:vault.field_vault_send_wizard__name +#: model:ir.model.fields,field_description:vault.field_vault_store_wizard__name +#: model:ir.model.fields,field_description:vault.field_vault_tag__name +msgid "Name" +msgstr "Naam" + +#. module: vault +#: model_terms:ir.ui.view,arch_db:vault.inbox +msgid "Name of your secret:" +msgstr "" + +#. module: vault +#. odoo-python +#: code:addons/vault/wizards/vault_send_wizard.py:0 +#, python-format +msgid "Neither a secret nor file was given" +msgstr "" + +#. module: vault +#: model_terms:ir.ui.view,arch_db:vault.view_users_form_keys_modif +msgid "New inbox link" +msgstr "" + +#. module: vault +#: model_terms:ir.ui.view,arch_db:vault.view_users_form_keys_modif +msgid "New private key" +msgstr "Nieuwe privésleutel" + +#. module: vault +#. odoo-python +#: code:addons/vault/controllers/main.py:0 +#, python-format +msgid "No secret found" +msgstr "Geen geheim gevonden" + +#. module: vault +#. odoo-python +#: code:addons/vault/models/vault_inbox.py:0 +#: code:addons/vault/wizards/vault_send_wizard.py:0 +#: model:ir.model.constraint,message:vault.constraint_vault_inbox_value_check +#: model:ir.model.constraint,message:vault.constraint_vault_send_wizard_value_check +#, python-format +msgid "No value found" +msgstr "Geen waarde gevonden" + +#. module: vault +#: model_terms:ir.ui.view,arch_db:vault.view_vault_entry_search +msgid "Not Expired" +msgstr "Niet verlopen" + +#. module: vault +#: model:ir.model.fields,field_description:vault.field_vault__note +#: model:ir.model.fields,field_description:vault.field_vault_entry__note +#: model_terms:ir.ui.view,arch_db:vault.view_vault_entry_form +msgid "Note" +msgstr "Notitie" + +#. module: vault +#: model:ir.model.fields,field_description:vault.field_vault__user_id +#: model:ir.model.fields,field_description:vault.field_vault_entry__user_id +msgid "Owner" +msgstr "Eigenaar" + +#. module: vault +#: model:ir.model.fields,field_description:vault.field_vault_entry__parent_id +msgid "Parent" +msgstr "Bovenliggend" + +#. module: vault +#: model:ir.model.fields,field_description:vault.field_vault_import_wizard__parent_id +msgid "Parent Entry" +msgstr "" + +#. module: vault +#. odoo-javascript +#: code:addons/vault/static/src/backend/templates.xml:0 +#, python-format +msgid "Password:" +msgstr "Wachtwoord:" + +#. module: vault +#: model:ir.model.fields,field_description:vault.field_vault_import_wizard__path +msgid "Path to import" +msgstr "Pad om te importeren" + +#. module: vault +#: model:ir.model.fields,field_description:vault.field_vault__perm_user +#: model:ir.model.fields,field_description:vault.field_vault_abstract_field__perm_user +#: model:ir.model.fields,field_description:vault.field_vault_entry__perm_user +#: model:ir.model.fields,field_description:vault.field_vault_field__perm_user +#: model:ir.model.fields,field_description:vault.field_vault_file__perm_user +#: model:ir.model.fields,field_description:vault.field_vault_right__perm_user +msgid "Perm User" +msgstr "" + +#. module: vault +#. odoo-javascript +#: code:addons/vault/static/src/backend/export.esm.js:0 +#: code:addons/vault/static/src/backend/import.esm.js:0 +#, python-format +msgid "Please enter the password for the database" +msgstr "Voer het wachtwoord van de database in" + +#. module: vault +#. odoo-javascript +#: code:addons/vault/static/src/backend/import.esm.js:0 +#, python-format +msgid "Please enter the password for the keepass database" +msgstr "Voer het wachtwoord van de keepass database in" + +#. module: vault +#. odoo-javascript +#: code:addons/vault/static/src/backend/vault.esm.js:0 +#, python-format +msgid "Please enter the password for your private key" +msgstr "Voer het wachtwoord voor uw privésleutel in" + +#. module: vault +#. odoo-javascript +#: code:addons/vault/static/src/backend/templates.xml:0 +#, python-format +msgid "Please enter your password or upload a keyfile:" +msgstr "Voer uw wachtwoord in of upload een keyfile:" + +#. module: vault +#. odoo-python +#: code:addons/vault/controllers/main.py:0 +#, python-format +msgid "Please specify a name" +msgstr "Geef een naam op" + +#. module: vault +#: model:ir.model.fields,field_description:vault.field_res_users_key__private +msgid "Private" +msgstr "Privé" + +#. module: vault +#: model:ir.model.fields,field_description:vault.field_res_users_key__public +#: model:ir.model.fields,field_description:vault.field_vault_send_wizard__public +msgid "Public" +msgstr "Openbaar" + +#. module: vault +#: model:ir.model.fields,field_description:vault.field_vault_right__public_key +msgid "Public Key" +msgstr "Openbare sleutel" + +#. module: vault +#: model_terms:ir.ui.view,arch_db:vault.view_vault_form +msgid "Re-encrypt" +msgstr "" + +#. module: vault +#: model:ir.model.fields,field_description:vault.field_vault__reencrypt_required +msgid "Reencrypt Required" +msgstr "" + +#. module: vault +#: model:ir.actions.act_window,name:vault.action_vault_right +#: model:ir.model.fields,field_description:vault.field_vault__right_ids +#: model:ir.ui.menu,name:vault.menu_vault_right +#: model_terms:ir.ui.view,arch_db:vault.view_vault_form +msgid "Rights" +msgstr "Rechten" + +#. module: vault +#: model:ir.model.fields,field_description:vault.field_res_users_key__salt +msgid "Salt" +msgstr "" + +#. module: vault +#. odoo-javascript +#: code:addons/vault/static/src/backend/fields/vault_export_file.esm.js:0 +#: code:addons/vault/static/src/backend/fields/vault_file.esm.js:0 +#, python-format +msgid "Save As..." +msgstr "Opslaan als..." + +#. module: vault +#. odoo-javascript +#: code:addons/vault/static/src/backend/fields/templates.xml:0 +#, python-format +msgid "Save in a vault" +msgstr "Opslaan in een kluis" + +#. module: vault +#: model:ir.model.fields,field_description:vault.field_vault_inbox__secret +#: model:ir.model.fields,field_description:vault.field_vault_send_wizard__secret +#: model:ir.model.fields,field_description:vault.field_vault_store_wizard__secret +#: model_terms:ir.ui.view,arch_db:vault.inbox +msgid "Secret" +msgstr "Geheim" + +#. module: vault +#: model:ir.model.fields,field_description:vault.field_vault_inbox__secret_file +#: model:ir.model.fields,field_description:vault.field_vault_send_wizard__secret_file +msgid "Secret File" +msgstr "Secret File" + +#. module: vault +#: model:ir.model.fields,field_description:vault.field_vault_store_wizard__secret_temporary +msgid "Secret Temporary" +msgstr "" + +#. module: vault +#: model_terms:ir.ui.view,arch_db:vault.inbox +msgid "Secret to share:" +msgstr "Geheim om te delen:" + +#. module: vault +#: model_terms:ir.ui.view,arch_db:vault.view_vault_send_wizard +msgid "Send" +msgstr "Verzenden" + +#. module: vault +#. odoo-javascript +#: code:addons/vault/static/src/backend/fields/templates.xml:0 +#, python-format +msgid "Send the secret to an user" +msgstr "Verzend het geheim naar een gebruiker" + +#. module: vault +#. odoo-javascript +#: code:addons/vault/static/src/backend/fields/vault_mixin.esm.js:0 +#, python-format +msgid "Send the secret to another user" +msgstr "Verzend het geheim naar een andere gebruiker" + +#. module: vault +#: model:ir.model.fields,field_description:vault.field_vault_right__perm_share +msgid "Share" +msgstr "Delen" + +#. module: vault +#. odoo-javascript +#: code:addons/vault/static/src/backend/fields/templates.xml:0 +#, python-format +msgid "Show" +msgstr "Toon" + +#. module: vault +#. odoo-python +#: code:addons/vault/controllers/main.py:0 +#, python-format +msgid "Something went wrong with the encryption" +msgstr "Er ging iets mis met de encryptie" + +#. module: vault +#. odoo-javascript +#: code:addons/vault/static/src/backend/templates.xml:0 +#, python-format +msgid "Special" +msgstr "Speciaal" + +#. module: vault +#: model:ir.model.fields,field_description:vault.field_vault_log__state +msgid "State" +msgstr "Status" + +#. module: vault +#: model_terms:ir.ui.view,arch_db:vault.view_vault_store_wizard +msgid "Store" +msgstr "" + +#. module: vault +#. odoo-javascript +#: code:addons/vault/static/src/backend/fields/vault_inbox_mixin.esm.js:0 +#, python-format +msgid "Store the secret in a vault" +msgstr "" + +#. module: vault +#: model_terms:ir.ui.view,arch_db:vault.inbox +msgid "Submit secret" +msgstr "" + +#. module: vault +#. odoo-python +#: code:addons/vault/controllers/main.py:0 +#, python-format +msgid "Successfully stored" +msgstr "Succesvol opgeslagen" + +#. module: vault +#: model:ir.model.fields,field_description:vault.field_vault_entry__tags +msgid "Tags" +msgstr "Labels" + +#. module: vault +#. odoo-python +#: code:addons/vault/models/vault.py:0 +#: code:addons/vault/models/vault_entry.py:0 +#: model:ir.model.constraint,message:vault.constraint_vault_entry_vault_uuid_uniq +#: model:ir.model.constraint,message:vault.constraint_vault_uuid_uniq +#, python-format +msgid "The UUID must be unique." +msgstr "De UUID moet uniek zijn." + +#. module: vault +#. odoo-javascript +#: code:addons/vault/static/src/backend/fields/vault_export_file.esm.js:0 +#: code:addons/vault/static/src/backend/fields/vault_file.esm.js:0 +#, python-format +msgid "The field is empty, there's nothing to save!" +msgstr "" + +#. module: vault +#: model_terms:ir.ui.view,arch_db:vault.view_vault_import_wizard +msgid "The files must end on one of the supported file type:" +msgstr "" + +#. module: vault +#. odoo-javascript +#: code:addons/vault/static/src/backend/controller.esm.js:0 +#, python-format +msgid "The following entries are broken:" +msgstr "" + +#. module: vault +#. odoo-javascript +#: code:addons/vault/static/src/common/utils.esm.js:0 +#, python-format +msgid "The passwords aren't matching" +msgstr "De wachtwoorden komen niet overeen" + +#. module: vault +#. odoo-python +#: code:addons/vault/models/abstract_vault.py:0 +#, python-format +msgid "" +"The requested operation can not be completed due to security restrictions." +msgstr "" + +#. module: vault +#. odoo-python +#: code:addons/vault/models/vault_tag.py:0 +#: model:ir.model.constraint,message:vault.constraint_vault_tag_name_uniq +#, python-format +msgid "The tag must be unique!" +msgstr "Het label moet uniek zijn!" + +#. module: vault +#. odoo-python +#: code:addons/vault/models/vault_right.py:0 +#: model:ir.model.constraint,message:vault.constraint_vault_right_user_uniq +#, python-format +msgid "The user must be unique" +msgstr "De gebruiker moet uniek zijn" + +#. module: vault +#: model:ir.model.fields,field_description:vault.field_vault_inbox__token +msgid "Token" +msgstr "Token" + +#. module: vault +#. odoo-javascript +#: code:addons/vault/static/src/backend/import.esm.js:0 +#, python-format +msgid "Unsupported file to import" +msgstr "Niet ondersteund bestand voor import" + +#. module: vault +#: model:ir.model.fields,field_description:vault.field_vault_entry__url +msgid "Url" +msgstr "Url" + +#. module: vault +#: model:ir.model,name:vault.model_res_users +#: model:ir.model.fields,field_description:vault.field_res_users_key__user_id +#: model:ir.model.fields,field_description:vault.field_vault_log__user_id +#: model:ir.model.fields,field_description:vault.field_vault_right__user_id +#: model:ir.model.fields,field_description:vault.field_vault_send_wizard__user_id +msgid "User" +msgstr "Gebruiker" + +#. module: vault +#. odoo-python +#: code:addons/vault/models/res_users_key.py:0 +#: model:ir.model,name:vault.model_res_users_key +#, python-format +msgid "User data of a vault" +msgstr "" + +#. module: vault +#: model:ir.model.fields,help:vault.field_vault_inbox__inbox_link +msgid "" +"Using this link you can write to the current inbox. If you want people to " +"create new inboxes you should give them your inbox link from your key " +"management." +msgstr "" + +#. module: vault +#: model:ir.model.fields,field_description:vault.field_res_users_key__uuid +#: model:ir.model.fields,field_description:vault.field_vault__uuid +#: model:ir.model.fields,field_description:vault.field_vault_entry__uuid +#: model:ir.model.fields,field_description:vault.field_vault_import_wizard__uuid +#: model:ir.model.fields,field_description:vault.field_vault_import_wizard_path__uuid +msgid "Uuid" +msgstr "Uuid" + +#. module: vault +#: model:ir.model.fields,field_description:vault.field_vault_field__value +#: model:ir.model.fields,field_description:vault.field_vault_file__value +msgid "Value" +msgstr "Waarde" + +#. module: vault +#. odoo-python +#: code:addons/vault/models/vault.py:0 +#: model:ir.actions.act_window,name:vault.action_vault +#: model:ir.model,name:vault.model_vault +#: model:ir.model.fields,field_description:vault.field_vault_abstract_field__vault_id +#: model:ir.model.fields,field_description:vault.field_vault_entry__vault_id +#: model:ir.model.fields,field_description:vault.field_vault_export_wizard__vault_id +#: model:ir.model.fields,field_description:vault.field_vault_field__vault_id +#: model:ir.model.fields,field_description:vault.field_vault_file__vault_id +#: model:ir.model.fields,field_description:vault.field_vault_import_wizard__vault_id +#: model:ir.model.fields,field_description:vault.field_vault_inbox__user_id +#: model:ir.model.fields,field_description:vault.field_vault_log__vault_id +#: model:ir.model.fields,field_description:vault.field_vault_right__vault_id +#: model:ir.model.fields,field_description:vault.field_vault_store_wizard__vault_id +#: model:ir.ui.menu,name:vault.menu_vault +#: model_terms:ir.ui.view,arch_db:vault.res_config_settings_view_form +#: model_terms:ir.ui.view,arch_db:vault.view_vault_entry_search +#, python-format +msgid "Vault" +msgstr "" + +#. module: vault +#. odoo-javascript +#: code:addons/vault/static/src/backend/fields/vault_field.esm.js:0 +#, python-format +msgid "Vault Field" +msgstr "" + +#. module: vault +#. odoo-javascript +#: code:addons/vault/static/src/backend/fields/vault_file.esm.js:0 +#, python-format +msgid "Vault File" +msgstr "" + +#. module: vault +#. odoo-javascript +#: code:addons/vault/static/src/backend/fields/vault_inbox_field.esm.js:0 +#, python-format +msgid "Vault Inbox Field" +msgstr "" + +#. module: vault +#. odoo-javascript +#: code:addons/vault/static/src/backend/fields/vault_inbox_file.esm.js:0 +#, python-format +msgid "Vault Inbox File" +msgstr "" + +#. module: vault +#: model:ir.model.fields,field_description:vault.field_res_users__vault_right_ids +msgid "Vault Right" +msgstr "" + +#. module: vault +#: model_terms:ir.ui.view,arch_db:vault.res_config_settings_view_form +msgid "Vault Share" +msgstr "" + +#. module: vault +#. odoo-python +#: code:addons/vault/models/vault_inbox_log.py:0 +#: model:ir.model,name:vault.model_vault_inbox_log +#, python-format +msgid "Vault inbox log" +msgstr "" + +#. module: vault +#. odoo-javascript +#: code:addons/vault/static/src/backend/controller.esm.js:0 +#, python-format +msgid "Vault is not supported" +msgstr "" + +#. module: vault +#. odoo-python +#: code:addons/vault/models/vault_right.py:0 +#: model:ir.model,name:vault.model_vault_right +#, python-format +msgid "Vault rights" +msgstr "" + +#. module: vault +#. odoo-python +#: code:addons/vault/models/vault_inbox.py:0 +#: model:ir.model,name:vault.model_vault_inbox +#, python-format +msgid "Vault share incoming secrets" +msgstr "" + +#. module: vault +#. odoo-python +#: code:addons/vault/models/vault_tag.py:0 +#: model:ir.model,name:vault.model_vault_tag +#, python-format +msgid "Vault tag" +msgstr "" + +#. module: vault +#: model_terms:ir.ui.view,arch_db:vault.view_vault_entry_search +msgid "Vaults" +msgstr "" + +#. module: vault +#: model_terms:ir.ui.view,arch_db:vault.view_vault_form +msgid "Verify" +msgstr "" + +#. module: vault +#: model:ir.model.fields,field_description:vault.field_res_users_key__version +msgid "Version" +msgstr "Versie" + +#. module: vault +#. odoo-python +#: code:addons/vault/models/vault_log.py:0 +#, python-format +msgid "Warning" +msgstr "Waarschuwing" + +#. module: vault +#. odoo-python +#: code:addons/vault/wizards/vault_store_wizard.py:0 +#: model:ir.model,name:vault.model_vault_store_wizard +#, python-format +msgid "Wizard store a shared secret in a vault" +msgstr "" + +#. module: vault +#. odoo-python +#: code:addons/vault/wizards/vault_send_wizard.py:0 +#: model:ir.model,name:vault.model_vault_send_wizard +#, python-format +msgid "Wizard to send another user a secret" +msgstr "" + +#. module: vault +#: model:ir.model.fields,field_description:vault.field_vault_right__perm_write +msgid "Write" +msgstr "" + +#. module: vault +#. odoo-python +#: code:addons/vault/models/vault_inbox.py:0 +#, python-format +msgid "Written by %(name)s via %(ip)s" +msgstr "Geschreven door %(name)s via %(ip)s" + +#. module: vault +#. odoo-python +#: code:addons/vault/models/vault_entry.py:0 +#, python-format +msgid "You can not create recursive entries." +msgstr "" + +#. module: vault +#: model_terms:ir.ui.view,arch_db:vault.view_vault_send_wizard +msgid "" +"You can only send the secret to the user who has generated a key-pair.\n" +" If an user is not showing please ask him to generate " +"these." +msgstr "" + +#. module: vault +#: model_terms:ir.ui.view,arch_db:vault.view_users_form_keys_modif +msgid "" +"You will loose access to all vaults and your inbox. Do you want to continue?" +msgstr "" + +#. module: vault +#. odoo-javascript +#: code:addons/vault/static/src/backend/templates.xml:0 +#, python-format +msgid "a-z" +msgstr "a-z" + +#. module: vault +#: model_terms:ir.ui.view,arch_db:vault.view_vault_import_wizard +#: model_terms:ir.ui.view,arch_db:vault.view_vault_send_wizard +#: model_terms:ir.ui.view,arch_db:vault.view_vault_store_wizard +msgid "or" +msgstr "of" + +#~ msgid "Users" +#~ msgstr "Gebruikers" + +#, python-format +#~ msgid "" +#~ "This will re-encrypt everything in the vault. Do you want to proceed?" +#~ msgstr "Dit zal alles in de kluis opnieuw versleutelen. Wil je doorgaan?" diff --git a/vault/i18n/vault.pot b/vault/i18n/vault.pot new file mode 100644 index 0000000000..1ff8dfa7d6 --- /dev/null +++ b/vault/i18n/vault.pot @@ -0,0 +1,1478 @@ +# Translation of Odoo Server. +# This file contains the translation of the following modules: +# * vault +# +msgid "" +msgstr "" +"Project-Id-Version: Odoo Server 16.0\n" +"Report-Msgid-Bugs-To: \n" +"Last-Translator: \n" +"Language-Team: \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: \n" +"Plural-Forms: \n" + +#. module: vault +#. odoo-python +#: code:addons/vault/models/vault_entry.py:0 +#, python-format +msgid "%(action)s entry %(name)s by %(user)s" +msgstr "" + +#. module: vault +#. odoo-javascript +#: code:addons/vault/static/src/backend/controller.esm.js:0 +#, python-format +msgid "%s '%s' of entry '%s'" +msgstr "" + +#. module: vault +#. odoo-python +#: code:addons/vault/models/vault_entry.py:0 +#, python-format +msgid "%s (copy)" +msgstr "" + +#. module: vault +#. odoo-javascript +#: code:addons/vault/static/src/backend/controller.esm.js:0 +#, python-format +msgid "" +"A secure browser context is required. Please switch to https or contact your" +" administrator" +msgstr "" + +#. module: vault +#. odoo-javascript +#: code:addons/vault/static/src/backend/templates.xml:0 +#, python-format +msgid "A-Z" +msgstr "" + +#. module: vault +#. odoo-python +#: code:addons/vault/models/abstract_vault_field.py:0 +#: model:ir.model,name:vault.model_vault_abstract_field +#, python-format +msgid "Abstract model to implement basic fields for encryption" +msgstr "" + +#. module: vault +#. odoo-python +#: code:addons/vault/models/abstract_vault.py:0 +#: model:ir.model,name:vault.model_vault_abstract +#, python-format +msgid "Abstract model to implement general access rights" +msgstr "" + +#. module: vault +#: model:ir.model.fields,field_description:vault.field_vault_inbox__accesses +msgid "Access counter" +msgstr "" + +#. module: vault +#: model:ir.model.fields,field_description:vault.field_res_users__active_key +msgid "Active Key" +msgstr "" + +#. module: vault +#: model:ir.actions.act_window,name:vault.action_vault_entry +#: model:ir.ui.menu,name:vault.menu_vault_entry +msgid "All Entries" +msgstr "" + +#. module: vault +#: model_terms:ir.ui.view,arch_db:vault.res_config_settings_view_form +msgid "Allow all users to export vaults accessible to them" +msgstr "" + +#. module: vault +#: model_terms:ir.ui.view,arch_db:vault.res_config_settings_view_form +msgid "Allow all users to import vaults accessible to them" +msgstr "" + +#. module: vault +#: model_terms:ir.ui.view,arch_db:vault.res_config_settings_view_form +msgid "Allow the usage to share secrets with external users" +msgstr "" + +#. module: vault +#: model:ir.model.fields,help:vault.field_vault_right__perm_create +msgid "Allow to create in the vault" +msgstr "" + +#. module: vault +#: model:ir.model.fields,help:vault.field_vault_right__perm_delete +msgid "Allow to delete a vault" +msgstr "" + +#. module: vault +#: model:res.groups,name:vault.group_vault_export +msgid "Allow to export vaults" +msgstr "" + +#. module: vault +#: model:res.groups,name:vault.group_vault_import +msgid "Allow to import vaults" +msgstr "" + +#. module: vault +#: model:ir.model.fields,help:vault.field_vault_right__perm_share +msgid "Allow to share a vault with new users" +msgstr "" + +#. module: vault +#: model:ir.model.fields,help:vault.field_vault_right__perm_write +msgid "Allow to write to the vault" +msgstr "" + +#. module: vault +#: model:ir.model.fields,field_description:vault.field_vault__allowed_create +#: model:ir.model.fields,field_description:vault.field_vault_abstract_field__allowed_create +#: model:ir.model.fields,field_description:vault.field_vault_entry__allowed_create +#: model:ir.model.fields,field_description:vault.field_vault_field__allowed_create +#: model:ir.model.fields,field_description:vault.field_vault_file__allowed_create +#: model:ir.model.fields,field_description:vault.field_vault_right__allowed_create +msgid "Allowed Create" +msgstr "" + +#. module: vault +#: model:ir.model.fields,field_description:vault.field_vault__allowed_delete +#: model:ir.model.fields,field_description:vault.field_vault_abstract_field__allowed_delete +#: model:ir.model.fields,field_description:vault.field_vault_entry__allowed_delete +#: model:ir.model.fields,field_description:vault.field_vault_field__allowed_delete +#: model:ir.model.fields,field_description:vault.field_vault_file__allowed_delete +#: model:ir.model.fields,field_description:vault.field_vault_right__allowed_delete +msgid "Allowed Delete" +msgstr "" + +#. module: vault +#: model:ir.model.fields,field_description:vault.field_vault__allowed_read +#: model:ir.model.fields,field_description:vault.field_vault_abstract_field__allowed_read +#: model:ir.model.fields,field_description:vault.field_vault_entry__allowed_read +#: model:ir.model.fields,field_description:vault.field_vault_field__allowed_read +#: model:ir.model.fields,field_description:vault.field_vault_file__allowed_read +#: model:ir.model.fields,field_description:vault.field_vault_right__allowed_read +msgid "Allowed Read" +msgstr "" + +#. module: vault +#: model:ir.model.fields,field_description:vault.field_vault__allowed_share +#: model:ir.model.fields,field_description:vault.field_vault_abstract_field__allowed_share +#: model:ir.model.fields,field_description:vault.field_vault_entry__allowed_share +#: model:ir.model.fields,field_description:vault.field_vault_field__allowed_share +#: model:ir.model.fields,field_description:vault.field_vault_file__allowed_share +#: model:ir.model.fields,field_description:vault.field_vault_right__allowed_share +msgid "Allowed Share" +msgstr "" + +#. module: vault +#: model:ir.model.fields,field_description:vault.field_vault__allowed_write +#: model:ir.model.fields,field_description:vault.field_vault_abstract_field__allowed_write +#: model:ir.model.fields,field_description:vault.field_vault_entry__allowed_write +#: model:ir.model.fields,field_description:vault.field_vault_field__allowed_write +#: model:ir.model.fields,field_description:vault.field_vault_file__allowed_write +#: model:ir.model.fields,field_description:vault.field_vault_right__allowed_write +msgid "Allowed Write" +msgstr "" + +#. module: vault +#. odoo-python +#: code:addons/vault/controllers/main.py:0 +#, python-format +msgid "An error occured. Please contact the user or administrator" +msgstr "" + +#. module: vault +#: model_terms:ir.ui.view,arch_db:vault.view_vault_right_overview_search +msgid "By user" +msgstr "" + +#. module: vault +#: model_terms:ir.ui.view,arch_db:vault.view_vault_right_overview_search +msgid "By vault" +msgstr "" + +#. module: vault +#. odoo-javascript +#: code:addons/vault/static/src/common/utils.esm.js:0 +#: code:addons/vault/static/src/common/utils.esm.js:0 +#: model_terms:ir.ui.view,arch_db:vault.view_users_form_keys_modif +#: model_terms:ir.ui.view,arch_db:vault.view_vault_import_wizard +#: model_terms:ir.ui.view,arch_db:vault.view_vault_send_wizard +#: model_terms:ir.ui.view,arch_db:vault.view_vault_store_wizard +#, python-format +msgid "Cancel" +msgstr "" + +#. module: vault +#. odoo-javascript +#: code:addons/vault/static/src/common/utils.esm.js:0 +#: code:addons/vault/static/src/common/utils.esm.js:0 +#, python-format +msgid "Cancelled" +msgstr "" + +#. module: vault +#. odoo-javascript +#: code:addons/vault/static/src/backend/templates.xml:0 +#, python-format +msgid "Characters:" +msgstr "" + +#. module: vault +#: model:ir.model.fields,field_description:vault.field_vault_entry__child_ids +msgid "Child" +msgstr "" + +#. module: vault +#: model_terms:ir.ui.view,arch_db:vault.view_vault_entry_form +msgid "Childs" +msgstr "" + +#. module: vault +#: model_terms:ir.ui.view,arch_db:vault.view_vault_export_wizard +msgid "Close" +msgstr "" + +#. module: vault +#: model:ir.model.fields,field_description:vault.field_vault_abstract_field__entry_name +#: model:ir.model.fields,field_description:vault.field_vault_entry__complete_name +#: model:ir.model.fields,field_description:vault.field_vault_field__entry_name +#: model:ir.model.fields,field_description:vault.field_vault_file__entry_name +msgid "Complete Name" +msgstr "" + +#. module: vault +#: model:ir.model,name:vault.model_res_config_settings +msgid "Config Settings" +msgstr "" + +#. module: vault +#. odoo-javascript +#: code:addons/vault/static/src/backend/templates.xml:0 +#, python-format +msgid "Confirm your password:" +msgstr "" + +#. module: vault +#: model_terms:ir.ui.view,arch_db:vault.view_vault_entry_form +msgid "Content" +msgstr "" + +#. module: vault +#. odoo-javascript +#: code:addons/vault/static/src/backend/fields/templates.xml:0 +#: code:addons/vault/static/src/backend/fields/templates.xml:0 +#, python-format +msgid "Copy to clipboard" +msgstr "" + +#. module: vault +#: model:ir.model.fields,field_description:vault.field_vault_right__perm_create +msgid "Create" +msgstr "" + +#. module: vault +#: model:ir.model.fields,field_description:vault.field_res_users_key__create_uid +#: model:ir.model.fields,field_description:vault.field_vault__create_uid +#: model:ir.model.fields,field_description:vault.field_vault_entry__create_uid +#: model:ir.model.fields,field_description:vault.field_vault_export_wizard__create_uid +#: model:ir.model.fields,field_description:vault.field_vault_field__create_uid +#: model:ir.model.fields,field_description:vault.field_vault_file__create_uid +#: model:ir.model.fields,field_description:vault.field_vault_import_wizard__create_uid +#: model:ir.model.fields,field_description:vault.field_vault_import_wizard_path__create_uid +#: model:ir.model.fields,field_description:vault.field_vault_inbox__create_uid +#: model:ir.model.fields,field_description:vault.field_vault_inbox_log__create_uid +#: model:ir.model.fields,field_description:vault.field_vault_log__create_uid +#: model:ir.model.fields,field_description:vault.field_vault_right__create_uid +#: model:ir.model.fields,field_description:vault.field_vault_send_wizard__create_uid +#: model:ir.model.fields,field_description:vault.field_vault_store_wizard__create_uid +#: model:ir.model.fields,field_description:vault.field_vault_tag__create_uid +msgid "Created by" +msgstr "" + +#. module: vault +#. odoo-python +#: code:addons/vault/models/vault_inbox.py:0 +#, python-format +msgid "Created by %(name)s via %(ip)s" +msgstr "" + +#. module: vault +#. odoo-python +#: code:addons/vault/wizards/vault_send_wizard.py:0 +#, python-format +msgid "Created by %s" +msgstr "" + +#. module: vault +#: model:ir.model.fields,field_description:vault.field_res_users_key__create_date +#: model:ir.model.fields,field_description:vault.field_vault__create_date +#: model:ir.model.fields,field_description:vault.field_vault_entry__create_date +#: model:ir.model.fields,field_description:vault.field_vault_export_wizard__create_date +#: model:ir.model.fields,field_description:vault.field_vault_field__create_date +#: model:ir.model.fields,field_description:vault.field_vault_file__create_date +#: model:ir.model.fields,field_description:vault.field_vault_import_wizard__create_date +#: model:ir.model.fields,field_description:vault.field_vault_import_wizard_path__create_date +#: model:ir.model.fields,field_description:vault.field_vault_inbox__create_date +#: model:ir.model.fields,field_description:vault.field_vault_inbox_log__create_date +#: model:ir.model.fields,field_description:vault.field_vault_log__create_date +#: model:ir.model.fields,field_description:vault.field_vault_right__create_date +#: model:ir.model.fields,field_description:vault.field_vault_send_wizard__create_date +#: model:ir.model.fields,field_description:vault.field_vault_store_wizard__create_date +#: model:ir.model.fields,field_description:vault.field_vault_tag__create_date +msgid "Created on" +msgstr "" + +#. module: vault +#: model:ir.model.fields,field_description:vault.field_vault_import_wizard__crypted_content +msgid "Crypted Content" +msgstr "" + +#. module: vault +#: model:ir.model.fields,field_description:vault.field_res_users_key__current +msgid "Current" +msgstr "" + +#. module: vault +#: model_terms:ir.ui.view,arch_db:vault.view_vault_import_wizard +msgid "Custom JSON format .json" +msgstr "" + +#. module: vault +#: model:ir.model.fields,field_description:vault.field_vault_import_wizard__content +msgid "Database" +msgstr "" + +#. module: vault +#: model:ir.model.fields,field_description:vault.field_vault_right__perm_delete +msgid "Delete" +msgstr "" + +#. module: vault +#: model:ir.model.fields,field_description:vault.field_res_users_key__display_name +#: model:ir.model.fields,field_description:vault.field_vault__display_name +#: model:ir.model.fields,field_description:vault.field_vault_entry__display_name +#: model:ir.model.fields,field_description:vault.field_vault_export_wizard__display_name +#: model:ir.model.fields,field_description:vault.field_vault_field__display_name +#: model:ir.model.fields,field_description:vault.field_vault_file__display_name +#: model:ir.model.fields,field_description:vault.field_vault_import_wizard__display_name +#: model:ir.model.fields,field_description:vault.field_vault_import_wizard_path__display_name +#: model:ir.model.fields,field_description:vault.field_vault_inbox__display_name +#: model:ir.model.fields,field_description:vault.field_vault_inbox_log__display_name +#: model:ir.model.fields,field_description:vault.field_vault_log__display_name +#: model:ir.model.fields,field_description:vault.field_vault_right__display_name +#: model:ir.model.fields,field_description:vault.field_vault_send_wizard__display_name +#: model:ir.model.fields,field_description:vault.field_vault_store_wizard__display_name +#: model:ir.model.fields,field_description:vault.field_vault_tag__display_name +msgid "Display Name" +msgstr "" + +#. module: vault +#. odoo-javascript +#: code:addons/vault/static/src/backend/controller.esm.js:0 +#, python-format +msgid "Do you really want to create a new key pair and set it active?" +msgstr "" + +#. module: vault +#: model:ir.model.fields,field_description:vault.field_vault_export_wizard__content +msgid "Download" +msgstr "" + +#. module: vault +#. odoo-javascript +#: code:addons/vault/static/src/common/utils.esm.js:0 +#: code:addons/vault/static/src/common/utils.esm.js:0 +#, python-format +msgid "Enter" +msgstr "" + +#. module: vault +#. odoo-javascript +#: code:addons/vault/static/src/backend/templates.xml:0 +#, python-format +msgid "Enter your password:" +msgstr "" + +#. module: vault +#: model:ir.actions.act_window,name:vault.action_open_entries +#: model:ir.model.fields,field_description:vault.field_vault__entry_ids +#: model:ir.model.fields,field_description:vault.field_vault_export_wizard__entry_id +#: model_terms:ir.ui.view,arch_db:vault.view_vault_entry_search +#: model_terms:ir.ui.view,arch_db:vault.view_vault_form +msgid "Entries" +msgstr "" + +#. module: vault +#: model:ir.model.fields,field_description:vault.field_vault_abstract_field__entry_id +#: model:ir.model.fields,field_description:vault.field_vault_field__entry_id +#: model:ir.model.fields,field_description:vault.field_vault_file__entry_id +#: model:ir.model.fields,field_description:vault.field_vault_log__entry_id +#: model:ir.model.fields,field_description:vault.field_vault_store_wizard__entry_id +msgid "Entry" +msgstr "" + +#. module: vault +#. odoo-python +#: code:addons/vault/models/vault_entry.py:0 +#: model:ir.model,name:vault.model_vault_entry +#, python-format +msgid "Entry inside a vault" +msgstr "" + +#. module: vault +#. odoo-python +#: code:addons/vault/models/vault_log.py:0 +#, python-format +msgid "Error" +msgstr "" + +#. module: vault +#: model:ir.model.fields,field_description:vault.field_vault_inbox__expiration +msgid "Expiration" +msgstr "" + +#. module: vault +#: model:ir.model.fields,field_description:vault.field_vault_entry__expired +#: model_terms:ir.ui.view,arch_db:vault.view_vault_entry_search +msgid "Expired" +msgstr "" + +#. module: vault +#: model:ir.model.fields,field_description:vault.field_vault_entry__expire_date +msgid "Expires on" +msgstr "" + +#. module: vault +#: model:ir.model.fields,field_description:vault.field_res_config_settings__group_vault_export +msgid "Export Vaults" +msgstr "" + +#. module: vault +#. odoo-python +#: code:addons/vault/models/vault.py:0 +#: code:addons/vault/models/vault_entry.py:0 +#: model_terms:ir.ui.view,arch_db:vault.view_vault_entry_form +#: model_terms:ir.ui.view,arch_db:vault.view_vault_form +#, python-format +msgid "Export to file" +msgstr "" + +#. module: vault +#. odoo-python +#: code:addons/vault/wizards/vault_export_wizard.py:0 +#: model:ir.model,name:vault.model_vault_export_wizard +#, python-format +msgid "Export wizard for vaults" +msgstr "" + +#. module: vault +#. odoo-javascript +#: code:addons/vault/static/src/backend/vault.esm.js:0 +#, python-format +msgid "Failed to export keys to object store" +msgstr "" + +#. module: vault +#. odoo-javascript +#: code:addons/vault/static/src/backend/vault.esm.js:0 +#, python-format +msgid "Failed to export the keys to the database" +msgstr "" + +#. module: vault +#. odoo-javascript +#: code:addons/vault/static/src/backend/vault.esm.js:0 +#, python-format +msgid "Failed to import keys from database" +msgstr "" + +#. module: vault +#. odoo-python +#: code:addons/vault/models/vault_field.py:0 +#: model:ir.model,name:vault.model_vault_field +#, python-format +msgid "Field of a vault" +msgstr "" + +#. module: vault +#: model:ir.model.fields,field_description:vault.field_vault__field_ids +#: model:ir.model.fields,field_description:vault.field_vault_entry__field_ids +msgid "Fields" +msgstr "" + +#. module: vault +#. odoo-python +#: code:addons/vault/models/vault_file.py:0 +#: model:ir.model,name:vault.model_vault_file +#, python-format +msgid "File of a vault" +msgstr "" + +#. module: vault +#: model_terms:ir.ui.view,arch_db:vault.inbox +msgid "File to share:" +msgstr "" + +#. module: vault +#: model:ir.model.fields,field_description:vault.field_vault_inbox__filename +#: model:ir.model.fields,field_description:vault.field_vault_send_wizard__filename +msgid "Filename" +msgstr "" + +#. module: vault +#: model:ir.model.fields,field_description:vault.field_vault__file_ids +#: model:ir.model.fields,field_description:vault.field_vault_entry__file_ids +msgid "Files" +msgstr "" + +#. module: vault +#: model:ir.model.fields,field_description:vault.field_res_users_key__fingerprint +msgid "Fingerprint" +msgstr "" + +#. module: vault +#. odoo-javascript +#: code:addons/vault/static/src/backend/fields/templates.xml:0 +#: code:addons/vault/static/src/backend/fields/templates.xml:0 +#, python-format +msgid "Generate" +msgstr "" + +#. module: vault +#. odoo-javascript +#: code:addons/vault/static/src/backend/templates.xml:0 +#, python-format +msgid "Generate a new secret:" +msgstr "" + +#. module: vault +#: model_terms:ir.ui.view,arch_db:vault.view_vault_right_overview_search +msgid "Grouped" +msgstr "" + +#. module: vault +#. odoo-javascript +#: code:addons/vault/static/src/backend/fields/templates.xml:0 +#: code:addons/vault/static/src/backend/fields/templates.xml:0 +#, python-format +msgid "Hide" +msgstr "" + +#. module: vault +#: model:ir.model.fields,field_description:vault.field_res_users_key__id +#: model:ir.model.fields,field_description:vault.field_vault__id +#: model:ir.model.fields,field_description:vault.field_vault_entry__id +#: model:ir.model.fields,field_description:vault.field_vault_export_wizard__id +#: model:ir.model.fields,field_description:vault.field_vault_field__id +#: model:ir.model.fields,field_description:vault.field_vault_file__id +#: model:ir.model.fields,field_description:vault.field_vault_import_wizard__id +#: model:ir.model.fields,field_description:vault.field_vault_import_wizard_path__id +#: model:ir.model.fields,field_description:vault.field_vault_inbox__id +#: model:ir.model.fields,field_description:vault.field_vault_inbox_log__id +#: model:ir.model.fields,field_description:vault.field_vault_log__id +#: model:ir.model.fields,field_description:vault.field_vault_right__id +#: model:ir.model.fields,field_description:vault.field_vault_send_wizard__id +#: model:ir.model.fields,field_description:vault.field_vault_store_wizard__id +#: model:ir.model.fields,field_description:vault.field_vault_tag__id +msgid "ID" +msgstr "" + +#. module: vault +#: model:ir.model.fields,help:vault.field_vault_inbox__expiration +msgid "If expired the inbox can't be written using the link" +msgstr "" + +#. module: vault +#: model:ir.model.fields,help:vault.field_vault_inbox__accesses +msgid "If this is 0 the inbox can't be written using the link" +msgstr "" + +#. module: vault +#: model_terms:ir.ui.view,arch_db:vault.view_vault_import_wizard +msgid "Import" +msgstr "" + +#. module: vault +#: model:ir.model.fields,field_description:vault.field_res_config_settings__group_vault_import +msgid "Import Vaults" +msgstr "" + +#. module: vault +#. odoo-python +#: code:addons/vault/models/vault.py:0 +#: code:addons/vault/models/vault_entry.py:0 +#: model_terms:ir.ui.view,arch_db:vault.view_vault_entry_form +#: model_terms:ir.ui.view,arch_db:vault.view_vault_form +#, python-format +msgid "Import from file" +msgstr "" + +#. module: vault +#. odoo-python +#: code:addons/vault/wizards/vault_import_wizard.py:0 +#: model:ir.model,name:vault.model_vault_import_wizard +#, python-format +msgid "Import wizard for vaults" +msgstr "" + +#. module: vault +#. odoo-python +#: code:addons/vault/wizards/vault_import_wizard.py:0 +#: model:ir.model,name:vault.model_vault_import_wizard_path +#, python-format +msgid "Import wizard path for vaults" +msgstr "" + +#. module: vault +#: model:ir.actions.act_window,name:vault.action_vault_inbox +#: model:ir.model.fields,field_description:vault.field_res_users__inbox_ids +#: model:ir.model.fields,field_description:vault.field_vault_inbox_log__inbox_id +#: model:ir.ui.menu,name:vault.menu_vault_inbox +msgid "Inbox" +msgstr "" + +#. module: vault +#: model:ir.model.fields,field_description:vault.field_res_users__inbox_enabled +msgid "Inbox Enabled" +msgstr "" + +#. module: vault +#: model:ir.model.fields,field_description:vault.field_res_users__inbox_link +#: model:ir.model.fields,field_description:vault.field_vault_inbox__inbox_link +msgid "Inbox Link" +msgstr "" + +#. module: vault +#: model:ir.model.fields,field_description:vault.field_res_users__inbox_token +msgid "Inbox Token" +msgstr "" + +#. module: vault +#: model:ir.model.fields,field_description:vault.field_vault_export_wizard__include_childs +msgid "Include Childs" +msgstr "" + +#. module: vault +#. odoo-python +#: code:addons/vault/models/vault_log.py:0 +#, python-format +msgid "Information" +msgstr "" + +#. module: vault +#. odoo-python +#: code:addons/vault/wizards/vault_import_wizard.py:0 +#, python-format +msgid "Invalid file to import from" +msgstr "" + +#. module: vault +#. odoo-python +#: code:addons/vault/models/res_users_key.py:0 +#: code:addons/vault/models/res_users_key.py:0 +#: code:addons/vault/models/res_users_key.py:0 +#, python-format +msgid "Invalid parameter" +msgstr "" + +#. module: vault +#. odoo-python +#: code:addons/vault/controllers/main.py:0 +#, python-format +msgid "Invalid token" +msgstr "" + +#. module: vault +#: model_terms:ir.ui.view,arch_db:vault.view_users_form_keys_modif +msgid "Invalidate private key" +msgstr "" + +#. module: vault +#: model:ir.model.fields,field_description:vault.field_res_users_key__iterations +msgid "Iterations" +msgstr "" + +#. module: vault +#: model:ir.model.fields,field_description:vault.field_res_users_key__iv +#: model:ir.model.fields,field_description:vault.field_vault_abstract_field__iv +#: model:ir.model.fields,field_description:vault.field_vault_field__iv +#: model:ir.model.fields,field_description:vault.field_vault_file__iv +#: model:ir.model.fields,field_description:vault.field_vault_inbox__iv +#: model:ir.model.fields,field_description:vault.field_vault_send_wizard__iv +#: model:ir.model.fields,field_description:vault.field_vault_store_wizard__iv +msgid "Iv" +msgstr "" + +#. module: vault +#: model_terms:ir.ui.view,arch_db:vault.view_vault_import_wizard +msgid "Keepass Database .kdbx" +msgstr "" + +#. module: vault +#: model:ir.model.fields,field_description:vault.field_vault_inbox__key +#: model:ir.model.fields,field_description:vault.field_vault_right__key +#: model:ir.model.fields,field_description:vault.field_vault_send_wizard__key +#: model:ir.model.fields,field_description:vault.field_vault_store_wizard__key +msgid "Key" +msgstr "" + +#. module: vault +#. odoo-javascript +#: code:addons/vault/static/src/backend/user_menu.esm.js:0 +#, python-format +msgid "Key Management" +msgstr "" + +#. module: vault +#: model:ir.model.fields,field_description:vault.field_vault_send_wizard__key_user +msgid "Key User" +msgstr "" + +#. module: vault +#. odoo-javascript +#: code:addons/vault/static/src/backend/templates.xml:0 +#, python-format +msgid "Keyfile:" +msgstr "" + +#. module: vault +#: model:ir.model.fields,field_description:vault.field_res_users__keys +msgid "Keys" +msgstr "" + +#. module: vault +#: model:ir.model.fields,field_description:vault.field_res_users_key____last_update +#: model:ir.model.fields,field_description:vault.field_vault____last_update +#: model:ir.model.fields,field_description:vault.field_vault_entry____last_update +#: model:ir.model.fields,field_description:vault.field_vault_export_wizard____last_update +#: model:ir.model.fields,field_description:vault.field_vault_field____last_update +#: model:ir.model.fields,field_description:vault.field_vault_file____last_update +#: model:ir.model.fields,field_description:vault.field_vault_import_wizard____last_update +#: model:ir.model.fields,field_description:vault.field_vault_import_wizard_path____last_update +#: model:ir.model.fields,field_description:vault.field_vault_inbox____last_update +#: model:ir.model.fields,field_description:vault.field_vault_inbox_log____last_update +#: model:ir.model.fields,field_description:vault.field_vault_log____last_update +#: model:ir.model.fields,field_description:vault.field_vault_right____last_update +#: model:ir.model.fields,field_description:vault.field_vault_send_wizard____last_update +#: model:ir.model.fields,field_description:vault.field_vault_store_wizard____last_update +#: model:ir.model.fields,field_description:vault.field_vault_tag____last_update +msgid "Last Modified on" +msgstr "" + +#. module: vault +#: model:ir.model.fields,field_description:vault.field_res_users_key__write_uid +#: model:ir.model.fields,field_description:vault.field_vault__write_uid +#: model:ir.model.fields,field_description:vault.field_vault_entry__write_uid +#: model:ir.model.fields,field_description:vault.field_vault_export_wizard__write_uid +#: model:ir.model.fields,field_description:vault.field_vault_field__write_uid +#: model:ir.model.fields,field_description:vault.field_vault_file__write_uid +#: model:ir.model.fields,field_description:vault.field_vault_import_wizard__write_uid +#: model:ir.model.fields,field_description:vault.field_vault_import_wizard_path__write_uid +#: model:ir.model.fields,field_description:vault.field_vault_inbox__write_uid +#: model:ir.model.fields,field_description:vault.field_vault_inbox_log__write_uid +#: model:ir.model.fields,field_description:vault.field_vault_log__write_uid +#: model:ir.model.fields,field_description:vault.field_vault_right__write_uid +#: model:ir.model.fields,field_description:vault.field_vault_send_wizard__write_uid +#: model:ir.model.fields,field_description:vault.field_vault_store_wizard__write_uid +#: model:ir.model.fields,field_description:vault.field_vault_tag__write_uid +msgid "Last Updated by" +msgstr "" + +#. module: vault +#: model:ir.model.fields,field_description:vault.field_res_users_key__write_date +#: model:ir.model.fields,field_description:vault.field_vault__write_date +#: model:ir.model.fields,field_description:vault.field_vault_entry__write_date +#: model:ir.model.fields,field_description:vault.field_vault_export_wizard__write_date +#: model:ir.model.fields,field_description:vault.field_vault_field__write_date +#: model:ir.model.fields,field_description:vault.field_vault_file__write_date +#: model:ir.model.fields,field_description:vault.field_vault_import_wizard__write_date +#: model:ir.model.fields,field_description:vault.field_vault_import_wizard_path__write_date +#: model:ir.model.fields,field_description:vault.field_vault_inbox__write_date +#: model:ir.model.fields,field_description:vault.field_vault_inbox_log__write_date +#: model:ir.model.fields,field_description:vault.field_vault_log__write_date +#: model:ir.model.fields,field_description:vault.field_vault_right__write_date +#: model:ir.model.fields,field_description:vault.field_vault_send_wizard__write_date +#: model:ir.model.fields,field_description:vault.field_vault_store_wizard__write_date +#: model:ir.model.fields,field_description:vault.field_vault_tag__write_date +msgid "Last Updated on" +msgstr "" + +#. module: vault +#. odoo-javascript +#: code:addons/vault/static/src/backend/templates.xml:0 +#, python-format +msgid "Length:" +msgstr "" + +#. module: vault +#: model:ir.model.fields,field_description:vault.field_vault__log_ids +#: model:ir.model.fields,field_description:vault.field_vault_entry__log_ids +#: model:ir.model.fields,field_description:vault.field_vault_inbox__log_ids +#: model_terms:ir.ui.view,arch_db:vault.view_vault_entry_form +#: model_terms:ir.ui.view,arch_db:vault.view_vault_form +msgid "Log" +msgstr "" + +#. module: vault +#. odoo-python +#: code:addons/vault/models/vault_log.py:0 +#: model:ir.model,name:vault.model_vault_log +#, python-format +msgid "Log entry of a vault" +msgstr "" + +#. module: vault +#: model:ir.actions.act_window,name:vault.action_res_users_keys +msgid "Manage my keys" +msgstr "" + +#. module: vault +#: model:ir.model.fields,field_description:vault.field_vault__master_key +#: model:ir.model.fields,field_description:vault.field_vault_abstract_field__master_key +#: model:ir.model.fields,field_description:vault.field_vault_export_wizard__master_key +#: model:ir.model.fields,field_description:vault.field_vault_field__master_key +#: model:ir.model.fields,field_description:vault.field_vault_file__master_key +#: model:ir.model.fields,field_description:vault.field_vault_import_wizard__master_key +#: model:ir.model.fields,field_description:vault.field_vault_right__master_key +#: model:ir.model.fields,field_description:vault.field_vault_store_wizard__master_key +msgid "Master Key" +msgstr "" + +#. module: vault +#: model:ir.model.fields,field_description:vault.field_vault_log__message +msgid "Message" +msgstr "" + +#. module: vault +#. odoo-python +#: code:addons/vault/controllers/main.py:0 +#, python-format +msgid "Missing filename" +msgstr "" + +#. module: vault +#. odoo-javascript +#: code:addons/vault/static/src/common/utils.esm.js:0 +#: code:addons/vault/static/src/common/utils.esm.js:0 +#, python-format +msgid "Missing password" +msgstr "" + +#. module: vault +#: model:ir.model.fields,field_description:vault.field_vault_store_wizard__model +msgid "Model" +msgstr "" + +#. module: vault +#: model:ir.model.fields,field_description:vault.field_res_config_settings__module_vault_share +msgid "Module Vault Share" +msgstr "" + +#. module: vault +#: model:ir.model.fields,field_description:vault.field_vault__name +#: model:ir.model.fields,field_description:vault.field_vault_abstract_field__name +#: model:ir.model.fields,field_description:vault.field_vault_entry__name +#: model:ir.model.fields,field_description:vault.field_vault_export_wizard__name +#: model:ir.model.fields,field_description:vault.field_vault_field__name +#: model:ir.model.fields,field_description:vault.field_vault_file__name +#: model:ir.model.fields,field_description:vault.field_vault_import_wizard__name +#: model:ir.model.fields,field_description:vault.field_vault_import_wizard_path__name +#: model:ir.model.fields,field_description:vault.field_vault_inbox__name +#: model:ir.model.fields,field_description:vault.field_vault_inbox_log__name +#: model:ir.model.fields,field_description:vault.field_vault_send_wizard__name +#: model:ir.model.fields,field_description:vault.field_vault_store_wizard__name +#: model:ir.model.fields,field_description:vault.field_vault_tag__name +msgid "Name" +msgstr "" + +#. module: vault +#: model_terms:ir.ui.view,arch_db:vault.inbox +msgid "Name of your secret:" +msgstr "" + +#. module: vault +#. odoo-python +#: code:addons/vault/wizards/vault_send_wizard.py:0 +#, python-format +msgid "Neither a secret nor file was given" +msgstr "" + +#. module: vault +#: model_terms:ir.ui.view,arch_db:vault.view_users_form_keys_modif +msgid "New inbox link" +msgstr "" + +#. module: vault +#: model_terms:ir.ui.view,arch_db:vault.view_users_form_keys_modif +msgid "New private key" +msgstr "" + +#. module: vault +#. odoo-python +#: code:addons/vault/controllers/main.py:0 +#, python-format +msgid "No secret found" +msgstr "" + +#. module: vault +#. odoo-python +#: code:addons/vault/models/vault_inbox.py:0 +#: code:addons/vault/wizards/vault_send_wizard.py:0 +#: model:ir.model.constraint,message:vault.constraint_vault_inbox_value_check +#: model:ir.model.constraint,message:vault.constraint_vault_send_wizard_value_check +#, python-format +msgid "No value found" +msgstr "" + +#. module: vault +#: model_terms:ir.ui.view,arch_db:vault.view_vault_entry_search +msgid "Not Expired" +msgstr "" + +#. module: vault +#: model:ir.model.fields,field_description:vault.field_vault__note +#: model:ir.model.fields,field_description:vault.field_vault_entry__note +#: model_terms:ir.ui.view,arch_db:vault.view_vault_entry_form +msgid "Note" +msgstr "" + +#. module: vault +#: model:ir.model.fields,field_description:vault.field_vault__user_id +#: model:ir.model.fields,field_description:vault.field_vault_entry__user_id +msgid "Owner" +msgstr "" + +#. module: vault +#: model:ir.model.fields,field_description:vault.field_vault_entry__parent_id +msgid "Parent" +msgstr "" + +#. module: vault +#: model:ir.model.fields,field_description:vault.field_vault_import_wizard__parent_id +msgid "Parent Entry" +msgstr "" + +#. module: vault +#. odoo-javascript +#: code:addons/vault/static/src/backend/templates.xml:0 +#, python-format +msgid "Password:" +msgstr "" + +#. module: vault +#: model:ir.model.fields,field_description:vault.field_vault_import_wizard__path +msgid "Path to import" +msgstr "" + +#. module: vault +#: model:ir.model.fields,field_description:vault.field_vault__perm_user +#: model:ir.model.fields,field_description:vault.field_vault_abstract_field__perm_user +#: model:ir.model.fields,field_description:vault.field_vault_entry__perm_user +#: model:ir.model.fields,field_description:vault.field_vault_field__perm_user +#: model:ir.model.fields,field_description:vault.field_vault_file__perm_user +#: model:ir.model.fields,field_description:vault.field_vault_right__perm_user +msgid "Perm User" +msgstr "" + +#. module: vault +#. odoo-javascript +#: code:addons/vault/static/src/backend/export.esm.js:0 +#: code:addons/vault/static/src/backend/import.esm.js:0 +#, python-format +msgid "Please enter the password for the database" +msgstr "" + +#. module: vault +#. odoo-javascript +#: code:addons/vault/static/src/backend/import.esm.js:0 +#, python-format +msgid "Please enter the password for the keepass database" +msgstr "" + +#. module: vault +#. odoo-javascript +#: code:addons/vault/static/src/backend/vault.esm.js:0 +#, python-format +msgid "Please enter the password for your private key" +msgstr "" + +#. module: vault +#. odoo-javascript +#: code:addons/vault/static/src/backend/templates.xml:0 +#, python-format +msgid "Please enter your password or upload a keyfile:" +msgstr "" + +#. module: vault +#. odoo-python +#: code:addons/vault/controllers/main.py:0 +#, python-format +msgid "Please specify a name" +msgstr "" + +#. module: vault +#: model:ir.model.fields,field_description:vault.field_res_users_key__private +msgid "Private" +msgstr "" + +#. module: vault +#: model:ir.model.fields,field_description:vault.field_res_users_key__public +#: model:ir.model.fields,field_description:vault.field_vault_send_wizard__public +msgid "Public" +msgstr "" + +#. module: vault +#: model:ir.model.fields,field_description:vault.field_vault_right__public_key +msgid "Public Key" +msgstr "" + +#. module: vault +#: model_terms:ir.ui.view,arch_db:vault.view_vault_form +msgid "Re-encrypt" +msgstr "" + +#. module: vault +#: model:ir.model.fields,field_description:vault.field_vault__reencrypt_required +msgid "Reencrypt Required" +msgstr "" + +#. module: vault +#: model:ir.actions.act_window,name:vault.action_vault_right +#: model:ir.model.fields,field_description:vault.field_vault__right_ids +#: model:ir.ui.menu,name:vault.menu_vault_right +#: model_terms:ir.ui.view,arch_db:vault.view_vault_form +msgid "Rights" +msgstr "" + +#. module: vault +#: model:ir.model.fields,field_description:vault.field_res_users_key__salt +msgid "Salt" +msgstr "" + +#. module: vault +#. odoo-javascript +#: code:addons/vault/static/src/backend/fields/vault_export_file.esm.js:0 +#: code:addons/vault/static/src/backend/fields/vault_file.esm.js:0 +#, python-format +msgid "Save As..." +msgstr "" + +#. module: vault +#. odoo-javascript +#: code:addons/vault/static/src/backend/fields/templates.xml:0 +#: code:addons/vault/static/src/backend/fields/templates.xml:0 +#: code:addons/vault/static/src/backend/fields/templates.xml:0 +#: code:addons/vault/static/src/backend/fields/templates.xml:0 +#, python-format +msgid "Save in a vault" +msgstr "" + +#. module: vault +#: model:ir.model.fields,field_description:vault.field_vault_inbox__secret +#: model:ir.model.fields,field_description:vault.field_vault_send_wizard__secret +#: model:ir.model.fields,field_description:vault.field_vault_store_wizard__secret +#: model_terms:ir.ui.view,arch_db:vault.inbox +msgid "Secret" +msgstr "" + +#. module: vault +#: model:ir.model.fields,field_description:vault.field_vault_inbox__secret_file +#: model:ir.model.fields,field_description:vault.field_vault_send_wizard__secret_file +msgid "Secret File" +msgstr "" + +#. module: vault +#: model:ir.model.fields,field_description:vault.field_vault_store_wizard__secret_temporary +msgid "Secret Temporary" +msgstr "" + +#. module: vault +#: model_terms:ir.ui.view,arch_db:vault.inbox +msgid "Secret to share:" +msgstr "" + +#. module: vault +#: model_terms:ir.ui.view,arch_db:vault.view_vault_send_wizard +msgid "Send" +msgstr "" + +#. module: vault +#. odoo-javascript +#: code:addons/vault/static/src/backend/fields/templates.xml:0 +#: code:addons/vault/static/src/backend/fields/templates.xml:0 +#, python-format +msgid "Send the secret to an user" +msgstr "" + +#. module: vault +#. odoo-javascript +#: code:addons/vault/static/src/backend/fields/vault_mixin.esm.js:0 +#, python-format +msgid "Send the secret to another user" +msgstr "" + +#. module: vault +#: model:ir.model.fields,field_description:vault.field_vault_right__perm_share +msgid "Share" +msgstr "" + +#. module: vault +#. odoo-javascript +#: code:addons/vault/static/src/backend/fields/templates.xml:0 +#: code:addons/vault/static/src/backend/fields/templates.xml:0 +#, python-format +msgid "Show" +msgstr "" + +#. module: vault +#. odoo-python +#: code:addons/vault/controllers/main.py:0 +#, python-format +msgid "Something went wrong with the encryption" +msgstr "" + +#. module: vault +#. odoo-javascript +#: code:addons/vault/static/src/backend/templates.xml:0 +#, python-format +msgid "Special" +msgstr "" + +#. module: vault +#: model:ir.model.fields,field_description:vault.field_vault_log__state +msgid "State" +msgstr "" + +#. module: vault +#: model_terms:ir.ui.view,arch_db:vault.view_vault_store_wizard +msgid "Store" +msgstr "" + +#. module: vault +#. odoo-javascript +#: code:addons/vault/static/src/backend/fields/vault_inbox_mixin.esm.js:0 +#, python-format +msgid "Store the secret in a vault" +msgstr "" + +#. module: vault +#: model_terms:ir.ui.view,arch_db:vault.inbox +msgid "Submit secret" +msgstr "" + +#. module: vault +#. odoo-python +#: code:addons/vault/controllers/main.py:0 +#, python-format +msgid "Successfully stored" +msgstr "" + +#. module: vault +#: model:ir.model.fields,field_description:vault.field_vault_entry__tags +msgid "Tags" +msgstr "" + +#. module: vault +#. odoo-python +#: code:addons/vault/models/vault.py:0 +#: code:addons/vault/models/vault_entry.py:0 +#: model:ir.model.constraint,message:vault.constraint_vault_entry_vault_uuid_uniq +#: model:ir.model.constraint,message:vault.constraint_vault_uuid_uniq +#, python-format +msgid "The UUID must be unique." +msgstr "" + +#. module: vault +#. odoo-javascript +#: code:addons/vault/static/src/backend/fields/vault_export_file.esm.js:0 +#: code:addons/vault/static/src/backend/fields/vault_file.esm.js:0 +#, python-format +msgid "The field is empty, there's nothing to save!" +msgstr "" + +#. module: vault +#: model_terms:ir.ui.view,arch_db:vault.view_vault_import_wizard +msgid "The files must end on one of the supported file type:" +msgstr "" + +#. module: vault +#. odoo-javascript +#: code:addons/vault/static/src/backend/controller.esm.js:0 +#, python-format +msgid "The following entries are broken:" +msgstr "" + +#. module: vault +#. odoo-javascript +#: code:addons/vault/static/src/common/utils.esm.js:0 +#, python-format +msgid "The passwords aren't matching" +msgstr "" + +#. module: vault +#. odoo-python +#: code:addons/vault/models/abstract_vault.py:0 +#, python-format +msgid "" +"The requested operation can not be completed due to security restrictions." +msgstr "" + +#. module: vault +#. odoo-python +#: code:addons/vault/models/vault_tag.py:0 +#: model:ir.model.constraint,message:vault.constraint_vault_tag_name_uniq +#, python-format +msgid "The tag must be unique!" +msgstr "" + +#. module: vault +#. odoo-python +#: code:addons/vault/models/vault_right.py:0 +#: model:ir.model.constraint,message:vault.constraint_vault_right_user_uniq +#, python-format +msgid "The user must be unique" +msgstr "" + +#. module: vault +#: model:ir.model.fields,field_description:vault.field_vault_inbox__token +msgid "Token" +msgstr "" + +#. module: vault +#. odoo-javascript +#: code:addons/vault/static/src/backend/import.esm.js:0 +#, python-format +msgid "Unsupported file to import" +msgstr "" + +#. module: vault +#: model:ir.model.fields,field_description:vault.field_vault_entry__url +msgid "Url" +msgstr "" + +#. module: vault +#: model:ir.model,name:vault.model_res_users +#: model:ir.model.fields,field_description:vault.field_res_users_key__user_id +#: model:ir.model.fields,field_description:vault.field_vault_log__user_id +#: model:ir.model.fields,field_description:vault.field_vault_right__user_id +#: model:ir.model.fields,field_description:vault.field_vault_send_wizard__user_id +msgid "User" +msgstr "" + +#. module: vault +#. odoo-python +#: code:addons/vault/models/res_users_key.py:0 +#: model:ir.model,name:vault.model_res_users_key +#, python-format +msgid "User data of a vault" +msgstr "" + +#. module: vault +#: model:ir.model.fields,help:vault.field_vault_inbox__inbox_link +msgid "" +"Using this link you can write to the current inbox. If you want people to " +"create new inboxes you should give them your inbox link from your key " +"management." +msgstr "" + +#. module: vault +#: model:ir.model.fields,field_description:vault.field_res_users_key__uuid +#: model:ir.model.fields,field_description:vault.field_vault__uuid +#: model:ir.model.fields,field_description:vault.field_vault_entry__uuid +#: model:ir.model.fields,field_description:vault.field_vault_import_wizard__uuid +#: model:ir.model.fields,field_description:vault.field_vault_import_wizard_path__uuid +msgid "Uuid" +msgstr "" + +#. module: vault +#: model:ir.model.fields,field_description:vault.field_vault_field__value +#: model:ir.model.fields,field_description:vault.field_vault_file__value +msgid "Value" +msgstr "" + +#. module: vault +#. odoo-python +#: code:addons/vault/models/vault.py:0 +#: model:ir.actions.act_window,name:vault.action_vault +#: model:ir.model,name:vault.model_vault +#: model:ir.model.fields,field_description:vault.field_vault_abstract_field__vault_id +#: model:ir.model.fields,field_description:vault.field_vault_entry__vault_id +#: model:ir.model.fields,field_description:vault.field_vault_export_wizard__vault_id +#: model:ir.model.fields,field_description:vault.field_vault_field__vault_id +#: model:ir.model.fields,field_description:vault.field_vault_file__vault_id +#: model:ir.model.fields,field_description:vault.field_vault_import_wizard__vault_id +#: model:ir.model.fields,field_description:vault.field_vault_inbox__user_id +#: model:ir.model.fields,field_description:vault.field_vault_log__vault_id +#: model:ir.model.fields,field_description:vault.field_vault_right__vault_id +#: model:ir.model.fields,field_description:vault.field_vault_store_wizard__vault_id +#: model:ir.ui.menu,name:vault.menu_vault +#: model_terms:ir.ui.view,arch_db:vault.res_config_settings_view_form +#: model_terms:ir.ui.view,arch_db:vault.view_vault_entry_search +#, python-format +msgid "Vault" +msgstr "" + +#. module: vault +#. odoo-javascript +#: code:addons/vault/static/src/backend/fields/vault_field.esm.js:0 +#, python-format +msgid "Vault Field" +msgstr "" + +#. module: vault +#. odoo-javascript +#: code:addons/vault/static/src/backend/fields/vault_file.esm.js:0 +#, python-format +msgid "Vault File" +msgstr "" + +#. module: vault +#. odoo-javascript +#: code:addons/vault/static/src/backend/fields/vault_inbox_field.esm.js:0 +#, python-format +msgid "Vault Inbox Field" +msgstr "" + +#. module: vault +#. odoo-javascript +#: code:addons/vault/static/src/backend/fields/vault_inbox_file.esm.js:0 +#, python-format +msgid "Vault Inbox File" +msgstr "" + +#. module: vault +#: model:ir.model.fields,field_description:vault.field_res_users__vault_right_ids +msgid "Vault Right" +msgstr "" + +#. module: vault +#: model_terms:ir.ui.view,arch_db:vault.res_config_settings_view_form +msgid "Vault Share" +msgstr "" + +#. module: vault +#. odoo-python +#: code:addons/vault/models/vault_inbox_log.py:0 +#: model:ir.model,name:vault.model_vault_inbox_log +#, python-format +msgid "Vault inbox log" +msgstr "" + +#. module: vault +#. odoo-javascript +#: code:addons/vault/static/src/backend/controller.esm.js:0 +#, python-format +msgid "Vault is not supported" +msgstr "" + +#. module: vault +#. odoo-python +#: code:addons/vault/models/vault_right.py:0 +#: model:ir.model,name:vault.model_vault_right +#, python-format +msgid "Vault rights" +msgstr "" + +#. module: vault +#. odoo-python +#: code:addons/vault/models/vault_inbox.py:0 +#: model:ir.model,name:vault.model_vault_inbox +#, python-format +msgid "Vault share incoming secrets" +msgstr "" + +#. module: vault +#. odoo-python +#: code:addons/vault/models/vault_tag.py:0 +#: model:ir.model,name:vault.model_vault_tag +#, python-format +msgid "Vault tag" +msgstr "" + +#. module: vault +#: model_terms:ir.ui.view,arch_db:vault.view_vault_entry_search +msgid "Vaults" +msgstr "" + +#. module: vault +#: model_terms:ir.ui.view,arch_db:vault.view_vault_form +msgid "Verify" +msgstr "" + +#. module: vault +#: model:ir.model.fields,field_description:vault.field_res_users_key__version +msgid "Version" +msgstr "" + +#. module: vault +#. odoo-python +#: code:addons/vault/models/vault_log.py:0 +#, python-format +msgid "Warning" +msgstr "" + +#. module: vault +#. odoo-python +#: code:addons/vault/wizards/vault_store_wizard.py:0 +#: model:ir.model,name:vault.model_vault_store_wizard +#, python-format +msgid "Wizard store a shared secret in a vault" +msgstr "" + +#. module: vault +#. odoo-python +#: code:addons/vault/wizards/vault_send_wizard.py:0 +#: model:ir.model,name:vault.model_vault_send_wizard +#, python-format +msgid "Wizard to send another user a secret" +msgstr "" + +#. module: vault +#: model:ir.model.fields,field_description:vault.field_vault_right__perm_write +msgid "Write" +msgstr "" + +#. module: vault +#. odoo-python +#: code:addons/vault/models/vault_inbox.py:0 +#, python-format +msgid "Written by %(name)s via %(ip)s" +msgstr "" + +#. module: vault +#. odoo-python +#: code:addons/vault/models/vault_entry.py:0 +#, python-format +msgid "You can not create recursive entries." +msgstr "" + +#. module: vault +#: model_terms:ir.ui.view,arch_db:vault.view_vault_send_wizard +msgid "" +"You can only send the secret to the user who has generated a key-pair.\n" +" If an user is not showing please ask him to generate these." +msgstr "" + +#. module: vault +#: model_terms:ir.ui.view,arch_db:vault.view_users_form_keys_modif +msgid "" +"You will loose access to all vaults and your inbox. Do you want to continue?" +msgstr "" + +#. module: vault +#. odoo-javascript +#: code:addons/vault/static/src/backend/templates.xml:0 +#, python-format +msgid "a-z" +msgstr "" + +#. module: vault +#: model_terms:ir.ui.view,arch_db:vault.view_vault_import_wizard +#: model_terms:ir.ui.view,arch_db:vault.view_vault_send_wizard +#: model_terms:ir.ui.view,arch_db:vault.view_vault_store_wizard +msgid "or" +msgstr "" diff --git a/vault/models/__init__.py b/vault/models/__init__.py new file mode 100644 index 0000000000..d9d3e40ebe --- /dev/null +++ b/vault/models/__init__.py @@ -0,0 +1,19 @@ +# © 2021 Florian Kantelberg - initOS GmbH +# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). + +from . import ( + abstract_vault, + abstract_vault_field, + res_config_settings, + res_users, + res_users_key, + vault, + vault_entry, + vault_field, + vault_file, + vault_inbox, + vault_inbox_log, + vault_log, + vault_right, + vault_tag, +) diff --git a/vault/models/abstract_vault.py b/vault/models/abstract_vault.py new file mode 100644 index 0000000000..614173056d --- /dev/null +++ b/vault/models/abstract_vault.py @@ -0,0 +1,77 @@ +# © 2021 Florian Kantelberg - initOS GmbH +# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). + +import logging + +from odoo import _, api, models +from odoo.exceptions import AccessError + +_logger = logging.getLogger(__name__) + + +class AbstractVault(models.AbstractModel): + """Models must have the following fields: + `perm_user`: The permissions are computed for this user + `allowed_read`: The current user can read from the vault + `allowed_create`: The current user can read from the vault + `allowed_write`: The current user has write access to the vault + `allowed_share`: The current user can share the vault with other users + `allowed_delete`: The current user can delete the vault or entries of it + """ + + _name = "vault.abstract" + _description = _("Abstract model to implement general access rights") + + @api.model + def raise_access_error(self): + raise AccessError( + _( + "The requested operation can not be completed due to security " + "restrictions." + ) + ) + + def check_access_rule(self, operation): + super().check_access_rule(operation) + + if self.env.su: + return + + # We have to recompute if the user of the environment changed + if self.env.user != self.mapped("perm_user"): + vault = self if self._name == "vault" else self.mapped("vault_id") + vault._compute_access() + + # Shortcut for vault.right because only the share right is required + if self._name == "vault.right": + if not self.filtered("allowed_share"): + self.raise_access_error() + return + + # Check the operation and matching permissions + if operation == "read" and not self.filtered("allowed_read"): + self.raise_access_error() + + if operation == "create" and not self.filtered("allowed_create"): + self.raise_access_error() + + if operation == "write" and not self.filtered("allowed_write"): + self.raise_access_error() + + if operation == "unlink" and not self.filtered("allowed_delete"): + self.raise_access_error() + + def _log_entry(self, msg, state): + raise NotImplementedError() + + def log_entry(self, msg): + return self._log_entry(msg, None) + + def log_info(self, msg): + return self._log_entry(msg, "info") + + def log_warn(self, msg): + return self._log_entry(msg, "warn") + + def log_error(self, msg): + return self._log_entry(msg, "error") diff --git a/vault/models/abstract_vault_field.py b/vault/models/abstract_vault_field.py new file mode 100644 index 0000000000..691d7b7d03 --- /dev/null +++ b/vault/models/abstract_vault_field.py @@ -0,0 +1,57 @@ +# © 2021 Florian Kantelberg - initOS GmbH +# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). + +import logging + +from odoo import _, api, fields, models + +_logger = logging.getLogger(__name__) + + +class AbstractVaultField(models.AbstractModel): + _name = "vault.abstract.field" + _description = _("Abstract model to implement basic fields for encryption") + + entry_id = fields.Many2one("vault.entry", ondelete="cascade", required=True) + entry_name = fields.Char(related="entry_id.complete_name") + vault_id = fields.Many2one(related="entry_id.vault_id") + master_key = fields.Char(compute="_compute_master_key", store=False) + + perm_user = fields.Many2one(related="vault_id.perm_user", store=False) + allowed_read = fields.Boolean(related="vault_id.allowed_read", store=False) + allowed_create = fields.Boolean(related="vault_id.allowed_create", store=False) + allowed_write = fields.Boolean(related="vault_id.allowed_write", store=False) + allowed_share = fields.Boolean(related="vault_id.allowed_share", store=False) + allowed_delete = fields.Boolean(related="vault_id.allowed_delete", store=False) + + name = fields.Char(required=True) + iv = fields.Char() + + @api.depends("entry_id.vault_id.master_key") + def _compute_master_key(self): + for rec in self: + rec.master_key = rec.vault_id.master_key + + def log_change(self, action): + if self.env.context.get("vault_skip_log"): + return + + for rec in self: + rec.entry_id.log_info( + f"{action} value {rec.name} of {rec.entry_id.complete_name} " + f"by {self.env.user.display_name}" + ) + + @api.model_create_multi + def create(self, vals_list): + res = super().create(vals_list) + res.log_change("Created") + return res + + def unlink(self): + self.log_change("Deleted") + return super().unlink() + + def write(self, values): + self.log_change("Changed") + return super().write(values) diff --git a/vault/models/res_config_settings.py b/vault/models/res_config_settings.py new file mode 100644 index 0000000000..105571263f --- /dev/null +++ b/vault/models/res_config_settings.py @@ -0,0 +1,16 @@ +# © 2021 Florian Kantelberg - initOS GmbH +# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). + +from odoo import fields, models + + +class ResConfigSettings(models.TransientModel): + _inherit = "res.config.settings" + + module_vault_share = fields.Boolean() + group_vault_export = fields.Boolean( + "Export Vaults", implied_group="vault.group_vault_export" + ) + group_vault_import = fields.Boolean( + "Import Vaults", implied_group="vault.group_vault_import" + ) diff --git a/vault/models/res_users.py b/vault/models/res_users.py new file mode 100644 index 0000000000..ecf5d3c91e --- /dev/null +++ b/vault/models/res_users.py @@ -0,0 +1,78 @@ +# © 2021 Florian Kantelberg - initOS GmbH +# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). + +import logging +from uuid import uuid4 + +from odoo import api, fields, models + +_logger = logging.getLogger(__name__) + + +class ResUsers(models.Model): + _inherit = "res.users" + + active_key = fields.Many2one( + "res.users.key", + compute="_compute_active_key", + store=False, + ) + keys = fields.One2many("res.users.key", "user_id", readonly=True) + vault_right_ids = fields.One2many("vault.right", "user_id", readonly=True) + inbox_ids = fields.One2many("vault.inbox", "user_id") + inbox_enabled = fields.Boolean(default=True) + inbox_link = fields.Char(compute="_compute_inbox_link", readonly=True, store=False) + inbox_token = fields.Char(default=lambda self: uuid4(), readonly=True) + + @api.depends("keys", "keys.current") + def _compute_active_key(self): + for rec in self: + keys = rec.sudo().keys.filtered("current") + rec.active_key = keys[0] if keys else None + + @api.depends("inbox_token") + def _compute_inbox_link(self): + base_url = self.env["ir.config_parameter"].sudo().get_param("web.base.url") + for rec in self: + rec.inbox_link = f"{base_url}/vault/inbox/{rec.inbox_token}" + + @api.model + def action_get_vault(self): + action = self.sudo().env.ref("vault.action_res_users_keys") + result = action.read()[0] + result["res_id"] = self.env.uid + return result + + def action_new_inbox_token(self): + self.ensure_one() + self.sudo().inbox_token = uuid4() + return self.action_get_vault() + + def action_invalidate_key(self): + """Disable the current key and remove all accesses to the vaults""" + self.ensure_one() + self.keys.write({"current": False}) + self.vault_right_ids.sudo().unlink() + self.inbox_ids.unlink() + self.env["vault"].search([])._compute_access() + return self.action_get_vault() + + @api.model + def find_user_of_inbox(self, token): + return self.search([("inbox_token", "=", token), ("inbox_enabled", "=", True)]) + + def get_vault_keys(self): + self.ensure_one() + + if not self.active_key: + return {} + + return { + "iterations": self.active_key.iterations, + "iv": self.active_key.iv, + "private": self.active_key.private, + "public": self.active_key.public, + "salt": self.active_key.salt, + "uuid": self.active_key.uuid, + "version": self.active_key.version, + } diff --git a/vault/models/res_users_key.py b/vault/models/res_users_key.py new file mode 100644 index 0000000000..6c3ae5bc1b --- /dev/null +++ b/vault/models/res_users_key.py @@ -0,0 +1,82 @@ +# © 2021 Florian Kantelberg - initOS GmbH +# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). + +import logging +import re +from hashlib import sha256 +from uuid import uuid4 + +from odoo import _, api, fields, models +from odoo.exceptions import ValidationError + +_logger = logging.getLogger(__name__) + + +class ResUsersKey(models.Model): + _name = "res.users.key" + _description = _("User data of a vault") + _rec_name = "fingerprint" + _order = "create_date DESC" + + user_id = fields.Many2one("res.users", required=True) + uuid = fields.Char(default=lambda self: uuid4(), required=True, readonly=True) + current = fields.Boolean(default=True, readonly=True) + fingerprint = fields.Char(compute="_compute_fingerprint", store=True) + public = fields.Char(required=True, readonly=True) + salt = fields.Char(required=True, readonly=True) + iv = fields.Char(required=True, readonly=True) + iterations = fields.Integer(required=True, readonly=True) + version = fields.Integer(readonly=True) + # Encrypted with master password of user + private = fields.Char(required=True, readonly=True) + + @api.depends("public") + def _compute_fingerprint(self): + for rec in self: + if rec.public: + hashed = sha256(rec.public.encode()).hexdigest() + rec.fingerprint = ":".join(re.findall(r".{2}", hashed)) + else: + rec.fingerprint = False + + def _prepare_values(self, iterations, iv, private, public, salt, version): + return { + "iterations": iterations, + "iv": iv, + "private": private, + "public": public, + "salt": salt, + "user_id": self.env.uid, + "current": True, + "version": version, + } + + def store(self, iterations, iv, private, public, salt, version): + if not all(isinstance(x, str) and x for x in [public, private, iv, salt]): + raise ValidationError(_("Invalid parameter")) + + if not isinstance(iterations, int) or iterations < 4000: + raise ValidationError(_("Invalid parameter")) + + if not isinstance(version, int): + raise ValidationError(_("Invalid parameter")) + + domain = [ + ("user_id", "=", self.env.uid), + ("private", "=", private), + ] + key = self.search(domain) + if not key: + # Disable all current keys + self.env.user.keys.write({"current": False}) + + rec = self.create( + self._prepare_values(iterations, iv, private, public, salt, version) + ) + return rec.uuid + + return False + + def extract_public_key(self, user): + user = self.sudo().search([("user_id", "=", user), ("current", "=", True)]) + return user.public or None diff --git a/vault/models/vault.py b/vault/models/vault.py new file mode 100644 index 0000000000..5aef99f230 --- /dev/null +++ b/vault/models/vault.py @@ -0,0 +1,165 @@ +# © 2021-2024 Florian Kantelberg - initOS GmbH +# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). + +import logging +from uuid import uuid4 + +from odoo import _, api, fields, models + +_logger = logging.getLogger(__name__) + + +class Vault(models.Model): + _name = "vault" + _description = _("Vault") + _inherit = ["vault.abstract"] + _order = "name" + + user_id = fields.Many2one( + "res.users", + "Owner", + readonly=True, + default=lambda self: self.env.user, + required=True, + ) + right_ids = fields.One2many( + "vault.right", + "vault_id", + "Rights", + default=lambda self: self._get_default_rights(), + ) + entry_ids = fields.One2many("vault.entry", "vault_id", "Entries") + field_ids = fields.One2many("vault.field", "vault_id", "Fields") + file_ids = fields.One2many("vault.file", "vault_id", "Files") + log_ids = fields.One2many("vault.log", "vault_id", "Log", readonly=True) + reencrypt_required = fields.Boolean(default=False) + + # Access control + perm_user = fields.Many2one("res.users", compute="_compute_access", store=False) + allowed_read = fields.Boolean(compute="_compute_access", store=False) + allowed_create = fields.Boolean(compute="_compute_access", store=False) + allowed_share = fields.Boolean(compute="_compute_access", store=False) + allowed_write = fields.Boolean(compute="_compute_access", store=False) + allowed_delete = fields.Boolean(compute="_compute_access", store=False) + + master_key = fields.Char( + compute="_compute_master_key", + inverse="_inverse_master_key", + store=False, + ) + + uuid = fields.Char(default=lambda self: uuid4(), required=True, readonly=True) + name = fields.Char(required=True) + note = fields.Text() + + _sql_constraints = [ + ("uuid_uniq", "UNIQUE(uuid)", _("The UUID must be unique.")), + ] + + @api.depends("right_ids.user_id") + def _compute_access(self): + user = self.env.user + for rec in self.sudo(): + rec.perm_user = user.id + + if user == rec.user_id: + rec.write( + { + "allowed_create": True, + "allowed_share": True, + "allowed_write": True, + "allowed_delete": True, + "allowed_read": True, + } + ) + continue + + rights = rec.right_ids + rec.allowed_read = user in rights.mapped("user_id") + rec.allowed_create = user in rights.filtered("perm_create").mapped( + "user_id" + ) + rec.allowed_share = user in rights.filtered("perm_share").mapped("user_id") + rec.allowed_write = user in rights.filtered("perm_write").mapped("user_id") + rec.allowed_delete = user in rights.filtered("perm_delete").mapped( + "user_id" + ) + + @api.depends("right_ids.key") + def _compute_master_key(self): + domain = [("user_id", "=", self.env.uid)] + for rec in self: + rights = rec.right_ids.filtered_domain(domain) + rec.master_key = rights[0].key if rights else False + + def _inverse_master_key(self): + domain = [("user_id", "=", self.env.uid)] + for rec in self: + rights = rec.right_ids.filtered_domain(domain) + if rights and not rights.key: + rights.key = rec.master_key + + def _get_default_rights(self): + return [ + ( + 0, + 0, + { + "user_id": self.env.uid, + "perm_create": True, + "perm_write": True, + "perm_delete": True, + "perm_share": True, + }, + ) + ] + + def _log_entry(self, msg, state): + self.ensure_one() + return ( + self.env["vault.log"] + .sudo() + .create( + { + "vault_id": self.id, + "user_id": self.env.uid, + "message": msg, + "state": state, + } + ) + ) + + def share_public_keys(self): + self.ensure_one() + result = [] + for right in self.right_ids: + result.append({"user": right.user_id.id, "public": right.public_key}) + return result + + def action_open_import_wizard(self): + self.ensure_one() + wizard = self.env.ref("vault.view_vault_import_wizard") + return { + "name": _("Import from file"), + "type": "ir.actions.act_window", + "view_mode": "form", + "res_model": "vault.import.wizard", + "views": [(wizard.id, "form")], + "view_id": wizard.id, + "target": "new", + "context": {"default_vault_id": self.id}, + } + + def action_open_export_wizard(self): + self.ensure_one() + wizard = self.env.ref("vault.view_vault_export_wizard") + return { + "name": _("Export to file"), + "type": "ir.actions.act_window", + "view_mode": "form", + "res_model": "vault.export.wizard", + "views": [(wizard.id, "form")], + "view_id": wizard.id, + "target": "new", + "context": {"default_vault_id": self.id}, + } diff --git a/vault/models/vault_entry.py b/vault/models/vault_entry.py new file mode 100644 index 0000000000..1f553c3561 --- /dev/null +++ b/vault/models/vault_entry.py @@ -0,0 +1,215 @@ +# © 2021 Florian Kantelberg - initOS GmbH +# Copyright 2022 Tecnativa - Víctor Martínez +# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). + +import logging +from datetime import datetime +from uuid import uuid4 + +from odoo import _, api, fields, models +from odoo.exceptions import ValidationError + +_logger = logging.getLogger(__name__) + + +class VaultEntry(models.Model): + _name = "vault.entry" + _description = _("Entry inside a vault") + _inherit = ["vault.abstract"] + _order = "complete_name" + _rec_name = "complete_name" + + parent_id = fields.Many2one( + "vault.entry", + "Parent", + ondelete="cascade", + domain="[('vault_id', '=', vault_id)]", + ) + child_ids = fields.One2many("vault.entry", "parent_id", "Child") + + vault_id = fields.Many2one("vault", "Vault", ondelete="cascade", required=True) + user_id = fields.Many2one(related="vault_id.user_id") + field_ids = fields.One2many("vault.field", "entry_id", "Fields") + file_ids = fields.One2many("vault.file", "entry_id", "Files") + log_ids = fields.One2many("vault.log", "entry_id", "Log", readonly=True) + + perm_user = fields.Many2one(related="vault_id.perm_user", store=False) + allowed_read = fields.Boolean(related="vault_id.allowed_read", store=False) + allowed_create = fields.Boolean(related="vault_id.allowed_create", store=False) + allowed_share = fields.Boolean(related="vault_id.allowed_share", store=False) + allowed_write = fields.Boolean(related="vault_id.allowed_write", store=False) + allowed_delete = fields.Boolean(related="vault_id.allowed_delete", store=False) + + complete_name = fields.Char( + compute="_compute_complete_name", + store=True, + readonly=True, + recursive=True, + ) + uuid = fields.Char(default=lambda self: uuid4(), required=True, copy=False) + name = fields.Char(required=True) + url = fields.Char() + note = fields.Text() + tags = fields.Many2many("vault.tag") + expire_date = fields.Datetime("Expires on", default=False) + expired = fields.Boolean( + compute="_compute_expired", + search="_search_expired", + store=False, + ) + + _sql_constraints = [ + ("vault_uuid_uniq", "UNIQUE(vault_id, uuid)", _("The UUID must be unique.")), + ] + + @api.constrains("parent_id") + def _check_parent_id(self): + if not self._check_recursion(): + raise ValidationError(_("You can not create recursive entries.")) + + @api.depends("name", "parent_id.complete_name") + def _compute_complete_name(self): + for rec in self: + if rec.parent_id: + rec.complete_name = f"{rec.parent_id.complete_name} / {rec.name}" + else: + rec.complete_name = rec.name + + @api.model + def search_panel_select_range(self, field_name, **kwargs): + """We add the following contexts related to searchpanel: + - entry_short_name: Show just the name instead of full path. + - from_search_panel: It will be used to overwrite domain. + Remove the limit of records (default is 200). + """ + return super( + VaultEntry, + self.with_context(from_search_panel=True, entry_short_name=True), + ).search_panel_select_range(field_name, **kwargs) + + def search_read(self, domain=None, fields=None, offset=0, limit=None, order=None): + """Changes related to searchpanel: + - Add a domain to only show records with children. + """ + domain = domain if domain else [] + if self.env.context.get("from_search_panel"): + domain += [("child_ids", "!=", False)] + return super().search_read( + domain=domain, fields=fields, offset=offset, limit=limit, order=order + ) + + def copy_data(self, default=None): + self.ensure_one() + + if default is None: + default = {} + + if "name" not in default: + default["name"] = _("%s (copy)", self.name) + + if "field_ids" not in default: + default["field_ids"] = [ + (0, 0, field.copy_data()[0]) for field in self.field_ids + ] + if "file_ids" not in default: + default["file_ids"] = [ + (0, 0, field.copy_data()[0]) for field in self.file_ids + ] + return super().copy_data(default) + + @api.depends("name", "complete_name") + def _compute_display_name(self): + if not self.env.context.get("entry_short_name", False): + return super()._compute_display_name() + for record in self: + record.display_name = record.name + + @api.depends("expire_date") + def _compute_expired(self): + now = datetime.now() + for rec in self: + rec.expired = rec.expire_date and now > rec.expire_date + + def _search_expired(self, operator, value): + if (operator not in ["=", "!="]) or (value not in [True, False]): + return [] + + if (operator, value) in [("=", True), ("!=", False)]: + return [("expire_date", "<", datetime.now())] + + return ["|", ("expire_date", ">=", datetime.now()), ("expire_date", "=", False)] + + def log_change(self, action): + if self.env.context.get("vault_skip_log"): + return + + for rec in self: + rec.log_info( + _("%(action)s entry %(name)s by %(user)s") + % { + "action": action, + "name": rec.complete_name, + "user": rec.env.user.display_name, + } + ) + + @api.model_create_multi + def create(self, vals_list): + res = super().create(vals_list) + res.log_change("Created") + return res + + def unlink(self): + self.log_change("Deleted") + + return super().unlink() + + def _log_entry(self, msg, state): + self.ensure_one() + return ( + self.env["vault.log"] + .sudo() + .create( + { + "vault_id": self.vault_id.id, + "entry_id": self.id, + "user_id": self.env.uid, + "message": msg, + "state": state, + } + ) + ) + + def action_open_import_wizard(self): + self.ensure_one() + wizard = self.env.ref("vault.view_vault_import_wizard") + return { + "name": _("Import from file"), + "type": "ir.actions.act_window", + "view_mode": "form", + "res_model": "vault.import.wizard", + "views": [(wizard.id, "form")], + "view_id": wizard.id, + "target": "new", + "context": { + "default_vault_id": self.vault_id.id, + "default_parent_id": self.id, + }, + } + + def action_open_export_wizard(self): + self.ensure_one() + wizard = self.env.ref("vault.view_vault_export_wizard") + return { + "name": _("Export to file"), + "type": "ir.actions.act_window", + "view_mode": "form", + "res_model": "vault.export.wizard", + "views": [(wizard.id, "form")], + "view_id": wizard.id, + "target": "new", + "context": { + "default_vault_id": self.vault_id.id, + "default_entry_id": self.id, + }, + } diff --git a/vault/models/vault_field.py b/vault/models/vault_field.py new file mode 100644 index 0000000000..26490b26e0 --- /dev/null +++ b/vault/models/vault_field.py @@ -0,0 +1,17 @@ +# © 2021 Florian Kantelberg - initOS GmbH +# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). + +import logging + +from odoo import _, fields, models + +_logger = logging.getLogger(__name__) + + +class VaultField(models.Model): + _name = "vault.field" + _description = _("Field of a vault") + _order = "name" + _inherit = ["vault.abstract.field", "vault.abstract"] + + value = fields.Char(required=True) diff --git a/vault/models/vault_file.py b/vault/models/vault_file.py new file mode 100644 index 0000000000..011412d38e --- /dev/null +++ b/vault/models/vault_file.py @@ -0,0 +1,25 @@ +# © 2021 Florian Kantelberg - initOS GmbH +# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). + +import logging + +from odoo import _, api, fields, models + +_logger = logging.getLogger(__name__) + + +class VaultFile(models.Model): + _name = "vault.file" + _description = _("File of a vault") + _order = "name" + _inherit = ["vault.abstract.field", "vault.abstract"] + + value = fields.Binary(attachment=False) + + @api.model + def search_read(self, *args, **kwargs): + if self.env.context.get("vault_reencrypt"): + return super(VaultFile, self.with_context(bin_size=False)).search_read( + *args, **kwargs + ) + return super().search_read(*args, **kwargs) diff --git a/vault/models/vault_inbox.py b/vault/models/vault_inbox.py new file mode 100644 index 0000000000..d8c8028e22 --- /dev/null +++ b/vault/models/vault_inbox.py @@ -0,0 +1,114 @@ +# © 2021 Florian Kantelberg - initOS GmbH +# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). + +import logging +from datetime import datetime, timedelta +from uuid import uuid4 + +from odoo import _, api, fields, models + +_logger = logging.getLogger(__name__) + + +class VaultInbox(models.Model): + _name = "vault.inbox" + _description = _("Vault share incoming secrets") + + token = fields.Char(default=lambda self: uuid4(), readonly=True, copy=False) + inbox_link = fields.Char( + compute="_compute_inbox_link", + readonly=True, + help="Using this link you can write to the current inbox. If you want people " + "to create new inboxes you should give them your inbox link from your key " + "management.", + ) + user_id = fields.Many2one( + "res.users", + "Vault", + required=True, + ) + name = fields.Char(required=True) + secret = fields.Char(readonly=True) + filename = fields.Char() + secret_file = fields.Binary(attachment=False, readonly=True) + key = fields.Char(required=True) + iv = fields.Char(required=True) + accesses = fields.Integer( + "Access counter", + default=1, + help="If this is 0 the inbox can't be written using the link", + ) + expiration = fields.Datetime( + default=lambda self: datetime.now() + timedelta(days=7), + help="If expired the inbox can't be written using the link", + ) + log_ids = fields.One2many("vault.inbox.log", "inbox_id", "Log", readonly=True) + + _sql_constraints = [ + ( + "value_check", + "CHECK(secret IS NOT NULL OR secret_file IS NOT NULL)", + _("No value found"), + ), + ] + + @api.depends("token") + def _compute_inbox_link(self): + base_url = self.env["ir.config_parameter"].sudo().get_param("web.base.url") + for rec in self: + rec.inbox_link = f"{base_url}/vault/inbox/{rec.token}" + + def read(self, *args, **kwargs): + # Always load the binary instead of the size + return super(VaultInbox, self.with_context(bin_size=False)).read( + *args, **kwargs + ) + + @api.model + def find_inbox(self, token): + return self.search([("token", "=", token)]) + + def store_in_inbox( + self, + name, + secret, + secret_file, + iv, + key, + user, + filename, + ip=None, + ): + log_info = {"name": user.name, "ip": ip or "n/a"} + if len(self) == 0: + log = _("Created by %(name)s via %(ip)s") % log_info + return self.create( + { + "name": name, + "accesses": 0, + "iv": iv, + "key": key, + "secret": secret or None, + "secret_file": secret_file or None, + "filename": filename, + "user_id": user.id, + "log_ids": [(0, 0, {"name": log})], + } + ) + + self.ensure_one() + if self.accesses > 0 and datetime.now() < self.expiration: + log = _("Written by %(name)s via %(ip)s") % log_info + + self.write( + { + "accesses": self.accesses - 1, + "iv": iv, + "key": key, + "secret": secret or None, + "secret_file": secret_file or None, + "filename": filename, + "log_ids": [(0, 0, {"name": log})], + } + ) + return self diff --git a/vault/models/vault_inbox_log.py b/vault/models/vault_inbox_log.py new file mode 100644 index 0000000000..e072283624 --- /dev/null +++ b/vault/models/vault_inbox_log.py @@ -0,0 +1,22 @@ +# © 2021 Florian Kantelberg - initOS GmbH +# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). + +import logging + +from odoo import _, fields, models + +_logger = logging.getLogger(__name__) + + +class VaultInboxLog(models.Model): + _name = "vault.inbox.log" + _description = _("Vault inbox log") + _order = "create_date DESC" + + inbox_id = fields.Many2one( + "vault.inbox", + ondelete="cascade", + readonly=True, + required=True, + ) + name = fields.Char(readonly=True) diff --git a/vault/models/vault_log.py b/vault/models/vault_log.py new file mode 100644 index 0000000000..3f44569c53 --- /dev/null +++ b/vault/models/vault_log.py @@ -0,0 +1,46 @@ +# © 2021 Florian Kantelberg - initOS GmbH +# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). + +import logging + +from odoo import _, api, fields, models + +_logger = logging.getLogger(__name__) + + +class VaultLog(models.Model): + _name = "vault.log" + _description = _("Log entry of a vault") + _order = "create_date DESC" + _rec_name = "message" + + vault_id = fields.Many2one( + "vault", + "Vault", + ondelete="cascade", + required=True, + readonly=True, + ) + entry_id = fields.Many2one( + "vault.entry", + "Entry", + ondelete="cascade", + readonly=True, + ) + user_id = fields.Many2one("res.users", "User", required=True, readonly=True) + state = fields.Selection(lambda self: self._get_log_state(), readonly=True) + message = fields.Char(readonly=True, required=True) + + def _get_log_state(self): + return [ + ("info", _("Information")), + ("warn", _("Warning")), + ("error", _("Error")), + ] + + @api.model_create_multi + def create(self, vals_list): + res = super().create(vals_list) + if not self.env.context.get("skip_log", False): + _logger.info("Vault log: %s", res.message) + return res diff --git a/vault/models/vault_right.py b/vault/models/vault_right.py new file mode 100644 index 0000000000..1f9fc3bc77 --- /dev/null +++ b/vault/models/vault_right.py @@ -0,0 +1,110 @@ +# © 2021 Florian Kantelberg - initOS GmbH +# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). + +from odoo import _, api, fields, models + + +class VaultRight(models.Model): + _name = "vault.right" + _description = _("Vault rights") + _inherit = ["vault.abstract"] + _order = "user_id" + + vault_id = fields.Many2one( + "vault", + "Vault", + readonly=True, + required=True, + ondelete="cascade", + ) + master_key = fields.Char(related="vault_id.master_key", readonly=True, store=False) + user_id = fields.Many2one( + "res.users", + "User", + domain=[("keys", "!=", False)], + required=True, + ) + public_key = fields.Char(compute="_compute_public_key", readonly=True, store=False) + perm_create = fields.Boolean( + "Create", + default=lambda self: self._get_is_owner(), + help="Allow to create in the vault", + ) + perm_write = fields.Boolean( + "Write", + default=lambda self: self._get_is_owner(), + help="Allow to write to the vault", + ) + perm_share = fields.Boolean( + "Share", + default=lambda self: self._get_is_owner(), + help="Allow to share a vault with new users", + ) + perm_delete = fields.Boolean( + "Delete", + default=lambda self: self._get_is_owner(), + help="Allow to delete a vault", + ) + + perm_user = fields.Many2one(related="vault_id.perm_user", store=False) + allowed_read = fields.Boolean(related="vault_id.allowed_read", store=False) + allowed_create = fields.Boolean(related="vault_id.allowed_create", store=False) + allowed_write = fields.Boolean(related="vault_id.allowed_write", store=False) + allowed_share = fields.Boolean(related="vault_id.allowed_share", store=False) + allowed_delete = fields.Boolean(related="vault_id.allowed_delete", store=False) + + # Encrypted with the public key of the user + key = fields.Char() + + _sql_constraints = ( + ("user_uniq", "UNIQUE(user_id, vault_id)", _("The user must be unique")), + ) + + def _get_is_owner(self): + return self.env.user == self.vault_id.user_id + + @api.depends("user_id") + def _compute_public_key(self): + for rec in self: + rec.public_key = rec.user_id.active_key.public + + def log_access(self): + for rec in self: + rights = ", ".join( + sorted( + ["read"] + + [ + right + for right in ["create", "write", "share", "delete"] + if getattr(rec, f"perm_{right}", False) + ] + ) + ) + + rec.vault_id.log_info( + f"Grant access to user {rec.user_id.display_name}: {rights}" + ) + + @api.model_create_multi + def create(self, vals_list): + res = super().create(vals_list) + if not res.allowed_share and not res.env.su: + self.raise_access_error() + + res.log_access() + return res + + def write(self, values): + res = super().write(values) + perms = ["perm_write", "perm_delete", "perm_share", "perm_create"] + if any(x in values for x in perms): + self.log_access() + + return res + + def unlink(self): + for rec in self: + rec.vault_id.log_info(f"Removed user {self.user_id.display_name}") + rec.vault_id.reencrypt_required = True + + return super().unlink() diff --git a/vault/models/vault_tag.py b/vault/models/vault_tag.py new file mode 100644 index 0000000000..f50ae6de88 --- /dev/null +++ b/vault/models/vault_tag.py @@ -0,0 +1,16 @@ +# © 2021 Florian Kantelberg - initOS GmbH +# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). + +from odoo import _, fields, models + + +class VaultTag(models.Model): + _name = "vault.tag" + _description = _("Vault tag") + _order = "name" + + name = fields.Char(required=True) + + _sql_constraints = [ + ("name_uniq", "unique(name)", _("The tag must be unique!")), + ] diff --git a/vault/readme/CONTRIBUTORS.rst b/vault/readme/CONTRIBUTORS.rst new file mode 100644 index 0000000000..e202826121 --- /dev/null +++ b/vault/readme/CONTRIBUTORS.rst @@ -0,0 +1 @@ +* Florian Kantelberg diff --git a/vault/readme/DESCRIPTION.rst b/vault/readme/DESCRIPTION.rst new file mode 100644 index 0000000000..50cf3c7679 --- /dev/null +++ b/vault/readme/DESCRIPTION.rst @@ -0,0 +1,7 @@ +This module implements a vault for secrets and files using end-to-end-encryption. The encryption and decryption happens in the browser using a vault specific shared master key. The master keys are encrypted using asymmetrically. For this the user has to enter a second password on the first login or if he needs to access data in a vault. The asymmetric keys are stored for a certain time in the browser storage. + +The server can never access the secrets with the information available. Only people registered in the vault can decrypt or encrypt values in a vault. The meta data isn't encrypted to be able to search/filter for entries more easily. + +This modules requires a secure context for the browser to work properly and therefore HTTPS support is required. + +The `vault-recovery `_ project focuses on disaster recovery in case of an incident to recover secrets from old database backups or old exports. diff --git a/vault/readme/ROADMAP.rst b/vault/readme/ROADMAP.rst new file mode 100644 index 0000000000..ccaf5abc1d --- /dev/null +++ b/vault/readme/ROADMAP.rst @@ -0,0 +1,14 @@ +* Field and file history for restoration + +* Import improvement + + * Support challenge-response/FIDO2 + * Support for argon2 and kdbx v4 + +* When changing an entry from one vault to another existing vault, the values added on + this entry cannot be accessed, so the field vault is going to be readonly when it + is defined. + + If you want to move entries between vaults you can use the export -> import option. + +* HTTPS or localhost (secure browser context) is required for the client side encryption diff --git a/vault/security/ir.model.access.csv b/vault/security/ir.model.access.csv new file mode 100644 index 0000000000..0863b98aa8 --- /dev/null +++ b/vault/security/ir.model.access.csv @@ -0,0 +1,16 @@ +id,name,model_id:id,group_id:id,perm_read,perm_write,perm_create,perm_unlink +access_vault,access_vault,model_vault,base.group_user,1,1,1,1 +access_vault_entry,access_vault_entry,model_vault_entry,base.group_user,1,1,1,1 +access_vault_export_wizard,access_vault_export_wizard,model_vault_export_wizard,base.group_user,1,1,1,1 +access_vault_field,access_vault_field,model_vault_field,base.group_user,1,1,1,1 +access_vault_file,access_vault_file,model_vault_file,base.group_user,1,1,1,1 +access_vault_import_wizard,access_vault_import_wizard,model_vault_import_wizard,base.group_user,1,1,1,1 +access_vault_import_wizard_path,access_vault_import_wizard_path,model_vault_import_wizard_path,base.group_user,1,1,1,1 +access_vault_inbox,access_vault_inbox,model_vault_inbox,base.group_user,1,1,1,1 +access_vault_inbox_log,access_vault_inbox_log,model_vault_inbox_log,base.group_user,1,1,1,1 +access_vault_log,access_vault_log,model_vault_log,base.group_user,1,0,0,0 +access_vault_right,access_vault_right,model_vault_right,base.group_user,1,1,1,1 +access_vault_send_wizard,access_vault_send_wizard,model_vault_send_wizard,base.group_user,1,1,1,1 +access_vault_store_wizard,access_vault_store_wizard,model_vault_store_wizard,base.group_user,1,1,1,1 +access_vault_tag,access_vault_tag,model_vault_tag,base.group_user,1,1,1,1 +access_vault_users_key,access_res_users_key,model_res_users_key,base.group_user,1,1,1,1 diff --git a/vault/security/ir_rule.xml b/vault/security/ir_rule.xml new file mode 100644 index 0000000000..13f7cdb45f --- /dev/null +++ b/vault/security/ir_rule.xml @@ -0,0 +1,111 @@ + + + + vault.access.default + + ['|', ('user_id', '=', user.id), ('right_ids.user_id', '=', user.id)] + + + + + + + + + vault.log.access.read + + ['|', ('vault_id.user_id', '=', user.id), ('vault_id.right_ids.user_id', '=', user.id)] + + + + + + + + + vault.entry.access.default + + ['|', ('vault_id.user_id', '=', user.id), ('vault_id.right_ids.user_id', '=', user.id)] + + + + + + + + + vault.field.access.default + + ['|', ('vault_id.user_id', '=', user.id), ('vault_id.right_ids.user_id', '=', user.id)] + + + + + + + + + vault.file.access.default + + ['|', ('vault_id.user_id', '=', user.id), ('vault_id.right_ids.user_id', '=', user.id)] + + + + + + + + + res.users.key.access.default + + [('user_id', '=', user.id)] + + + + + + + + + vault.inbox.access.owner + + [('user_id', '=', user.id)] + + + + + + + + vault.right.access.default + + [('vault_id.right_ids.user_id', '=', user.id)] + + + + + + + + + vault.inbox.log.access.owner + + [('inbox_id.user_id', '=', user.id)] + + + + + + diff --git a/vault/security/vault_security.xml b/vault/security/vault_security.xml new file mode 100644 index 0000000000..a810f29538 --- /dev/null +++ b/vault/security/vault_security.xml @@ -0,0 +1,13 @@ + + + + Allow to export vaults + + + + + Allow to import vaults + + + + diff --git a/vault/static/description/icon.png b/vault/static/description/icon.png new file mode 100644 index 0000000000..a0c9035d9b Binary files /dev/null and b/vault/static/description/icon.png differ diff --git a/vault/static/description/index.html b/vault/static/description/index.html new file mode 100644 index 0000000000..99cd2f80d1 --- /dev/null +++ b/vault/static/description/index.html @@ -0,0 +1,447 @@ + + + + + + +Vault + + + +
+

Vault

+ + +

Beta License: AGPL-3 OCA/server-auth Translate me on Weblate Try me on Runboat

+

This module implements a vault for secrets and files using end-to-end-encryption. The encryption and decryption happens in the browser using a vault specific shared master key. The master keys are encrypted using asymmetrically. For this the user has to enter a second password on the first login or if he needs to access data in a vault. The asymmetric keys are stored for a certain time in the browser storage.

+

The server can never access the secrets with the information available. Only people registered in the vault can decrypt or encrypt values in a vault. The meta data isn’t encrypted to be able to search/filter for entries more easily.

+

This modules requires a secure context for the browser to work properly and therefore HTTPS support is required.

+

The vault-recovery project focuses on disaster recovery in case of an incident to recover secrets from old database backups or old exports.

+

Table of contents

+ +
+

Known issues / Roadmap

+
    +
  • Field and file history for restoration
  • +
  • Import improvement
  • +
+
+
    +
  • Support challenge-response/FIDO2
  • +
  • Support for argon2 and kdbx v4
  • +
+
+
    +
  • When changing an entry from one vault to another existing vault, the values added on +this entry cannot be accessed, so the field vault is going to be readonly when it +is defined.

    +

    If you want to move entries between vaults you can use the export -> import option.

    +
  • +
  • HTTPS or localhost (secure browser context) is required for the client side encryption

    +
  • +
+
+
+

Bug Tracker

+

Bugs are tracked on GitHub Issues. +In case of trouble, please check there if your issue has already been reported. +If you spotted it first, help us to smash it by providing a detailed and welcomed +feedback.

+

Do not contact contributors directly about support or help with technical issues.

+
+
+

Credits

+
+

Authors

+
    +
  • initOS GmbH
  • +
+
+
+

Contributors

+ +
+
+

Maintainers

+

This module is maintained by the OCA.

+Odoo Community Association +

OCA, or the Odoo Community Association, is a nonprofit organization whose +mission is to support the collaborative development of Odoo features and +promote its widespread use.

+

This module is part of the OCA/server-auth project on GitHub.

+

You are welcome to contribute. To learn how please visit https://odoo-community.org/page/Contribute.

+
+
+
+ + diff --git a/vault/static/lib/kdbxweb/kdbxweb.min.js b/vault/static/lib/kdbxweb/kdbxweb.min.js new file mode 100644 index 0000000000..eee616aa20 --- /dev/null +++ b/vault/static/lib/kdbxweb/kdbxweb.min.js @@ -0,0 +1,2 @@ +/*! kdbxweb v1.10.0, (c) 2020 Antelle, opensource.org/licenses/MIT */ +!function(e,t){"object"==typeof exports&&"object"==typeof module?module.exports=t(require("crypto"),require("xmldom")):"function"==typeof define&&define.amd?define(["crypto","xmldom"],t):"object"==typeof exports?exports.kdbxweb=t(require("crypto"),require("xmldom")):e.kdbxweb=t(e.crypto,e.xmldom)}(this,(function(e,t){return function(e){var t={};function r(i){if(t[i])return t[i].exports;var n=t[i]={i:i,l:!1,exports:{}};return e[i].call(n.exports,n,n.exports,r),n.l=!0,n.exports}return r.m=e,r.c=t,r.d=function(e,t,i){r.o(e,t)||Object.defineProperty(e,t,{enumerable:!0,get:i})},r.r=function(e){"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})},r.t=function(e,t){if(1&t&&(e=r(e)),8&t)return e;if(4&t&&"object"==typeof e&&e&&e.__esModule)return e;var i=Object.create(null);if(r.r(i),Object.defineProperty(i,"default",{enumerable:!0,value:e}),2&t&&"string"!=typeof e)for(var n in e)r.d(i,n,function(t){return e[t]}.bind(null,n));return i},r.n=function(e){var t=e&&e.__esModule?function(){return e.default}:function(){return e};return r.d(t,"a",t),t},r.o=function(e,t){return Object.prototype.hasOwnProperty.call(e,t)},r.p="",r(r.s=29)}([function(e,t,r){"use strict";(function(t){var i=t.TextEncoder,n=t.TextDecoder;if(!i||!n){var o=r(40);i=o.TextEncoder,n=o.TextDecoder}var a=new i,s=new n;e.exports.arrayBufferEquals=function(e,t){if(e.byteLength!==t.byteLength)return!1;for(var r=new Uint8Array(e),i=new Uint8Array(t),n=0,o=r.length;n0;){var r=e%65536;r=r>0?r:65536;var i=new Uint8Array(r);s.getRandomValues(i),e-=r,t.set(i,e)}return t}(e);if(h)return new Uint8Array(h.randomBytes(e));throw new n(o.ErrorCodes.NotImplemented,"Random not implemented")},e.exports.createAesCbc=function(){if(d)return new u;if(h)return new l;throw new n(o.ErrorCodes.NotImplemented,"AES-CBC not implemented")},e.exports.chacha20=function(e,t,r){return Promise.resolve().then((function(){var n=new a(new Uint8Array(t),new Uint8Array(r));return i.arrayToBuffer(n.encrypt(new Uint8Array(e)))}))},e.exports.argon2=function(e,t,r,i,a,s,d,h){return Promise.reject(new n(o.ErrorCodes.NotImplemented,"Argon2 not implemented"))},e.exports.configure=function(e,t,r){d=e,s=t,h=r}}).call(this,r(13))},function(e,t,r){"use strict";(function(t){var i=r(2),n=r(1),o=r(6),a=r(7),s=r(9),d=r(0),h=r(8),u=r(16),l=/\.\d\d\d/,c=t.DOMParser?t:r(44),f=t.DOMParser?void 0:{errorHandler:{error:function(e){throw e},fatalError:function(e){throw e}}},p=62135596800;function m(e){var t,r=f?new c.DOMParser(f):new c.DOMParser;try{t=r.parseFromString(e,"application/xml")}catch(e){throw new i(n.ErrorCodes.FileCorrupt,"bad xml: "+e.message)}if(!t.documentElement)throw new i(n.ErrorCodes.FileCorrupt,"bad xml");var o=t.getElementsByTagName("parsererror")[0];if(o)throw new i(n.ErrorCodes.FileCorrupt,"bad xml: "+o.textContent);return t}function y(e,t){var r=e.childNodes.length;if(0!==r){for(var i,n="\n"+" ".repeat(t),o=t>0?"\n"+" ".repeat(t-1):"",a=e.ownerDocument||e,s=[],d=0;d0){var l=a.createTextNode(o);e.appendChild(l)}y(i,t+1)}}}function g(e){if(e&&e.childNodes)return e.protectedValue?e.protectedValue.text:e.textContent}function _(e,t){e.textContent=t||""}function b(e){var t=g(e);return t?d.arrayToBuffer(d.base64ToBytes(t)):void 0}function v(e,t){"string"==typeof t&&(t=d.base64ToBytes(t)),_(e,t?d.bytesToBase64(d.arrayToBuffer(t)):void 0)}function w(e){switch(e&&e.toLowerCase&&e.toLowerCase()){case"true":return!0;case"false":return!1;case"null":return null}}function k(e,t){t(e);for(var r=0,i=e.childNodes,n=i.length;r)<'+e+"/>")},e.exports.getChildNode=function(e,t,r){if(e&&e.childNodes)for(var o=0,a=e.childNodes,s=a.length;o0)return new Date(t);var r=new DataView(d.arrayToBuffer(d.base64ToBytes(t))),i=new h(r.getUint32(0,!0),r.getUint32(4,!0)).value;return new Date(1e3*(i-p))}},e.exports.setDate=function(e,t,r){if(t)if(r){var i=Math.floor(t.getTime()/1e3)+p,n=new DataView(new ArrayBuffer(8)),o=h.from(i);n.setUint32(0,o.lo,!0),n.setUint32(4,o.hi,!0),_(e,d.bytesToBase64(n.buffer))}else _(e,t.toISOString().replace(l,""));else _(e,"")},e.exports.getNumber=function(e){var t=g(e);return t?+t:void 0},e.exports.setNumber=function(e,t){_(e,"number"!=typeof t||isNaN(t)?void 0:t.toString())},e.exports.getBoolean=function(e){var t=g(e);return t?w(t):void 0},e.exports.setBoolean=function(e,t){_(e,void 0===t?"":null===t?"null":t?"True":"False")},e.exports.strToBoolean=w,e.exports.getUuid=function(e){var t=b(e);return t?new a(t):void 0},e.exports.setUuid=function(e,t){v(e,t instanceof a?t.toBytes():t)},e.exports.getProtectedText=function(e){return e.protectedValue||e.textContent},e.exports.setProtectedText=function(e,t){t instanceof s?(e.protectedValue=t,e.setAttribute(o.Attr.Protected,"True")):_(e,t)},e.exports.getProtectedBinary=function(e){if(e.protectedValue)return e.protectedValue;var t=e.textContent,r=e.getAttribute(o.Attr.Ref);if(r)return{ref:r};if(t){var i=w(e.getAttribute(o.Attr.Compressed)),n=d.base64ToBytes(t);return i&&(n=u.ungzip(n)),d.arrayToBuffer(n)}},e.exports.setProtectedBinary=function(e,t){t instanceof s?(e.protectedValue=t,e.setAttribute(o.Attr.Protected,"True")):t&&t.ref?e.setAttribute(o.Attr.Ref,t.ref):v(e,t)},e.exports.setProtectedValues=function(e,t){k(e,(function(e){if(w(e.getAttribute(o.Attr.Protected)))try{var r=d.arrayToBuffer(d.base64ToBytes(e.textContent));if(r.byteLength){var a=t.getSalt(r.byteLength);e.protectedValue=new s(r,a)}}catch(t){throw new i(n.ErrorCodes.FileCorrupt,"bad protected value at line "+e.lineNumber+": "+t)}}))},e.exports.updateProtectedValuesSalt=function(e,t){k(e,(function(e){if(w(e.getAttribute(o.Attr.Protected))&&e.protectedValue){var r=t.getSalt(e.protectedValue.byteLength);e.protectedValue.setSalt(r),e.textContent=e.protectedValue.toString()}}))},e.exports.unprotectValues=function(e){k(e,(function(e){w(e.getAttribute(o.Attr.Protected))&&e.protectedValue&&(e.removeAttribute(o.Attr.Protected),e.setAttribute(o.Attr.ProtectedInMemPlainXml,"True"),e.textContent=e.protectedValue.getText())}))},e.exports.protectUnprotectedValues=function(e){k(e,(function(e){w(e.getAttribute(o.Attr.ProtectedInMemPlainXml))&&e.protectedValue&&(e.removeAttribute(o.Attr.ProtectedInMemPlainXml),e.setAttribute(o.Attr.Protected,"True"),e.textContent=e.protectedValue.toString())}))},e.exports.protectPlainValues=function(e){k(e,(function(e){w(e.getAttribute(o.Attr.ProtectedInMemPlainXml))&&(e.protectedValue=s.fromString(e.textContent),e.textContent=e.protectedValue.toString(),e.removeAttribute(o.Attr.ProtectedInMemPlainXml),e.setAttribute(o.Attr.Protected,"True"))}))}}).call(this,r(13))},function(e,t,r){"use strict";var i="undefined"!=typeof Uint8Array&&"undefined"!=typeof Uint16Array&&"undefined"!=typeof Int32Array;t.assign=function(e){for(var t=Array.prototype.slice.call(arguments,1);t.length;){var r=t.shift();if(r){if("object"!=typeof r)throw new TypeError(r+"must be non-object");for(var i in r)r.hasOwnProperty(i)&&(e[i]=r[i])}}return e},t.shrinkBuf=function(e,t){return e.length===t?e:e.subarray?e.subarray(0,t):(e.length=t,e)};var n={arraySet:function(e,t,r,i,n){if(t.subarray&&e.subarray)e.set(t.subarray(r,r+i),n);else for(var o=0;o=2097152)throw new Error("too large number");return 4294967296*this.hi+this.lo}return this.lo}}),i.prototype.valueOf=function(){return this.value},i.from=function(e){if(e>9007199254740991)throw new Error("too large number");var t=e>>>0;return new i(t,(e-t)/4294967296>>>0)},e.exports=i},function(e,t,r){"use strict";var i=r(0),n=r(3),o=r(10),a=function(e,t){Object.defineProperty(this,"_value",{value:new Uint8Array(e)}),Object.defineProperty(this,"_salt",{value:new Uint8Array(t)})};a.prototype.toString=function(){return i.bytesToBase64(this._value)},a.fromString=function(e){for(var t=i.stringToBytes(e),r=o.getBytes(t.length),n=0,s=t.length;n=0;i--)r[i]=e[i]^t[i];return r},a.prototype.setSalt=function(e){for(var t=new Uint8Array(e),r=this._value,i=this._salt,n=0,o=r.length;n=0;--i)t[i]^=r[i];return t}},function(e,t,r){"use strict";function i(e){this._arrayBuffer=e||new ArrayBuffer(1024),this._dataView=new DataView(this._arrayBuffer),this._pos=0,this._canExpand=!e}["Int","Uint","Float"].forEach((function(e){("Float"===e?[4,8]:[1,2,4]).forEach((function(t){var r="get"+e+8*t;i.prototype[r]=function(e){var i=this._dataView[r].call(this._dataView,this._pos,e);return this._pos+=t,i};var n="set"+e+8*t;i.prototype[n]=function(e,r){this._checkCapacity(t),this._dataView[n].call(this._dataView,this._pos,e,r),this._pos+=t}}))})),i.prototype.getUint64=function(e){var t=this.getUint32(e),r=this.getUint32(e);return e?r*=4294967296:t*=4294967296,t+r},i.prototype.setUint64=function(e,t){t?(this.setUint32(4294967295&e,!0),this.setUint32(Math.floor(e/4294967296),!0)):(this._checkCapacity(8),this.setUint32(Math.floor(e/4294967296),!1),this.setUint32(4294967295&e,!1))},i.prototype.readBytes=function(e){var t=this._arrayBuffer.slice(this._pos,this._pos+e);return this._pos+=e,t},i.prototype.readBytesToEnd=function(){var e=this._arrayBuffer.byteLength-this._pos;return this.readBytes(e)},i.prototype.readBytesNoAdvance=function(e,t){return this._arrayBuffer.slice(e,t)},i.prototype.writeBytes=function(e){e instanceof ArrayBuffer&&(e=new Uint8Array(e)),this._checkCapacity(e.length),new Uint8Array(this._arrayBuffer).set(e,this._pos),this._pos+=e.length},i.prototype.getWrittenBytes=function(){return this._arrayBuffer.slice(0,this._pos)},i.prototype._checkCapacity=function(e){var t=this._arrayBuffer.byteLength-this._pos;if(this._canExpand&&t1)throw new i(n.ErrorCodes.InvalidVersion)},d.prototype._readItem=function(e){var t=e.getUint8();if(!t)return!1;var r=e.getInt32(!0);if(r<=0)throw new i(n.ErrorCodes.FileCorrupt,"bad key length");var d,h=o.bytesToString(e.readBytes(r)),u=e.getInt32(!0);if(u<0)throw new i(n.ErrorCodes.FileCorrupt,"bad value length");switch(t){case s.UInt32:if(4!==u)throw new i(n.ErrorCodes.FileCorrupt,"bad uint32");d=e.getUint32(!0);break;case s.UInt64:if(8!==u)throw new i(n.ErrorCodes.FileCorrupt,"bad uint64");var l=e.getUint32(!0),c=e.getUint32(!0);d=new a(l,c);break;case s.Bool:if(1!==u)throw new i(n.ErrorCodes.FileCorrupt,"bad bool");d=0!==e.getUint8();break;case s.Int32:if(4!==u)throw new i(n.ErrorCodes.FileCorrupt,"bad int32");d=e.getInt32(!0);break;case s.Int64:if(8!==u)throw new i(n.ErrorCodes.FileCorrupt,"bad int64");var f=e.getUint32(!0),p=e.getUint32(!0);d=new a(f,p);break;case s.String:d=o.bytesToString(e.readBytes(u));break;case s.Bytes:d=e.readBytes(u);break;default:throw new i(n.ErrorCodes.FileCorrupt,"bad value type: "+t)}return{key:h,type:t,value:d}},d.prototype.write=function(e){this._writeVersion(e),Object.keys(this._items).forEach((function(t){this._writeItem(e,this._items[t])}),this),e.setUint8(0)},d.prototype._writeVersion=function(e){e.setUint16(256,!0)},d.prototype._writeItem=function(e,t){e.setUint8(t.type);var r=o.stringToBytes(t.key);switch(e.setInt32(r.length,!0),e.writeBytes(r),t.type){case s.UInt32:e.setInt32(4,!0),e.setUint32(t.value,!0);break;case s.UInt64:e.setInt32(8,!0),e.setUint32(t.value.lo,!0),e.setUint32(t.value.hi,!0);break;case s.Bool:e.setInt32(1,!0),e.setUint8(t.value?1:0);break;case s.Int32:e.setInt32(4,!0),e.setInt32(t.value,!0);break;case s.Int64:e.setInt32(8,!0),e.setUint32(t.value.lo,!0),e.setUint32(t.value.hi,!0);break;case s.String:var a=o.stringToBytes(t.value);e.setInt32(a.length,!0),e.writeBytes(a);break;case s.Bytes:var d=o.arrayToBuffer(t.value);e.setInt32(d.byteLength,!0),e.writeBytes(d);break;default:throw new i(n.ErrorCodes.Unsupported)}},e.exports=d},function(e,t,r){"use strict";var i=r(6),n=r(4),o={read:function(e){for(var t={},r=0,n=e.childNodes,a=n.length;r>>16&65535|0,a=0;0!==r;){r-=a=r>2e3?2e3:r;do{o=o+(n=n+t[i++]|0)|0}while(--a);n%=65521,o%=65521}return n|o<<16|0}},function(e,t,r){"use strict";var i=function(){for(var e,t=[],r=0;r<256;r++){e=r;for(var i=0;i<8;i++)e=1&e?3988292384^e>>>1:e>>>1;t[r]=e}return t}();e.exports=function(e,t,r,n){var o=i,a=n+r;e^=-1;for(var s=n;s>>8^o[255&(e^t[s])];return-1^e}},function(e,t,r){"use strict";var i=r(5),n=!0,o=!0;try{String.fromCharCode.apply(null,[0])}catch(e){n=!1}try{String.fromCharCode.apply(null,new Uint8Array(1))}catch(e){o=!1}for(var a=new i.Buf8(256),s=0;s<256;s++)a[s]=s>=252?6:s>=248?5:s>=240?4:s>=224?3:s>=192?2:1;function d(e,t){if(t<65537&&(e.subarray&&o||!e.subarray&&n))return String.fromCharCode.apply(null,i.shrinkBuf(e,t));for(var r="",a=0;a>>6,t[a++]=128|63&r):r<65536?(t[a++]=224|r>>>12,t[a++]=128|r>>>6&63,t[a++]=128|63&r):(t[a++]=240|r>>>18,t[a++]=128|r>>>12&63,t[a++]=128|r>>>6&63,t[a++]=128|63&r);return t},t.buf2binstring=function(e){return d(e,e.length)},t.binstring2buf=function(e){for(var t=new i.Buf8(e.length),r=0,n=t.length;r4)h[i++]=65533,r+=o-1;else{for(n&=2===o?31:3===o?15:7;o>1&&r1?h[i++]=65533:n<65536?h[i++]=n:(n-=65536,h[i++]=55296|n>>10&1023,h[i++]=56320|1023&n)}return d(h,i)},t.utf8border=function(e,t){var r;for((t=t||e.length)>e.length&&(t=e.length),r=t-1;r>=0&&128==(192&e[r]);)r--;return r<0||0===r?t:r+a[e[r]]>t?r:t}},function(e,t,r){"use strict";e.exports=function(){this.input=null,this.next_in=0,this.avail_in=0,this.total_in=0,this.output=null,this.next_out=0,this.avail_out=0,this.total_out=0,this.msg="",this.state=null,this.data_type=2,this.adler=0}},function(e,t,r){"use strict";e.exports={Z_NO_FLUSH:0,Z_PARTIAL_FLUSH:1,Z_SYNC_FLUSH:2,Z_FULL_FLUSH:3,Z_FINISH:4,Z_BLOCK:5,Z_TREES:6,Z_OK:0,Z_STREAM_END:1,Z_NEED_DICT:2,Z_ERRNO:-1,Z_STREAM_ERROR:-2,Z_DATA_ERROR:-3,Z_BUF_ERROR:-5,Z_NO_COMPRESSION:0,Z_BEST_SPEED:1,Z_BEST_COMPRESSION:9,Z_DEFAULT_COMPRESSION:-1,Z_FILTERED:1,Z_HUFFMAN_ONLY:2,Z_RLE:3,Z_FIXED:4,Z_DEFAULT_STRATEGY:0,Z_BINARY:0,Z_TEXT:1,Z_UNKNOWN:2,Z_DEFLATED:8}},function(e,t,r){"use strict";var i=r(7),n=r(1),o=r(9),a=r(2),s=r(11),d=r(0),h=r(14),u=r(8),l=r(10),c=[{name:"EndOfHeader"},{name:"Comment"},{name:"CipherID"},{name:"CompressionFlags"},{name:"MasterSeed"},{name:"TransformSeed",ver:[3]},{name:"TransformRounds",ver:[3]},{name:"EncryptionIV"},{name:"ProtectedStreamKey",ver:[3]},{name:"StreamStartBytes",ver:[3]},{name:"InnerRandomStreamID",ver:[3]},{name:"KdfParameters",ver:[4]},{name:"PublicCustomData",ver:[4]}],f=[{name:"EndOfHeader"},{name:"InnerRandomStreamID"},{name:"InnerRandomStreamKey"},{name:"Binary",skipHeader:!0}],p={DefaultFileVersionMajor:4,DefaultFileVersionMinor:0,MaxFileVersionMajor:4,MaxFileVersionMinor:1,MaxSupportedVersion:4,FlagBinaryProtected:1,InnerHeaderBinaryFieldId:3,DefaultKdfAlgo:n.KdfId.Argon2,DefaultKdfSaltLength:32,DefaultKdfParallelism:1,DefaultKdfIterations:2,DefaultKdfMemory:1048576,DefaultKdfVersion:19},m={3:1,4:0},y=function(){this.versionMajor=void 0,this.versionMinor=void 0,this.dataCipherUuid=void 0,this.compression=void 0,this.masterSeed=void 0,this.transformSeed=void 0,this.keyEncryptionRounds=void 0,this.encryptionIV=void 0,this.protectedStreamKey=void 0,this.streamStartBytes=void 0,this.crsAlgorithm=void 0,this.endPos=void 0,this.kdfParameters=void 0,this.publicCustomData=void 0,Object.preventExtensions(this)};y.prototype._readSignature=function(e){if(e.byteLength<8)throw new a(n.ErrorCodes.FileCorrupt,"not enough data");var t=e.getUint32(!0),r=e.getUint32(!0);if(t!==n.Signatures.FileMagic||r!==n.Signatures.Sig2Kdbx)throw new a(n.ErrorCodes.BadSignature)},y.prototype._writeSignature=function(e){e.setUint32(n.Signatures.FileMagic,!0),e.setUint32(n.Signatures.Sig2Kdbx,!0)},y.prototype._readVersion=function(e){var t=e.getUint16(!0),r=e.getUint16(!0);if(r>p.MaxSupportedVersion)throw new a(n.ErrorCodes.InvalidVersion);this.versionMinor=t,this.versionMajor=r},y.prototype._writeVersion=function(e){e.setUint16(this.versionMinor,!0),e.setUint16(this.versionMajor,!0)},y.prototype._readCipherID=function(e){if(16!==e.byteLength)throw new a(n.ErrorCodes.Unsupported,"cipher");this.dataCipherUuid=new i(e)},y.prototype._writeCipherID=function(e){this._writeFieldSize(e,16),e.writeBytes(this.dataCipherUuid.bytes)},y.prototype._readCompressionFlags=function(e){var t=new DataView(e).getUint32(e,!0);if(t<0||t>=Object.keys(n.CompressionAlgorithm).length)throw new a(n.ErrorCodes.Unsupported,"compression");this.compression=t},y.prototype._writeCompressionFlags=function(e){this._writeFieldSize(e,4),e.setUint32(this.compression,!0)},y.prototype._readMasterSeed=function(e){this.masterSeed=e},y.prototype._writeMasterSeed=function(e){this._writeFieldBytes(e,this.masterSeed)},y.prototype._readTransformSeed=function(e){this.transformSeed=e},y.prototype._writeTransformSeed=function(e){this._writeFieldBytes(e,this.transformSeed)},y.prototype._readTransformRounds=function(e){this.keyEncryptionRounds=new s(e).getUint64(!0)},y.prototype._writeTransformRounds=function(e){this._writeFieldSize(e,8),e.setUint64(this.keyEncryptionRounds,!0)},y.prototype._readEncryptionIV=function(e){this.encryptionIV=e},y.prototype._writeEncryptionIV=function(e){this._writeFieldBytes(e,this.encryptionIV)},y.prototype._readProtectedStreamKey=function(e){this.protectedStreamKey=e},y.prototype._writeProtectedStreamKey=function(e){this._writeFieldBytes(e,this.protectedStreamKey)},y.prototype._readStreamStartBytes=function(e){this.streamStartBytes=e},y.prototype._writeStreamStartBytes=function(e){this._writeFieldBytes(e,this.streamStartBytes)},y.prototype._readInnerRandomStreamID=function(e){this.crsAlgorithm=new DataView(e).getUint32(e,!0)},y.prototype._writeInnerRandomStreamID=function(e){this._writeFieldSize(e,4),e.setUint32(this.crsAlgorithm,!0)},y.prototype._readInnerRandomStreamKey=function(e){this.protectedStreamKey=e},y.prototype._writeInnerRandomStreamKey=function(e){this._writeFieldBytes(e,this.protectedStreamKey)},y.prototype._readKdfParameters=function(e){this.kdfParameters=h.read(new s(e))},y.prototype._writeKdfParameters=function(e){var t=new s;this.kdfParameters.write(t),this._writeFieldBytes(e,t.getWrittenBytes())},y.prototype._readPublicCustomData=function(e){this.publicCustomData=h.read(new s(e))},y.prototype._hasPublicCustomData=function(){return this.publicCustomData},y.prototype._writePublicCustomData=function(e){if(this.publicCustomData){var t=new s;this.publicCustomData.write(t),this._writeFieldBytes(e,t.getWrittenBytes())}},y.prototype._readBinary=function(e,t){var r=new DataView(e).getUint8(0)&p.FlagBinaryProtected,i=e.slice(1),n=r?o.fromBinary(i):i,a=Object.keys(t.kdbx.binaries).length;t.kdbx.binaries[a]=n},y.prototype._writeBinary=function(e,t){if(!(this.versionMajor<4))for(var r=t.kdbx.binaries.hashOrder,i=0;i0&&(i=e.readBytes(o));var a=t[n];if(a){var s=this["_read"+a.name];s&&s.call(this,i,r)}return 0!==n},y.prototype._writeField=function(e,t,r,i){var n=r[t];if(n){if(n.ver&&n.ver.indexOf(this.versionMajor)<0)return;var o=this["_write"+n.name];if(o){var a=this["_has"+n.name];if(a&&!a.call(this))return;n.skipHeader||e.setUint8(t),o.call(this,e,i)}}},y.prototype._readFieldSize=function(e){return this.versionMajor>=4?e.getUint32(!0):e.getUint16(!0)},y.prototype._writeFieldSize=function(e,t){this.versionMajor>=4?e.setUint32(t,!0):e.setUint16(t,!0)},y.prototype._writeFieldBytes=function(e,t){this._writeFieldSize(e,t.byteLength),e.writeBytes(t)},y.prototype._validate=function(){if(void 0===this.dataCipherUuid)throw new a(n.ErrorCodes.FileCorrupt,"no cipher in header");if(void 0===this.compression)throw new a(n.ErrorCodes.FileCorrupt,"no compression in header");if(!this.masterSeed)throw new a(n.ErrorCodes.FileCorrupt,"no master seed in header");if(this.versionMajor<4&&!this.transformSeed)throw new a(n.ErrorCodes.FileCorrupt,"no transform seed in header");if(this.versionMajor<4&&!this.keyEncryptionRounds)throw new a(n.ErrorCodes.FileCorrupt,"no key encryption rounds in header");if(!this.encryptionIV)throw new a(n.ErrorCodes.FileCorrupt,"no encryption iv in header");if(this.versionMajor<4&&!this.protectedStreamKey)throw new a(n.ErrorCodes.FileCorrupt,"no protected stream key in header");if(this.versionMajor<4&&!this.streamStartBytes)throw new a(n.ErrorCodes.FileCorrupt,"no stream start bytes in header");if(this.versionMajor<4&&!this.crsAlgorithm)throw new a(n.ErrorCodes.FileCorrupt,"no crs algorithm in header");if(this.versionMajor>=4&&!this.kdfParameters)throw new a(n.ErrorCodes.FileCorrupt,"no kdf parameters in header")},y.prototype._validateInner=function(){if(!this.protectedStreamKey)throw new a(n.ErrorCodes.FileCorrupt,"no protected stream key in header");if(!this.crsAlgorithm)throw new a(n.ErrorCodes.FileCorrupt,"no crs algorithm in header")},y.prototype._createKdfParameters=function(e){switch(e||(e=p.DefaultKdfAlgo),e){case n.KdfId.Argon2:this.kdfParameters=new h,this.kdfParameters.set("$UUID",h.ValueType.Bytes,d.base64ToBytes(n.KdfId.Argon2)),this.kdfParameters.set("S",h.ValueType.Bytes,l.getBytes(p.DefaultKdfSaltLength)),this.kdfParameters.set("P",h.ValueType.UInt32,p.DefaultKdfParallelism),this.kdfParameters.set("I",h.ValueType.UInt64,new u(p.DefaultKdfIterations)),this.kdfParameters.set("M",h.ValueType.UInt64,new u(p.DefaultKdfMemory)),this.kdfParameters.set("V",h.ValueType.UInt32,p.DefaultKdfVersion);break;case n.KdfId.Aes:this.kdfParameters=new h,this.kdfParameters.set("$UUID",h.ValueType.Bytes,d.base64ToBytes(n.KdfId.Aes)),this.kdfParameters.set("S",h.ValueType.Bytes,l.getBytes(p.DefaultKdfSaltLength)),this.kdfParameters.set("R",h.ValueType.UInt64,new u(n.Defaults.KeyEncryptionRounds));break;default:throw new a(n.ErrorCodes.InvalidArg,"bad KDF algo")}},y.prototype.write=function(e){this._validate(),this._writeSignature(e),this._writeVersion(e);for(var t=1;t>4&15]),r.push(t[15&i[n]]);return r.join("")},i.prototype._reset=function(){this.counterWords[0]=0,this.counterWords[1]=0,this.blockUsed=64},i.prototype._incrementCounter=function(){this.counterWords[0]=this.counterWords[0]+1&4294967295,0===this.counterWords[0]&&(this.counterWords[1]=this.counterWords[1]+1&4294967295)},i.prototype._generateBlock=function(){for(var e,t=this.sigmaWords[0],r=this.keyWords[0],i=this.keyWords[1],n=this.keyWords[2],o=this.keyWords[3],a=this.sigmaWords[1],s=this.nonceWords[0],d=this.nonceWords[1],h=this.counterWords[0],u=this.counterWords[1],l=this.sigmaWords[2],c=this.keyWords[4],f=this.keyWords[5],p=this.keyWords[6],m=this.keyWords[7],y=this.sigmaWords[3],g=t,_=r,b=i,v=n,w=o,k=a,C=s,x=d,E=h,B=u,T=l,A=c,S=f,U=p,D=m,I=y,N=0;N>>25)+g)<<9|e>>>23)+w)<<13|e>>>19)+E)<<18|e>>>14,k^=(e=(_^=(e=(U^=(e=(B^=(e=k+_)<<7|e>>>25)+k)<<9|e>>>23)+B)<<13|e>>>19)+U)<<18|e>>>14,T^=(e=(C^=(e=(b^=(e=(D^=(e=T+C)<<7|e>>>25)+T)<<9|e>>>23)+D)<<13|e>>>19)+b)<<18|e>>>14,I^=(e=(A^=(e=(x^=(e=(v^=(e=I+A)<<7|e>>>25)+I)<<9|e>>>23)+v)<<13|e>>>19)+x)<<18|e>>>14,g^=(e=(v^=(e=(b^=(e=(_^=(e=g+v)<<7|e>>>25)+g)<<9|e>>>23)+_)<<13|e>>>19)+b)<<18|e>>>14,k^=(e=(w^=(e=(x^=(e=(C^=(e=k+w)<<7|e>>>25)+k)<<9|e>>>23)+C)<<13|e>>>19)+x)<<18|e>>>14,T^=(e=(B^=(e=(E^=(e=(A^=(e=T+B)<<7|e>>>25)+T)<<9|e>>>23)+A)<<13|e>>>19)+E)<<18|e>>>14,I^=(e=(D^=(e=(U^=(e=(S^=(e=I+D)<<7|e>>>25)+I)<<9|e>>>23)+S)<<13|e>>>19)+U)<<18|e>>>14;g+=t,_+=r,b+=i,v+=n,w+=o,k+=a,C+=s,x+=d,E+=h,B+=u,T+=l,A+=c,S+=f,U+=p,D+=m,I+=y,this.block[0]=g>>>0&255,this.block[1]=g>>>8&255,this.block[2]=g>>>16&255,this.block[3]=g>>>24&255,this.block[4]=_>>>0&255,this.block[5]=_>>>8&255,this.block[6]=_>>>16&255,this.block[7]=_>>>24&255,this.block[8]=b>>>0&255,this.block[9]=b>>>8&255,this.block[10]=b>>>16&255,this.block[11]=b>>>24&255,this.block[12]=v>>>0&255,this.block[13]=v>>>8&255,this.block[14]=v>>>16&255,this.block[15]=v>>>24&255,this.block[16]=w>>>0&255,this.block[17]=w>>>8&255,this.block[18]=w>>>16&255,this.block[19]=w>>>24&255,this.block[20]=k>>>0&255,this.block[21]=k>>>8&255,this.block[22]=k>>>16&255,this.block[23]=k>>>24&255,this.block[24]=C>>>0&255,this.block[25]=C>>>8&255,this.block[26]=C>>>16&255,this.block[27]=C>>>24&255,this.block[28]=x>>>0&255,this.block[29]=x>>>8&255,this.block[30]=x>>>16&255,this.block[31]=x>>>24&255,this.block[32]=E>>>0&255,this.block[33]=E>>>8&255,this.block[34]=E>>>16&255,this.block[35]=E>>>24&255,this.block[36]=B>>>0&255,this.block[37]=B>>>8&255,this.block[38]=B>>>16&255,this.block[39]=B>>>24&255,this.block[40]=T>>>0&255,this.block[41]=T>>>8&255,this.block[42]=T>>>16&255,this.block[43]=T>>>24&255,this.block[44]=A>>>0&255,this.block[45]=A>>>8&255,this.block[46]=A>>>16&255,this.block[47]=A>>>24&255,this.block[48]=S>>>0&255,this.block[49]=S>>>8&255,this.block[50]=S>>>16&255,this.block[51]=S>>>24&255,this.block[52]=U>>>0&255,this.block[53]=U>>>8&255,this.block[54]=U>>>16&255,this.block[55]=U>>>24&255,this.block[56]=D>>>0&255,this.block[57]=D>>>8&255,this.block[58]=D>>>16&255,this.block[59]=D>>>24&255,this.block[60]=I>>>0&255,this.block[61]=I>>>8&255,this.block[62]=I>>>16&255,this.block[63]=I>>>24&255},e.exports=i},function(e,t,r){"use strict";function i(e,t){this.sigmaWords=[1634760805,857760878,2036477234,1797285236],this.block=new Uint8Array(64),this.blockUsed=64,this.x=new Uint32Array(16);var r=new Uint32Array(16);r[0]=this.sigmaWords[0],r[1]=this.sigmaWords[1],r[2]=this.sigmaWords[2],r[3]=this.sigmaWords[3],r[4]=o(e,0),r[5]=o(e,4),r[6]=o(e,8),r[7]=o(e,12),r[8]=o(e,16),r[9]=o(e,20),r[10]=o(e,24),r[11]=o(e,28),r[12]=0,12===t.length?(r[13]=o(t,0),r[14]=o(t,4),r[15]=o(t,8)):(r[13]=0,r[14]=o(t,0),r[15]=o(t,4)),this.input=r}function n(e,t,r,i,n){e[t]+=e[r],e[n]=s(e[n]^e[t],16),e[i]+=e[n],e[r]=s(e[r]^e[i],12),e[t]+=e[r],e[n]=s(e[n]^e[t],8),e[i]+=e[n],e[r]=s(e[r]^e[i],7)}function o(e,t){return e[t]|e[t+1]<<8|e[t+2]<<16|e[t+3]<<24}function a(e,t,r){e[t]=r,r>>>=8,e[t+1]=r,r>>>=8,e[t+2]=r,r>>>=8,e[t+3]=r}function s(e,t){return e<>>32-t}i.prototype.getBytes=function(e){for(var t=new Uint8Array(e),r=0;r0;e-=2)n(r,0,4,8,12),n(r,1,5,9,13),n(r,2,6,10,14),n(r,3,7,11,15),n(r,0,5,10,15),n(r,1,6,11,12),n(r,2,7,8,13),n(r,3,4,9,14);for(e=16;e--;)r[e]+=t[e];for(e=16;e--;)a(i,4*e,r[e]);t[12]+=1,t[12]||(t[13]+=1)},i.prototype.encrypt=function(e){for(var t=e.length,r=new Uint8Array(t),i=0,n=this.block;i0;){var d=Math.min(r,1e4);r-=d;var h=o*d;n=s(e,n,a.length===h?a.buffer:i.arrayToBuffer(a.subarray(0,h)))}return n.then((function(e){return new Uint8Array(e)}))}function s(e,t,r){return t.then((function(t){return e.encrypt(r,t)})).then((function(e){var t=i.arrayToBuffer(new Uint8Array(e).subarray(-32,-16));return i.zeroBuffer(e),t}))}e.exports.encrypt=function(e,t,r){var s=n.createAesCbc();return s.importKey(i.arrayToBuffer(t)).then((function(){for(var t=[],i=0;i<32;i+=o)t.push(a(s,e.subarray(i,i+o),r));return Promise.all(t)})).then((function(e){var t=new Uint8Array(32);return e.forEach((function(e,r){for(var n=r*o,a=0;a\n \n";return a.stringToBytes(t)},e.exports=u},function(e,t,r){"use strict";var i=r(6),n=r(4),o=function(){this.creationTime=void 0,this.lastModTime=void 0,this.lastAccessTime=void 0,this.expiryTime=void 0,this.expires=void 0,this.usageCount=void 0,this.locationChanged=new Date,Object.preventExtensions(this)};o.prototype._readNode=function(e){switch(e.tagName){case i.Elem.CreationTime:this.creationTime=n.getDate(e);break;case i.Elem.LastModTime:this.lastModTime=n.getDate(e);break;case i.Elem.LastAccessTime:this.lastAccessTime=n.getDate(e);break;case i.Elem.ExpiryTime:this.expiryTime=n.getDate(e);break;case i.Elem.Expires:this.expires=n.getBoolean(e);break;case i.Elem.UsageCount:this.usageCount=n.getNumber(e);break;case i.Elem.LocationChanged:this.locationChanged=n.getDate(e)}},o.prototype.clone=function(){var e=new o;return e.creationTime=this.creationTime,e.lastModTime=this.lastModTime,e.lastAccessTime=this.lastAccessTime,e.expiryTime=this.expiryTime,e.expires=this.expires,e.usageCount=this.usageCount,e.locationChanged=this.locationChanged,e},o.prototype.update=function(){var e=new Date;this.lastModTime=e,this.lastAccessTime=e},o.prototype.write=function(e,t){var r=n.addChildNode(e,i.Elem.Times);t.setXmlDate(n.addChildNode(r,i.Elem.CreationTime),this.creationTime),t.setXmlDate(n.addChildNode(r,i.Elem.LastModTime),this.lastModTime),t.setXmlDate(n.addChildNode(r,i.Elem.LastAccessTime),this.lastAccessTime),t.setXmlDate(n.addChildNode(r,i.Elem.ExpiryTime),this.expiryTime),n.setBoolean(n.addChildNode(r,i.Elem.Expires),this.expires),n.setNumber(n.addChildNode(r,i.Elem.UsageCount),this.usageCount),t.setXmlDate(n.addChildNode(r,i.Elem.LocationChanged),this.locationChanged)},o.create=function(){var e=new o,t=new Date;return e.creationTime=t,e.lastModTime=t,e.lastAccessTime=t,e.expiryTime=t,e.expires=!1,e.usageCount=0,e.locationChanged=t,e},o.read=function(e){for(var t=new o,r=0,i=e.childNodes,n=i.length;rt.times.lastModTime){if(!this.history.some((function(e){return+e.times.lastModTime==+t.times.lastModTime}))){var i=new l;i.copyFrom(t),r.push(i)}}this.history=this._mergeHistory(r,t.times.lastModTime)}},l.prototype._mergeHistory=function(e,t){this.history.sort((function(e,t){return e.times.lastModTime-t.times.lastModTime})),e.sort((function(e,t){return e.times.lastModTime-t.times.lastModTime}));var r={},i={};this.history.forEach((function(e){r[e.times.lastModTime.getTime()]=e})),e.forEach((function(e){i[e.times.lastModTime.getTime()]=e}));for(var n=0,o=0,a=[];nu){if(!this._editState||this._editState.deleted.indexOf(u)<0){var c=new l;c.copyFrom(d),a.push(c)}o++}else(this._editState&&this._editState.added.indexOf(h)>=0||h>t)&&a.push(s),n++;else a.push(s),n++,o++}return a},l.create=function(e,t){var r=new l(t);return r.uuid=d.random(),r.icon=a.Icons.Key,r.times=h.create(),r.parentGroup=t,r._setField("Title","",e.memoryProtection.title),r._setField("UserName",e.defaultUser||"",e.memoryProtection.userName),r._setField("Password","",e.memoryProtection.password),r._setField("URL","",e.memoryProtection.url),r._setField("Notes","",e.memoryProtection.notes),r.autoType.enabled="boolean"!=typeof t.enableAutoType||t.enableAutoType,r.autoType.obfuscation=a.AutoTypeObfuscationOptions.None,r},l.read=function(e,t,r){for(var i=new l,n=0,o=e.childNodes,a=o.length;n=0?t[i].splice(r,0,e):t[i].push(e);else{var a=new Date;e instanceof h?e.forEach((function(e,t){this.addDeletedObject((e||t).uuid,a)}),this):this.addDeletedObject(e.uuid,a)}e.parentGroup=t,e.times.locationChanged=new Date}},y.prototype.addDeletedObject=function(e,t){var r=new l;r.uuid=e,r.deletionTime=t,this.deletedObjects.push(r)},y.prototype.remove=function(e){var t=null;this.meta.recycleBinEnabled&&(this.createRecycleBin(),t=this.getGroup(this.meta.recycleBinUuid)),this.move(e,t)},y.prototype.createBinary=function(e){return this.binaries.add(e)},y.prototype.importEntry=function(e,t,r){var i=new u,n=c.random();i.copyFrom(e),i.uuid=n,e.history.forEach((function(e){var t=new u;t.copyFrom(e),t.uuid=n,i.history.push(t)}));var o={},a={};return i.history.concat(i).forEach((function(e){e.customIcon&&(a[e.customIcon]=e.customIcon),Object.values(e.binaries).forEach((function(e){e.ref&&(o[e.ref]=e)}))})),Object.values(o).forEach((function(e){var t=r.binaries[e.ref];t&&!this.binaries[e.ref]&&(this.binaries[e.ref]=t)}),this),Object.values(a).forEach((function(e){var t=r.meta.customIcons[e];t&&(this.meta.customIcons[e]=t)}),this),t.entries.push(i),i.parentGroup=t,i.times.update(),i},y.prototype.cleanup=function(e){var t=new Date,r=e&&e.historyRules&&"number"==typeof this.meta.historyMaxItems&&this.meta.historyMaxItems>=0?this.meta.historyMaxItems:1/0,i={},n={},o=function(e){e&&e.customIcon&&(i[e.customIcon]=!0),e&&e.binaries&&Object.keys(e.binaries).forEach((function(t){e.binaries[t]&&e.binaries[t].ref&&(n[e.binaries[t].ref]=!0)}))};this.getDefaultGroup().forEach((function(e,t){e&&e.history.length>r&&e.removeHistory(0,e.history.length-r),e&&o(e),e&&e.history&&e.history.forEach((function(e){o(e)})),t&&t.customIcon&&(i[t.customIcon]=!0)})),e&&e.customIcons&&Object.keys(this.meta.customIcons).forEach((function(e){if(!i[e]){var r=new c(e);this.addDeletedObject(r,t),delete this.meta.customIcons[e]}}),this),e&&e.binaries&&Object.keys(this.binaries).forEach((function(e){n[e]||delete this.binaries[e]}),this)},y.prototype.merge=function(e){var t=this.getDefaultGroup(),r=e.getDefaultGroup();if(!t||!r)throw new n(f.ErrorCodes.MergeError,"no default group");if(!t.uuid.equals(r.uuid))throw new n(f.ErrorCodes.MergeError,"default group is different");var i=this._getObjectMap();e.deletedObjects.forEach((function(e){i.deleted[e.uuid]||(this.deletedObjects.push(e),i.deleted[e.uuid]=e.deletionTime)}),this),Object.keys(e.binaries).forEach((function(t){this.binaries[t]||i.deleted[t]||(this.binaries[t]=e.binaries[t])}),this),i.remote=e._getObjectMap().objects,this.meta.merge(e.meta,i),t.merge(i),this.cleanup({historyRules:!0,customIcons:!0,binaries:!0})},y.prototype.getLocalEditState=function(){var e={};return this.getDefaultGroup().forEach((function(t){t&&t._editState&&(e[t.uuid]=t._editState)})),this.meta._editState&&(e.meta=this.meta._editState),e},y.prototype.setLocalEditState=function(e){this.getDefaultGroup().forEach((function(t){t&&e[t.uuid]&&(t._editState=e[t.uuid])})),e.meta&&(this.meta._editState=e.meta)},y.prototype.removeLocalEditState=function(){this.getDefaultGroup().forEach((function(e){e&&(e._editState=void 0)})),this.meta._editState=void 0},y.prototype.upgrade=function(){this.setVersion(a.MaxFileVersion)},y.prototype.setVersion=function(e){this.meta.headerHash=null,this.meta.settingsChanged=new Date,this.header.setVersion(e)},y.prototype.setKdf=function(e){this.meta.headerHash=null,this.meta.settingsChanged=new Date,this.header.setKdf(e)},y.prototype._getObjectMap=function(){var e={},t={};return this.getDefaultGroup().forEach((function(t,r){var i=t||r;if(e[i.uuid])throw new n(f.ErrorCodes.MergeError,"Duplicate: "+i.uuid);e[i.uuid]=i})),this.deletedObjects.forEach((function(e){t[e.uuid]=e.deletionTime})),{objects:e,deleted:t}},y.prototype._loadFromXml=function(e){if(this.xml.documentElement.tagName!==p.Elem.DocNode)throw new n(f.ErrorCodes.FileCorrupt,"bad xml root");this._parseMeta(e);var t=this;return this.binaries.hash().then((function(){return t._parseRoot(e),t}))},y.prototype._parseMeta=function(e){var t=m.getChildNode(this.xml.documentElement,p.Elem.Meta,"no meta node");this.meta=s.read(t,e)},y.prototype._parseRoot=function(e){this.groups=[],this.deletedObjects=[];for(var t=0,r=m.getChildNode(this.xml.documentElement,p.Elem.Root,"no root node").childNodes,i=r.length;t0?t.windowBits=-t.windowBits:t.gzip&&t.windowBits>0&&t.windowBits<16&&(t.windowBits+=16),this.err=0,this.msg="",this.ended=!1,this.chunks=[],this.strm=new s,this.strm.avail_out=0;var r=i.deflateInit2(this.strm,t.level,t.method,t.windowBits,t.memLevel,t.strategy);if(0!==r)throw new Error(a[r]);if(t.header&&i.deflateSetHeader(this.strm,t.header),t.dictionary){var u;if(u="string"==typeof t.dictionary?o.string2buf(t.dictionary):"[object ArrayBuffer]"===d.call(t.dictionary)?new Uint8Array(t.dictionary):t.dictionary,0!==(r=i.deflateSetDictionary(this.strm,u)))throw new Error(a[r]);this._dict_set=!0}}function u(e,t){var r=new h(t);if(r.push(e,!0),r.err)throw r.msg;return r.result}h.prototype.push=function(e,t){var r,a,s=this.strm,h=this.options.chunkSize;if(this.ended)return!1;a=t===~~t?t:!0===t?4:0,"string"==typeof e?s.input=o.string2buf(e):"[object ArrayBuffer]"===d.call(e)?s.input=new Uint8Array(e):s.input=e,s.next_in=0,s.avail_in=s.input.length;do{if(0===s.avail_out&&(s.output=new n.Buf8(h),s.next_out=0,s.avail_out=h),1!==(r=i.deflate(s,a))&&0!==r)return this.onEnd(r),this.ended=!0,!1;0!==s.avail_out&&(0!==s.avail_in||4!==a&&2!==a)||("string"===this.options.to?this.onData(o.buf2binstring(n.shrinkBuf(s.output,s.next_out))):this.onData(n.shrinkBuf(s.output,s.next_out)))}while((s.avail_in>0||0===s.avail_out)&&1!==r);return 4===a?(r=i.deflateEnd(this.strm),this.onEnd(r),this.ended=!0,0===r):2!==a||(this.onEnd(0),s.avail_out=0,!0)},h.prototype.onData=function(e){this.chunks.push(e)},h.prototype.onEnd=function(e){0===e&&("string"===this.options.to?this.result=this.chunks.join(""):this.result=n.flattenChunks(this.chunks)),this.chunks=[],this.err=e,this.msg=this.strm.msg},t.Deflate=h,t.deflate=u,t.deflateRaw=function(e,t){return(t=t||{}).raw=!0,u(e,t)},t.gzip=function(e,t){return(t=t||{}).gzip=!0,u(e,t)}},function(e,t,r){"use strict";var i,n=r(5),o=r(34),a=r(17),s=r(18),d=r(12),h=-2,u=258,l=262,c=103,f=113,p=666;function m(e,t){return e.msg=d[t],t}function y(e){return(e<<1)-(e>4?9:0)}function g(e){for(var t=e.length;--t>=0;)e[t]=0}function _(e){var t=e.state,r=t.pending;r>e.avail_out&&(r=e.avail_out),0!==r&&(n.arraySet(e.output,t.pending_buf,t.pending_out,r,e.next_out),e.next_out+=r,t.pending_out+=r,e.total_out+=r,e.avail_out-=r,t.pending-=r,0===t.pending&&(t.pending_out=0))}function b(e,t){o._tr_flush_block(e,e.block_start>=0?e.block_start:-1,e.strstart-e.block_start,t),e.block_start=e.strstart,_(e.strm)}function v(e,t){e.pending_buf[e.pending++]=t}function w(e,t){e.pending_buf[e.pending++]=t>>>8&255,e.pending_buf[e.pending++]=255&t}function k(e,t){var r,i,n=e.max_chain_length,o=e.strstart,a=e.prev_length,s=e.nice_match,d=e.strstart>e.w_size-l?e.strstart-(e.w_size-l):0,h=e.window,c=e.w_mask,f=e.prev,p=e.strstart+u,m=h[o+a-1],y=h[o+a];e.prev_length>=e.good_match&&(n>>=2),s>e.lookahead&&(s=e.lookahead);do{if(h[(r=t)+a]===y&&h[r+a-1]===m&&h[r]===h[o]&&h[++r]===h[o+1]){o+=2,r++;do{}while(h[++o]===h[++r]&&h[++o]===h[++r]&&h[++o]===h[++r]&&h[++o]===h[++r]&&h[++o]===h[++r]&&h[++o]===h[++r]&&h[++o]===h[++r]&&h[++o]===h[++r]&&oa){if(e.match_start=t,a=i,i>=s)break;m=h[o+a-1],y=h[o+a]}}}while((t=f[t&c])>d&&0!=--n);return a<=e.lookahead?a:e.lookahead}function C(e){var t,r,i,o,d,h,u,c,f,p,m=e.w_size;do{if(o=e.window_size-e.lookahead-e.strstart,e.strstart>=m+(m-l)){n.arraySet(e.window,e.window,m,m,0),e.match_start-=m,e.strstart-=m,e.block_start-=m,t=r=e.hash_size;do{i=e.head[--t],e.head[t]=i>=m?i-m:0}while(--r);t=r=m;do{i=e.prev[--t],e.prev[t]=i>=m?i-m:0}while(--r);o+=m}if(0===e.strm.avail_in)break;if(h=e.strm,u=e.window,c=e.strstart+e.lookahead,f=o,p=void 0,(p=h.avail_in)>f&&(p=f),r=0===p?0:(h.avail_in-=p,n.arraySet(u,h.input,h.next_in,p,c),1===h.state.wrap?h.adler=a(h.adler,u,p,c):2===h.state.wrap&&(h.adler=s(h.adler,u,p,c)),h.next_in+=p,h.total_in+=p,p),e.lookahead+=r,e.lookahead+e.insert>=3)for(d=e.strstart-e.insert,e.ins_h=e.window[d],e.ins_h=(e.ins_h<=3&&(e.ins_h=(e.ins_h<=3)if(i=o._tr_tally(e,e.strstart-e.match_start,e.match_length-3),e.lookahead-=e.match_length,e.match_length<=e.max_lazy_match&&e.lookahead>=3){e.match_length--;do{e.strstart++,e.ins_h=(e.ins_h<=3&&(e.ins_h=(e.ins_h<4096)&&(e.match_length=2)),e.prev_length>=3&&e.match_length<=e.prev_length){n=e.strstart+e.lookahead-3,i=o._tr_tally(e,e.strstart-1-e.prev_match,e.prev_length-3),e.lookahead-=e.prev_length-1,e.prev_length-=2;do{++e.strstart<=n&&(e.ins_h=(e.ins_h<15&&(s=2,i-=16),o<1||o>9||8!==r||i<8||i>15||t<0||t>9||a<0||a>4)return m(e,h);8===i&&(i=9);var d=new T;return e.state=d,d.strm=e,d.wrap=s,d.gzhead=null,d.w_bits=i,d.w_size=1<e.pending_buf_size-5&&(r=e.pending_buf_size-5);;){if(e.lookahead<=1){if(C(e),0===e.lookahead&&0===t)return 1;if(0===e.lookahead)break}e.strstart+=e.lookahead,e.lookahead=0;var i=e.block_start+r;if((0===e.strstart||e.strstart>=i)&&(e.lookahead=e.strstart-i,e.strstart=i,b(e,!1),0===e.strm.avail_out))return 1;if(e.strstart-e.block_start>=e.w_size-l&&(b(e,!1),0===e.strm.avail_out))return 1}return e.insert=0,4===t?(b(e,!0),0===e.strm.avail_out?3:4):(e.strstart>e.block_start&&(b(e,!1),e.strm.avail_out),1)})),new B(4,4,8,4,x),new B(4,5,16,8,x),new B(4,6,32,32,x),new B(4,4,16,16,E),new B(8,16,32,32,E),new B(8,16,128,128,E),new B(8,32,128,256,E),new B(32,128,258,1024,E),new B(32,258,258,4096,E)],t.deflateInit=function(e,t){return U(e,t,8,15,8,0)},t.deflateInit2=U,t.deflateReset=S,t.deflateResetKeep=A,t.deflateSetHeader=function(e,t){return e&&e.state?2!==e.state.wrap?h:(e.state.gzhead=t,0):h},t.deflate=function(e,t){var r,n,a,d;if(!e||!e.state||t>5||t<0)return e?m(e,h):h;if(n=e.state,!e.output||!e.input&&0!==e.avail_in||n.status===p&&4!==t)return m(e,0===e.avail_out?-5:h);if(n.strm=e,r=n.last_flush,n.last_flush=t,42===n.status)if(2===n.wrap)e.adler=0,v(n,31),v(n,139),v(n,8),n.gzhead?(v(n,(n.gzhead.text?1:0)+(n.gzhead.hcrc?2:0)+(n.gzhead.extra?4:0)+(n.gzhead.name?8:0)+(n.gzhead.comment?16:0)),v(n,255&n.gzhead.time),v(n,n.gzhead.time>>8&255),v(n,n.gzhead.time>>16&255),v(n,n.gzhead.time>>24&255),v(n,9===n.level?2:n.strategy>=2||n.level<2?4:0),v(n,255&n.gzhead.os),n.gzhead.extra&&n.gzhead.extra.length&&(v(n,255&n.gzhead.extra.length),v(n,n.gzhead.extra.length>>8&255)),n.gzhead.hcrc&&(e.adler=s(e.adler,n.pending_buf,n.pending,0)),n.gzindex=0,n.status=69):(v(n,0),v(n,0),v(n,0),v(n,0),v(n,0),v(n,9===n.level?2:n.strategy>=2||n.level<2?4:0),v(n,3),n.status=f);else{var l=8+(n.w_bits-8<<4)<<8;l|=(n.strategy>=2||n.level<2?0:n.level<6?1:6===n.level?2:3)<<6,0!==n.strstart&&(l|=32),l+=31-l%31,n.status=f,w(n,l),0!==n.strstart&&(w(n,e.adler>>>16),w(n,65535&e.adler)),e.adler=1}if(69===n.status)if(n.gzhead.extra){for(a=n.pending;n.gzindex<(65535&n.gzhead.extra.length)&&(n.pending!==n.pending_buf_size||(n.gzhead.hcrc&&n.pending>a&&(e.adler=s(e.adler,n.pending_buf,n.pending-a,a)),_(e),a=n.pending,n.pending!==n.pending_buf_size));)v(n,255&n.gzhead.extra[n.gzindex]),n.gzindex++;n.gzhead.hcrc&&n.pending>a&&(e.adler=s(e.adler,n.pending_buf,n.pending-a,a)),n.gzindex===n.gzhead.extra.length&&(n.gzindex=0,n.status=73)}else n.status=73;if(73===n.status)if(n.gzhead.name){a=n.pending;do{if(n.pending===n.pending_buf_size&&(n.gzhead.hcrc&&n.pending>a&&(e.adler=s(e.adler,n.pending_buf,n.pending-a,a)),_(e),a=n.pending,n.pending===n.pending_buf_size)){d=1;break}d=n.gzindexa&&(e.adler=s(e.adler,n.pending_buf,n.pending-a,a)),0===d&&(n.gzindex=0,n.status=91)}else n.status=91;if(91===n.status)if(n.gzhead.comment){a=n.pending;do{if(n.pending===n.pending_buf_size&&(n.gzhead.hcrc&&n.pending>a&&(e.adler=s(e.adler,n.pending_buf,n.pending-a,a)),_(e),a=n.pending,n.pending===n.pending_buf_size)){d=1;break}d=n.gzindexa&&(e.adler=s(e.adler,n.pending_buf,n.pending-a,a)),0===d&&(n.status=c)}else n.status=c;if(n.status===c&&(n.gzhead.hcrc?(n.pending+2>n.pending_buf_size&&_(e),n.pending+2<=n.pending_buf_size&&(v(n,255&e.adler),v(n,e.adler>>8&255),e.adler=0,n.status=f)):n.status=f),0!==n.pending){if(_(e),0===e.avail_out)return n.last_flush=-1,0}else if(0===e.avail_in&&y(t)<=y(r)&&4!==t)return m(e,-5);if(n.status===p&&0!==e.avail_in)return m(e,-5);if(0!==e.avail_in||0!==n.lookahead||0!==t&&n.status!==p){var k=2===n.strategy?function(e,t){for(var r;;){if(0===e.lookahead&&(C(e),0===e.lookahead)){if(0===t)return 1;break}if(e.match_length=0,r=o._tr_tally(e,0,e.window[e.strstart]),e.lookahead--,e.strstart++,r&&(b(e,!1),0===e.strm.avail_out))return 1}return e.insert=0,4===t?(b(e,!0),0===e.strm.avail_out?3:4):e.last_lit&&(b(e,!1),0===e.strm.avail_out)?1:2}(n,t):3===n.strategy?function(e,t){for(var r,i,n,a,s=e.window;;){if(e.lookahead<=u){if(C(e),e.lookahead<=u&&0===t)return 1;if(0===e.lookahead)break}if(e.match_length=0,e.lookahead>=3&&e.strstart>0&&(i=s[n=e.strstart-1])===s[++n]&&i===s[++n]&&i===s[++n]){a=e.strstart+u;do{}while(i===s[++n]&&i===s[++n]&&i===s[++n]&&i===s[++n]&&i===s[++n]&&i===s[++n]&&i===s[++n]&&i===s[++n]&&ne.lookahead&&(e.match_length=e.lookahead)}if(e.match_length>=3?(r=o._tr_tally(e,1,e.match_length-3),e.lookahead-=e.match_length,e.strstart+=e.match_length,e.match_length=0):(r=o._tr_tally(e,0,e.window[e.strstart]),e.lookahead--,e.strstart++),r&&(b(e,!1),0===e.strm.avail_out))return 1}return e.insert=0,4===t?(b(e,!0),0===e.strm.avail_out?3:4):e.last_lit&&(b(e,!1),0===e.strm.avail_out)?1:2}(n,t):i[n.level].func(n,t);if(3!==k&&4!==k||(n.status=p),1===k||3===k)return 0===e.avail_out&&(n.last_flush=-1),0;if(2===k&&(1===t?o._tr_align(n):5!==t&&(o._tr_stored_block(n,0,0,!1),3===t&&(g(n.head),0===n.lookahead&&(n.strstart=0,n.block_start=0,n.insert=0))),_(e),0===e.avail_out))return n.last_flush=-1,0}return 4!==t?0:n.wrap<=0?1:(2===n.wrap?(v(n,255&e.adler),v(n,e.adler>>8&255),v(n,e.adler>>16&255),v(n,e.adler>>24&255),v(n,255&e.total_in),v(n,e.total_in>>8&255),v(n,e.total_in>>16&255),v(n,e.total_in>>24&255)):(w(n,e.adler>>>16),w(n,65535&e.adler)),_(e),n.wrap>0&&(n.wrap=-n.wrap),0!==n.pending?0:1)},t.deflateEnd=function(e){var t;return e&&e.state?42!==(t=e.state.status)&&69!==t&&73!==t&&91!==t&&t!==c&&t!==f&&t!==p?m(e,h):(e.state=null,t===f?m(e,-3):0):h},t.deflateSetDictionary=function(e,t){var r,i,o,s,d,u,l,c,f=t.length;if(!e||!e.state)return h;if(2===(s=(r=e.state).wrap)||1===s&&42!==r.status||r.lookahead)return h;for(1===s&&(e.adler=a(e.adler,t,f,0)),r.wrap=0,f>=r.w_size&&(0===s&&(g(r.head),r.strstart=0,r.block_start=0,r.insert=0),c=new n.Buf8(r.w_size),n.arraySet(c,t,f-r.w_size,r.w_size,0),t=c,f=r.w_size),d=e.avail_in,u=e.next_in,l=e.input,e.avail_in=f,e.next_in=0,e.input=t,C(r);r.lookahead>=3;){i=r.strstart,o=r.lookahead-2;do{r.ins_h=(r.ins_h<=0;)e[t]=0}var o=256,a=286,s=30,d=15,h=[0,0,0,0,0,0,0,0,1,1,1,1,2,2,2,2,3,3,3,3,4,4,4,4,5,5,5,5,0],u=[0,0,0,0,1,1,2,2,3,3,4,4,5,5,6,6,7,7,8,8,9,9,10,10,11,11,12,12,13,13],l=[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,3,7],c=[16,17,18,0,8,7,9,6,10,5,11,4,12,3,13,2,14,1,15],f=new Array(576);n(f);var p=new Array(60);n(p);var m=new Array(512);n(m);var y=new Array(256);n(y);var g=new Array(29);n(g);var _,b,v,w=new Array(s);function k(e,t,r,i,n){this.static_tree=e,this.extra_bits=t,this.extra_base=r,this.elems=i,this.max_length=n,this.has_stree=e&&e.length}function C(e,t){this.dyn_tree=e,this.max_code=0,this.stat_desc=t}function x(e){return e<256?m[e]:m[256+(e>>>7)]}function E(e,t){e.pending_buf[e.pending++]=255&t,e.pending_buf[e.pending++]=t>>>8&255}function B(e,t,r){e.bi_valid>16-r?(e.bi_buf|=t<>16-e.bi_valid,e.bi_valid+=r-16):(e.bi_buf|=t<>>=1,r<<=1}while(--t>0);return r>>>1}function S(e,t,r){var i,n,o=new Array(16),a=0;for(i=1;i<=d;i++)o[i]=a=a+r[i-1]<<1;for(n=0;n<=t;n++){var s=e[2*n+1];0!==s&&(e[2*n]=A(o[s]++,s))}}function U(e){var t;for(t=0;t8?E(e,e.bi_buf):e.bi_valid>0&&(e.pending_buf[e.pending++]=e.bi_buf),e.bi_buf=0,e.bi_valid=0}function I(e,t,r,i){var n=2*t,o=2*r;return e[n]>1;r>=1;r--)N(e,o,r);n=h;do{r=e.heap[1],e.heap[1]=e.heap[e.heap_len--],N(e,o,1),i=e.heap[1],e.heap[--e.heap_max]=r,e.heap[--e.heap_max]=i,o[2*n]=o[2*r]+o[2*i],e.depth[n]=(e.depth[r]>=e.depth[i]?e.depth[r]:e.depth[i])+1,o[2*r+1]=o[2*i+1]=n,e.heap[1]=n++,N(e,o,1)}while(e.heap_len>=2);e.heap[--e.heap_max]=e.heap[1],function(e,t){var r,i,n,o,a,s,h=t.dyn_tree,u=t.max_code,l=t.stat_desc.static_tree,c=t.stat_desc.has_stree,f=t.stat_desc.extra_bits,p=t.stat_desc.extra_base,m=t.stat_desc.max_length,y=0;for(o=0;o<=d;o++)e.bl_count[o]=0;for(h[2*e.heap[e.heap_max]+1]=0,r=e.heap_max+1;r<573;r++)(o=h[2*h[2*(i=e.heap[r])+1]+1]+1)>m&&(o=m,y++),h[2*i+1]=o,i>u||(e.bl_count[o]++,a=0,i>=p&&(a=f[i-p]),s=h[2*i],e.opt_len+=s*(o+a),c&&(e.static_len+=s*(l[2*i+1]+a)));if(0!==y){do{for(o=m-1;0===e.bl_count[o];)o--;e.bl_count[o]--,e.bl_count[o+1]+=2,e.bl_count[m]--,y-=2}while(y>0);for(o=m;0!==o;o--)for(i=e.bl_count[o];0!==i;)(n=e.heap[--r])>u||(h[2*n+1]!==o&&(e.opt_len+=(o-h[2*n+1])*h[2*n],h[2*n+1]=o),i--)}}(e,t),S(o,u,e.bl_count)}function F(e,t,r){var i,n,o=-1,a=t[1],s=0,d=7,h=4;for(0===a&&(d=138,h=3),t[2*(r+1)+1]=65535,i=0;i<=r;i++)n=a,a=t[2*(i+1)+1],++s>=7;i0?(2===e.strm.data_type&&(e.strm.data_type=function(e){var t,r=4093624447;for(t=0;t<=31;t++,r>>>=1)if(1&r&&0!==e.dyn_ltree[2*t])return 0;if(0!==e.dyn_ltree[18]||0!==e.dyn_ltree[20]||0!==e.dyn_ltree[26])return 1;for(t=32;t=3&&0===e.bl_tree[2*c[t]+1];t--);return e.opt_len+=3*(t+1)+5+5+4,t}(e),n=e.opt_len+3+7>>>3,(a=e.static_len+3+7>>>3)<=n&&(n=a)):n=a=r+5,r+4<=n&&-1!==t?V(e,t,r,i):4===e.strategy||a===n?(B(e,2+(i?1:0),3),P(e,f,p)):(B(e,4+(i?1:0),3),function(e,t,r,i){var n;for(B(e,t-257,5),B(e,r-1,5),B(e,i-4,4),n=0;n>>8&255,e.pending_buf[e.d_buf+2*e.last_lit+1]=255&t,e.pending_buf[e.l_buf+e.last_lit]=255&r,e.last_lit++,0===t?e.dyn_ltree[2*r]++:(e.matches++,t--,e.dyn_ltree[2*(y[r]+o+1)]++,e.dyn_dtree[2*x(t)]++),e.last_lit===e.lit_bufsize-1},t._tr_align=function(e){B(e,2,3),T(e,256,f),function(e){16===e.bi_valid?(E(e,e.bi_buf),e.bi_buf=0,e.bi_valid=0):e.bi_valid>=8&&(e.pending_buf[e.pending++]=255&e.bi_buf,e.bi_buf>>=8,e.bi_valid-=8)}(e)}},function(e,t,r){"use strict";var i=r(36),n=r(5),o=r(19),a=r(21),s=r(12),d=r(20),h=r(39),u=Object.prototype.toString;function l(e){if(!(this instanceof l))return new l(e);this.options=n.assign({chunkSize:16384,windowBits:0,to:""},e||{});var t=this.options;t.raw&&t.windowBits>=0&&t.windowBits<16&&(t.windowBits=-t.windowBits,0===t.windowBits&&(t.windowBits=-15)),!(t.windowBits>=0&&t.windowBits<16)||e&&e.windowBits||(t.windowBits+=32),t.windowBits>15&&t.windowBits<48&&0==(15&t.windowBits)&&(t.windowBits|=15),this.err=0,this.msg="",this.ended=!1,this.chunks=[],this.strm=new d,this.strm.avail_out=0;var r=i.inflateInit2(this.strm,t.windowBits);if(r!==a.Z_OK)throw new Error(s[r]);this.header=new h,i.inflateGetHeader(this.strm,this.header)}function c(e,t){var r=new l(t);if(r.push(e,!0),r.err)throw r.msg;return r.result}l.prototype.push=function(e,t){var r,s,d,h,l,c,f=this.strm,p=this.options.chunkSize,m=this.options.dictionary,y=!1;if(this.ended)return!1;s=t===~~t?t:!0===t?a.Z_FINISH:a.Z_NO_FLUSH,"string"==typeof e?f.input=o.binstring2buf(e):"[object ArrayBuffer]"===u.call(e)?f.input=new Uint8Array(e):f.input=e,f.next_in=0,f.avail_in=f.input.length;do{if(0===f.avail_out&&(f.output=new n.Buf8(p),f.next_out=0,f.avail_out=p),(r=i.inflate(f,a.Z_NO_FLUSH))===a.Z_NEED_DICT&&m&&(c="string"==typeof m?o.string2buf(m):"[object ArrayBuffer]"===u.call(m)?new Uint8Array(m):m,r=i.inflateSetDictionary(this.strm,c)),r===a.Z_BUF_ERROR&&!0===y&&(r=a.Z_OK,y=!1),r!==a.Z_STREAM_END&&r!==a.Z_OK)return this.onEnd(r),this.ended=!0,!1;f.next_out&&(0!==f.avail_out&&r!==a.Z_STREAM_END&&(0!==f.avail_in||s!==a.Z_FINISH&&s!==a.Z_SYNC_FLUSH)||("string"===this.options.to?(d=o.utf8border(f.output,f.next_out),h=f.next_out-d,l=o.buf2string(f.output,d),f.next_out=h,f.avail_out=p-h,h&&n.arraySet(f.output,f.output,d,h,0),this.onData(l)):this.onData(n.shrinkBuf(f.output,f.next_out)))),0===f.avail_in&&0===f.avail_out&&(y=!0)}while((f.avail_in>0||0===f.avail_out)&&r!==a.Z_STREAM_END);return r===a.Z_STREAM_END&&(s=a.Z_FINISH),s===a.Z_FINISH?(r=i.inflateEnd(this.strm),this.onEnd(r),this.ended=!0,r===a.Z_OK):s!==a.Z_SYNC_FLUSH||(this.onEnd(a.Z_OK),f.avail_out=0,!0)},l.prototype.onData=function(e){this.chunks.push(e)},l.prototype.onEnd=function(e){e===a.Z_OK&&("string"===this.options.to?this.result=this.chunks.join(""):this.result=n.flattenChunks(this.chunks)),this.chunks=[],this.err=e,this.msg=this.strm.msg},t.Inflate=l,t.inflate=c,t.inflateRaw=function(e,t){return(t=t||{}).raw=!0,c(e,t)},t.ungzip=c},function(e,t,r){"use strict";var i=r(5),n=r(17),o=r(18),a=r(37),s=r(38),d=-2,h=12,u=30;function l(e){return(e>>>24&255)+(e>>>8&65280)+((65280&e)<<8)+((255&e)<<24)}function c(){this.mode=0,this.last=!1,this.wrap=0,this.havedict=!1,this.flags=0,this.dmax=0,this.check=0,this.total=0,this.head=null,this.wbits=0,this.wsize=0,this.whave=0,this.wnext=0,this.window=null,this.hold=0,this.bits=0,this.length=0,this.offset=0,this.extra=0,this.lencode=null,this.distcode=null,this.lenbits=0,this.distbits=0,this.ncode=0,this.nlen=0,this.ndist=0,this.have=0,this.next=null,this.lens=new i.Buf16(320),this.work=new i.Buf16(288),this.lendyn=null,this.distdyn=null,this.sane=0,this.back=0,this.was=0}function f(e){var t;return e&&e.state?(t=e.state,e.total_in=e.total_out=t.total=0,e.msg="",t.wrap&&(e.adler=1&t.wrap),t.mode=1,t.last=0,t.havedict=0,t.dmax=32768,t.head=null,t.hold=0,t.bits=0,t.lencode=t.lendyn=new i.Buf32(852),t.distcode=t.distdyn=new i.Buf32(592),t.sane=1,t.back=-1,0):d}function p(e){var t;return e&&e.state?((t=e.state).wsize=0,t.whave=0,t.wnext=0,f(e)):d}function m(e,t){var r,i;return e&&e.state?(i=e.state,t<0?(r=0,t=-t):(r=1+(t>>4),t<48&&(t&=15)),t&&(t<8||t>15)?d:(null!==i.window&&i.wbits!==t&&(i.window=null),i.wrap=r,i.wbits=t,p(e))):d}function y(e,t){var r,i;return e?(i=new c,e.state=i,i.window=null,0!==(r=m(e,t))&&(e.state=null),r):d}var g,_,b=!0;function v(e){if(b){var t;for(g=new i.Buf32(512),_=new i.Buf32(32),t=0;t<144;)e.lens[t++]=8;for(;t<256;)e.lens[t++]=9;for(;t<280;)e.lens[t++]=7;for(;t<288;)e.lens[t++]=8;for(s(1,e.lens,0,288,g,0,e.work,{bits:9}),t=0;t<32;)e.lens[t++]=5;s(2,e.lens,0,32,_,0,e.work,{bits:5}),b=!1}e.lencode=g,e.lenbits=9,e.distcode=_,e.distbits=5}function w(e,t,r,n){var o,a=e.state;return null===a.window&&(a.wsize=1<=a.wsize?(i.arraySet(a.window,t,r-a.wsize,a.wsize,0),a.wnext=0,a.whave=a.wsize):((o=a.wsize-a.wnext)>n&&(o=n),i.arraySet(a.window,t,r-n,o,a.wnext),(n-=o)?(i.arraySet(a.window,t,r-n,n,0),a.wnext=n,a.whave=a.wsize):(a.wnext+=o,a.wnext===a.wsize&&(a.wnext=0),a.whave>>8&255,r.check=o(r.check,O,2,0),_=0,b=0,r.mode=2;break}if(r.flags=0,r.head&&(r.head.done=!1),!(1&r.wrap)||(((255&_)<<8)+(_>>8))%31){e.msg="incorrect header check",r.mode=u;break}if(8!=(15&_)){e.msg="unknown compression method",r.mode=u;break}if(b-=4,N=8+(15&(_>>>=4)),0===r.wbits)r.wbits=N;else if(N>r.wbits){e.msg="invalid window size",r.mode=u;break}r.dmax=1<>8&1),512&r.flags&&(O[0]=255&_,O[1]=_>>>8&255,r.check=o(r.check,O,2,0)),_=0,b=0,r.mode=3;case 3:for(;b<32;){if(0===y)break e;y--,_+=c[p++]<>>8&255,O[2]=_>>>16&255,O[3]=_>>>24&255,r.check=o(r.check,O,4,0)),_=0,b=0,r.mode=4;case 4:for(;b<16;){if(0===y)break e;y--,_+=c[p++]<>8),512&r.flags&&(O[0]=255&_,O[1]=_>>>8&255,r.check=o(r.check,O,2,0)),_=0,b=0,r.mode=5;case 5:if(1024&r.flags){for(;b<16;){if(0===y)break e;y--,_+=c[p++]<>>8&255,r.check=o(r.check,O,2,0)),_=0,b=0}else r.head&&(r.head.extra=null);r.mode=6;case 6:if(1024&r.flags&&((x=r.length)>y&&(x=y),x&&(r.head&&(N=r.head.extra_len-r.length,r.head.extra||(r.head.extra=new Array(r.head.extra_len)),i.arraySet(r.head.extra,c,p,x,N)),512&r.flags&&(r.check=o(r.check,c,x,p)),y-=x,p+=x,r.length-=x),r.length))break e;r.length=0,r.mode=7;case 7:if(2048&r.flags){if(0===y)break e;x=0;do{N=c[p+x++],r.head&&N&&r.length<65536&&(r.head.name+=String.fromCharCode(N))}while(N&&x>9&1,r.head.done=!0),e.adler=r.check=0,r.mode=h;break;case 10:for(;b<32;){if(0===y)break e;y--,_+=c[p++]<>>=7&b,b-=7&b,r.mode=27;break}for(;b<3;){if(0===y)break e;y--,_+=c[p++]<>>=1)){case 0:r.mode=14;break;case 1:if(v(r),r.mode=20,6===t){_>>>=2,b-=2;break e}break;case 2:r.mode=17;break;case 3:e.msg="invalid block type",r.mode=u}_>>>=2,b-=2;break;case 14:for(_>>>=7&b,b-=7&b;b<32;){if(0===y)break e;y--,_+=c[p++]<>>16^65535)){e.msg="invalid stored block lengths",r.mode=u;break}if(r.length=65535&_,_=0,b=0,r.mode=15,6===t)break e;case 15:r.mode=16;case 16:if(x=r.length){if(x>y&&(x=y),x>g&&(x=g),0===x)break e;i.arraySet(f,c,p,x,m),y-=x,p+=x,g-=x,m+=x,r.length-=x;break}r.mode=h;break;case 17:for(;b<14;){if(0===y)break e;y--,_+=c[p++]<>>=5,b-=5,r.ndist=1+(31&_),_>>>=5,b-=5,r.ncode=4+(15&_),_>>>=4,b-=4,r.nlen>286||r.ndist>30){e.msg="too many length or distance symbols",r.mode=u;break}r.have=0,r.mode=18;case 18:for(;r.have>>=3,b-=3}for(;r.have<19;)r.lens[V[r.have++]]=0;if(r.lencode=r.lendyn,r.lenbits=7,M={bits:r.lenbits},P=s(0,r.lens,0,19,r.lencode,0,r.work,M),r.lenbits=M.bits,P){e.msg="invalid code lengths set",r.mode=u;break}r.have=0,r.mode=19;case 19:for(;r.have>>16&255,S=65535&z,!((T=z>>>24)<=b);){if(0===y)break e;y--,_+=c[p++]<>>=T,b-=T,r.lens[r.have++]=S;else{if(16===S){for(F=T+2;b>>=T,b-=T,0===r.have){e.msg="invalid bit length repeat",r.mode=u;break}N=r.lens[r.have-1],x=3+(3&_),_>>>=2,b-=2}else if(17===S){for(F=T+3;b>>=T)),_>>>=3,b-=3}else{for(F=T+7;b>>=T)),_>>>=7,b-=7}if(r.have+x>r.nlen+r.ndist){e.msg="invalid bit length repeat",r.mode=u;break}for(;x--;)r.lens[r.have++]=N}}if(r.mode===u)break;if(0===r.lens[256]){e.msg="invalid code -- missing end-of-block",r.mode=u;break}if(r.lenbits=9,M={bits:r.lenbits},P=s(1,r.lens,0,r.nlen,r.lencode,0,r.work,M),r.lenbits=M.bits,P){e.msg="invalid literal/lengths set",r.mode=u;break}if(r.distbits=6,r.distcode=r.distdyn,M={bits:r.distbits},P=s(2,r.lens,r.nlen,r.ndist,r.distcode,0,r.work,M),r.distbits=M.bits,P){e.msg="invalid distances set",r.mode=u;break}if(r.mode=20,6===t)break e;case 20:r.mode=21;case 21:if(y>=6&&g>=258){e.next_out=m,e.avail_out=g,e.next_in=p,e.avail_in=y,r.hold=_,r.bits=b,a(e,C),m=e.next_out,f=e.output,g=e.avail_out,p=e.next_in,c=e.input,y=e.avail_in,_=r.hold,b=r.bits,r.mode===h&&(r.back=-1);break}for(r.back=0;A=(z=r.lencode[_&(1<>>16&255,S=65535&z,!((T=z>>>24)<=b);){if(0===y)break e;y--,_+=c[p++]<>U)])>>>16&255,S=65535&z,!(U+(T=z>>>24)<=b);){if(0===y)break e;y--,_+=c[p++]<>>=U,b-=U,r.back+=U}if(_>>>=T,b-=T,r.back+=T,r.length=S,0===A){r.mode=26;break}if(32&A){r.back=-1,r.mode=h;break}if(64&A){e.msg="invalid literal/length code",r.mode=u;break}r.extra=15&A,r.mode=22;case 22:if(r.extra){for(F=r.extra;b>>=r.extra,b-=r.extra,r.back+=r.extra}r.was=r.length,r.mode=23;case 23:for(;A=(z=r.distcode[_&(1<>>16&255,S=65535&z,!((T=z>>>24)<=b);){if(0===y)break e;y--,_+=c[p++]<>U)])>>>16&255,S=65535&z,!(U+(T=z>>>24)<=b);){if(0===y)break e;y--,_+=c[p++]<>>=U,b-=U,r.back+=U}if(_>>>=T,b-=T,r.back+=T,64&A){e.msg="invalid distance code",r.mode=u;break}r.offset=S,r.extra=15&A,r.mode=24;case 24:if(r.extra){for(F=r.extra;b>>=r.extra,b-=r.extra,r.back+=r.extra}if(r.offset>r.dmax){e.msg="invalid distance too far back",r.mode=u;break}r.mode=25;case 25:if(0===g)break e;if(x=C-g,r.offset>x){if((x=r.offset-x)>r.whave&&r.sane){e.msg="invalid distance too far back",r.mode=u;break}x>r.wnext?(x-=r.wnext,E=r.wsize-x):E=r.wnext-x,x>r.length&&(x=r.length),B=r.window}else B=f,E=m-r.offset,x=r.length;x>g&&(x=g),g-=x,r.length-=x;do{f[m++]=B[E++]}while(--x);0===r.length&&(r.mode=21);break;case 26:if(0===g)break e;f[m++]=r.length,g--,r.mode=21;break;case 27:if(r.wrap){for(;b<32;){if(0===y)break e;y--,_|=c[p++]<>>=v=b>>>24,p-=v,0===(v=b>>>16&255))B[o++]=65535&b;else{if(!(16&v)){if(0==(64&v)){b=m[(65535&b)+(f&(1<>>=v,p-=v),p<15&&(f+=E[i++]<>>=v=b>>>24,p-=v,!(16&(v=b>>>16&255))){if(0==(64&v)){b=y[(65535&b)+(f&(1<d){e.msg="invalid distance too far back",r.mode=30;break e}if(f>>>=v,p-=v,k>(v=o-a)){if((v=k-v)>u&&r.sane){e.msg="invalid distance too far back",r.mode=30;break e}if(C=0,x=c,0===l){if(C+=h-v,v2;)B[o++]=x[C++],B[o++]=x[C++],B[o++]=x[C++],w-=3;w&&(B[o++]=x[C++],w>1&&(B[o++]=x[C++]))}else{C=o-k;do{B[o++]=B[C++],B[o++]=B[C++],B[o++]=B[C++],w-=3}while(w>2);w&&(B[o++]=B[C++],w>1&&(B[o++]=B[C++]))}break}}break}}while(i>3,f&=(1<<(p-=w<<3))-1,e.next_in=i,e.next_out=o,e.avail_in=i=1&&0===F[T];T--);if(A>T&&(A=T),0===T)return u[l++]=20971520,u[l++]=20971520,f.bits=1,0;for(B=1;B0&&(0===e||1!==T))return-1;for(z[1]=0,x=1;x852||2===e&&I>592)return 1;for(;;){v=x-U,c[E]b?(w=O[V+c[E]],k=P[M+c[E]]):(w=96,k=0),p=1<>U)+(m-=p)]=v<<24|w<<16|k|0}while(0!==m);for(p=1<>=1;if(0!==p?(N&=p-1,N+=p):N=0,E++,0==--F[x]){if(x===T)break;x=t[r+c[E]]}if(x>A&&(N&g)!==y){for(0===U&&(U=A),_+=B,D=1<<(S=x-U);S+U852||2===e&&I>592)return 1;u[y=N&g]=A<<24|S<<16|_-l|0}}return 0!==N&&(u[_+N]=x-U<<24|64<<16|0),f.bits=A,0}},function(e,t,r){"use strict";e.exports=function(){this.text=0,this.time=0,this.xflags=0,this.os=0,this.extra=null,this.extra_len=0,this.name="",this.comment="",this.hcrc=0,this.done=!1}},function(e,t,r){var i=r(41);e.exports={TextEncoder:i.TextEncoder,TextDecoder:i.TextDecoder}},function(e,t,r){!function(t){"use strict";function r(e,t,r){return t<=e&&e<=r}function i(e){if(void 0===e)return{};if(e===Object(e))return e;throw TypeError("Could not convert argument to dictionary")}var n=-1;function o(e){this.tokens=[].slice.call(e),this.tokens.reverse()}o.prototype={endOfStream:function(){return!this.tokens.length},read:function(){return this.tokens.length?this.tokens.pop():n},prepend:function(e){if(Array.isArray(e))for(var t=e;t.length;)this.tokens.push(t.pop());else this.tokens.push(e)},push:function(e){if(Array.isArray(e))for(var t=e;t.length;)this.tokens.unshift(t.shift());else this.tokens.unshift(e)}};var a=-1;function s(e,t){if(e)throw TypeError("Decoder error");return t||65533}function d(e){return e=String(e).trim().toLowerCase(),Object.prototype.hasOwnProperty.call(h,e)?h[e]:null}var h={};[{encodings:[{labels:["unicode-1-1-utf-8","utf-8","utf8"],name:"UTF-8"}],heading:"The Encoding"}].forEach((function(e){e.encodings.forEach((function(e){e.labels.forEach((function(t){h[t]=e}))}))}));var u={},l={};function c(e,t){if(!(this instanceof c))throw TypeError("Called as a function. Did you forget 'new'?");e=void 0!==e?String(e):"utf-8",t=i(t),this._encoding=null,this._decoder=null,this._ignoreBOM=!1,this._BOMseen=!1,this._error_mode="replacement",this._do_not_flush=!1;var r=d(e);if(null===r||"replacement"===r.name)throw RangeError("Unknown encoding: "+e);if(!l[r.name])throw Error("Decoder not present. Did you forget to include encoding-indexes.js?");var n=this;return n._encoding=r,Boolean(t.fatal)&&(n._error_mode="fatal"),Boolean(t.ignoreBOM)&&(n._ignoreBOM=!0),n}function f(e,r){if(!(this instanceof f))throw TypeError("Called as a function. Did you forget 'new'?");r=i(r),this._encoding=null,this._encoder=null,this._do_not_flush=!1,this._fatal=Boolean(r.fatal)?"fatal":"replacement";return this._encoding=d("utf-8"),void 0!==e&&"console"in t&&console.warn("TextEncoder constructor called with encoding label, which is ignored."),this}function p(e){var t=e.fatal,i=0,o=0,d=0,h=128,u=191;this.handler=function(e,l){if(l===n&&0!==d)return d=0,s(t);if(l===n)return a;if(0===d){if(r(l,0,127))return l;if(r(l,194,223))d=1,i=31&l;else if(r(l,224,239))224===l&&(h=160),237===l&&(u=159),d=2,i=15&l;else{if(!r(l,240,244))return s(t);240===l&&(h=144),244===l&&(u=143),d=3,i=7&l}return null}if(!r(l,h,u))return i=d=o=0,h=128,u=191,e.prepend(l),s(t);if(h=128,u=191,i=i<<6|63&l,(o+=1)!==d)return null;var c=i;return i=d=o=0,c}}function m(e){e.fatal;this.handler=function(e,t){if(t===n)return a;if(r(t,0,127))return t;var i,o;r(t,128,2047)?(i=1,o=192):r(t,2048,65535)?(i=2,o=224):r(t,65536,1114111)&&(i=3,o=240);for(var s=[(t>>6*i)+o];i>0;){var d=t>>6*(i-1);s.push(128|63&d),i-=1}return s}}Object.defineProperty&&(Object.defineProperty(c.prototype,"encoding",{get:function(){return this._encoding.name.toLowerCase()}}),Object.defineProperty(c.prototype,"fatal",{get:function(){return"fatal"===this._error_mode}}),Object.defineProperty(c.prototype,"ignoreBOM",{get:function(){return this._ignoreBOM}})),c.prototype.decode=function(e,t){var r;r="object"==typeof e&&e instanceof ArrayBuffer?new Uint8Array(e):"object"==typeof e&&"buffer"in e&&e.buffer instanceof ArrayBuffer?new Uint8Array(e.buffer,e.byteOffset,e.byteLength):new Uint8Array(0),t=i(t),this._do_not_flush||(this._decoder=l[this._encoding.name]({fatal:"fatal"===this._error_mode}),this._BOMseen=!1),this._do_not_flush=Boolean(t.stream);for(var s,d=new o(r),h=[];;){var u=d.read();if(u===n)break;if((s=this._decoder.handler(d,u))===a)break;null!==s&&(Array.isArray(s)?h.push.apply(h,s):h.push(s))}if(!this._do_not_flush){do{if((s=this._decoder.handler(d,d.read()))===a)break;null!==s&&(Array.isArray(s)?h.push.apply(h,s):h.push(s))}while(!d.endOfStream());this._decoder=null}return function(e){var t,r;return t=["UTF-8","UTF-16LE","UTF-16BE"],r=this._encoding.name,-1===t.indexOf(r)||this._ignoreBOM||this._BOMseen||(e.length>0&&65279===e[0]?(this._BOMseen=!0,e.shift()):e.length>0&&(this._BOMseen=!0)),function(e){for(var t="",r=0;r>10),56320+(1023&i)))}return t}(e)}.call(this,h)},Object.defineProperty&&Object.defineProperty(f.prototype,"encoding",{get:function(){return this._encoding.name.toLowerCase()}}),f.prototype.encode=function(e,t){e=e?String(e):"",t=i(t),this._do_not_flush||(this._encoder=u[this._encoding.name]({fatal:"fatal"===this._fatal})),this._do_not_flush=Boolean(t.stream);for(var r,s=new o(function(e){for(var t=String(e),r=t.length,i=0,n=[];i57343)n.push(o);else if(56320<=o&&o<=57343)n.push(65533);else if(55296<=o&&o<=56319)if(i===r-1)n.push(65533);else{var a=t.charCodeAt(i+1);if(56320<=a&&a<=57343){var s=1023&o,d=1023&a;n.push(65536+(s<<10)+d),i+=1}else n.push(65533)}i+=1}return n}(e)),d=[];;){var h=s.read();if(h===n)break;if((r=this._encoder.handler(s,h))===a)break;Array.isArray(r)?d.push.apply(d,r):d.push(r)}if(!this._do_not_flush){for(;(r=this._encoder.handler(s,s.read()))!==a;)Array.isArray(r)?d.push.apply(d,r):d.push(r);this._encoder=null}return new Uint8Array(d)},u["UTF-8"]=function(e){return new m(e)},l["UTF-8"]=function(e){return new p(e)},t.TextEncoder||(t.TextEncoder=f),t.TextDecoder||(t.TextDecoder=c),e.exports&&(e.exports={TextEncoder:t.TextEncoder,TextDecoder:t.TextDecoder})}(this)},function(t,r){t.exports=e},function(e,t,r){"use strict";var i=r(4),n=function(e){this.kdbx=e.kdbx,this.exportXml=e.exportXml||!1};n.prototype.setXmlDate=function(e,t){var r=this.kdbx.header.versionMajor>=4&&!this.exportXml;i.setDate(e,t,r)},e.exports=n},function(e,r){e.exports=t},function(e,t,r){"use strict";var i=r(11),n=r(2),o=r(1),a=r(0),s=r(3);e.exports.decrypt=function(e){return Promise.resolve().then((function(){var t,r=new i(e),d=[],h=0,u=0,l=function(){if(r.getUint32(!0),t=r.readBytes(32),(h=r.getUint32(!0))>0){u+=h;var e=r.readBytes(h);return s.sha256(e).then((function(r){if(a.arrayBufferEquals(r,t))return d.push(e),l();throw new n(o.ErrorCodes.FileCorrupt,"invalid hash block")}))}for(var i=new Uint8Array(u),c=0,f=0;f0){var h=Math.min(1048576,t);t-=h;var u=e.slice(r,r+h);return s.sha256(u).then((function(e){var t=new ArrayBuffer(40),s=new i(t);return s.setUint32(n,!0),s.writeBytes(e),s.setUint32(h,!0),a.push(t),o+=t.byteLength,a.push(u),o+=u.byteLength,n++,r+=h,d()}))}var l=new ArrayBuffer(40);new DataView(l).setUint32(0,n,!0),a.push(l),o+=l.byteLength;for(var c=new Uint8Array(o),f=0,p=0;p0){h+=d;var c=r.readBytes(d);return u(t,s,d,c).then((function(t){if(a.arrayBufferEquals(t,e))return i.push(c),s++,l();throw new n(o.ErrorCodes.FileCorrupt,"invalid hash block")}))}for(var f=new Uint8Array(h),p=0,m=0;m0)return a.push(l),o+=l.byteLength,n++,i+=h,d();for(var u=new Uint8Array(o),c=0,f=0;fthis.nameChanged&&(this._name=e.name,this.nameChanged=e.nameChanged),e.descChanged>this.descChanged&&(this._desc=e.desc,this.descChanged=e.descChanged),e.defaultUserChanged>this.defaultUserChanged&&(this._defaultUser=e.defaultUser,this.defaultUserChanged=e.defaultUserChanged),e.keyChanged>this.keyChanged&&(this.keyChanged=e.keyChanged),e.settingsChanged>this.settingsChanged&&(this.settingsChanged=e.settingsChanged),e.recycleBinChanged>this.recycleBinChanged&&(this._recycleBinEnabled=e.recycleBinEnabled,this._recycleBinUuid=e.recycleBinUuid,this.recycleBinChanged=e.recycleBinChanged),e.entryTemplatesGroupChanged>this.entryTemplatesGroupChanged&&(this._entryTemplatesGroup=e.entryTemplatesGroup,this.entryTemplatesGroupChanged=e.entryTemplatesGroupChanged),Object.keys(e.customData).forEach((function(r){this.customData[r]||t.deleted[r]||(this.customData[r]=e.customData[r])}),this),Object.keys(e.customIcons).forEach((function(r){this.customIcons[r]||t.deleted[r]||(this.customIcons[r]=e.customIcons[r])}),this),this._editState&&this._editState.historyMaxItems||(this.historyMaxItems=e.historyMaxItems),this._editState&&this._editState.historyMaxSize||(this.historyMaxSize=e.historyMaxSize),this._editState&&this._editState.keyChangeRec||(this.keyChangeRec=e.keyChangeRec),this._editState&&this._editState.keyChangeForce||(this.keyChangeForce=e.keyChangeForce),this._editState&&this._editState.mntncHistoryDays||(this.mntncHistoryDays=e.mntncHistoryDays),this._editState&&this._editState.color||(this.color=e.color)},h.create=function(){var e=new Date,t=new h;return t.generator=d.Generator,t.settingsChanged=e,t.mntncHistoryDays=s.Defaults.MntncHistoryDays,t.recycleBinEnabled=!0,t.historyMaxItems=s.Defaults.HistoryMaxItems,t.historyMaxSize=s.Defaults.HistoryMaxSize,t.nameChanged=e,t.descChanged=e,t.defaultUserChanged=e,t.recycleBinChanged=e,t.keyChangeRec=-1,t.keyChangeForce=-1,t.entryTemplatesGroup=new n,t.entryTemplatesGroupChanged=e,t.memoryProtection={title:!1,userName:!1,password:!0,url:!1,notes:!1},t},h.read=function(e,t){for(var r=new h,i=0,n=e.childNodes,o=n.length;ithis.times.lastModTime&&this.copyFrom(t),this.groups=this._mergeCollection(this.groups,t.groups,e),this.entries=this._mergeCollection(this.entries,t.entries,e),this.groups.forEach((function(t){t.merge(e)})),this.entries.forEach((function(t){t.merge(e)})))},u.prototype._mergeCollection=function(e,t,r){var i=[];return e.forEach((function(e){if(!r.deleted[e.uuid]){var t=r.remote[e.uuid];t?t.times.locationChanged<=e.times.locationChanged&&i.push(e):i.push(e)}}),this),t.forEach((function(e,n){if(!r.deleted[e.uuid]){var o=r.objects[e.uuid];if(o&&e.times.locationChanged>o.times.locationChanged)o.parentGroup=this,i.splice(this._findInsertIx(i,t,n),0,o);else if(!o){var a=new e.constructor;a.copyFrom(e),a.parentGroup=this,i.splice(this._findInsertIx(i,t,n),0,a)}}}),this),i},u.prototype._findInsertIx=function(e,t,r){for(var i=e.length,n=-1,o=0;o<=e.length;o++){var a=0,s=r>0?t[r-1].uuid.id:void 0,d=r+10?e[o-1].uuid.id:void 0,u=on&&(i=o,n=a)}return i},u.prototype.copyFrom=function(e){this.uuid=e.uuid,this.name=e.name,this.notes=e.notes,this.icon=e.icon,this.customIcon=e.customIcon,this.times=e.times.clone(),this.expanded=e.expanded,this.defaultAutoTypeSeq=e.defaultAutoTypeSeq,this.enableAutoType=e.enableAutoType,this.enableSearching=e.enableSearching,this.lastTopVisibleEntry=e.lastTopVisibleEntry},u.create=function(e,t){var r=new u;return r.uuid=d.random(),r.icon=o.Icons.Folder,r.times=s.create(),r.name=e,r.parentGroup=t,r.expanded=!0,r.enableAutoType=null,r.enableSearching=null,r.lastTopVisibleEntry=new d,r},u.read=function(e,t,r){for(var i=new u,n=0,o=e.childNodes,a=o.length;n").html(problems.join("
\n")), + }); + } + + if (!verify) { + await this.rpc("/vault/replace", {data: changes}); + await this.model.root.load(); + } + } finally { + framework.unblockUI(); + } + }, + + /** + * Call the right importer in the import wizard onchange of the content field + * + * @private + */ + async _vaultImportWizard() { + const record = this.model.root; + if (record.resModel !== "vault.import.wizard") return; + + // Try to import the file on the fly and store the compatible JSON in the + // crypted_content field for the python backend + const importer = new Importer(); + const data = await importer.import( + await vault.unwrap(record.data.master_key), + record.data.name, + atob(record.data.content) + ); + + if (data) await record.update({crypted_content: JSON.stringify(data)}); + }, + + /** + * Ensure that a vault.right as the shared master_key set + * + * @private + * @param {Object} root + * @param {Object} right + */ + async _vaultEnsureRightKey(root, right) { + if (!root.data.master_key || right.data.key) return; + + const params = {user_id: right.data.user_id[0]}; + const user = await this.rpc("/vault/public", params); + + if (!user || !user.public_key) throw new TypeError("User has no public key"); + + await right.update({ + key: await vault.share(root.data.master_key, user.public_key), + }); + }, + + /** + * Ensures that the master_key of the vault and right lines are set + * + * @private + */ + async _vaultEnsureKeys() { + const root = this.model.root; + if (root.resModel !== "vault") return; + + if (!root.data.master_key) + await root.update({ + master_key: await vault.wrap(await utils.generate_key()), + }); + + if (root.data.right_ids) + for (const right of root.data.right_ids.records) + await this._vaultEnsureRightKey(root, right); + }, + + /** + * Check the model of the form and call the above functions for the right case + * + * @private + * @param {Object} button + */ + async _vaultAction(button) { + if (!utils.supported()) { + await this.dialogService.add(AlertDialog, { + title: _lt("Vault is not supported"), + body: _lt( + "A secure browser context is required. Please switch to " + + "https or contact your administrator" + ), + }); + return false; + } + + const root = this.model.root; + switch (root.resModel) { + case "res.users": + if (button && button.name === "vault_generate_key") { + await this._vaultRegenerateKey(); + return false; + } + break; + case "vault": + if (button && button.name === "vault_reencrypt") { + await this._reencryptVault(false, true); + return false; + } else if (button && button.name === "vault_verify") { + await this._reencryptVault(true, false); + return false; + } + + await this._vaultEnsureKeys(); + break; + + case "vault.send.wizard": + await this._vaultSendWizard(); + break; + + case "vault.store.wizard": + await this._vaultStoreWizard(); + break; + + case "vault.import.wizard": + await this._vaultImportWizard(); + break; + } + + return true; + }, + + /** + * Add the required rpc service to the controller which will be used to + * get/store information from/to the vault controller + */ + setup() { + if (this.props.resModel === "vault" && !utils.supported()) { + this.props.preventCreate = true; + this.props.preventEdit = true; + } + + this._super(...arguments); + this.rpc = useService("rpc"); + }, + + /** + * Hook into the relevant functions + */ + async create() { + const _super = this._super.bind(this); + if (this.model.root.isDirty) await this._vaultAction(); + + const ret = await _super(...arguments); + return ret; + }, + + async onPagerUpdate() { + const _super = this._super.bind(this); + if (this.model.root.isDirty) await this._vaultAction(); + return await _super(...arguments); + }, + + async saveButtonClicked() { + const _super = this._super.bind(this); + if (this.model.root.isDirty) await this._vaultAction(); + return await _super(...arguments); + }, + + async beforeLeave() { + const _super = this._super.bind(this); + if (this.model.root.isDirty) await this._vaultAction(); + return await _super(...arguments); + }, + + async beforeUnload() { + const _super = this._super.bind(this); + if (this.model.root.isDirty) await this._vaultAction(); + return await _super(...arguments); + }, + + async beforeExecuteActionButton(clickParams) { + const _super = this._super.bind(this); + if (clickParams.special !== "cancel") { + const _continue = await this._vaultAction(clickParams); + if (!_continue) return false; + } + + return await _super(...arguments); + }, +}); + +patch(ListController.prototype, "vault", { + setup() { + this._super(...arguments); + if (this.props.resModel === "vault" && !utils.supported()) + this.props.showButtons = false; + }, +}); diff --git a/vault/static/src/backend/export.esm.js b/vault/static/src/backend/export.esm.js new file mode 100644 index 0000000000..f14ac14cec --- /dev/null +++ b/vault/static/src/backend/export.esm.js @@ -0,0 +1,128 @@ +/** @odoo-module alias=vault.export **/ +// © 2021-2024 Florian Kantelberg - initOS GmbH +// License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). + +import {_lt} from "@web/core/l10n/translation"; +import utils from "vault.utils"; + +// This class handles the export to different formats by using a standardize +// JSON formatted data generated by the python backend. +// +// JSON format description: +// +// Entries are represented as objects with the following attributes +// `name`, `uuid`, `url`, `note` +// Specific fields of the entry. `uuid` is used for updating existing records +// `childs` +// Child entries +// `fields`, `files` +// List of encypted fields/files with `name`, `iv`, and `value` +// +export default class VaultExporter { + /** + * Encrypt a field of the above format properly for the backend to store. + * The changes are done inplace. + * + * @private + * @param {CryptoKey} master_key + * @param {Object} node + */ + async _export_json_entry(master_key, node) { + const fields = []; + for (const field of node.fields || []) + fields.push({ + name: field.name, + value: await utils.sym_decrypt(master_key, field.value, field.iv), + }); + + const files = []; + for (const file of node.files || []) + files.push({ + name: file.name, + value: await utils.sym_decrypt(master_key, file.value, file.iv), + }); + + const childs = []; + for (const entry of node.childs || []) + childs.push(await this._export_json_entry(master_key, entry)); + + return { + name: node.name || "", + uuid: node.uuid || null, + url: node.url || "", + note: node.note || "", + childs: childs, + fields: fields, + files: files, + }; + } + + /** + * Decrypt the data fro the JSON export. + * + * @private + * @param {CryptoKey} master_key + * @param {Object} data + * @returns the encrypted entry for the database + */ + async _export_json_data(master_key, data) { + const result = []; + for (const node of data) + result.push(await this._export_json_entry(master_key, node)); + return JSON.stringify(result); + } + + /** + * Export using JSON format. The database is stored in the `data` field of the JSON + * type and is an encrypted JSON object. For the encryption the needed encryption + * parameter `iv`, `salt` and `iterations` are stored in the file. + * This will add `iv` to fields and files and encrypt the `value` + * + * @private + * @param {CryptoKey} master_key + * @param {String} data + * @returns the encrypted entry for the database + */ + async _export_json(master_key, data) { + // Get the password for the exported file from the user + const askpass = await utils.askpass( + _lt("Please enter the password for the database") + ); + let password = askpass.password || ""; + if (askpass.keyfile) + password += await utils.digest(utils.toBinary(askpass.keyfile)); + + const iv = utils.generate_iv_base64(); + const salt = utils.generate_bytes(utils.SaltLength).buffer; + const iterations = utils.Derive.iterations; + const key = await utils.derive_key(password, salt, iterations); + + // Unwrap the master key and decrypt the entries + const content = await this._export_json_data(master_key, JSON.parse(data)); + return { + type: "encrypted", + iv: iv, + salt: utils.toBase64(salt), + data: await utils.sym_encrypt(key, content, iv), + iterations: iterations, + }; + } + + /** + * The main export functions which checks the file ending and calls the right function + * to handle the rest of the export + * + * @private + * @param {CryptoKey} master_key + * @param {String} filename + * @param {String} content + * @returns the data importable by the backend or false on error + */ + async export(master_key, filename, content) { + if (!utils.supported()) return false; + + if (filename.endsWith(".json")) + return await this._export_json(master_key, content); + return false; + } +} diff --git a/vault/static/src/backend/fields/templates.xml b/vault/static/src/backend/fields/templates.xml new file mode 100644 index 0000000000..b5619af48b --- /dev/null +++ b/vault/static/src/backend/fields/templates.xml @@ -0,0 +1,121 @@ + + + +