diff --git a/app/config.json b/app/config.json index 8408c042d745fa2949748bb91940b280932138f2..3315785a01620b5483834d32644c115e824b7e43 100644 --- a/app/config.json +++ b/app/config.json @@ -132,12 +132,12 @@ } }, "node": { - "host": "gtest.duniter.org", - "port": 10900 + "host": "localhost", + "port": 9600 }, "plugins":{ "es": { - "enable": true, + "enable": false, "askEnable": false, "host": "localhost", "port": 9200, diff --git a/scss/ionic.app.scss b/scss/ionic.app.scss index 7616303713b0f2aa6024d4d1d22fe061654adb73..5884fbcb50b64249c37aa88e4de39e61ce994bff 100644 --- a/scss/ionic.app.scss +++ b/scss/ionic.app.scss @@ -654,7 +654,12 @@ $screen-menu: 845px; .button-text-stable { color: #b2b2b2 !important; } - +.popup-buttons .button.icon-right, +.popup-buttons .button.icon-left { + padding-left: 32px !important; + padding-right: 32px !important; + line-height: 42px; +} /* ============ Home page =============== */ diff --git a/www/css/ionic.app.css b/www/css/ionic.app.css index f12bcce9cf80c13cf24ad7ec0876c6d3718b3885..5c5c5ec4e27a706e54e96052657784578df382d3 100644 --- a/www/css/ionic.app.css +++ b/www/css/ionic.app.css @@ -14144,6 +14144,12 @@ a { .button-text-stable { color: #b2b2b2 !important; } +.popup-buttons .button.icon-right, +.popup-buttons .button.icon-left { + padding-left: 32px !important; + padding-right: 32px !important; + line-height: 42px; } + /* ============ Home page =============== */ diff --git a/www/css/style.css b/www/css/style.css index bfee1d6854f79f69fdf8b1e0030cc67b1867f3e1..9b02869e0ba114c204a971564139afee44e3d068 100644 --- a/www/css/style.css +++ b/www/css/style.css @@ -37,6 +37,10 @@ color: grey; } +#modal-license { + color:rgb(0, 0, 0); +} + .bar .button.button-clear { font-size: 12px !important; font-weight: 300 !important; @@ -205,3 +209,4 @@ .item-block.item-block-empty.compacted { border-bottom: double 1px #eee !important; } + diff --git a/www/i18n/locale-en-GB.json b/www/i18n/locale-en-GB.json index f9d3b2ec2e7ab38c7af99c5e8154bcc0a8e38873..d4c409be32b9e633f47c5d4dccd9373f982f87bd 100644 --- a/www/i18n/locale-en-GB.json +++ b/www/i18n/locale-en-GB.json @@ -35,6 +35,8 @@ "BTN_OPTIONS": "Options", "BTN_HELP_TOUR": "Features tour", "BTN_HELP_TOUR_SCREEN": "Discover this screen", + "BTN_DOWNLOAD": "Download", + "BTN_MODIFY": "Modify", "DAYS": "days", "NO_ACCOUNT_QUESTION": "Not a member yet? Register now!", "SEARCH_NO_RESULT": "No result found", @@ -396,8 +398,9 @@ "LAST_SLIDE_CONGRATULATION": "You completed all required fields.<br/><b>You can send the account creation request</b>.<br/><br/>For information, the public key below identifies your future account.<br/>It can be communicated to third parties to receive their payment.<br/>Once your account has been approved, you can find this key under <b>{{'ACCOUNT.TITLE'|translate}}</b>.", "CONFIRMATION_MEMBER_ACCOUNT": "<b class=\"assertive\">Warning:</b> your secret identifier, password and pseudonym can not be changed.<br/><b>Make sure you always remember it!</b><br/><b>Are you sure</b> you want to send this account creation request?", "CONFIRMATION_WALLET_ACCOUNT": "<b class=\"assertive\">Warning:</b> your password and pseudonym can not be changed.<br/><b>Make sure you always remember it!</b><br/><b>Are you sure</b> you want to continue?", - "MSG_UID_ALREADY_USED": "This pseudonym is already used by an existing member.<br/>Please choose another one.", - "MSG_PUBKEY_ALREADY_USED": "Public key already used by an existing member.<br/>Please choose other connection parameters." + "PSEUDO_AVAILABLE": "This nickname is available", + "PSEUDO_NOT_AVAILABLE": "This nickname is not available", + "INFO_LICENSE": "To be able to adhere to the currency, we ask you to kindly read and accept this license." }, "POPUP_REGISTER": { "TITLE": "Enter a pseudonym", @@ -435,6 +438,7 @@ "QUESTION_19": "What was your grand-father's job ?", "RECOVER_ID": "Recover your password", "REVOCATION": "Revocation ...", + "REVOCATION_SAVE": "revocation", "REVOKE" : "Revoke this identity", "REVOKE_WITH_FILE" : "Rekoke this identity with a file", "SAVE_ID": "Save your login", @@ -531,7 +535,9 @@ "SALT_OR_PASSWORD_NOT_CONFIRMED": "Wrong secret identifier or password ", "RECOVER_ID_FAILED": "Could not recover password", "LOAD_FILE_FAILED" : "Unable to load file", - "ONLY_TEXT_FILE": "You have to select a text file" + "ONLY_TEXT_FILE": "You have to select a text file", + "EXISTING_ACCOUNT": "Your identifiers correspond to an already existing account, whose <a ng-click=\"showHelpModal('pubkey')\">public key</a> is:", + "EXISTING_ACCOUNT_REQUEST": "Please modify your credentials so that they correspond to an unused account." }, "INFO": { "POPUP_TITLE": "Information", @@ -565,7 +571,12 @@ "NOT_NEED_RENEW_MEMBERSHIP": "Your membership does not need to be renewed (it will only expire in {{membershipExpiresIn|formatDuration}}).<br/></br/><b>Are you sure you</b> want to renew your membership?", "SAVE_BEFORE_LEAVE": "Do you want to <b>save your changes</b> before leaving the page?", "SAVE_BEFORE_LEAVE_TITLE": "Changes not saved", - "LOGOUT": "Are you sure you want to logout?" + "LOGOUT": "Are you sure you want to logout?", + "LICENCE": "I declare that I have read and accepted the conditions of the license Äž1" + }, + "DOWNLOAD": { + "POPUP_TITLE": "<b>Revocation file</b>", + "POPUP_REVOKE_MESSAGE": "The revocation file now needs to be retrieved by clicking on the button below.</br></br>The revocation file allows you to cancel your account (in the event of an account theft, A change of identifier, an incorrectly created account etc.), it is therefore<b> important to store it in place on.</b>" }, "HELP": { "TITLE": "Online help", @@ -577,7 +588,7 @@ }, "GLOSSARY": { "SECTION": "Glossary", - "PUBKEY_DEF": "A public key always identifies a wallet. It may identify a member.", + "PUBKEY_DEF": "A public key always identifies a wallet. It may identify a member. In Cesium it is calculated using the secret identifier and the password.", "MEMBER": "Member", "MEMBER_DEF": "A member is a real and living human, wishing to participate freely to the monitary community. The member will receive universal dividend, according to the period and amount as defined in the <span class=\"text-italic\">currency parameters</span>.", "CURRENCY_RULES": "Currency rules", diff --git a/www/i18n/locale-en.json b/www/i18n/locale-en.json index 227a2c7e6d321ac6676034b60d97fcb38bac94c2..9047699397ac8baf24929b77a5f0e0fa10d27122 100644 --- a/www/i18n/locale-en.json +++ b/www/i18n/locale-en.json @@ -35,6 +35,8 @@ "BTN_OPTIONS": "Options", "BTN_HELP_TOUR": "Features tour", "BTN_HELP_TOUR_SCREEN": "Discover this screen", + "BTN_DOWNLOAD": "Download", + "BTN_MODIFY": "Modify", "DAYS": "days", "NO_ACCOUNT_QUESTION": "Not a member yet? Register now!", "SEARCH_NO_RESULT": "No result found", @@ -396,8 +398,9 @@ "LAST_SLIDE_CONGRATULATION": "You completed all required fields.<br/><b>You can send the account creation request</b>.<br/><br/>For information, the public key below identifies your future account.<br/>It can be communicated to third parties to receive their payment.<br/>Once your account has been approved, you can find this key under <b>{{'ACCOUNT.TITLE'|translate}}</b>.", "CONFIRMATION_MEMBER_ACCOUNT": "<b class=\"assertive\">Warning:</b> your secret identifier, password and pseudonym can not be changed.<br/><b>Make sure you always remember it!</b><br/><b>Are you sure</b> you want to send this account creation request?", "CONFIRMATION_WALLET_ACCOUNT": "<b class=\"assertive\">Warning:</b> your password and pseudonym can not be changed.<br/><b>Make sure you always remember it!</b><br/><b>Are you sure</b> you want to continue?", - "MSG_UID_ALREADY_USED": "This pseudonym is already used by an existing member.<br/>Please choose another one.", - "MSG_PUBKEY_ALREADY_USED": "Public key already used by an existing member.<br/>Please choose other connection parameters." + "PSEUDO_AVAILABLE": "This nickname is available", + "PSEUDO_NOT_AVAILABLE": "This nickname is not available", + "INFO_LICENSE": "To be able to adhere to the currency, we ask you to kindly read and accept this license." }, "POPUP_REGISTER": { "TITLE": "Enter a pseudonym", @@ -435,6 +438,7 @@ "QUESTION_19": "What was your grand-father's job ?", "RECOVER_ID": "Recover your password", "REVOCATION": "Revocation ...", + "REVOCATION_SAVE": "revocation", "REVOKE" : "Revoke this identity", "REVOKE_WITH_FILE" : "Rekoke this identity with a file", "SAVE_ID": "Save your login", @@ -531,7 +535,9 @@ "SALT_OR_PASSWORD_NOT_CONFIRMED": "Wrong secret identifier or password ", "RECOVER_ID_FAILED": "Could not recover password", "LOAD_FILE_FAILED" : "Unable to load file", - "ONLY_TEXT_FILE": "You have to select a text file" + "ONLY_TEXT_FILE": "You have to select a text file", + "EXISTING_ACCOUNT": "Your identifiers correspond to an already existing account, whose <a ng-click=\"showHelpModal('pubkey')\">public key</a> is:", + "EXISTING_ACCOUNT_REQUEST": "Please modify your credentials so that they correspond to an unused account." }, "INFO": { "POPUP_TITLE": "Information", @@ -565,7 +571,12 @@ "NOT_NEED_RENEW_MEMBERSHIP": "Your membership does not need to be renewed (it will only expire in {{membershipExpiresIn|formatDuration}}).<br/></br/><b>Are you sure you</b> want to renew your membership?", "SAVE_BEFORE_LEAVE": "Do you want to <b>save your changes</b> before leaving the page?", "SAVE_BEFORE_LEAVE_TITLE": "Changes not saved", - "LOGOUT": "Are you sure you want to logout?" + "LOGOUT": "Are you sure you want to logout?", + "LICENCE": "I declare that I have read and accepted the conditions of the license Äž1" + }, + "DOWNLOAD": { + "POPUP_TITLE": "<b>Revocation file</b>", + "POPUP_REVOKE_MESSAGE": "The revocation file now needs to be retrieved by clicking on the button below.</br></br>The revocation file allows you to cancel your account (in the event of an account theft, A change of identifier, an incorrectly created account etc.), it is therefore<b> important to store it in place on.</b>" }, "HELP": { "TITLE": "Online help", @@ -577,7 +588,7 @@ }, "GLOSSARY": { "SECTION": "Glossary", - "PUBKEY_DEF": "A public key always identifies a wallet. It may identify a member.", + "PUBKEY_DEF": "A public key always identifies a wallet. It may identify a member. In Cesium it is calculated using the secret identifier and the password.", "MEMBER": "Member", "MEMBER_DEF": "A member is a real and living human, wishing to participate freely to the monitary community. The member will receive universal dividend, according to the period and amount as defined in the <span class=\"text-italic\">currency parameters</span>.", "CURRENCY_RULES": "Currency rules", diff --git a/www/i18n/locale-es-ES.json b/www/i18n/locale-es-ES.json index 5ebb46e6ae0fd0088627ee1acfcdb589ef061146..259f5e38e7dde2ff5d6c08f77be8c3559c4e7661 100644 --- a/www/i18n/locale-es-ES.json +++ b/www/i18n/locale-es-ES.json @@ -35,6 +35,8 @@ "BTN_OPTIONS": "Opciónes", "BTN_HELP_TOUR": "Visita guiada", "BTN_HELP_TOUR_SCREEN": "Descubrir esta pantalla", + "BTN_DOWNLOAD": "Descargar", + "BTN_MODIFY": "Cambio", "DAYS": "Dias", "NO_ACCOUNT_QUESTION": "TodavÃa no miembre ? Creer una cuenta !", "SEARCH_NO_RESULT": "Ninguno resultado encontrado", @@ -381,8 +383,9 @@ "LAST_SLIDE_CONGRATULATION": "<b>Bravo !</b> Ha introducido todas las informaciónes necesarias.<br/><b>Puede mandar la solicitud</b> de creación de su cuenta.</b><br/><br/>Por su información, la llave pública más abajo identificará su cuenta futura.<br/>Podrá estar comunicada a terceros para recibir sus pagos.<br/>Sin embargo, <b>no es útil</b> anotarla aquÃ.", "CONFIRMATION_MEMBER_ACCOUNT": "<b class=\"assertive\">Advertencia :</b> el identificador secreto, la contraseña y el seudónimo no podrán estar modificados.<br/><b>Asegurase siempre se los recordar !</b><br/><br/><b>Está usted seguro</b> querer mandar esta solicitud de inscripción ?", "CONFIRMATION_WALLET_ACCOUNT": "<b class=\"assertive\">Advertencia :</b> el identificador secreto y la contraseña no podrán estar modificados.<br/><b>Asegurase siempre se los recordar !</b><br/><br/><b>Está usted seguro</b> querer continuar con estos identificadores ?", - "MSG_UID_ALREADY_USED": "Seudónimo ya utilizado por una otra persona.<br/>Elige un otro por favor.", - "MSG_PUBKEY_ALREADY_USED": "Llave pública ya utilizada por una otra persona.<br/>Elige otros identificadores de conexión por favor." + "PSEUDO_AVAILABLE": "Este nombre está disponible", + "PSEUDO_NOT_AVAILABLE": "Este nombre de usuario no está disponible", + "INFO_LICENSE": "Para unirse a la moneda, le pedimos que leer y aceptar esta licencia." }, "POPUP_REGISTER": { "TITLE": "Elige un seudónimo", @@ -420,6 +423,7 @@ "QUESTION_19": "Cuál fue el oficio de su abuelo ?", "RECOVER_ID": "Recuperar sus identificadores", "REVOCATION": "Revocación ...", + "REVOCATION_SAVE": "revocacion", "REVOKE": "Revocar esta identidad", "REVOKE_WITH_FILE": "Revocar una identidad a partir de un fichero", "SAVE_ID": "Salvar sus identificadores", @@ -516,7 +520,9 @@ "SALT_OR_PASSWORD_NOT_CONFIRMED": "Identificador secreto o contraseña incorrectos", "RECOVER_ID_FAILED": "Fracaso en la recuperación de los identificadores", "LOAD_FILE_FAILED" : "Fracaso en la carga del fichero", - "ONLY_TEXT_FILE": "Debe seleccionar un fichero texto" + "ONLY_TEXT_FILE": "Debe seleccionar un fichero texto", + "EXISTING_ACCOUNT": "Su contraseña corresponde a una cuenta existente, la <a ng-click=\"showHelpModal('pubkey')\">clave pública</a> es:", + "EXISTING_ACCOUNT_REQUEST": "Por favor, cambie su contraseña para que coincida con una cuenta sin usar." }, "INFO": { "POPUP_TITLE": "Información", @@ -550,7 +556,12 @@ "NOT_NEED_RENEW_MEMBERSHIP": "Su adhesión no necesita estar renovada (solo va a caducar en {{membershipExpiresIn|formatDuration}}).<br/></br/><b>Está usted seguro</b> querer renovar su adhesión ?", "SAVE_BEFORE_LEAVE": "Quiere usted <b>guardar sus modificaciónes</b> antes dejar la página ?", "SAVE_BEFORE_LEAVE_TITLE": "Modificaciónes no registradas", - "LOGOUT": "Está usted seguro querer desconectarse ?" + "LOGOUT": "Está usted seguro querer desconectarse ?", + "LICENCE": "He leÃdo y acepto las condiciones de la licencia G1" + }, + "DOWNLOAD": { + "POPUP_TITLE": "<b>Revocación del archivo</b>", + "POPUP_REVOKE_MESSAGE": "Ahora tenemos que recuperar el archivo de revocación, puede descargarlo haciendo clic en el botón de abajo.</br></br>El archivo de revocación, se cancelará su cuenta (en caso de robo de cuenta, un cambio de identificador, una cuenta falsamente creado etc.), por lo que es<b> importante para almacenarlo en un lugar seguro.</b>" }, "HELP": { "TITLE": "Ayuda en lÃnea", @@ -562,7 +573,7 @@ }, "GLOSSARY": { "SECTION": "Glosario", - "PUBKEY_DEF": "Una llave pública identifica un monedero. Puede identificar un miembro", + "PUBKEY_DEF": "Una llave pública identifica un monedero. Puede identificar un miembro. En Cesium se calcula con el identificador y la contraseña secreta.", "MEMBER": "Miembro", "MEMBER_DEF": "Un miembro es una persona humana fÃsica y viva, deseosa de participar libremente a la comunidad monetaria. Percibe un dividendo universal, dependiendo de un perÃodo y un importe como definido en las <span class=\"text-italic\">reglas de la moneda</span>", "CURRENCY_RULES": "Reglas de la moneda", diff --git a/www/i18n/locale-fr-FR.json b/www/i18n/locale-fr-FR.json index ebb2acbdb6ccf4eca180b9c5266c9ad44ba26f25..e7a2652b6f96d0e9a8818d51b40657f320cd870a 100644 --- a/www/i18n/locale-fr-FR.json +++ b/www/i18n/locale-fr-FR.json @@ -35,6 +35,8 @@ "BTN_OPTIONS": "Options", "BTN_HELP_TOUR": "Visite guidée", "BTN_HELP_TOUR_SCREEN": "Découvrir cet écran", + "BTN_DOWNLOAD": "Télécharger", + "BTN_MODIFY": "Modifier", "DAYS": "jours", "NO_ACCOUNT_QUESTION": "Pas de encore membre ? Créer un compte !", "SEARCH_NO_RESULT": "Aucun résultat trouvé", @@ -396,8 +398,10 @@ "LAST_SLIDE_CONGRATULATION": "<b>Bravo !</b> Vous avez saisi toutes les informations nécessaires.<br/><b>Vous pouvez envoyer la demande</b> de création de compte.</b><br/><br/>Pour information, la clé publique ci-dessous identifiera votre futur compte.<br/>Elle pourra être communiquée à des tiers pour recevoir leur paiement.<br/>Cependant, <b>il n'est pas utile</b> de la noter ici.", "CONFIRMATION_MEMBER_ACCOUNT": "<b class=\"assertive\">Avertissement :</b> l'identifiant secret, le mot de passe et le pseudonyme ne pourront plus être modifiés.<br/><b>Assurez-vous de toujours vous en rappeller !</b><br/><br/><b>Etes-vous sûr</b> de vouloir envoyer cette demande d'inscription ?", "CONFIRMATION_WALLET_ACCOUNT": "<b class=\"assertive\">Avertissement :</b> l'identifiant secret et le mot de passe ne pourront plus être modifiés.<br/><b>Assurez-vous de toujours vous en rappeller !</b><br/><br/><b>Etes-vous sûr</b> de vouloir continuer avec ces identifiants ?", - "MSG_UID_ALREADY_USED": "Pseudonyme déjà utilisé par quelqu'un d'autre.<br/>Veuillez en choisir un autre.", - "MSG_PUBKEY_ALREADY_USED": "Clé publique déjà utilisée par quelqu'un d'autre.<br/>Veuillez choisir d'autres identifiants de connexion." + "PSEUDO_AVAILABLE": "Ce pseudo est disponible", + "PSEUDO_NOT_AVAILABLE": "Ce pseudo n'est pas disponible", + "INFO_LICENSE": "Pour pouvoir adhérer à la monnaie, nous vous demandons de bien vouloir lire et accepter cette licence." + }, "POPUP_REGISTER": { "TITLE": "Choisissez un pseudonyme", @@ -435,6 +439,7 @@ "QUESTION_19": "Quel était le métier de votre grand-père ?", "RECOVER_ID": "Recupérer vos identifiants", "REVOCATION": "Révocation ...", + "REVOCATION_FILENAME": "revocation-{{uid}}-{{pubkey|formatPubkey}}-{{currency}}.txt", "REVOKE": "Révoquer cette identité", "REVOKE_WITH_FILE": "Révoquer une identité à partir d'un fichier", "SAVE_ID": "Sauvegarder vos identifiants", @@ -523,15 +528,9 @@ "UNABLE_TO_CERTIFY_TITLE": "Certification impossible", "LOAD_NEWCOMERS_FAILED": "Echec du chargement des nouveaux membres.", "LOAD_PENDING_FAILED": "Echec du chargement des inscriptions en attente.", - "ONLY_MEMBER_CAN_EXECUTE_THIS_ACTION": "Vous devez <b>être membre</b> pour pouvoir effectuer cette action.", - "ONLY_SELF_CAN_EXECUTE_THIS_ACTION": "Vous devez avoir <b>publié votre identité</b> pour pouvoir effectuer cette action.", - "GET_BLOCK_FAILED": "Echec de la récupération du bloc", - "INVALID_BLOCK_HASH": "Bloc non trouvé (hash différent)", - "REVOCATION_FAILED": "Echec de la révocation.", - "SALT_OR_PASSWORD_NOT_CONFIRMED": "Identifiant secret ou mot de passe incorrects", - "RECOVER_ID_FAILED": "Echec de la récupération des identifiants", - "LOAD_FILE_FAILED" : "Echec du chargement du fichier", - "ONLY_TEXT_FILE": "Vous devez selectionner un fichier texte" + "ONLY_MEMBER_CAN_EXECUTE_THIS_ACTION": "Vous devez <b>être membre</b> pour pouvoir effectuerTING", + "EXISTING_ACCOUNT": "Vos identifiants correspondent à un compte déjà existant, dont la <a ng-click=\"showHelpModal('pubkey')\">clef publique</a> est :", + "EXISTING_ACCOUNT_REQUEST": "Veuillez modifier vos identifiants afin qu'ils correspondent à un compte non utilisé." }, "INFO": { "POPUP_TITLE": "Information", @@ -565,7 +564,12 @@ "NOT_NEED_RENEW_MEMBERSHIP": "Votre adhésion n'a pas besoin d'être renouvellée (elle n'expirera que dans {{membershipExpiresIn|formatDuration}}).<br/></br/><b>Etes-vous sûr</b> de vouloir renouveler votre adhésion ?", "SAVE_BEFORE_LEAVE": "Voulez-vous <b>sauvegarder vos modifications</b> avant de quitter la page ?", "SAVE_BEFORE_LEAVE_TITLE": "Modifications non enregistrées", - "LOGOUT": "Etes-vous de vouloir vous déconnecter ?" + "LOGOUT": "Etes-vous de vouloir vous déconnecter ?", + "LICENCE": "Je déclare avoir lu et accepté les conditions de la licence Äž1" + }, + "DOWNLOAD": { + "POPUP_TITLE": "<b>Fichier de révocation</b>", + "POPUP_REVOKE_MESSAGE": "Il faut maintenant récupérer le fichier de révocation, veuillez le télécharger en cliquant sur le boutton ci-dessous.</br></br> Le fichier de révocation permet d'annuler son compte (en cas d'un vol de compte, d'un changement d'identifiant, d'un compte créé à tort etc.), il est donc <b>important de le stocker en lieu sûr</b>." }, "HELP": { "TITLE": "Aide en ligne", @@ -577,7 +581,7 @@ }, "GLOSSARY": { "SECTION": "Glossaire", - "PUBKEY_DEF": "Une clé publique identifie un portefeuille de monnaie. Il peut identifier un membre", + "PUBKEY_DEF": "Une clé publique identifie un portefeuille de monnaie. Il peut identifier un membre. Dans Cesium elle est calculée grâce à l'identifiant secret et au mot de passe.", "MEMBER": "Membre", "MEMBER_DEF": "Un membre est une personne humaine physique et vivante, désireuse de participer librement à la communauté monétaire. Elle percoit un dividende universel, suivant une période et un montant tels que définis dans les <span class=\"text-italic\">règles de la monnaie</span>", "CURRENCY_RULES": "Règles de la monnaie", diff --git a/www/i18n/locale-nl-NL.json b/www/i18n/locale-nl-NL.json index 5e4b1199b7214c5bceaab19c86a3ab885de8f695..bb27b7ac137b948bf5b31eb419d86c1b7f2394c9 100644 --- a/www/i18n/locale-nl-NL.json +++ b/www/i18n/locale-nl-NL.json @@ -35,6 +35,8 @@ "BTN_OPTIONS": "Opties", "BTN_HELP_TOUR": "Rondleiding", "BTN_HELP_TOUR_SCREEN": "Ontdek dit scherm", + "BTN_DOWNLOAD": "Downloaden", + "BTN_MODIFY": "Bewerken", "DAYS": "dagen", "NO_ACCOUNT_QUESTION": "Nog geen lid? Registreer nu!", "SEARCH_NO_RESULT": "Geen resultaten", @@ -335,8 +337,9 @@ "LAST_SLIDE_CONGRATULATION": "Bravo! Je hebt alle verplichte velden ingevuld.<br/>Je kunt je <b>rekeningaanvraag verzenden</b>.<br/><br/>Ter informatie, de publieke sleutel hieronder identificeert je toekomstige rekening.<br/>Je kunt deze aan derde partijen communiceren om geld te ontvangen. Zodra je rekening geopend is, kun je de sleutel terugvinden onder <b>{{'ACCOUNT.TITLE'|translate}}</b>.", "CONFIRMATION_MEMBER_ACCOUNT": "<b class=\"assertive\">Waarschuwing:</b> je beveiligingszin, wachtwoord en pseudoniem kunnen hierna niet gewijzigd worden.<br/><b>Zorg dat ze goed onthoudt!</b><br/><b>Weet je zeker</b> dat je je persoonlijke rekeningaanvraag wil verzenden?", "CONFIRMATION_WALLET_ACCOUNT": "<b class=\"assertive\">Waarschuwing:</b> je wachtwoord en pseudoniem kunnen hierna niet gewijzigd worden.<br/><b>Zorg dat ze goed onthoudt!</b><br/><b>Weet je zeker</b> dat je deze portefeilleaanvraag wil verzenden?", - "MSG_UID_ALREADY_USED": "Deze pseudoniem is al in gebruik door een bestaand lid.<br/>Kies een andere.", - "MSG_PUBKEY_ALREADY_USED": "Publieke sleutel komt overeen met die van een bestaand lid.<br/>Kies andere verbindingsparameters." + "PSEUDO_AVAILABLE": "Deze naam is beschikbaar", + "PSEUDO_NOT_AVAILABLE": "Deze gebruikersnaam is niet beschikbaar", + "INFO_LICENSE": "Om de valuta te sluiten, vragen wij u om te lezen en deze licentie te accepteren." }, "POPUP_REGISTER": { "TITLE": "Voer een pseudoniem in", @@ -420,7 +423,9 @@ "LOAD_NEWCOMERS_FAILED": "Unable to load new members.", "LOAD_PENDING_FAILED": "Unable to load pending registrations.", "ONLY_MEMBER_CAN_EXECUTE_THIS_ACTION": "You must <b>be a member</b> in order to perform this action.", - "ONLY_SELF_CAN_EXECUTE_THIS_ACTION": "You must have <b>published your identity</b> in order to perform this action." + "ONLY_SELF_CAN_EXECUTE_THIS_ACTION": "You must have <b>published your identity</b> in order to perform this action.", + "EXISTING_ACCOUNT": "Uw wachtwoord overeenkomen met een bestaande account, de <a ng-click=\"showHelpModal('pubkey')\">publieke sleutel</a> is:", + "EXISTING_ACCOUNT_REQUEST": "Gelieve uw wachtwoord wijzigen om een ongebruikte account." }, "INFO": { "POPUP_TITLE": "Informatie", @@ -448,7 +453,12 @@ "REVOKE_IDENTITY_2": "Deze handeling is <b>niet terug te draaien</b>!<br/><br/><b>Weet je zeker</b> dat je door wil gaan?", "NOT_NEED_RENEW_MEMBERSHIP": "Je lidmaatschap hoeft niet verlengd te worden (het zal pas verlopen na {{membershipExpiresIn|formatDuration}}).<br/></br/><b>Weet je zeker</b> dat je een verlengingsaanvraag wil versturen?", "SAVE_BEFORE_LEAVE": "Wil je <b>je wijzigingen opslaan</b> voor je de pagina verlaat?", - "SAVE_BEFORE_LEAVE_TITLE": "Wijzigingen niet opgeslagen" + "SAVE_BEFORE_LEAVE_TITLE": "Wijzigingen niet opgeslagen", + "LICENCE": "Ik heb gelezen en geaccepteerd de voorwaarden van de vergunning G1" + }, + "DOWNLOAD": { + "POPUP_TITLE": "<b>Intrekking File</b>", + "POPUP_REVOKE_MESSAGE": "We moeten nu herstellen van de herroeping bestand, dan kunt u downloaden door te klikken op de onderstaande knop.</br></br>De herroeping bestand zullen hun rekening (in het geval van de rekening van diefstal te annuleren, een verandering van de identifier, een ten onrechte gemaakte account etc.), dus het is<b> belangrijk om het op te slaan op een veilige plaats.</b>" }, "HELP": { "TITLE": "Online help", @@ -460,7 +470,7 @@ }, "GLOSSARY": { "SECTION": "Glossary", - "PUBKEY_DEF": "A public key always identifies a wallet. It may identify a member.", + "PUBKEY_DEF": "Een publieke sleutel identificeert altijd een portemonnee. Het kan een lid identificeren. In Cesium wordt berekend met de geheime ID en wachtwoord.", "MEMBER": "Member", "MEMBER_DEF": "A member is a real and living human, wishing to participate freely to the monitary community. The member will receive universal dividend, according to the period and amount as defined in the <span class=\"text-italic\">currency parameters</span>.", "CURRENCY_RULES": "Currency rules", diff --git a/www/js/config.js b/www/js/config.js index 1d6543f6ef2f33d1094a7bab52a87f13f40fe293..1fc8fc211afcc672b0547ea5a190c7c51c5107b5 100644 --- a/www/js/config.js +++ b/www/js/config.js @@ -10,33 +10,41 @@ angular.module("cesium.config", []) .constant("csConfig", { "cacheTimeMs": 60000, - "fallbackLanguage": "en", + "fallbackLanguage": "fr-FR", + "defaultLanguage": "fr-FR", "rememberMe": true, "showUDHistory": false, - "timeout": 10000, + "timeout": 6000, "timeWarningExpireMembership": 5184000, "timeWarningExpire": 7776000, "useLocalStorage": true, - "useRelative": false, - "initPhase": false, + "useRelative": true, "expertMode": true, "decimalCount": 2, - "httpsMode": false, "helptip": { "enable": false, - "installDocUrl": "https://github.com/duniter/duniter/blob/master/doc/install-a-node.md" + "installDocUrl": { + "fr-FR": "http://www.le-sou.org/devenir-noeud/", + "en": "https://github.com/duniter/duniter/blob/master/doc/install-a-node.md" + } }, "node": { - "host": "g1.duniter.org", - "port": "443" + "host": "localhost", + "port": 9600 }, "plugins": { "es": { - "enable": true, + "enable": false, "askEnable": false, "host": "localhost", - "port": "9200", - "wsPort": "9400" + "port": 9200, + "wsPort": 9400, + "notifications": { + "txSent": true, + "txReceived": true, + "certSent": true, + "certReceived": true + } }, "graph": { "enable": true @@ -46,7 +54,7 @@ angular.module("cesium.config", []) } }, "version": "0.12.2", - "build": "2017-05-09T14:47:38.758Z", + "build": "2017-05-15T09:21:45.439Z", "newIssueUrl": "https://github.com/duniter/cesium/issues/new?labels=bug" }) diff --git a/www/js/controllers/app-controllers.js b/www/js/controllers/app-controllers.js index e2384e58181ba91c5cfea0135350cd557eb1a0d5..81328cc445716c4664a0f2334ad4a3afb1ac1ce5 100644 --- a/www/js/controllers/app-controllers.js +++ b/www/js/controllers/app-controllers.js @@ -205,17 +205,22 @@ function AppController($scope, $rootScope, $state, $ionicSideMenuDelegate, $q, $ // Warn if wallet has been never used - see #167 var showAlert = !csConfig.initPhase && csWallet.isNeverUsed() && (!csSettings.data.wallet || csSettings.data.wallet.alertIfUnusedWallet); if (!showAlert) return walletData; - return UIUtils.loading.hide() - .then(function(){ - return UIUtils.alert.confirm('CONFIRM.LOGIN_UNUSED_WALLET', 'CONFIRM.LOGIN_UNUSED_WALLET_TITLE', - { - okText: 'COMMON.BTN_CONTINUE' - }); - }) - .then(function(confirm) { - if (confirm) return walletData; - return csWallet.logout(); - }); + if($rootScope.accountType === "member"){ + return UIUtils.loading.hide() + .then(function(){ + return UIUtils.alert.confirm('CONFIRM.LOGIN_UNUSED_WALLET', 'CONFIRM.LOGIN_UNUSED_WALLET_TITLE', + { + okText: 'COMMON.BTN_CONTINUE' + }); + }) + .then(function(confirm) { + if (confirm) return walletData; + return csWallet.logout(); + }); + } + else{ + return walletData; + } }) .then(function(walletData) { @@ -392,7 +397,19 @@ function AppController($scope, $rootScope, $state, $ionicSideMenuDelegate, $q, $ $scope.showJoinModal = function() { $scope.closeProfilePopover(); - return Modals.showJoin(); + return Modals.showJoin() + .then(function(res){ + if (!res) return; + if (res === 'member'){ + $rootScope.accountType = 'member'; + Modals.showJoinMember(); + $rootScope.startLicenceRead(); + } + else if (res === 'wallet'){ + $rootScope.accountType = 'wallet'; + Modals.showJoinWallet(); + } + }); }; $scope.showSettings = function() { diff --git a/www/js/controllers/join-controllers.js b/www/js/controllers/join-controllers.js index ec1c7ca49c61ec6225763803990113a6572d1c19..69038836048f8d60b9edcef17e3046568cbcf0c6 100644 --- a/www/js/controllers/join-controllers.js +++ b/www/js/controllers/join-controllers.js @@ -1,4 +1,3 @@ - angular.module('cesium.join.controllers', ['cesium.services']) .config(function($stateProvider) { @@ -36,7 +35,7 @@ function JoinController($timeout, Modals) { } -function JoinModalController($scope, $state, UIUtils, CryptoUtils, csSettings, Modals, csWallet, csCurrency, BMA) { +function JoinModalController($scope, $state, $interval, $rootScope, UIUtils, CryptoUtils, csSettings, Modals, csWallet, csCurrency, BMA) { 'ngInject'; $scope.formData = { @@ -54,8 +53,11 @@ function JoinModalController($scope, $state, UIUtils, CryptoUtils, csSettings, $scope.search = { looking: true }; + + $scope.isLicenceRead = false; $scope.showUsername = false; $scope.showPassword = false; + $scope.formData.computing=false; $scope.smallscreen = UIUtils.screen.isSmall(); $scope.userIdPattern = BMA.constants.regex.USER_ID; @@ -98,6 +100,7 @@ function JoinModalController($scope, $state, UIUtils, CryptoUtils, csSettings, .then(function(keypair) { $scope.formData.pubkey = CryptoUtils.util.encode_base58(keypair.signPk); $scope.formData.computing=false; + $scope.checkAccountAvailable(); }) .catch(function(err) { $scope.formData.computing=false; @@ -113,37 +116,45 @@ function JoinModalController($scope, $state, UIUtils, CryptoUtils, csSettings, $scope.doNext = function(formName) { console.debug("[join] form " + formName + " OK. index=" + $scope.slides.slider.activeIndex); - if (!formName) { - formName = $scope.slides.slider.activeIndex === 2 ? 'saltForm' : - ($scope.slides.slider.activeIndex === 3 ? 'passwordForm' : ($scope.slides.slider.activeIndex === 4 ? 'pseudoForm' : formName)); + if($rootScope.accountType === 'member'){ + if (formName) { + if((formName === 'pseudoForm') || + (formName === 'saltForm') || + (formName === 'passwordForm')){ + $scope[formName].$submitted=true; + if(!$scope[formName].$valid) { + return; + } + } + + if (formName === 'passwordForm') { + $scope.showAccountPubkey(); + } + $scope.slideNext(); + } } - if (formName) { + else{ $scope[formName].$submitted=true; if(!$scope[formName].$valid) { return; } - if (formName === 'passwordForm' && !$scope.formData.isMember) { - $scope.slideNext(2); // skip pseudo + if(formName === 'passwordForm'){ $scope.showAccountPubkey(); } - else { - $scope.slideNext(); - if (formName === 'pseudoForm') { - $scope.showAccountPubkey(); - } - } + $scope.slideNext(); } }; $scope.doNewAccount = function(confirm) { if (!confirm) { - return UIUtils.alert.confirm($scope.formData.isMember ? 'ACCOUNT.NEW.CONFIRMATION_MEMBER_ACCOUNT' : + + return UIUtils.alert.confirm(($rootScope.accountType === 'member') ? 'ACCOUNT.NEW.CONFIRMATION_MEMBER_ACCOUNT' : 'ACCOUNT.NEW.CONFIRMATION_WALLET_ACCOUNT') .then(function(confirm) { if (confirm) { $scope.doNewAccount(true); - } + } }); } @@ -160,36 +171,62 @@ function JoinModalController($scope, $state, UIUtils, CryptoUtils, csSettings, csWallet.login($scope.formData.username, $scope.formData.password) .then(function() { - if (!$scope.formData.isMember) { + if ($rootScope.accountType === "member") { $scope.closeModal(); csSettings.data.wallet = csSettings.data.wallet || {}; csSettings.data.wallet.alertIfUnusedWallet = false; // do not alert if empty // Redirect to wallet $state.go('app.view_wallet'); - return; - } + - // Send self - csWallet.self($scope.formData.pseudo, false/*do NOT load membership here*/) - .then(function() { - // Send membership IN - csWallet.membership.inside() + // Send self + csWallet.self($scope.formData.pseudo, false/*do NOT load membership here*/) .then(function() { - - $scope.closeModal(); - - // Redirect to wallet - $state.go('app.view_wallet'); + // Send membership IN + csWallet.membership.inside() + .then(function() { + + $scope.closeModal(); + + // Redirect to wallet + $state.go('app.view_wallet') + .then(function() { + $scope.dowloadRevocationRegistration(); + }); + }) + .catch(function(err) { + // + if (err && err.ucode == BMA.errorCodes.MEMBERSHIP_ALREADY_SEND) { + + } + onErrorLogout('ERROR.SEND_MEMBERSHIP_IN_FAILED')(err); + }); }) - .catch(onErrorLogout('ERROR.SEND_MEMBERSHIP_IN_FAILED')); - }) - .catch(onErrorLogout('ERROR.SEND_IDENTITY_FAILED')); + .catch(onErrorLogout('ERROR.SEND_IDENTITY_FAILED')); + } + else{ + + $scope.closeModal(); + + //Redirect to wallet + $state.go('app.view_wallet'); + + } }) .catch(function(err) { UIUtils.loading.hide(); console.error('>>>>>>>' , err); UIUtils.alert.error('ERROR.CRYPTO_UNKNOWN_ERROR'); }); + + }; + + + $scope.dowloadRevocationRegistration = function() { + return UIUtils.alert.download('DOWNLOAD.POPUP_REVOKE_MESSAGE', 'DOWNLOAD.POPUP_TITLE') + .then(function() { + return csWallet.downloadRevocation(); + }); }; $scope.showHelpModal = function(helpAnchor) { @@ -201,6 +238,88 @@ function JoinModalController($scope, $state, UIUtils, CryptoUtils, csSettings, Modals.showHelp({anchor: helpAnchor}); }; + $scope.isBottom = function(){ + var yPos = document.getElementById("iframe").contentWindow.document.body.scrollTop; + var scrollHeight = document.getElementById("iframe").contentWindow.document.body.scrollHeight; + var clientHeight = document.getElementById("iframe").contentWindow.document.body.clientHeight; + if(scrollHeight - clientHeight === yPos){ + return true; + } + return false; + }; + + $rootScope.startLicenceRead = function(){ + + $scope.licenceReadInterval = $interval(function(){ + var counter = 0; + if(counter === 0){ + $scope.slides.slider.lockSwipes(); + counter++; + } + + if($scope.isBottom()){ + $scope.isLicenceRead = true; + $interval.cancel($scope.licenceReadInterval); + } + },1000); + }; + + $scope.checkUID = function(){ + var uid = $scope.formData.pseudo; + $scope.UIDFound = false; + $scope.formData.computing=true; + BMA.wot.lookup({ search: uid }) // search on uid + .then(function(res) { + var found; + if(!res.ucode){ + found = res.results && + res.results.length > 0 && + res.results.some(function(pub){ + return pub.uids && pub.uids.length > 0 && + pub.uids.some(function(idty) { + return (idty.uid.toUpperCase() === uid.toUpperCase()); // same Uid + }); + }); + } + if(found){ + $scope.formData.computing=false; + $scope.UIDFound = true; + } + else{ + $scope.formData.computing=false; + $scope.UIDFound = false; + } + }) + .catch(function(){ + $scope.formData.computing=false; + $scope.UIDFound = false; + }); + }; + $scope.$watch('formData.pseudo', $scope.checkUID, true); + + $scope.checkAccountAvailable = function() { + var pub = $scope.formData.pubkey; + $scope.accountAvailable = false; + BMA.tx.sources({ pubkey: pub }) // search on pubkey + .then(function(res) { + if(!res.sources.length) { + $scope.formData.computing=false; + $scope.accountAvailable = true; + } + else{ + $scope.formData.computing=false; + } + }); + }; + + $scope.identifierRecovery = function() { + for (var i = 0; i < 2; i++) + $scope.slidePrev(); + }; + + + + // TODO: remove auto add account when done /*$timeout(function() { //$scope.selectCurrency('test_net'); @@ -214,3 +333,4 @@ function JoinModalController($scope, $state, UIUtils, CryptoUtils, csSettings, //$scope.doNext(); }, 400);*/ } + diff --git a/www/js/services/crypto-services.js b/www/js/services/crypto-services.js index f9119d841e8a45f658c6ddb03799003058d47594..bc5dedac1e313dbb82e0bb7aea34e59d6ef4f5cb 100644 --- a/www/js/services/crypto-services.js +++ b/www/js/services/crypto-services.js @@ -241,8 +241,8 @@ angular.module('cesium.crypto.services', ['ngResource', 'cesium.device.services' this.connect = function(salt, password) { return $q(function(resolve, reject) { var seed = that.scrypt.crypto_scrypt( - that.util.encode_utf8(password), that.util.encode_utf8(salt), + that.util.encode_utf8(password), that.constants.SCRYPT_PARAMS.N, that.constants.SCRYPT_PARAMS.r, that.constants.SCRYPT_PARAMS.p, diff --git a/www/js/services/modal-services.js b/www/js/services/modal-services.js index 7e13b524b1bc15abb40d4406f9b7551f11ce1444..de89a6960723f82b94634b5c7f0811faa1fd428d 100644 --- a/www/js/services/modal-services.js +++ b/www/js/services/modal-services.js @@ -160,6 +160,16 @@ angular.module('cesium.modal.services', []) parameters); } + function showJoinMember(parameters) { + return ModalUtils.show('templates/join/modal_join_member.html','JoinModalCtrl', + parameters); + } + + function showJoinWallet(parameters) { + return ModalUtils.show('templates/join/modal_join_wallet.html','JoinModalCtrl', + parameters); + } + function showHelp(parameters) { return ModalUtils.show('templates/help/modal_help.html','HelpModalCtrl', parameters); @@ -173,6 +183,8 @@ angular.module('cesium.modal.services', []) showNetworkLookup: showNetworkLookup, showAbout: showAbout, showJoin: showJoin, + showJoinMember: showJoinMember, + showJoinWallet: showJoinWallet, showHelp: showHelp, showAccountSecurity: showAccountSecurity }; diff --git a/www/js/services/utils-services.js b/www/js/services/utils-services.js index a2d0d85b0c2a4b8879abd8b4acb422673bbb00e2..c892c9b022b708ea6d3bc0e08570b06a20c7fe95 100644 --- a/www/js/services/utils-services.js +++ b/www/js/services/utils-services.js @@ -98,6 +98,27 @@ angular.module('cesium.utils.services', ['ngResource']) }); } + function alertDownload(message, title) { + return $q(function(resolve) { + $translate([message, title, 'COMMON.BTN_DOWNLOAD']) + .then(function (translations) { + $ionicPopup.show({ + template: '<p>' + translations[message] + '</p>', + title: translations[title], + buttons: [ + { + text: translations['COMMON.BTN_DOWNLOAD'], + type: 'button-assertive icon-right ion-android-archive', + onTap: function(e) { + resolve(e); + } + } + ] + }); + }); + }); + } + function hideLoading(timeout){ if (timeout) { return $timeout(function(){ @@ -668,7 +689,8 @@ angular.module('cesium.utils.services', ['ngResource']) error: alertError, info: alertInfo, confirm: askConfirm, - notImplemented: alertNotImplemented + notImplemented: alertNotImplemented, + download: alertDownload }, loading: { show: showLoading, diff --git a/www/js/services/wallet-services.js b/www/js/services/wallet-services.js index 9c3189590abaad81b9aefce788c70ea437c4a8f6..560db84faa5f52574e0d10ff449bdee36eac8f53 100644 --- a/www/js/services/wallet-services.js +++ b/www/js/services/wallet-services.js @@ -1251,62 +1251,10 @@ angular.module('cesium.wallet.services', ['ngResource', 'ngApi', 'cesium.bma.ser }); }, - checkUidNotExists = function(uid, pubkey) { - return $q(function(resolve, reject) { - BMA.wot.lookup({ search: uid }) // search on uid - .then(function(res) { - var found = res.results && - res.results.length > 0 && - res.results.some(function(pub){ - return pub.uids && pub.uids.length > 0 && - pub.uids.some(function(idty) { - return (idty.uid === uid) && // same Uid - (idty.revoked || pub.pubkey !== pubkey); // but not same pubkey - }); - }); - if (found) { // uid is already used : display a message and call failed callback - reject('ACCOUNT.NEW.MSG_UID_ALREADY_USED'); - } - else { - resolve(uid); - } - }) - .catch(function() { - resolve(uid); // not found, so OK - }); - }); - }, - - checkPubkeyNotExists = function(uid, pubkey) { - return $q(function(resolve, reject) { - BMA.wot.lookup({ search: pubkey }) // search on pubkey - .then(function(res) { - var found = res.results && - res.results.length > 0 && - res.results.some(function(pub){ - return pub.pubkey === pubkey && - pub.uids && pub.uids.length > 0 && - pub.uids.some(function(idty) { - return (!idty.revoked); // excluded revoked uid - }); - }); - if (found) { // uid is already used : display a message and reopen the popup - reject('ACCOUNT.NEW.MSG_PUBKEY_ALREADY_USED'); - } - else { - resolve(uid); - } - }) - .catch(function() { - resolve(uid); // not found, so OK - }); - }); - }, - getIdentityDocument = function(uid, blockUid) { uid = uid || data.uid; blockUid = blockUid || data.blockUid; - if (!uid || !blockUid) { + if ((!uid || !blockUid)) { throw {message: 'ERROR.WALLET_HAS_NO_SELF'}; } if (data.requirements && data.requirements.expired) { @@ -1331,59 +1279,56 @@ angular.module('cesium.wallet.services', ['ngResource', 'ngApi', 'cesium.bma.ser * Send self identity */ self = function(uid, needToLoadRequirements) { - if (!BMA.regexp.USER_ID.test(uid)){ - return $q.reject({message: 'ERROR.INVALID_USER_ID'}); - } - var block; - return $q.all([ - // check uid used by another pubkey - checkUidNotExists(uid, data.pubkey), - - // Load parameters (need to known the currency) - loadParameters(), + if (!BMA.regexp.USER_ID.test(uid)){ + return $q.reject({message: 'ERROR.INVALID_USER_ID'}); + } + var block; + return $q.all([ - // Get th current block - BMA.blockchain.current() - .then(function(current) { - block = current; - }) - .catch(function(err) { - // Special case for currency init (root block not exists): use fixed values - if (err && err.ucode == BMA.errorCodes.NO_CURRENT_BLOCK) { - block = {number: 0, hash: BMA.constants.ROOT_BLOCK_HASH}; - } - else { - throw err; - } - }) - ]) + // Load parameters (need to known the currency) + loadParameters(), - // Create identity document - .then(function() { - return getIdentityDocument(uid, block.number + '-' + block.hash); - }) + // Get th current block + BMA.blockchain.current() + .then(function(current) { + block = current; + }) + .catch(function(err) { + // Special case for currency init (root block not exists): use fixed values + if (err && err.ucode == BMA.errorCodes.NO_CURRENT_BLOCK) { + block = {number: 0, hash: BMA.constants.ROOT_BLOCK_HASH}; + } + else { + throw err; + } + }) + ]) + // Create identity document + .then(function() { + return getIdentityDocument(uid, block.number + '-' + block.hash); + }) - // Send to node - .then(function (identity) { - return BMA.wot.add({identity: identity}); - }) + // Send to node + .then(function (identity) { + return BMA.wot.add({identity: identity}); + }) - .then(function () { - if (!!needToLoadRequirements) { - // Refresh membership data (if need) - return loadRequirements(); - } - else { - data.uid = uid; - data.blockUid = block.number + '-' + block.hash; - } - }) - .catch(function (err) { - if (err && err.ucode === BMA.errorCodes.IDENTITY_SANDBOX_FULL) { - throw {ucode: BMA.errorCodes.IDENTITY_SANDBOX_FULL, message: 'ERROR.IDENTITY_SANDBOX_FULL'}; - } - throw err; - }); + .then(function () { + if (!!needToLoadRequirements) { + // Refresh membership data (if need) + return loadRequirements(); + } + else { + data.uid = uid; + data.blockUid = block.number + '-' + block.hash; + } + }) + .catch(function (err) { + if (err && err.ucode === BMA.errorCodes.IDENTITY_SANDBOX_FULL) { + throw {ucode: BMA.errorCodes.IDENTITY_SANDBOX_FULL, message: 'ERROR.IDENTITY_SANDBOX_FULL'}; + } + throw err; + }); }, /** @@ -1698,7 +1643,10 @@ angular.module('cesium.wallet.services', ['ngResource', 'ngApi', 'cesium.bma.ser return getRevocationDocument() .then(function(revocation) { var revocationFile = new Blob([revocation], {type: 'text/plain; charset=utf-8'}); - FileSaver.saveAs(revocationFile, 'revocation.txt'); + return $translate('ACCOUNT.SECURITY.REVOCATION_FILENAME', {uid: data.uid, currency: data.currency, pubkey: data.pubkey}) + .then(function(fileName){ + FileSaver.saveAs(revocationFile, fileName); + }); }); }, diff --git a/www/licence_g1.txt b/www/licence_g1.txt new file mode 100644 index 0000000000000000000000000000000000000000..a72cb6821230bdf98bab6dae66bbdb32194fdf5c --- /dev/null +++ b/www/licence_g1.txt @@ -0,0 +1,75 @@ + +Licence Äž1 - v0.2 +================= + +:date: 2017-04-04 12:59 +:modified: 2017-04-04 12:59 + +**Licence de la monnaie et engagement de responsabilité.** + +Toute opération de certification d'un nouveau membre de Äž1 doit préalablement s'accompagner de la transmission de cette licence de la monnaie Äž1 dont le certificateur doit s'assurer qu'elle a été étudiée, comprise et acceptée par la personne qui sera certifiée. + +Monnaie Äž1 +---------- + +Äž1 se produit via un Dividende Universel (DU) pour tout être humain membre de la Toile de Confiance Äž1, qui est de la forme : + +* 1 DU par personne et par jour + +Le montant du DU est identique chaque jour jusqu'au prochain équinoxe, où le DU sera alors réévalué selon la formule : + +* DUjour(équinoxe suivant) = DUjour(équinoxe) + c² (M/N)(équinoxe) / (15778800 secondes) + +Avec comme paramètres : + +* c = 4,88% / équinoxe +* UD(0) = 10,00 Äž1 + +Et comme variables : + +* *M* la masse monétaire totale à l'équinoxe +* *N* le nombre de membres à l'équinoxe + +Toile de confiance Äž1 (TdC Äž1) +------------------------------ + +**Avertissement :** Certifier n'est pas uniquement s'assurer que vous avez rencontré la personne, c'est assurer à la communauté Äž1 que vous connaissez suffisamment bien la personne certifiée et que vous saurez repérer un double compte effectué par une personne certifiée par vous-même, ou d'autres types de problèmes (disparition...), en effectuant des recoupements qui permettront de révéler le problème le cas échéant. + +Lorsque vous êtes membre de la TdC Äž1 et que vous vous apprêtez à certifier un nouveau compte : + +**Vous êtes vous assuré :** + +1°) De suffisamment bien connaître (pas seulement de la connaître "de visu") la personne qui déclare gérer cette clé publique (nouveau compte) et d'avoir personnellement vérifié avec elle qu'il s'agit bien de cette clé publique que vous vous apprêtez à certifier. + +2a°) De la rencontrer physiquement pour vous assurer que c'est bien cette personne que vous connaissez qui gère cette clé publique. + +2b°) Ou bien de vérifer à distance le lien personne / clé publique en contactant la personne par plusieurs moyens de communication différents, comme réseau social + forum + mail + vidéo conférence + téléphone (reconnaître la voix). Car si l'on peut pirater un compte mail ou un compte forum, il sera bien plus difficile d'imaginer pirater quatre moyens de communication distincts, et imiter l'apparence (vidéo) ainsi que la voix de la personne en plus. Le 2a°) restant toutefois préférable au 2b°), tandis que le 1°) est toujours indispensable dans tous les cas. + +3°) D'avoir bien vérifié avec la personne concernée qu'elle a bien généré son document Duniter de révocation de compte, qui lui permettra le cas échéant de pouvoir annuler son compte (cas d'un vol de compte, d'un changement de ID, d'un compte créé à tort etc.). + +**Règles abrégées de la TdC :** + +Chaque membre a un stock de 100 certifications possibles, qu'il ne peut émettre qu'au rythme de 1 certification / 5 jours. + +Valable 2 mois, une certification pour un nouveau membre n'est définitivement adoptée que si le certifié possède au moins 4 autres certifications au bout de ces 2 mois, sinon le processus d'entrée devra être relancé. + +Pour devenir un nouveau membre de la TdC Äž1 il faut donc obtenir 5 certifications et ne pas se trouver à une distance > 5 de 80% des membre référent de la TdC. + +Un membre de la TdC Äž1 est membre référent lorsqu'il a reçu et émis au moins Y[N] certifications où N est le nombre de membres de la TdC et Y[N] = plafond N^(1/5). Exemples : + +* Pour 1024 < N ≤ 3125 on a Y[N] = 5 +* Pour 7776 < N ≤ 16807 on a Y[N] = 7 +* pour 59049 < N ≤ 100 000 on a Y[N] = 10 + +Une fois que le nouveau membre est partie prenante de la TdC Äž1 ses certifications restent valables 2 ans. + +Pour rester membre il faut renouveler son accord régulièrement avec sa clé privée (tous les 12 mois) et s'assurer d'avoir toujours au moins 5 certifications valides au delà des 2 ans. + +Logiciels Äž1 et licence Äž1 +-------------------------- + +Les logiciels Äž1 permettant aux utilisateurs de gérer leur utilisation de Äž1 doivent transmettre cette licence avec le logiciel ainsi que l'ensemble des paramètres techniques de la monnaie Äž1 et de la TdC Äž1 qui sont inscrits dans le bloc 0 de Äž1. + +Pour plus de précisions dans les détails techniques il est possible de consulter directement le code de Duniter qui est un logiciel libre ansi que les données de la blockchain Äž1 en la récupérant via une instance (ou noeud) Duniter Äž1. + +Plus d'informations sur le site de l'équipe Duniter https://www.duniter.org \ No newline at end of file diff --git a/www/templates/currency/items_wot.html b/www/templates/currency/items_wot.html index 851f17e3b4ee70fd38b51756c8af149e944625bf..33ebf873f151589c73de2161f456cf39ce704175 100644 --- a/www/templates/currency/items_wot.html +++ b/www/templates/currency/items_wot.html @@ -75,6 +75,12 @@ <span class="badge badge-stable" ng-if="!loading">{{formData.stepMax}}</span> </ion-item> + <ion-item class="item-icon-left"> + <i class="icon ion-steam"></i> + <span translate>TEST</span> + <span class="badge badge-stable" ng-if="!loading">{{formData.stepMax}}</span> + </ion-item> + <ion-item class="item-icon-left item-text-wrap"> <i class="icon ion-pull-request"></i> <span class="col col-75" translate>CURRENCY.VIEW.XPERCENT</span> diff --git a/www/templates/join/modal_join.html b/www/templates/join/modal_join.html index 9adf4ca986651ba50c1945cad3a57f3414f9ab7c..831e68282f1c97bbc8cf179d468cfec71c0f7eab 100644 --- a/www/templates/join/modal_join.html +++ b/www/templates/join/modal_join.html @@ -22,11 +22,6 @@ <span translate>COMMON.BTN_NEXT</span> <i class="icon ion-ios-arrow-right"></i> </button> - <button class="button button-clear icon-right visible-xs" - ng-if="isLastSlide" - ng-click="doNewAccount()"> - <i class="icon ion-android-send"></i> - </button> </ion-header-bar> @@ -61,7 +56,7 @@ <div class="list"> <!-- member account --> <div class="item item-complex card stable-bg item-icon-left item-icon-right ink" - ng-click="selectAccountType('member')"> + ng-click="closeModal('member')"> <div class="item-content item-text-wrap"> <i class="item-image icon dark ion-person"></i> <h2 translate>ACCOUNT.NEW.MEMBER_ACCOUNT</h2> @@ -75,289 +70,19 @@ <!-- simple wallet --> <div class="item item-complex card stable-bg item-icon-left item-icon-right ink" - ng-click="selectAccountType('anonymous')"> + ng-click="closeModal('wallet')"> <div class="item-content item-text-wrap"> <i class="item-image icon dark ion-card"></i> <h2 translate>ACCOUNT.NEW.WALLET_ACCOUNT</h2> <h4 class="gray" translate>ACCOUNT.NEW.WALLET_ACCOUNT_HELP</h4> - <i class="icon dark ion-ios-arrow-right"></i> - </div> - </div> - </div> - <div class="padding hidden-xs text-right"> - <button class="button button-clear button-dark ink" ng-click="closeModal()" type="button" translate>COMMON.BTN_CANCEL - </button> - </div> - </ion-content> - </ion-slide-page> - - <!-- STEP 3: salt --> - <ion-slide-page> - <ion-content class="has-header" scroll="false"> - <form name="saltForm" novalidate="" ng-submit="doNext('saltForm')"> - - <div class="list" - ng-init="setForm(saltForm, 'saltForm')"> - - <div class="item item-text-wrap text-center padding hidden-xs" > - <a class="pull-right icon-help" ng-click="showHelpModal('join-salt')"></a> - <span translate>ACCOUNT.NEW.SALT_WARNING</span> - </div> - - <!-- salt --> - <div class="item item-input" - ng-class="{ 'item-input-error': saltForm.$submitted && saltForm.username.$invalid}"> - <span class="input-label" translate>LOGIN.SALT</span> - <input ng-if="!showUsername" - name="username" type="password" placeholder="{{'LOGIN.SALT_HELP' | translate}}" - ng-change="formDataChanged()" - ng-model="formData.username" - ng-minlength="8" - required> - <input ng-if="showUsername" - name="username" type="text" placeholder="{{'LOGIN.SALT_HELP' | translate}}" - ng-change="formDataChanged()" - ng-model="formData.username" - ng-minlength="8" - required> - </div> - <div class="form-errors" - ng-show="saltForm.$submitted && saltForm.username.$error" - ng-messages="saltForm.username.$error"> - <div class="form-error" ng-message="minlength"> - <span translate="ERROR.FIELD_TOO_SHORT_WITH_LENGTH" translate-values="{minLength: 8}"></span> - </div> - <div class="form-error" ng-message="required"> - <span translate="ERROR.FIELD_REQUIRED"></span> - </div> - </div> - - <!-- confirm salt --> - <div class="item item-input" - ng-class="{ 'item-input-error': saltForm.$submitted && saltForm.confirmSalt.$invalid}"> - <span class="input-label pull-right" translate>ACCOUNT.NEW.SALT_CONFIRM</span> - <input ng-if="!showUsername" - name="confirmUsername" type="password" - placeholder="{{'ACCOUNT.NEW.SALT_CONFIRM_HELP' | translate}}" - ng-model="formData.confirmUsername" - compare-to="formData.username"> - <input ng-if="showUsername" - name="confirmUsername" type="text" - placeholder="{{'ACCOUNT.NEW.SALT_CONFIRM_HELP' | translate}}" - ng-model="formData.confirmUsername" - compare-to="formData.username"> - </div> - <div class="form-errors" - ng-show="saltForm.$submitted && saltForm.confirmUsername.$error" - ng-messages="saltForm.confirmUsername.$error"> - <div class="form-error" ng-message="compareTo"> - <span translate="ERROR.SALT_NOT_CONFIRMED"></span> - </div> - </div> - - <!-- Show values --> - <div class="item item-toggle dark"> - <span translate>COMMON.SHOW_VALUES</span> - <label class="toggle toggle-royal"> - <input type="checkbox" ng-model="showUsername"> - <div class="track"> - <div class="handle"></div> - </div> - </label> - </div> - - <div class="padding hidden-xs text-right"> - <button class="button button-clear button-dark ink" ng-click="closeModal()" type="button" translate>COMMON.BTN_CANCEL - </button> - <button class="button button-calm icon-right ion-chevron-right ink" type="submit" translate> - COMMON.BTN_NEXT - <i class="icon ion-arrow-right-a"></i> - </button> - </div> - </div> - </form> - </ion-content> - </ion-slide-page> - - <!-- STEP 4: password--> - <ion-slide-page> - <ion-content class="has-header" scroll="false"> - <form name="passwordForm" novalidate="" ng-submit="doNext('passwordForm')"> - - <div class="item item-text-wrap text-center padding hidden-xs" > - <a class="pull-right icon-help" ng-click="showHelpModal('join-password')"></a> - <span translate>ACCOUNT.NEW.PASSWORD_WARNING</span> - </div> - - <div class="list" - ng-init="setForm(passwordForm, 'passwordForm')"> - - <!-- password --> - <div class="item item-input" - ng-class="{ 'item-input-error': passwordForm.$submitted && passwordForm.password.$invalid}"> - <span class="input-label" translate>LOGIN.PASSWORD</span> - <input ng-if="!showPassword" - name="password" type="password" placeholder="{{'LOGIN.PASSWORD_HELP' | translate}}" - ng-model="formData.password" - ng-change="formDataChanged()" - ng-minlength="8" - required> - <input ng-if="showPassword" - name="text" type="text" placeholder="{{'LOGIN.PASSWORD_HELP' | translate}}" - ng-model="formData.password" - ng-change="formDataChanged()" - ng-minlength="8" - required> - </div> - <div class="form-errors" - ng-show="passwordForm.$submitted && passwordForm.password.$error" - ng-messages="passwordForm.password.$error"> - <div class="form-error" ng-message="minlength"> - <span translate="ERROR.FIELD_TOO_SHORT_WITH_LENGTH" translate-values="{minLength: 8}"></span> - </div> - <div class="form-error" ng-message="required"> - <span translate="ERROR.FIELD_REQUIRED"></span> - </div> - </div> - - <!-- confirm password --> - <div class="item item-input" - ng-class="{ 'item-input-error': passwordForm.$submitted && passwordForm.confirmPassword.$invalid}"> - <span class="input-label" translate>ACCOUNT.NEW.PASSWORD_CONFIRM</span> - <input ng-if="!showPassword" - name="confirmPassword" type="password" - placeholder="{{'ACCOUNT.NEW.PASSWORD_CONFIRM_HELP' | translate}}" - ng-model="formData.confirmPassword" - compare-to="formData.password"> - <input ng-if="showPassword" - name="confirmPassword" type="text" - placeholder="{{'ACCOUNT.NEW.PASSWORD_CONFIRM_HELP' | translate}}" - ng-model="formData.confirmPassword" - compare-to="formData.password"> - </div> - <div class="form-errors" - ng-show="passwordForm.$submitted && passwordForm.confirmPassword.$error" - ng-messages="passwordForm.confirmPassword.$error"> - <div class="form-error" ng-message="compareTo"> - <span translate="ERROR.PASSWORD_NOT_CONFIRMED"></span> - </div> - </div> - - <!-- Show values --> - <div class="item item-toggle dark"> - <span translate>COMMON.SHOW_VALUES</span> - <label class="toggle toggle-royal"> - <input type="checkbox" ng-model="showPassword"> - <div class="track"> - <div class="handle"></div> - </div> - </label> - </div> - </div> - - <div class="padding hidden-xs text-right"> - <button class="button button-clear button-dark ink" ng-click="closeModal()" type="button" translate>COMMON.BTN_CANCEL - </button> - <button class="button button-calm icon-right ion-chevron-right ink" type="submit" translate> - COMMON.BTN_NEXT - </button> - </div> - - <div class="padding hidden-xs"> - </div> - </form> - </ion-content> - </ion-slide-page> - - <!-- STEP 5: pseudo--> - <ion-slide-page ng-if="formData.isMember"> - <ion-content class="has-header" scroll="false"> - <form name="pseudoForm" novalidate="" ng-submit="doNext('pseudoForm')"> - - <div class="item item-text-wrap text-center padding hidden-xs" > - <a class="pull-right icon-help" ng-click="showHelpModal('join-pseudo')"></a> - <span translate>ACCOUNT.NEW.PSEUDO_WARNING</span> - </div> - - <div class="list" - ng-init="setForm(pseudoForm, 'pseudoForm')"> - - <!-- pseudo --> - <div class="item item-input" - ng-if="formData.isMember" - ng-class="{'item-input-error': pseudoForm.$submitted && pseudoForm.pseudo.$invalid}"> - <span class="input-label" translate>ACCOUNT.NEW.PSEUDO</span> - <input name="pseudo" type="text" placeholder="{{'ACCOUNT.NEW.PSEUDO_HELP' | translate}}" - ng-model="formData.pseudo" - ng-minlength="3" - ng-maxlength="100" - ng-pattern="userIdPattern" - required> - </div> - <div class="form-errors" - ng-if="formData.isMember" - ng-show="pseudoForm.$submitted && pseudoForm.pseudo.$error" - ng-messages="pseudoForm.pseudo.$error"> - <div class="form-error" ng-message="minlength"> - <span translate="ERROR.FIELD_TOO_SHORT_WITH_LENGTH" translate-values="{minLength: 3}"></span> - </div> - <div class="form-error" ng-message="maxlength"> - <span translate="ERROR.FIELD_TOO_LONG_WITH_LENGTH" translate-values="{maxLength: 100}"></span> - </div> - <div class="form-error" ng-message="required"> - <span translate="ERROR.FIELD_REQUIRED"></span> - </div> - <div class="form-error" ng-message="pattern"> - <span translate="ERROR.INVALID_USER_ID"></span> - </div> - </div> - - <div class="padding hidden-xs text-right"> - <button class="button button-clear button-dark ink" ng-click="closeModal()" type="button" translate>COMMON.BTN_CANCEL - </button> - <button class="button button-calm icon-right ion-chevron-right ink" type="submit" translate> - COMMON.BTN_NEXT - </button> - </div> + <i class="icon dark ion-ios-arrow-right"></i> </div> </div> - </form> - </ion-content> - </ion-slide-page> - - <!--<cs-extension-point name="last-slide"></cs-extension-point>--> - - <!-- STEP 6: last slide --> - <ion-slide-page> - <ion-content class="has-header" scroll="false"> - - <div class="padding text-center" translate>ACCOUNT.NEW.LAST_SLIDE_CONGRATULATION</div> - - <div class="list"> - - <ion-item class="item item-text-wrap item-border"> - <div class="dark pull-right padding-right" ng-if="formData.computing"> - <ion-spinner icon="android"></ion-spinner> - </div> - <span class="input-label" translate>COMMON.PUBKEY</span> - <span class="gray text-no-wrap" ng-if="formData.computing" translate> - ACCOUNT.NEW.COMPUTING_PUBKEY - </span> - <span class="gray text-no-wrap" ng-if="formData.pubkey"> - {{formData.pubkey}} - </span> - </ion-item> </div> - <div class="padding hidden-xs text-right"> <button class="button button-clear button-dark ink" ng-click="closeModal()" type="button" translate>COMMON.BTN_CANCEL </button> - <button class="button button-positive ink" ng-click="doNewAccount()" translate> - COMMON.BTN_SEND - <i class="icon ion-android-send"></i> - </button> </div> </ion-content> </ion-slide-page> - </ion-slide-box> </ion-modal-view> diff --git a/www/templates/join/modal_join_member.html b/www/templates/join/modal_join_member.html new file mode 100644 index 0000000000000000000000000000000000000000..2d3267303cb95bcd9cb54cf4b6efcaf1e1703e01 --- /dev/null +++ b/www/templates/join/modal_join_member.html @@ -0,0 +1,392 @@ +<ion-modal-view class="modal-full-height"> + + <ion-header-bar class="bar-positive"> + + <button class="button button-clear visible-xs" + ng-if="!slides.slider.activeIndex" + ng-click="closeModal()" translate>COMMON.BTN_CANCEL + </button> + <button class="button button-icon button-clear icon ion-ios-arrow-back buttons header-item" + ng-click="slidePrev()" + ng-if="slides.slider.activeIndex"> + </button> + <button class="button button-icon button-clear icon ion-ios-help-outline visible-xs" + ng-if="slides.slider.activeIndex > 1 && !isLastSlide" + ng-click="showHelpModal()"></button> + + <h1 class="title" translate>ACCOUNT.NEW.TITLE</h1> + + <button class="button button-clear icon-right visible-xs" + ng-if="!isLastSlide && slides.slider.activeIndex > 1" + ng-click="doNext()"> + <span translate>COMMON.BTN_NEXT</span> + <i class="icon ion-ios-arrow-right"></i> + </button> + <button class="button button-clear icon-right visible-xs" + ng-if="isLastSlide" + ng-click="doNewAccount()"> + <i class="icon ion-android-send"></i> + </button> + </ion-header-bar> + + + <ion-slides options="slides.options" slider="slides.slider"> + + <!-- STEP 1: license --> + <ion-slide-page> + <ion-content class="has-header padding" scroll="false"> + <div class="item item-text-wrap text-center padding hidden-xs no-border"> + <span translate>ACCOUNT.NEW.INFO_LICENSE</span> + </div> + <iframe width="100%" height="60%" src="licence_g1.txt" style="margin-bottom : 20px" id="iframe"></iframe> + <ion-checkbox class="item item-text-wrap item-border" ng-model="isLicenceAccept" + ng-disabled="!isLicenceRead" class="no-border"> + <p id="modal-license" ng-class="{'gray': !isLicenceRead, 'black': isLicenceRead}" translate> + CONFIRM.LICENCE + </p> + </ion-checkbox> + <div class="padding hidden-xs text-right"> + <button class="button button-clear button-dark ink" ng-click="closeModal()" type="button" translate> + COMMON.BTN_CANCEL + </button> + <button class="button button-calm icon-right ion-chevron-right ink" ng-click="doNext('licenceForm')" + ng-disabled="!isLicenceAccept" type="button" translate> + COMMON.BTN_NEXT + </button> + </div> + </ion-content> + </ion-slide-page> + + <!-- STEP 2: pseudo--> + <ion-slide-page> + <ion-content class="has-header" scroll="false"> + <form name="pseudoForm" novalidate="" ng-submit="doNext('pseudoForm')"> + + <div class="item item-text-wrap text-center padding hidden-xs" > + <a class="pull-right icon-help" ng-click="showHelpModal('join-pseudo')"></a> + <span translate>ACCOUNT.NEW.PSEUDO_WARNING</span> + </div> + + <div class="list" + ng-init="setForm(pseudoForm, 'pseudoForm')"> + + <!-- pseudo --> + <div class="item item-input" + ng-class="{'item-input-error': pseudoForm.$submitted && pseudoForm.pseudo.$invalid}"> + <span class="input-label" translate>ACCOUNT.NEW.PSEUDO</span> + <input name="pseudo" type="text" placeholder="{{'ACCOUNT.NEW.PSEUDO_HELP' | translate}}" + ng-model="formData.pseudo" + ng-minlength="3" + ng-maxlength="100" + ng-pattern="userIdPattern" + ng-model-options="{ debounce: 250 }" + required> + </div> + <div class="form-errors" + ng-if="formData.isMember" + ng-show="pseudoForm.$submitted && pseudoForm.pseudo.$error" + ng-messages="pseudoForm.pseudo.$error"> + <div class="form-error" ng-message="minlength"> + <span translate="ERROR.FIELD_TOO_SHORT_WITH_LENGTH" translate-values="{minLength: 3}"></span> + </div> + <div class="form-error" ng-message="maxlength"> + <span translate="ERROR.FIELD_TOO_LONG_WITH_LENGTH" translate-values="{maxLength: 100}"></span> + </div> + <div class="form-error" ng-message="required"> + <span translate="ERROR.FIELD_REQUIRED"></span> + </div> + <div class="form-error" ng-message="pattern"> + <span translate="ERROR.INVALID_USER_ID"></span> + </div> + </div> + + <!-- Show if valid pseudo--> + <div class="item item-button-right left" ng-if="formData.computing && formData.pseudo"> + <ion-spinner icon="android"></ion-spinner> + </div> + <ion-item class="item-icon-left" ng-if="!UIDFound && !formData.computing && formData.pseudo"> + <i class="icon ion-checkmark-circled active"></i> + <span translate>ACCOUNT.NEW.PSEUDO_AVAILABLE</span> + </ion-item> + <ion-item class="item-icon-left" ng-if="UIDFound && !formData.computing && formData.pseudo"> + <i class="icon ion-android-close active"></i> + <span translate>ACCOUNT.NEW.PSEUDO_NOT_AVAILABLE</span> + </ion-item> + + <div class="padding hidden-xs text-right"> + <button class="button button-clear button-dark ink" ng-click="closeModal()" type="button" translate>COMMON.BTN_CANCEL + </button> + <button class="button button-calm icon-right ion-chevron-right ink" type="submit" + ng-disabled="UIDFound" translate> + COMMON.BTN_NEXT + </button> + </div> + </div> + </form> + </ion-content> + </ion-slide-page> + + + <!-- STEP 3: salt --> + <ion-slide-page> + <ion-content class="has-header" scroll="false"> + <form name="saltForm" novalidate="" ng-submit="doNext('saltForm')"> + + <div class="list" + ng-init="setForm(saltForm, 'saltForm')"> + + <div class="item item-text-wrap text-center padding hidden-xs" > + <a class="pull-right icon-help" ng-click="showHelpModal('join-salt')"></a> + <span translate>ACCOUNT.NEW.SALT_WARNING</span> + </div> + + <!-- salt --> + <div class="item item-input" + ng-class="{ 'item-input-error': saltForm.$submitted && saltForm.username.$invalid}"> + <span class="input-label" translate>LOGIN.SALT</span> + <input ng-if="!showUsername" + name="username" type="password" placeholder="{{'LOGIN.SALT_HELP' | translate}}" + ng-change="formDataChanged()" + ng-model="formData.username" + ng-minlength="8" + required> + <input ng-if="showUsername" + name="username" type="text" placeholder="{{'LOGIN.SALT_HELP' | translate}}" + ng-change="formDataChanged()" + ng-model="formData.username" + ng-minlength="8" + required> + </div> + <div class="form-errors" + ng-show="saltForm.$submitted && saltForm.username.$error" + ng-messages="saltForm.username.$error"> + <div class="form-error" ng-message="minlength"> + <span translate="ERROR.FIELD_TOO_SHORT_WITH_LENGTH" translate-values="{minLength: 8}"></span> + </div> + <div class="form-error" ng-message="required"> + <span translate="ERROR.FIELD_REQUIRED"></span> + </div> + </div> + + <!-- confirm salt --> + <div class="item item-input" + ng-class="{ 'item-input-error': saltForm.$submitted && saltForm.confirmSalt.$invalid}"> + <span class="input-label pull-right" translate>ACCOUNT.NEW.SALT_CONFIRM</span> + <input ng-if="!showUsername" + name="confirmUsername" type="password" + placeholder="{{'ACCOUNT.NEW.SALT_CONFIRM_HELP' | translate}}" + ng-model="formData.confirmUsername" + compare-to="formData.username"> + <input ng-if="showUsername" + name="confirmUsername" type="text" + placeholder="{{'ACCOUNT.NEW.SALT_CONFIRM_HELP' | translate}}" + ng-model="formData.confirmUsername" + compare-to="formData.username"> + </div> + <div class="form-errors" + ng-show="saltForm.$submitted && saltForm.confirmUsername.$error" + ng-messages="saltForm.confirmUsername.$error"> + <div class="form-error" ng-message="compareTo"> + <span translate="ERROR.SALT_NOT_CONFIRMED"></span> + </div> + </div> + + <!-- Show values --> + <div class="item item-toggle dark"> + <span translate>COMMON.SHOW_VALUES</span> + <label class="toggle toggle-royal"> + <input type="checkbox" ng-model="showUsername"> + <div class="track"> + <div class="handle"></div> + </div> + </label> + </div> + + <div class="padding hidden-xs text-right"> + <button class="button button-clear button-dark ink" ng-click="closeModal()" type="button" translate>COMMON.BTN_CANCEL + </button> + <button class="button button-calm icon-right ion-chevron-right ink" type="submit" translate> + COMMON.BTN_NEXT + <i class="icon ion-arrow-right-a"></i> + </button> + </div> + </div> + </form> + </ion-content> + </ion-slide-page> + + <!-- STEP 4: password--> + <ion-slide-page> + <ion-content class="has-header" scroll="false"> + <form name="passwordForm" novalidate="" ng-submit="doNext('passwordForm')"> + + <div class="item item-text-wrap text-center padding hidden-xs" > + <a class="pull-right icon-help" ng-click="showHelpModal('join-password')"></a> + <span translate>ACCOUNT.NEW.PASSWORD_WARNING</span> + </div> + + <div class="list" + ng-init="setForm(passwordForm, 'passwordForm')"> + + <!-- password --> + <div class="item item-input" + ng-class="{ 'item-input-error': passwordForm.$submitted && passwordForm.password.$invalid}"> + <span class="input-label" translate>LOGIN.PASSWORD</span> + <input ng-if="!showPassword" + name="password" type="password" placeholder="{{'LOGIN.PASSWORD_HELP' | translate}}" + ng-model="formData.password" + ng-change="formDataChanged()" + ng-minlength="8" + required> + <input ng-if="showPassword" + name="text" type="text" placeholder="{{'LOGIN.PASSWORD_HELP' | translate}}" + ng-model="formData.password" + ng-change="formDataChanged()" + ng-minlength="8" + required> + </div> + <div class="form-errors" + ng-show="passwordForm.$submitted && passwordForm.password.$error" + ng-messages="passwordForm.password.$error"> + <div class="form-error" ng-message="minlength"> + <span translate="ERROR.FIELD_TOO_SHORT_WITH_LENGTH" translate-values="{minLength: 8}"></span> + </div> + <div class="form-error" ng-message="required"> + <span translate="ERROR.FIELD_REQUIRED"></span> + </div> + </div> + + <!-- confirm password --> + <div class="item item-input" + ng-class="{ 'item-input-error': passwordForm.$submitted && passwordForm.confirmPassword.$invalid}"> + <span class="input-label" translate>ACCOUNT.NEW.PASSWORD_CONFIRM</span> + <input ng-if="!showPassword" + name="confirmPassword" type="password" + placeholder="{{'ACCOUNT.NEW.PASSWORD_CONFIRM_HELP' | translate}}" + ng-model="formData.confirmPassword" + compare-to="formData.password"> + <input ng-if="showPassword" + name="confirmPassword" type="text" + placeholder="{{'ACCOUNT.NEW.PASSWORD_CONFIRM_HELP' | translate}}" + ng-model="formData.confirmPassword" + compare-to="formData.password"> + </div> + <div class="form-errors" + ng-show="passwordForm.$submitted && passwordForm.confirmPassword.$error" + ng-messages="passwordForm.confirmPassword.$error"> + <div class="form-error" ng-message="compareTo"> + <span translate="ERROR.PASSWORD_NOT_CONFIRMED"></span> + </div> + </div> + + <!-- Show values --> + <div class="item item-toggle dark"> + <span translate>COMMON.SHOW_VALUES</span> + <label class="toggle toggle-royal"> + <input type="checkbox" ng-model="showPassword"> + <div class="track"> + <div class="handle"></div> + </div> + </label> + </div> + </div> + + <div class="padding hidden-xs text-right"> + <button class="button button-clear button-dark ink" ng-click="closeModal()" type="button" translate>COMMON.BTN_CANCEL + </button> + <button class="button button-calm icon-right ion-chevron-right ink" type="submit" ng-click="getRevocationDocument()" translate> + COMMON.BTN_NEXT + </button> + </div> + + <div class="padding hidden-xs"> + </div> + </form> + </ion-content> + </ion-slide-page> + + <!--<cs-extension-point name="last-slide"></cs-extension-point>--> + + <!-- STEP 5: last slide --> + <ion-slide-page> + <ion-content class="has-header" scroll="false"> + + <!-- Computing --> + + <div class="padding text-center" ng-if="formData.computing"> + <ion-spinner icon="android"></ion-spinner> + </div> + <!-- ng-if="formData.computing" --> + + <!-- Account available --> + <div ng-if="accountAvailable && !formData.computing"> + <div class="padding text-center" translate>ACCOUNT.NEW.LAST_SLIDE_CONGRATULATION</div> + + <div class="list"> + + <ion-item class="item item-text-wrap item-border"> + <div class="dark pull-right padding-right" ng-if="formData.computing"> + <ion-spinner icon="android"></ion-spinner> + </div> + <span class="input-label" translate>COMMON.PUBKEY</span> + <span class="gray text-no-wrap" ng-if="formData.computing" translate> + ACCOUNT.NEW.COMPUTING_PUBKEY + </span> + <span class="gray text-no-wrap" ng-if="formData.pubkey"> + {{formData.pubkey}} + </span> + </ion-item> + </div> + + <div class="padding hidden-xs text-right"> + <button class="button button-clear button-dark ink" ng-click="closeModal()" type="button" translate>COMMON.BTN_CANCEL + </button> + <button class="button button-positive ink" ng-click="doNewAccount()" translate> + COMMON.BTN_SEND + <i class="icon ion-android-send"></i> + </button> + </div> + </div> + + <!-- Existing non-empty account --> + <div ng-if="!accountAvailable && !formData.computing"> + + <ion-item class="item-icon-left item-text-wrap text-center"> + <i class="icon ion-alert-circled active"></i> + <span id="modal-license" translate>ERROR.EXISTING_ACCOUNT</span> + </ion-item> + + <div class="list"> + + <ion-item class="item item-text-wrap item-border"> + <div class="dark pull-right padding-right" ng-if="formData.computing"> + <ion-spinner icon="android"></ion-spinner> + </div> + <span class="gray text-no-wrap" ng-if="formData.computing" translate> + ACCOUNT.NEW.COMPUTING_PUBKEY + </span> + <div class="padding text-center"> + <span class="gray text-no-wrap" ng-if="formData.pubkey"> + {{formData.pubkey}} + </span> + </div> + </ion-item> + + <div class="padding text-center"> + <span translate>ERROR.EXISTING_ACCOUNT_REQUEST</span> + </div> + + </div> + <div class="padding hidden-xs text-left"> + <button class="button button-assertive icon-left ion-chevron-left ink" + ng-click="identifierRecovery()" translate> + COMMON.BTN_MODIFY + </button> + </div> + </div> + + </ion-content> + </ion-slide-page> + </ion-slides> + </ion-slide-box> +</ion-modal-view> diff --git a/www/templates/join/modal_join_wallet.html b/www/templates/join/modal_join_wallet.html new file mode 100644 index 0000000000000000000000000000000000000000..7998ba0f4533813d62e2c3f7bbce36884e609522 --- /dev/null +++ b/www/templates/join/modal_join_wallet.html @@ -0,0 +1,298 @@ +<ion-modal-view class="modal-full-height"> + + <ion-header-bar class="bar-positive"> + + <button class="button button-clear visible-xs" + ng-if="!slides.slider.activeIndex" + ng-click="closeModal()" translate>COMMON.BTN_CANCEL + </button> + <button class="button button-icon button-clear icon ion-ios-arrow-back buttons header-item" + ng-click="slidePrev()" + ng-if="slides.slider.activeIndex"> + </button> + <button class="button button-icon button-clear icon ion-ios-help-outline visible-xs" + ng-if="slides.slider.activeIndex > 1 && !isLastSlide" + ng-click="showHelpModal()"></button> + + <h1 class="title" translate>ACCOUNT.NEW.TITLE</h1> + + <button class="button button-clear icon-right visible-xs" + ng-if="!isLastSlide && slides.slider.activeIndex > 1" + ng-click="doNext()"> + <span translate>COMMON.BTN_NEXT</span> + <i class="icon ion-ios-arrow-right"></i> + </button> + <button class="button button-clear icon-right visible-xs" + ng-if="isLastSlide" + ng-click="doNewAccount()"> + <i class="icon ion-android-send"></i> + </button> + </ion-header-bar> + + + <ion-slides options="slides.options" slider="slides.slider"> + + <!-- STEP 1: salt --> + <ion-slide-page> + <ion-content class="has-header" scroll="false"> + <form name="saltForm" novalidate="" ng-submit="doNext('saltForm')"> + + <div class="list" + ng-init="setForm(saltForm, 'saltForm')"> + + <div class="item item-text-wrap text-center padding hidden-xs" > + <a class="pull-right icon-help" ng-click="showHelpModal('join-salt')"></a> + <span translate>ACCOUNT.NEW.SALT_WARNING</span> + </div> + + <!-- salt --> + <div class="item item-input" + ng-class="{ 'item-input-error': saltForm.$submitted && saltForm.username.$invalid}"> + <span class="input-label" translate>LOGIN.SALT</span> + <input ng-if="!showUsername" + name="username" type="password" placeholder="{{'LOGIN.SALT_HELP' | translate}}" + ng-change="formDataChanged()" + ng-model="formData.username" + ng-minlength="8" + required> + <input ng-if="showUsername" + name="username" type="text" placeholder="{{'LOGIN.SALT_HELP' | translate}}" + ng-change="formDataChanged()" + ng-model="formData.username" + ng-minlength="8" + required> + </div> + <div class="form-errors" + ng-show="saltForm.$submitted && saltForm.username.$error" + ng-messages="saltForm.username.$error"> + <div class="form-error" ng-message="minlength"> + <span translate="ERROR.FIELD_TOO_SHORT_WITH_LENGTH" translate-values="{minLength: 8}"></span> + </div> + <div class="form-error" ng-message="required"> + <span translate="ERROR.FIELD_REQUIRED"></span> + </div> + </div> + + <!-- confirm salt --> + <div class="item item-input" + ng-class="{ 'item-input-error': saltForm.$submitted && saltForm.confirmSalt.$invalid}"> + <span class="input-label pull-right" translate>ACCOUNT.NEW.SALT_CONFIRM</span> + <input ng-if="!showUsername" + name="confirmUsername" type="password" + placeholder="{{'ACCOUNT.NEW.SALT_CONFIRM_HELP' | translate}}" + ng-model="formData.confirmUsername" + compare-to="formData.username"> + <input ng-if="showUsername" + name="confirmUsername" type="text" + placeholder="{{'ACCOUNT.NEW.SALT_CONFIRM_HELP' | translate}}" + ng-model="formData.confirmUsername" + compare-to="formData.username"> + </div> + <div class="form-errors" + ng-show="saltForm.$submitted && saltForm.confirmUsername.$error" + ng-messages="saltForm.confirmUsername.$error"> + <div class="form-error" ng-message="compareTo"> + <span translate="ERROR.SALT_NOT_CONFIRMED"></span> + </div> + </div> + + <!-- Show values --> + <div class="item item-toggle dark"> + <span translate>COMMON.SHOW_VALUES</span> + <label class="toggle toggle-royal"> + <input type="checkbox" ng-model="showUsername"> + <div class="track"> + <div class="handle"></div> + </div> + </label> + </div> + + <div class="padding hidden-xs text-right"> + <button class="button button-clear button-dark ink" ng-click="closeModal()" type="button" translate>COMMON.BTN_CANCEL + </button> + <button class="button button-calm icon-right ion-chevron-right ink" type="submit" translate> + COMMON.BTN_NEXT + <i class="icon ion-arrow-right-a"></i> + </button> + </div> + </div> + </form> + </ion-content> + </ion-slide-page> + + <!-- STEP 2: password--> + <ion-slide-page> + <ion-content class="has-header" scroll="false"> + <form name="passwordForm" novalidate="" ng-submit="doNext('passwordForm')"> + + <div class="item item-text-wrap text-center padding hidden-xs" > + <a class="pull-right icon-help" ng-click="showHelpModal('join-password')"></a> + <span translate>ACCOUNT.NEW.PASSWORD_WARNING</span> + </div> + + <div class="list" + ng-init="setForm(passwordForm, 'passwordForm')"> + + <!-- password --> + <div class="item item-input" + ng-class="{ 'item-input-error': passwordForm.$submitted && passwordForm.password.$invalid}"> + <span class="input-label" translate>LOGIN.PASSWORD</span> + <input ng-if="!showPassword" + name="password" type="password" placeholder="{{'LOGIN.PASSWORD_HELP' | translate}}" + ng-model="formData.password" + ng-change="formDataChanged()" + ng-minlength="8" + required> + <input ng-if="showPassword" + name="text" type="text" placeholder="{{'LOGIN.PASSWORD_HELP' | translate}}" + ng-model="formData.password" + ng-change="formDataChanged()" + ng-minlength="8" + required> + </div> + <div class="form-errors" + ng-show="passwordForm.$submitted && passwordForm.password.$error" + ng-messages="passwordForm.password.$error"> + <div class="form-error" ng-message="minlength"> + <span translate="ERROR.FIELD_TOO_SHORT_WITH_LENGTH" translate-values="{minLength: 8}"></span> + </div> + <div class="form-error" ng-message="required"> + <span translate="ERROR.FIELD_REQUIRED"></span> + </div> + </div> + + <!-- confirm password --> + <div class="item item-input" + ng-class="{ 'item-input-error': passwordForm.$submitted && passwordForm.confirmPassword.$invalid}"> + <span class="input-label" translate>ACCOUNT.NEW.PASSWORD_CONFIRM</span> + <input ng-if="!showPassword" + name="confirmPassword" type="password" + placeholder="{{'ACCOUNT.NEW.PASSWORD_CONFIRM_HELP' | translate}}" + ng-model="formData.confirmPassword" + compare-to="formData.password"> + <input ng-if="showPassword" + name="confirmPassword" type="text" + placeholder="{{'ACCOUNT.NEW.PASSWORD_CONFIRM_HELP' | translate}}" + ng-model="formData.confirmPassword" + compare-to="formData.password"> + </div> + <div class="form-errors" + ng-show="passwordForm.$submitted && passwordForm.confirmPassword.$error" + ng-messages="passwordForm.confirmPassword.$error"> + <div class="form-error" ng-message="compareTo"> + <span translate="ERROR.PASSWORD_NOT_CONFIRMED"></span> + </div> + </div> + + <!-- Show values --> + <div class="item item-toggle dark"> + <span translate>COMMON.SHOW_VALUES</span> + <label class="toggle toggle-royal"> + <input type="checkbox" ng-model="showPassword"> + <div class="track"> + <div class="handle"></div> + </div> + </label> + </div> + </div> + + <div class="padding hidden-xs text-right"> + <button class="button button-clear button-dark ink" ng-click="closeModal()" type="button" translate>COMMON.BTN_CANCEL + </button> + <button class="button button-calm icon-right ion-chevron-right ink" type="submit" translate> + COMMON.BTN_NEXT + </button> + </div> + + <div class="padding hidden-xs"> + </div> + </form> + </ion-content> + </ion-slide-page> + + + <!--<cs-extension-point name="last-slide"></cs-extension-point>--> + + <!-- STEP 3: last slide --> + <ion-slide-page> + <ion-content class="has-header" scroll="false"> + + <!-- Computing --> + + <div class="padding text-center" ng-if="formData.computing"> + <ion-spinner icon="android"></ion-spinner> + </div> + <!-- ng-if="formData.computing" --> + + <!-- Account available --> + <div ng-if="accountAvailable && !formData.computing"> + <div class="padding text-center" translate>ACCOUNT.NEW.LAST_SLIDE_CONGRATULATION</div> + + <div class="list"> + + <ion-item class="item item-text-wrap item-border"> + <div class="dark pull-right padding-right" ng-if="formData.computing"> + <ion-spinner icon="android"></ion-spinner> + </div> + <span class="input-label" translate>COMMON.PUBKEY</span> + <span class="gray text-no-wrap" ng-if="formData.computing" translate> + ACCOUNT.NEW.COMPUTING_PUBKEY + </span> + <span class="gray text-no-wrap" ng-if="formData.pubkey"> + {{formData.pubkey}} + </span> + </ion-item> + </div> + + <div class="padding hidden-xs text-right"> + <button class="button button-clear button-dark ink" ng-click="closeModal()" type="button" translate>COMMON.BTN_CANCEL + </button> + <button class="button button-positive ink" ng-click="doNewAccount()" translate> + COMMON.BTN_SEND + <i class="icon ion-android-send"></i> + </button> + </div> + </div> + + <!-- Existing non-empty account --> + <div ng-if="!accountAvailable && !formData.computing"> + + <ion-item class="item-icon-left item-text-wrap text-center"> + <i class="icon ion-android-close active"></i> + <span id="modal-license" translate>ERROR.EXISTING_ACCOUNT</span> + </ion-item> + + + <div class="list"> + + <ion-item class="item item-text-wrap item-border"> + <div class="dark pull-right padding-right" ng-if="formData.computing"> + <ion-spinner icon="android"></ion-spinner> + </div> + <span class="gray text-no-wrap" ng-if="formData.computing" translate> + ACCOUNT.NEW.COMPUTING_PUBKEY + </span> + <div class="padding text-center"> + <span class="gray text-no-wrap" ng-if="formData.pubkey"> + {{formData.pubkey}} + </span> + </div> + </ion-item> + + <div class="padding text-center"> + <span translate>ERROR.EXISTING_ACCOUNT_REQUEST</span> + </div> + + </div> + <div class="padding hidden-xs text-left"> + <button class="button button-assertive icon-left ion-chevron-left ink" + ng-click="identifierRecovery()" translate> + COMMON.BTN_MODIFY + </button> + </div> + </div> + + </ion-content> + </ion-slide-page> + </ion-slide-box> +</ion-modal-view> diff --git a/www/templates/wallet/slides/slides_revocation_1.html b/www/templates/wallet/slides/slides_revocation_1.html index 8d76ac730b4a12fe46d95df78f0ae2fdbec5f8b5..5d427b37c88ed7cb2945a1b3aefaa25a4acbb124 100644 --- a/www/templates/wallet/slides/slides_revocation_1.html +++ b/www/templates/wallet/slides/slides_revocation_1.html @@ -2,11 +2,11 @@ <ion-content class="has-header padding"> <h3 translate>ACCOUNT.SECURITY.REVOCATION</h3> <div class="list"> - <div class="item card item-icon-right stable-bg padding ink dark" + <button class="item card item-icon-right stable-bg padding ink dark" ng-click="downloadRevokeFile()" ng-if="isLogin && hasSelf"> <i class="icon ion-android-archive"></i> <span ng-bind-html="'ACCOUNT.SECURITY.DOWNLOAD_REVOKE' | translate"></span> - </div> + </button> <div class="item card item-icon-right stable-bg padding ink dark" ng-click="slideNext()"> <i class="icon ion-ios-arrow-right"></i>