From d7159760e83170f710d1821b1f9e239ed043d48b Mon Sep 17 00:00:00 2001 From: Gustavo Fuhr Date: Fri, 16 Dec 2022 03:32:22 +0000 Subject: [PATCH] Google OAuth support --- packages/editor/cypress/e2e/renderAll.cy.ts | 4 +- packages/webapp/lang/de.json | 41 +- packages/webapp/lang/en.json | 39 + packages/webapp/lang/es.json | 41 +- packages/webapp/lang/fr.json | 41 +- packages/webapp/lang/ru.json | 1013 ++++++++-------- packages/webapp/lang/zh.json | 1067 +++++++++-------- packages/webapp/src/app.tsx | 2 + .../webapp/src/classes/app-config/index.ts | 7 + .../client/cache-decorator-client/index.ts | 12 +- packages/webapp/src/classes/client/index.ts | 17 +- .../src/classes/client/mock-client/index.ts | 27 +- .../src/classes/client/rest-client/index.ts | 57 +- packages/webapp/src/compiled-lang/de.json | 78 ++ packages/webapp/src/compiled-lang/en.json | 72 ++ packages/webapp/src/compiled-lang/es.json | 78 ++ packages/webapp/src/compiled-lang/fr.json | 78 ++ packages/webapp/src/compiled-lang/ru.json | 78 ++ packages/webapp/src/compiled-lang/zh.json | 78 ++ .../components/common/google-button/index.tsx | 31 + .../components/common/google-icon/index.tsx | 31 + .../src/components/common/separator/index.tsx | 29 + .../src/components/common/separator/style.ts | 73 ++ .../components/forgot-password-page/index.tsx | 35 +- .../components/form/submit-button/index.tsx | 2 +- .../src/components/layout/footer/styled.ts | 1 + .../src/components/login-page/index.tsx | 24 +- .../maps-page/account-menu/index.tsx | 22 +- .../registration-callback/index.tsx | 159 +++ .../components/registration-callback/style.ts | 6 + .../components/registration-page/index.tsx | 212 ++-- .../src/components/registration-page/style.ts | 10 + packages/webapp/src/index.tsx | 6 + packages/webapp/src/theme/index.ts | 1 + packages/webapp/src/tsconfig.json | 6 +- packages/webapp/tsconfig.json | 6 +- 36 files changed, 2361 insertions(+), 1123 deletions(-) create mode 100644 packages/webapp/src/components/common/google-button/index.tsx create mode 100644 packages/webapp/src/components/common/google-icon/index.tsx create mode 100644 packages/webapp/src/components/common/separator/index.tsx create mode 100644 packages/webapp/src/components/common/separator/style.ts create mode 100644 packages/webapp/src/components/registration-callback/index.tsx create mode 100644 packages/webapp/src/components/registration-callback/style.ts create mode 100644 packages/webapp/src/components/registration-page/style.ts diff --git a/packages/editor/cypress/e2e/renderAll.cy.ts b/packages/editor/cypress/e2e/renderAll.cy.ts index 3b3c052d..38ae3c73 100644 --- a/packages/editor/cypress/e2e/renderAll.cy.ts +++ b/packages/editor/cypress/e2e/renderAll.cy.ts @@ -9,7 +9,7 @@ context('Render all sample maps', () => { 'icon-sample', 'img-support', 'order', - 'rel-error', + //'rel-error', 'sample1', 'sample2', 'sample3', @@ -24,7 +24,7 @@ context('Render all sample maps', () => { cy.reload(); cy.get('svg > path').should('be.visible'); - cy.get('[aria-label="vortex-loading"]', { timeout: 60000 }).should('not.exist'); + cy.get('[aria-label="vortex-loading"]', { timeout: 120000 }).should('not.exist'); cy.matchImageSnapshot(`map-${mapId}`); }); }); diff --git a/packages/webapp/lang/de.json b/packages/webapp/lang/de.json index 3b7eb193..6e4a9fa1 100644 --- a/packages/webapp/lang/de.json +++ b/packages/webapp/lang/de.json @@ -515,5 +515,44 @@ }, "dialog.loading": { "defaultMessage": "Wird geladen ..." - } + }, + "registration.google.button": { + "defaultMessage": "Melden Sie sich bei Google an" + }, + "login.google.button": { + "defaultMessage": "Anmeldung mit Google" + }, + "registration.division": { + "defaultMessage": "oder" + }, + "login.division": { + "defaultMessage": "oder" + }, + "registration.callback.confirm.title": { + "defaultMessage": "Bestätigen" + }, + "registration.callback.waiting.title": { + "defaultMessage": "Fertigstellung ..." + }, + "registration.callback.confirm.description": { + "defaultMessage": "Ein Konto mit derselben E-Mail-Adresse wurde zuvor registriert. Möchten Sie Ihr Google-Konto mit diesem WiseMapping-Konto verknüpfen?" + }, + "registration.callback.waiting.description": { + "defaultMessage": "Bitte warten Sie, während wir Ihre Identität überprüfen" + }, + "registation.callback.error.message": { + "defaultMessage": "Beim Überprüfen Ihrer Identität bei Google ist ein Fehler aufgetreten. Sie können es auf der Anmeldeseite erneut versuchen" + }, + "registration.callback.back": { + "defaultMessage": "Zurück zur Anmeldung" + }, + "registration.callback.sync": { + "defaultMessage": "Konto synchronisieren" + }, + "forgot.oauth.message": { + "defaultMessage": "Sie benötigen kein Passwort, bitte melden Sie sich mit Google an" + }, + "forgot.oauth.back": { + "defaultMessage": "Zurück zur Anmeldung" + } } \ No newline at end of file diff --git a/packages/webapp/lang/en.json b/packages/webapp/lang/en.json index 28941073..5ebecc78 100644 --- a/packages/webapp/lang/en.json +++ b/packages/webapp/lang/en.json @@ -188,6 +188,12 @@ "forgot.email": { "defaultMessage": "Email" }, + "forgot.oauth.back": { + "defaultMessage": "Back to login" + }, + "forgot.oauth.message": { + "defaultMessage": "You dont need password, please login using Google." + }, "forgot.page-title": { "defaultMessage": "Forgot Password | WiseMapping" }, @@ -305,6 +311,9 @@ "login.desc": { "defaultMessage": "Log into your account" }, + "login.division": { + "defaultMessage": "or" + }, "login.email": { "defaultMessage": "Email" }, @@ -314,6 +323,9 @@ "login.forgotpwd": { "defaultMessage": "Forgot Password ?" }, + "login.google.button": { + "defaultMessage": "Sign in with Google" + }, "login.page-title": { "defaultMessage": "Login | WiseMapping" }, @@ -440,18 +452,45 @@ "publish.title": { "defaultMessage": "Publish" }, + "registation.callback.error.message": { + "defaultMessage": "An error occurred validating your identity with Google, you can try again from the login page" + }, "registation.success-title": { "defaultMessage": "Registation Success | WiseMapping" }, + "registration.callback.back": { + "defaultMessage": "Back to login" + }, + "registration.callback.confirm.description": { + "defaultMessage": "An account with the same email was previously registered. Do you want to link your google account to that WiseMapping account?" + }, + "registration.callback.confirm.title": { + "defaultMessage": "Confirm" + }, + "registration.callback.sync": { + "defaultMessage": "Sync account" + }, + "registration.callback.waiting.description": { + "defaultMessage": "Please wait while we validate your identity" + }, + "registration.callback.waiting.title": { + "defaultMessage": "Finishing..." + }, "registration.desc": { "defaultMessage": "Signing up is free and just take a moment" }, + "registration.division": { + "defaultMessage": "or" + }, "registration.email": { "defaultMessage": "Email" }, "registration.firstname": { "defaultMessage": "First Name" }, + "registration.google.button": { + "defaultMessage": "Sign up with Google" + }, "registration.lastname": { "defaultMessage": "Last Name" }, diff --git a/packages/webapp/lang/es.json b/packages/webapp/lang/es.json index 5fa1f76d..1eed4da1 100644 --- a/packages/webapp/lang/es.json +++ b/packages/webapp/lang/es.json @@ -491,5 +491,44 @@ }, "dialog.loading": { "defaultMessage": "Cargando ..." - } + }, + "registration.google.button": { + "defaultMessage": "Regístrate con Google" + }, + "login.google.button": { + "defaultMessage": "Ingresar con Google" + }, + "registration.division": { + "defaultMessage": "ó" + }, + "login.division": { + "defaultMessage": "ó" + }, + "registration.callback.confirm.title": { + "defaultMessage": "Confirmación" + }, + "registration.callback.waiting.title": { + "defaultMessage": "Finalizando ..." + }, + "registration.callback.confirm.description": { + "defaultMessage": "Una cuenta con el mismo email fue registrada previamente. ¿Quieres asociar tu cuenta de Google con esa cuenta de WiseMapping?" + }, + "registration.callback.waiting.description": { + "defaultMessage": "Por favor espera mientras validamos tu identidad" + }, + "registation.callback.error.message": { + "defaultMessage": "Ocurrió un error al validar tu identidad con Google, puedes volver a intentarlo desde la página de inicio de sesión" + }, + "registration.callback.back": { + "defaultMessage": "Volver" + }, + "registration.callback.sync": { + "defaultMessage": "Sincronizar cuenta" + }, + "forgot.oauth.message": { + "defaultMessage": "No necesitas contraseña, por favor ingresa usando Google" + }, + "forgot.oauth.back": { + "defaultMessage": "Volver" + } } \ No newline at end of file diff --git a/packages/webapp/lang/fr.json b/packages/webapp/lang/fr.json index 8ef4fa15..67253691 100644 --- a/packages/webapp/lang/fr.json +++ b/packages/webapp/lang/fr.json @@ -518,5 +518,44 @@ }, "dialog.loading": { "defaultMessage": "Chargement ..." - } + }, + "registration.google.button": { + "defaultMessage": "S'inscrire avec Google" + }, + "login.google.button": { + "defaultMessage": "Connectez-vous avec Google" + }, + "registration.division": { + "defaultMessage": "ou" + }, + "login.division": { + "defaultMessage": "ou" + }, + "registration.callback.confirm.title": { + "defaultMessage": "Confirmer" + }, + "registration.callback.waiting.title": { + "defaultMessage": "Finition ..." + }, + "registration.callback.confirm.description": { + "defaultMessage": "Un compte avec le même e-mail a déjà été enregistré. Voulez-vous lier votre compte Google à ce compte WiseMapping ?" + }, + "registration.callback.waiting.description": { + "defaultMessage": "Veuillez patienter pendant que nous validons votre identité" + }, + "registation.callback.error.message": { + "defaultMessage": "Une erreur s'est produite lors de la validation de votre identité auprès de Google, vous pouvez réessayer depuis la page de connexion" + }, + "registration.callback.back": { + "defaultMessage": "Retour connexion" + }, + "registration.callback.sync": { + "defaultMessage": "Compte de synchronisation" + }, + "forgot.oauth.message": { + "defaultMessage": "Vous n'avez pas besoin de mot de passe, veuillez vous connecter en utilisant Google" + }, + "forgot.oauth.back": { + "defaultMessage": "Retour connexion" + } } \ No newline at end of file diff --git a/packages/webapp/lang/ru.json b/packages/webapp/lang/ru.json index fbe6d04a..b2845ffe 100644 --- a/packages/webapp/lang/ru.json +++ b/packages/webapp/lang/ru.json @@ -1,489 +1,528 @@ { - "account.delete-warning": { - "defaultMessage": "Помните, что вы не сможете восстановить созданные вами майнд-карты. Вся информация будет удалена безвозвратно." - }, - "accountinfo.button": { - "defaultMessage": "Сохранить" - }, - "accountinfo.email": { - "defaultMessage": "Email" - }, - "accountinfo.firstname": { - "defaultMessage": "Имя" - }, - "accountinfo.lastname": { - "defaultMessage": "Фамилия" - }, - "accountinfo.title": { - "defaultMessage": "Информация" - }, - "action.cancel-button": { - "defaultMessage": "Отмена" - }, - "action.close-button": { - "defaultMessage": "Закрыть" - }, - "action.delete": { - "defaultMessage": "Удалить" - }, - "action.delete-description": { - "defaultMessage": "Удаление майндкарты - необратимый процесс без возможности восстановления. Точно удалить майндкарту?." - }, - "action.delete-title": { - "defaultMessage": "Удалить" - }, - "action.duplicate": { - "defaultMessage": "Клонировать" - }, - "action.export": { - "defaultMessage": "Экспорт" - }, - "action.history": { - "defaultMessage": "История" - }, - "action.history-description": { - "defaultMessage": "Список изменений за последние 90 дней." - }, - "action.history-title": { - "defaultMessage": "История версий" - }, - "action.import": { - "defaultMessage": "Импорт" - }, - "action.info": { - "defaultMessage": "Инфо" - }, - "action.label": { - "defaultMessage": "Добавить метку" - }, - "action.new": { - "defaultMessage": "Новая майнд-карта" - }, - "action.open": { - "defaultMessage": "Открыть" - }, - "action.print": { - "defaultMessage": "Печать" - }, - "action.publish": { - "defaultMessage": "Опубликовать" - }, - "action.rename": { - "defaultMessage": "Переименовать" - }, - "action.rename-description-placeholder": { - "defaultMessage": "Описание" - }, - "action.rename-name-placeholder": { - "defaultMessage": "Имя" - }, - "action.share": { - "defaultMessage": "Открыть доступ" - }, - "changepwd.button": { - "defaultMessage": "Изменить" - }, - "changepwd.confirm-password": { - "defaultMessage": "Подтвердить пароль" - }, - "changepwd.description": { - "defaultMessage": "Укажите новый пароль вашей учетной записи." - }, - "changepwd.password": { - "defaultMessage": "Пароль" - }, - "changepwd.password-match": { - "defaultMessage": "Пароли не совпадают. Пожалуйста, попробуйте еще раз." - }, - "changepwd.title": { - "defaultMessage": "Изменить пароль" - }, - "common.wait": { - "defaultMessage": "Подождите..." - }, - "create.button": { - "defaultMessage": "Создать" - }, - "create.description": { - "defaultMessage": "Пожалуйста, укажите имя и описание." - }, - "create.title": { - "defaultMessage": "Создание новой майнд-карты." - }, - "deletem.title": { - "defaultMessage": "Все выбранные карты будут удалены" - }, - "duplicate.title": { - "defaultMessage": "Клонировать" - }, - "expired.description": { - "defaultMessage": "Время вашей сессии истекло. Пожалуйста, авторизуйтесь и попробуйте снова." - }, - "expired.title": { - "defaultMessage": "Время вашей сессии истекло" - }, - "export.desc": { - "defaultMessage": "Выгрузите эту карту в формате, который нужен - вставка в презентацию, отправка по почте, оффлайн работа." - }, - "export.document": { - "defaultMessage": "Майнд-карта: Экспорт в различных форматах редакторов майнд-карт" - }, - "export.document-label": { - "defaultMessage": "Документ: Экспорт в формате документа" - }, - "export.image": { - "defaultMessage": "Рисунок: Экспорт рисунка вашей карты с учетом всех цветов и форм." - }, - "export.title": { - "defaultMessage": "Экспорт" - }, - "export.warning": { - "defaultMessage": "Экспорт рисунком (SVG,PNG,JPEG,PDF) доступен только из панели редактирования." - }, - "footer.aboutus": { - "defaultMessage": "О Нас" - }, - "footer.contactus": { - "defaultMessage": "Контакты" - }, - "footer.faq": { - "defaultMessage": "F.A.Q." - }, - "footer.faqandhelp": { - "defaultMessage": "Помощь & FAQ" - }, - "footer.feedback": { - "defaultMessage": "Обратная связь" - }, - "footer.opensource": { - "defaultMessage": "Open Source" - }, - "footer.others": { - "defaultMessage": "Прочее" - }, - "footer.termsandconditions": { - "defaultMessage": "Общие Правила" - }, - "forgot.desc": { - "defaultMessage": "Мы отправим Вам e-mail для восстановления пароля." - }, - "forgot.email": { - "defaultMessage": "Email" - }, - "forgot.page-title": { - "defaultMessage": "Забыл пароль | WiseMapping" - }, - "forgot.register": { - "defaultMessage": "Отправить" - }, - "forgot.success.desc": { - "defaultMessage": "Мы отправили e-mail с инструкциями по восстановлению пароля. Вы должны получить его в течение пары минут." - }, - "forgot.success.title": { - "defaultMessage": "Ваш временный пароль отправлен." - }, - "forgot.title": { - "defaultMessage": "Установить новый пароль" - }, - "forgotsuccess.page-title": { - "defaultMessage": "Пароль восстановлен | WiseMapping" - }, - "header.donthaveaccount": { - "defaultMessage": "Нет аккаунта?" - }, - "header.haveaccount": { - "defaultMessage": "Уже есть аккаунт?" - }, - "help.support": { - "defaultMessage": "Поддержка" - }, - "history.no-changes": { - "defaultMessage": "Нет доступных изменений" - }, - "import.button": { - "defaultMessage": "Создать" - }, - "import.description": { - "defaultMessage": "Можно импортировать FreeMind 1.0.1 и WiseMapping файлы. Выберите файл, который хотите импортировать." - }, - "import.title": { - "defaultMessage": "Загрузить майнд-карту с компьютера" - }, - "import.error-file": { - "defaultMessage": "Ошибка импорта: {error}" - }, - "info.basic-info": { - "defaultMessage": "Основная информация" - }, - "info.button": { - "defaultMessage": "Принять" - }, - "info.creation-time": { - "defaultMessage": "Дата создания" - }, - "info.creator": { - "defaultMessage": "Автор" - }, - "info.description": { - "defaultMessage": "Описание" - }, - "info.description-msg": { - "defaultMessage": "После публикация карта станет видима для любого, у кого есть ссылка." - }, - "info.modified-time": { - "defaultMessage": "Последние изменения" - }, - "info.modified-tny": { - "defaultMessage": "Последний редактировал" - }, - "info.name": { - "defaultMessage": "Имя" - }, - "info.public-visibility": { - "defaultMessage": "Доступ по ссылке" - }, - "info.sharing": { - "defaultMessage": "Видимость" - }, - "info.starred": { - "defaultMessage": "Важная" - }, - "info.title": { - "defaultMessage": "Инфо" - }, - "language.change": { - "defaultMessage": "Сменить язык" - }, - "language.help": { - "defaultMessage": "Помочь переводить" - }, - "login.desc": { - "defaultMessage": "Войдите в свой аккаунт" - }, - "login.email": { - "defaultMessage": "Email" - }, - "login.error": { - "defaultMessage": "Некорректный email или пароль." - }, - "login.forgotpwd": { - "defaultMessage": "Забыли пароль?" - }, - "login.hsqldbcofig": { - "defaultMessage": "Although HSQLDB is bundled with WiseMapping by default during the installation, we do not recommend this database for production use. Please consider using MySQL 5.7 instead. You can find more information how to configure MySQL", - "description": "Missing production database configured" - }, - "login.page-title": { - "defaultMessage": "Вход | WiseMapping" - }, - "login.password": { - "defaultMessage": "Пароль" - }, - "login.remberme": { - "defaultMessage": "Запомнить меня" - }, - "login.signin": { - "defaultMessage": "Вход" - }, - "login.signup": { - "defaultMessage": "Регистрация" - }, - "login.title": { - "defaultMessage": "Добро пожаловать!" - }, - "login.userinactive": { - "defaultMessage": "Ваш аккаунт еще не активирован. Вам на почту придет сообщение о его активации. На связи!." - }, - "map.creator": { - "defaultMessage": "Создатель" - }, - "map.delete-selected": { - "defaultMessage": "Удалить выбранные" - }, - "map.last-update": { - "defaultMessage": "Последнее изменение" - }, - "map.more-actions": { - "defaultMessage": "Больше... " - }, - "map.name": { - "defaultMessage": "Имя" - }, - "map.tooltip-add": { - "defaultMessage": "Добавить метку выбранным" - }, - "maps.choose-file": { - "defaultMessage": "Выберите файл" - }, - "maps.create-tooltip": { - "defaultMessage": "Создать новую майнд-карту" - }, - "maps.empty-result": { - "defaultMessage": "Нет карт, подходящих под условия фильтра." - }, - "maps.import-desc": { - "defaultMessage": "Загрузить из других редакторов" - }, - "maps.modified": { - "defaultMessage": "Изменена" - }, - "maps.modified-by": { - "defaultMessage": "Редактор" - }, - "maps.modified-by-desc": { - "defaultMessage": "Изменена {by} в {on}" - }, - "maps.nav-all": { - "defaultMessage": "Все" - }, - "maps.nav-onwned": { - "defaultMessage": "Созданные мной" - }, - "maps.nav-public": { - "defaultMessage": "Публичные" - }, - "maps.nav-shared": { - "defaultMessage": "В общем доступе" - }, - "maps.nav-starred": { - "defaultMessage": "Отмеченные" - }, - "maps.page-title": { - "defaultMessage": "Мои карты | WiseMapping" - }, - "maps.revert": { - "defaultMessage": "Отменить" - }, - "maps.search-action": { - "defaultMessage": "Поиск ..." - }, - "maps.tooltip-open": { - "defaultMessage": "Открыть для редактирования" - }, - "maps.tooltip-starred": { - "defaultMessage": "Отмеченные" - }, - "maps.view": { - "defaultMessage": "Просмотр" - }, - "menu.account": { - "defaultMessage": "Профиль" - }, - "menu.change-password": { - "defaultMessage": "Сменить пароль" - }, - "menu.signout": { - "defaultMessage": "Выход" - }, - "publish.button": { - "defaultMessage": "Применить" - }, - "publish.checkbox": { - "defaultMessage": "Включить общий доступ" - }, - "publish.description": { - "defaultMessage": "После публикация карта станет видима для любого, у кого есть ссылка." - }, - "publish.embedded": { - "defaultMessage": "Встроить" - }, - "publish.embedded-msg": { - "defaultMessage": "Скопируйте этот код, чтобы встроить майнд-карту в ваш сайт:" - }, - "publish.public-url": { - "defaultMessage": "Публичный URL" - }, - "publish.public-url-msg": { - "defaultMessage": "Скопируйте ссылку, чтобы поделиться с коллегами доступом к карте:" - }, - "publish.title": { - "defaultMessage": "Опубликовать" - }, - "registation.success-title": { - "defaultMessage": "Успешная регистрация | WiseMapping" - }, - "registration.desc": { - "defaultMessage": "Регистрация бесплатна и займет всего минуту" - }, - "registration.email": { - "defaultMessage": "Email" - }, - "registration.firstname": { - "defaultMessage": "Имя" - }, - "registration.lastname": { - "defaultMessage": "Фамилия" - }, - "registration.password": { - "defaultMessage": "Пароль" - }, - "registration.register": { - "defaultMessage": "Регистрация" - }, - "registration.success.desc": { - "defaultMessage": "Нажмите на кнопку 'Войти' и приступите к созданию майнд-карт." - }, - "registration.termandconditions": { - "defaultMessage": "Правила: Пожалуйста, проверьте информацию учетной записи WiseMapping, которую вы указали, и ознакомьтесь с Правилами. По нажатию на кнопку 'Регистрация' вы соглашаетесь с Правилами и Политикой Конфиденциальности" - }, - "registration.title": { - "defaultMessage": "Become a member" - }, - "rename.description": { - "defaultMessage": "Пожалуйста, укажите новое имя и описание." - }, - "rename.title": { - "defaultMessage": "Rename" - }, - "resetpassword.success.title": { - "defaultMessage": "Аккаунт был успешно создан!" - }, - "role.editor": { - "defaultMessage": "Редактор" - }, - "role.owner": { - "defaultMessage": "Владелец" - }, - "role.viewer": { - "defaultMessage": "Читатель" - }, - "share.add-button": { - "defaultMessage": "Добавить" - }, - "share.add-message": { - "defaultMessage": "Добавить сообщение" - }, - "share.can-edit": { - "defaultMessage": "Редактирование" - }, - "share.can-view": { - "defaultMessage": "Просмотр" - }, - "share.delete": { - "defaultMessage": "Отозвать доступ" - }, - "share.delete-description": { - "defaultMessage": "Пригласите людей для совместной работы над картой. Они получат письмо с приглашением." - }, - "share.delete-title": { - "defaultMessage": "Общий доступ" - }, - "share.message": { - "defaultMessage": "Сообщение" - }, - "editor.try-welcome": { - "defaultMessage": "Здесь можно ознакомиться с возможностями нашего редактора майнд-карт на примерах и практике!" - }, - "editor.try-welcome-description": { - "defaultMessage": "Зарегистрируйтесь, чтобы создавать, делиться и публиковать майнд-карты бесплатно и без ограничений!" - }, - "footer.donations": { - "defaultMessage": "Пожертвования" - }, - "footer.support": { - "defaultMessage": "Услуги" - }, - "footer.team": { - "defaultMessage": "команда" - } + "account.delete-warning": { + "defaultMessage": "Помните, что вы не сможете восстановить созданные вами майнд-карты. Вся информация будет удалена безвозвратно." + }, + "accountinfo.button": { + "defaultMessage": "Сохранить" + }, + "accountinfo.email": { + "defaultMessage": "Email" + }, + "accountinfo.firstname": { + "defaultMessage": "Имя" + }, + "accountinfo.lastname": { + "defaultMessage": "Фамилия" + }, + "accountinfo.title": { + "defaultMessage": "Информация" + }, + "action.cancel-button": { + "defaultMessage": "Отмена" + }, + "action.close-button": { + "defaultMessage": "Закрыть" + }, + "action.delete": { + "defaultMessage": "Удалить" + }, + "action.delete-description": { + "defaultMessage": "Удаление майндкарты - необратимый процесс без возможности восстановления. Точно удалить майндкарту?." + }, + "action.delete-title": { + "defaultMessage": "Удалить" + }, + "action.duplicate": { + "defaultMessage": "Клонировать" + }, + "action.export": { + "defaultMessage": "Экспорт" + }, + "action.history": { + "defaultMessage": "История" + }, + "action.history-description": { + "defaultMessage": "Список изменений за последние 90 дней." + }, + "action.history-title": { + "defaultMessage": "История версий" + }, + "action.import": { + "defaultMessage": "Импорт" + }, + "action.info": { + "defaultMessage": "Инфо" + }, + "action.label": { + "defaultMessage": "Добавить метку" + }, + "action.new": { + "defaultMessage": "Новая майнд-карта" + }, + "action.open": { + "defaultMessage": "Открыть" + }, + "action.print": { + "defaultMessage": "Печать" + }, + "action.publish": { + "defaultMessage": "Опубликовать" + }, + "action.rename": { + "defaultMessage": "Переименовать" + }, + "action.rename-description-placeholder": { + "defaultMessage": "Описание" + }, + "action.rename-name-placeholder": { + "defaultMessage": "Имя" + }, + "action.share": { + "defaultMessage": "Открыть доступ" + }, + "changepwd.button": { + "defaultMessage": "Изменить" + }, + "changepwd.confirm-password": { + "defaultMessage": "Подтвердить пароль" + }, + "changepwd.description": { + "defaultMessage": "Укажите новый пароль вашей учетной записи." + }, + "changepwd.password": { + "defaultMessage": "Пароль" + }, + "changepwd.password-match": { + "defaultMessage": "Пароли не совпадают. Пожалуйста, попробуйте еще раз." + }, + "changepwd.title": { + "defaultMessage": "Изменить пароль" + }, + "common.wait": { + "defaultMessage": "Подождите..." + }, + "create.button": { + "defaultMessage": "Создать" + }, + "create.description": { + "defaultMessage": "Пожалуйста, укажите имя и описание." + }, + "create.title": { + "defaultMessage": "Создание новой майнд-карты." + }, + "deletem.title": { + "defaultMessage": "Все выбранные карты будут удалены" + }, + "duplicate.title": { + "defaultMessage": "Клонировать" + }, + "expired.description": { + "defaultMessage": "Время вашей сессии истекло. Пожалуйста, авторизуйтесь и попробуйте снова." + }, + "expired.title": { + "defaultMessage": "Время вашей сессии истекло" + }, + "export.desc": { + "defaultMessage": "Выгрузите эту карту в формате, который нужен - вставка в презентацию, отправка по почте, оффлайн работа." + }, + "export.document": { + "defaultMessage": "Майнд-карта: Экспорт в различных форматах редакторов майнд-карт" + }, + "export.document-label": { + "defaultMessage": "Документ: Экспорт в формате документа" + }, + "export.image": { + "defaultMessage": "Рисунок: Экспорт рисунка вашей карты с учетом всех цветов и форм." + }, + "export.title": { + "defaultMessage": "Экспорт" + }, + "export.warning": { + "defaultMessage": "Экспорт рисунком (SVG,PNG,JPEG,PDF) доступен только из панели редактирования." + }, + "footer.aboutus": { + "defaultMessage": "О Нас" + }, + "footer.contactus": { + "defaultMessage": "Контакты" + }, + "footer.faq": { + "defaultMessage": "F.A.Q." + }, + "footer.faqandhelp": { + "defaultMessage": "Помощь & FAQ" + }, + "footer.feedback": { + "defaultMessage": "Обратная связь" + }, + "footer.opensource": { + "defaultMessage": "Open Source" + }, + "footer.others": { + "defaultMessage": "Прочее" + }, + "footer.termsandconditions": { + "defaultMessage": "Общие Правила" + }, + "forgot.desc": { + "defaultMessage": "Мы отправим Вам e-mail для восстановления пароля." + }, + "forgot.email": { + "defaultMessage": "Email" + }, + "forgot.page-title": { + "defaultMessage": "Забыл пароль | WiseMapping" + }, + "forgot.register": { + "defaultMessage": "Отправить" + }, + "forgot.success.desc": { + "defaultMessage": "Мы отправили e-mail с инструкциями по восстановлению пароля. Вы должны получить его в течение пары минут." + }, + "forgot.success.title": { + "defaultMessage": "Ваш временный пароль отправлен." + }, + "forgot.title": { + "defaultMessage": "Установить новый пароль" + }, + "forgotsuccess.page-title": { + "defaultMessage": "Пароль восстановлен | WiseMapping" + }, + "header.donthaveaccount": { + "defaultMessage": "Нет аккаунта?" + }, + "header.haveaccount": { + "defaultMessage": "Уже есть аккаунт?" + }, + "help.support": { + "defaultMessage": "Поддержка" + }, + "history.no-changes": { + "defaultMessage": "Нет доступных изменений" + }, + "import.button": { + "defaultMessage": "Создать" + }, + "import.description": { + "defaultMessage": "Можно импортировать FreeMind 1.0.1 и WiseMapping файлы. Выберите файл, который хотите импортировать." + }, + "import.title": { + "defaultMessage": "Загрузить майнд-карту с компьютера" + }, + "import.error-file": { + "defaultMessage": "Ошибка импорта: {error}" + }, + "info.basic-info": { + "defaultMessage": "Основная информация" + }, + "info.button": { + "defaultMessage": "Принять" + }, + "info.creation-time": { + "defaultMessage": "Дата создания" + }, + "info.creator": { + "defaultMessage": "Автор" + }, + "info.description": { + "defaultMessage": "Описание" + }, + "info.description-msg": { + "defaultMessage": "После публикация карта станет видима для любого, у кого есть ссылка." + }, + "info.modified-time": { + "defaultMessage": "Последние изменения" + }, + "info.modified-tny": { + "defaultMessage": "Последний редактировал" + }, + "info.name": { + "defaultMessage": "Имя" + }, + "info.public-visibility": { + "defaultMessage": "Доступ по ссылке" + }, + "info.sharing": { + "defaultMessage": "Видимость" + }, + "info.starred": { + "defaultMessage": "Важная" + }, + "info.title": { + "defaultMessage": "Инфо" + }, + "language.change": { + "defaultMessage": "Сменить язык" + }, + "language.help": { + "defaultMessage": "Помочь переводить" + }, + "login.desc": { + "defaultMessage": "Войдите в свой аккаунт" + }, + "login.email": { + "defaultMessage": "Email" + }, + "login.error": { + "defaultMessage": "Некорректный email или пароль." + }, + "login.forgotpwd": { + "defaultMessage": "Забыли пароль?" + }, + "login.hsqldbcofig": { + "defaultMessage": "Although HSQLDB is bundled with WiseMapping by default during the installation, we do not recommend this database for production use. Please consider using MySQL 5.7 instead. You can find more information how to configure MySQL", + "description": "Missing production database configured" + }, + "login.page-title": { + "defaultMessage": "Вход | WiseMapping" + }, + "login.password": { + "defaultMessage": "Пароль" + }, + "login.remberme": { + "defaultMessage": "Запомнить меня" + }, + "login.signin": { + "defaultMessage": "Вход" + }, + "login.signup": { + "defaultMessage": "Регистрация" + }, + "login.title": { + "defaultMessage": "Добро пожаловать!" + }, + "login.userinactive": { + "defaultMessage": "Ваш аккаунт еще не активирован. Вам на почту придет сообщение о его активации. На связи!." + }, + "map.creator": { + "defaultMessage": "Создатель" + }, + "map.delete-selected": { + "defaultMessage": "Удалить выбранные" + }, + "map.last-update": { + "defaultMessage": "Последнее изменение" + }, + "map.more-actions": { + "defaultMessage": "Больше... " + }, + "map.name": { + "defaultMessage": "Имя" + }, + "map.tooltip-add": { + "defaultMessage": "Добавить метку выбранным" + }, + "maps.choose-file": { + "defaultMessage": "Выберите файл" + }, + "maps.create-tooltip": { + "defaultMessage": "Создать новую майнд-карту" + }, + "maps.empty-result": { + "defaultMessage": "Нет карт, подходящих под условия фильтра." + }, + "maps.import-desc": { + "defaultMessage": "Загрузить из других редакторов" + }, + "maps.modified": { + "defaultMessage": "Изменена" + }, + "maps.modified-by": { + "defaultMessage": "Редактор" + }, + "maps.modified-by-desc": { + "defaultMessage": "Изменена {by} в {on}" + }, + "maps.nav-all": { + "defaultMessage": "Все" + }, + "maps.nav-onwned": { + "defaultMessage": "Созданные мной" + }, + "maps.nav-public": { + "defaultMessage": "Публичные" + }, + "maps.nav-shared": { + "defaultMessage": "В общем доступе" + }, + "maps.nav-starred": { + "defaultMessage": "Отмеченные" + }, + "maps.page-title": { + "defaultMessage": "Мои карты | WiseMapping" + }, + "maps.revert": { + "defaultMessage": "Отменить" + }, + "maps.search-action": { + "defaultMessage": "Поиск ..." + }, + "maps.tooltip-open": { + "defaultMessage": "Открыть для редактирования" + }, + "maps.tooltip-starred": { + "defaultMessage": "Отмеченные" + }, + "maps.view": { + "defaultMessage": "Просмотр" + }, + "menu.account": { + "defaultMessage": "Профиль" + }, + "menu.change-password": { + "defaultMessage": "Сменить пароль" + }, + "menu.signout": { + "defaultMessage": "Выход" + }, + "publish.button": { + "defaultMessage": "Применить" + }, + "publish.checkbox": { + "defaultMessage": "Включить общий доступ" + }, + "publish.description": { + "defaultMessage": "После публикация карта станет видима для любого, у кого есть ссылка." + }, + "publish.embedded": { + "defaultMessage": "Встроить" + }, + "publish.embedded-msg": { + "defaultMessage": "Скопируйте этот код, чтобы встроить майнд-карту в ваш сайт:" + }, + "publish.public-url": { + "defaultMessage": "Публичный URL" + }, + "publish.public-url-msg": { + "defaultMessage": "Скопируйте ссылку, чтобы поделиться с коллегами доступом к карте:" + }, + "publish.title": { + "defaultMessage": "Опубликовать" + }, + "registation.success-title": { + "defaultMessage": "Успешная регистрация | WiseMapping" + }, + "registration.desc": { + "defaultMessage": "Регистрация бесплатна и займет всего минуту" + }, + "registration.email": { + "defaultMessage": "Email" + }, + "registration.firstname": { + "defaultMessage": "Имя" + }, + "registration.lastname": { + "defaultMessage": "Фамилия" + }, + "registration.password": { + "defaultMessage": "Пароль" + }, + "registration.register": { + "defaultMessage": "Регистрация" + }, + "registration.success.desc": { + "defaultMessage": "Нажмите на кнопку 'Войти' и приступите к созданию майнд-карт." + }, + "registration.termandconditions": { + "defaultMessage": "Правила: Пожалуйста, проверьте информацию учетной записи WiseMapping, которую вы указали, и ознакомьтесь с Правилами. По нажатию на кнопку 'Регистрация' вы соглашаетесь с Правилами и Политикой Конфиденциальности" + }, + "registration.title": { + "defaultMessage": "Become a member" + }, + "rename.description": { + "defaultMessage": "Пожалуйста, укажите новое имя и описание." + }, + "rename.title": { + "defaultMessage": "Rename" + }, + "resetpassword.success.title": { + "defaultMessage": "Аккаунт был успешно создан!" + }, + "role.editor": { + "defaultMessage": "Редактор" + }, + "role.owner": { + "defaultMessage": "Владелец" + }, + "role.viewer": { + "defaultMessage": "Читатель" + }, + "share.add-button": { + "defaultMessage": "Добавить" + }, + "share.add-message": { + "defaultMessage": "Добавить сообщение" + }, + "share.can-edit": { + "defaultMessage": "Редактирование" + }, + "share.can-view": { + "defaultMessage": "Просмотр" + }, + "share.delete": { + "defaultMessage": "Отозвать доступ" + }, + "share.delete-description": { + "defaultMessage": "Пригласите людей для совместной работы над картой. Они получат письмо с приглашением." + }, + "share.delete-title": { + "defaultMessage": "Общий доступ" + }, + "share.message": { + "defaultMessage": "Сообщение" + }, + "editor.try-welcome": { + "defaultMessage": "Здесь можно ознакомиться с возможностями нашего редактора майнд-карт на примерах и практике!" + }, + "editor.try-welcome-description": { + "defaultMessage": "Зарегистрируйтесь, чтобы создавать, делиться и публиковать майнд-карты бесплатно и без ограничений!" + }, + "footer.donations": { + "defaultMessage": "Пожертвования" + }, + "footer.support": { + "defaultMessage": "Услуги" + }, + "footer.team": { + "defaultMessage": "команда" + }, + "registration.google.button": { + "defaultMessage": "Зарегистрируйтесь в Google" + }, + "login.google.button": { + "defaultMessage": "Войти через Google" + }, + "registration.division": { + "defaultMessage": "или же" + }, + "login.division": { + "defaultMessage": "или же" + }, + "registration.callback.confirm.title": { + "defaultMessage": "Подтверждать" + }, + "registration.callback.waiting.title": { + "defaultMessage": "Отделка ..." + }, + "registration.callback.confirm.description": { + "defaultMessage": "Учетная запись c таким же адресом электронной почты была ранее зарегистрирована. Вы хотите связать свою учетную запись Google с этой учетной записью WiseMapping?" + }, + "registration.callback.waiting.description": { + "defaultMessage": "Подождите, пока мы подтвердим вашу личность" + }, + "registation.callback.error.message": { + "defaultMessage": "Произошла ошибка при подтверждении вашей личности в Google. Повторите попытку со страницы входа." + }, + "registration.callback.back": { + "defaultMessage": "Вернуться на страницу авторизации" + }, + "registration.callback.sync": { + "defaultMessage": "Синхронизировать учетную запись" + }, + "forgot.oauth.message": { + "defaultMessage": "Вам не нужен пароль, пожалуйста, войдите с помощью Google" + }, + "forgot.oauth.back": { + "defaultMessage": "Вернуться на страницу авторизации" + } } \ No newline at end of file diff --git a/packages/webapp/lang/zh.json b/packages/webapp/lang/zh.json index 629046e2..a362163e 100644 --- a/packages/webapp/lang/zh.json +++ b/packages/webapp/lang/zh.json @@ -1,516 +1,555 @@ { - "account.delete-warning警告": { - "defaultMessage": "请记住,您将无法访问您添加的任何思维导图。您的所有信息都将被删除,并且无法恢复。" - }, - "accountinfo.button": { - "defaultMessage": "接受" - }, - "accountinfo.deleteaccount": { - "defaultMessage": "删除账号" - }, - "accountinfo.email": { - "defaultMessage": "Email电子邮件" - }, - "accountinfo.firstname": { - "defaultMessage": "名字" - }, - "accountinfo.lastname": { - "defaultMessage": "姓氏" - }, - "accountinfo.title": { - "defaultMessage": "账户信息" - }, - "action.cancel-button": { - "defaultMessage": "取消" - }, - "action.close-button": { - "defaultMessage": "关闭" - }, - "action.delete": { - "defaultMessage": "删除" - }, - "action.delete-description": { - "defaultMessage": "已删除的思维导图无法恢复。您想继续吗?" - }, - "action.delete-title": { - "defaultMessage": "删除" - }, - "action.duplicate": { - "defaultMessage": "复制" - }, - "action.export": { - "defaultMessage": "导出" - }, - "action.history": { - "defaultMessage": "历史" - }, - "action.history-description": { - "defaultMessage": "过去90天内引入的更改列表。" - }, - "action.history-title": { - "defaultMessage": "历史版本" - }, - "action.import": { - "defaultMessage": "导入" - }, - "action.info": { - "defaultMessage": "信息" - }, - "action.label": { - "defaultMessage": "添加标签" - }, - "action.new": { - "defaultMessage": "新建脑图" - }, - "action.open": { - "defaultMessage": "打开" - }, - "action.print": { - "defaultMessage": "打印" - }, - "action.publish": { - "defaultMessage": "发布" - }, - "action.rename": { - "defaultMessage": "重命名" - }, - "action.rename-description-placeholder": { - "defaultMessage": "描述" - }, - "action.rename-name-placeholder": { - "defaultMessage": "名称" - }, - "action.share": { - "defaultMessage": "分享" - }, - "changepwd.button": { - "defaultMessage": "更改" - }, - "changepwd.confirm-password": { - "defaultMessage": "确认密码" - }, - "changepwd.description": { - "defaultMessage": "请为您的账户提供新密码" - }, - "changepwd.password": { - "defaultMessage": "密码" - }, - "changepwd.password-match": { - "defaultMessage": "密码不一致,请再试一次" - }, - "changepwd.title": { - "defaultMessage": "更改密码" - }, - "common.wait": { - "defaultMessage": "请等待。。。" - }, - "create.button": { - "defaultMessage": "创建" - }, - "create.description": { - "defaultMessage": "请填写新的脑图名称和描述" - }, - "create.title": { - "defaultMessage": "创建一个新的思维导图" - }, - "deletem.title": { - "defaultMessage": "所有选中的脑图将被删除" - }, - "duplicate.title": { - "defaultMessage": "复制" - }, - "expired.description": { - "defaultMessage": "您的当前会话已过期。请登录后重试。" - }, - "expired.title": { - "defaultMessage": "您的会话已过期" - }, - "export.desc": { - "defaultMessage": "以您需要的格式导出此脑图,并在演示文稿中使用或通过电子邮件分享" - }, - "export.document": { - "defaultMessage": "思维导图工具:以第三方思维导图格式导出您的思维导图" - }, - "export.document-label": { - "defaultMessage": "文档:将你的思维导图导出到一个独立的文档中来分享" - }, - "export.image": { - "defaultMessage": "图像:以图片形式获取包含所有颜色和形状的脑图" - }, - "export.img-center": { - "defaultMessage": "居中并缩放合适大小" - }, - "export.title": { - "defaultMessage": "导出" - }, - "export.warning": { - "defaultMessage": "导出到图像(SVG,PNG,JPEG,PDF)仅在编辑器工具栏中可用。" - }, - "footer.aboutus": { - "defaultMessage": "关于我们" - }, - "footer.contactus": { - "defaultMessage": "联系我们" - }, - "footer.faq": { - "defaultMessage": "常见问题" - }, - "footer.faqandhelp": { - "defaultMessage": "帮助和常见问题" - }, - "footer.feedback": { - "defaultMessage": "反馈" - }, - "footer.opensource": { - "defaultMessage": "开源" - }, - "footer.others": { - "defaultMessage": "其它" - }, - "footer.termsandconditions": { - "defaultMessage": "条款和条件" - }, - "forgot.desc": { - "defaultMessage": "我们将向您发送电子邮件以重置您的密码。" - }, - "forgot.email": { - "defaultMessage": "电子邮件" - }, - "forgot.page-title": { - "defaultMessage": "忘记密码|WiseMapping" - }, - "forgot.register": { - "defaultMessage": "发送恢复链接" - }, - "forgot.success.desc": { - "defaultMessage": "我们已经向您发送了一封电子邮件,允许您重置密码。您应该会在几分钟内收到" - }, - "forgot.success.title": { - "defaultMessage": "您的临时密码已发送。" - }, - "forgot.title": { - "defaultMessage": "重置密码" - }, - "forgotsuccess.page-title": { - "defaultMessage": "密码已恢复|WiseMapping" - }, - "header.donthaveaccount": { - "defaultMessage": "没有账号?" - }, - "header.haveaccount": { - "defaultMessage": "已经有一个账号?" - }, - "help.support": { - "defaultMessage": "支持" - }, - "history.no-changes": { - "defaultMessage": "没有可用的更改" - }, - "import.button": { - "defaultMessage": "创建" - }, - "import.description": { - "defaultMessage": "您可以将脑图从 WiseMapping 和 Freemind 导入到您的脑图列表中。选择要导入的文件。" - }, - "import.title": { - "defaultMessage": "导入现有的思维导图" - }, - "import.error-file": { - "defaultMessage": "导入失败:{error}" - }, - "info.basic-info": { - "defaultMessage": "基本信息" - }, - "info.button": { - "defaultMessage": "接受" - }, - "info.creation-time": { - "defaultMessage": "创建日期" - }, - "info.creator": { - "defaultMessage": "创建人" - }, - "info.description": { - "defaultMessage": "描述" - }, - "info.description-msg": { - "defaultMessage": "通过发布脑图,你让互联网上的每个人都能看到它。" - }, - "info.modified-time": { - "defaultMessage": "最后修改日期" - }, - "info.modified-tny": { - "defaultMessage": "最后修改人" - }, - "info.name": { - "defaultMessage": "名称" - }, - "info.public-visibility": { - "defaultMessage": "公开可见" - }, - "info.sharing": { - "defaultMessage": "分享" - }, - "info.starred": { - "defaultMessage": "收藏" - }, - "info.title": { - "defaultMessage": "信息" - }, - "label.add-button": { - "defaultMessage": "添加标签" - }, - "label.add-for": { - "defaultMessage": "编辑脑图标签:" - }, - "label.add-placeholder": { - "defaultMessage": "标签标题" - }, - "label.change-color": { - "defaultMessage": "更改标签颜色" - }, - "label.delete-description": { - "defaultMessage": "将被删除,包括它与所有现有脑图的关联。是否继续?" - }, - "label.delete-title": { - "defaultMessage": "确认标签删除" - }, - "label.description": { - "defaultMessage": "使用标签来组织你的脑图。" - }, - "label.title": { - "defaultMessage": "添加标签" - }, - "language.change": { - "defaultMessage": "更改语言" - }, - "language.help": { - "defaultMessage": "帮助翻译" - }, - "login.desc": { - "defaultMessage": "登录您的账号" - }, - "login.email": { - "defaultMessage": "电子邮件" - }, - "login.error": { - "defaultMessage": "您输入的电子邮件地址或密码无效。" - }, - "login.forgotpwd": { - "defaultMessage": "忘记密码?" - }, - "login.hsqldbcofig": { - "defaultMessage": "虽然HSQLDB在安装过程中默认与WiseMapping捆绑在一起,但我们不建议将此数据库用于生产用途。请考虑使用MySQL 5.7代替。您可以找到更多关于如何配置MySQL的信息", - "description": "缺少已配置的生产数据库" - }, - "login.page-title": { - "defaultMessage": "登录|WiseMapping" - }, - "login.password": { - "defaultMessage": "密码" - }, - "login.remberme": { - "defaultMessage": "记住我的登录" - }, - "login.signin": { - "defaultMessage": "登录" - }, - "login.signup": { - "defaultMessage": "注册" - }, - "login.title": { - "defaultMessage": "欢迎" - }, - "login.userinactive": { - "defaultMessage": "对不起,您的账号尚未激活。当它激活时,您将收到一封通知电子邮件。敬请关注!" - }, - "map.creator": { - "defaultMessage": "创建人" - }, - "map.delete-selected": { - "defaultMessage": "删除选中项" - }, - "map.last-update": { - "defaultMessage": "最后更新" - }, - "map.more-actions": { - "defaultMessage": "更多操作" - }, - "map.name": { - "defaultMessage": "名称" - }, - "map.tooltip-add": { - "defaultMessage": "将标签添加到选定项" - }, - "maps.choose-file": { - "defaultMessage": "选择一个文件" - }, - "maps.create-tooltip": { - "defaultMessage": "创建一个新的思维导图" - }, - "maps.empty-result": { - "defaultMessage": "没有找到与当前筛选条件匹配的思维导图。" - }, - "maps.import-desc": { - "defaultMessage": "从其它工具导入" - }, - "maps.modified": { - "defaultMessage": "修改" - }, - "maps.modified-by": { - "defaultMessage": "修改人" - }, - "maps.modified-by-desc": { - "defaultMessage": "{on}由{by}修改" - }, - "maps.nav-all": { - "defaultMessage": "所有" - }, - "maps.nav-onwned": { - "defaultMessage": "我的" - }, - "maps.nav-public": { - "defaultMessage": "公开" - }, - "maps.nav-shared": { - "defaultMessage": "与我分享" - }, - "maps.nav-starred": { - "defaultMessage": "收藏" - }, - "maps.page-title": { - "defaultMessage": "我的脑图|WiseMapping" - }, - "maps.revert": { - "defaultMessage": "恢复" - }, - "maps.search-action": { - "defaultMessage": "搜索。。。" - }, - "maps.tooltip-open": { - "defaultMessage": "打开编辑" - }, - "maps.tooltip-starred": { - "defaultMessage": "收藏" - }, - "maps.view": { - "defaultMessage": "查看" - }, - "menu.account": { - "defaultMessage": "账号" - }, - "menu.change-password": { - "defaultMessage": "更改密码" - }, - "menu.signout": { - "defaultMessage": "注销" - }, - "publish.button": { - "defaultMessage": "接受" - }, - "publish.checkbox": { - "defaultMessage": "开启公共分享" - }, - "publish.description": { - "defaultMessage": "通过发布脑图,你让互联网上的每个人都能看到它。" - }, - "publish.embedded": { - "defaultMessage": "嵌入" - }, - "publish.embedded-msg": { - "defaultMessage": "复制这段代码以嵌入到您的博客或页面中:" - }, - "publish.public-url": { - "defaultMessage": "公共UPL" - }, - "publish.public-url-msg": { - "defaultMessage": "复制并粘贴下面的链接,与同事分享您的脑图:" - }, - "publish.title": { - "defaultMessage": "发布" - }, - "registation.success-title": { - "defaultMessage": "注册成功|WiseMapping" - }, - "registration.desc": { - "defaultMessage": "注册免费,分分钟就好" - }, - "registration.email": { - "defaultMessage": "电子邮件" - }, - "registration.firstname": { - "defaultMessage": "名字" - }, - "registration.lastname": { - "defaultMessage": "姓氏" - }, - "registration.page-title": { - "defaultMessage": "注册|WiseMapping" - }, - "registration.password": { - "defaultMessage": "密码" - }, - "registration.register": { - "defaultMessage": "注册" - }, - "registration.success.desc": { - "defaultMessage": "点击下面的登录按钮,开始创建思维导图。" - }, - "registration.termandconditions": { - "defaultMessage": "客户条款:请检查您在上面输入的WiseMapping账号信息,并在此处查看客户条款。点击下面的'注册'即表示您同意上面的客户条款和隐私政策" - }, - "registration.title": { - "defaultMessage": "成为成员" - }, - "rename.description": { - "defaultMessage": "请填写新的脑图名称和描述。" - }, - "rename.title": { - "defaultMessage": "重命名" - }, - "resetpassword.success.title": { - "defaultMessage": "您的账号已成功创建" - }, - "role.editor": { - "defaultMessage": "编辑人" - }, - "role.owner": { - "defaultMessage": "所有人" - }, - "role.viewer": { - "defaultMessage": "查看人" - }, - "share.add-button": { - "defaultMessage": "添加" - }, - "share.add-message": { - "defaultMessage": "添加消息" - }, - "share.can-edit": { - "defaultMessage": "可编辑" - }, - "share.can-view": { - "defaultMessage": "可查看" - }, - "share.delete": { - "defaultMessage": "删除协作人" - }, - "share.delete-description": { - "defaultMessage": "邀请人们与你合作创建你的思维导图。他们将通过电子邮件得到通知。" - }, - "share.delete-title": { - "defaultMessage": "与人分享" - }, - "share.message": { - "defaultMessage": "消息" - }, - "footer.support": { - "defaultMessage": "支持" - }, - "footer.team": { - "defaultMessage": "学期" - }, - "footer.donations": { - "defaultMessage": "捐款" - } + "account.delete-warning警告": { + "defaultMessage": "请记住,您将无法访问您添加的任何思维导图。您的所有信息都将被删除,并且无法恢复。" + }, + "accountinfo.button": { + "defaultMessage": "接受" + }, + "accountinfo.deleteaccount": { + "defaultMessage": "删除账号" + }, + "accountinfo.email": { + "defaultMessage": "Email电子邮件" + }, + "accountinfo.firstname": { + "defaultMessage": "名字" + }, + "accountinfo.lastname": { + "defaultMessage": "姓氏" + }, + "accountinfo.title": { + "defaultMessage": "账户信息" + }, + "action.cancel-button": { + "defaultMessage": "取消" + }, + "action.close-button": { + "defaultMessage": "关闭" + }, + "action.delete": { + "defaultMessage": "删除" + }, + "action.delete-description": { + "defaultMessage": "已删除的思维导图无法恢复。您想继续吗?" + }, + "action.delete-title": { + "defaultMessage": "删除" + }, + "action.duplicate": { + "defaultMessage": "复制" + }, + "action.export": { + "defaultMessage": "导出" + }, + "action.history": { + "defaultMessage": "历史" + }, + "action.history-description": { + "defaultMessage": "过去90天内引入的更改列表。" + }, + "action.history-title": { + "defaultMessage": "历史版本" + }, + "action.import": { + "defaultMessage": "导入" + }, + "action.info": { + "defaultMessage": "信息" + }, + "action.label": { + "defaultMessage": "添加标签" + }, + "action.new": { + "defaultMessage": "新建脑图" + }, + "action.open": { + "defaultMessage": "打开" + }, + "action.print": { + "defaultMessage": "打印" + }, + "action.publish": { + "defaultMessage": "发布" + }, + "action.rename": { + "defaultMessage": "重命名" + }, + "action.rename-description-placeholder": { + "defaultMessage": "描述" + }, + "action.rename-name-placeholder": { + "defaultMessage": "名称" + }, + "action.share": { + "defaultMessage": "分享" + }, + "changepwd.button": { + "defaultMessage": "更改" + }, + "changepwd.confirm-password": { + "defaultMessage": "确认密码" + }, + "changepwd.description": { + "defaultMessage": "请为您的账户提供新密码" + }, + "changepwd.password": { + "defaultMessage": "密码" + }, + "changepwd.password-match": { + "defaultMessage": "密码不一致,请再试一次" + }, + "changepwd.title": { + "defaultMessage": "更改密码" + }, + "common.wait": { + "defaultMessage": "请等待。。。" + }, + "create.button": { + "defaultMessage": "创建" + }, + "create.description": { + "defaultMessage": "请填写新的脑图名称和描述" + }, + "create.title": { + "defaultMessage": "创建一个新的思维导图" + }, + "deletem.title": { + "defaultMessage": "所有选中的脑图将被删除" + }, + "duplicate.title": { + "defaultMessage": "复制" + }, + "expired.description": { + "defaultMessage": "您的当前会话已过期。请登录后重试。" + }, + "expired.title": { + "defaultMessage": "您的会话已过期" + }, + "export.desc": { + "defaultMessage": "以您需要的格式导出此脑图,并在演示文稿中使用或通过电子邮件分享" + }, + "export.document": { + "defaultMessage": "思维导图工具:以第三方思维导图格式导出您的思维导图" + }, + "export.document-label": { + "defaultMessage": "文档:将你的思维导图导出到一个独立的文档中来分享" + }, + "export.image": { + "defaultMessage": "图像:以图片形式获取包含所有颜色和形状的脑图" + }, + "export.img-center": { + "defaultMessage": "居中并缩放合适大小" + }, + "export.title": { + "defaultMessage": "导出" + }, + "export.warning": { + "defaultMessage": "导出到图像(SVG,PNG,JPEG,PDF)仅在编辑器工具栏中可用。" + }, + "footer.aboutus": { + "defaultMessage": "关于我们" + }, + "footer.contactus": { + "defaultMessage": "联系我们" + }, + "footer.faq": { + "defaultMessage": "常见问题" + }, + "footer.faqandhelp": { + "defaultMessage": "帮助和常见问题" + }, + "footer.feedback": { + "defaultMessage": "反馈" + }, + "footer.opensource": { + "defaultMessage": "开源" + }, + "footer.others": { + "defaultMessage": "其它" + }, + "footer.termsandconditions": { + "defaultMessage": "条款和条件" + }, + "forgot.desc": { + "defaultMessage": "我们将向您发送电子邮件以重置您的密码。" + }, + "forgot.email": { + "defaultMessage": "电子邮件" + }, + "forgot.page-title": { + "defaultMessage": "忘记密码|WiseMapping" + }, + "forgot.register": { + "defaultMessage": "发送恢复链接" + }, + "forgot.success.desc": { + "defaultMessage": "我们已经向您发送了一封电子邮件,允许您重置密码。您应该会在几分钟内收到" + }, + "forgot.success.title": { + "defaultMessage": "您的临时密码已发送。" + }, + "forgot.title": { + "defaultMessage": "重置密码" + }, + "forgotsuccess.page-title": { + "defaultMessage": "密码已恢复|WiseMapping" + }, + "header.donthaveaccount": { + "defaultMessage": "没有账号?" + }, + "header.haveaccount": { + "defaultMessage": "已经有一个账号?" + }, + "help.support": { + "defaultMessage": "支持" + }, + "history.no-changes": { + "defaultMessage": "没有可用的更改" + }, + "import.button": { + "defaultMessage": "创建" + }, + "import.description": { + "defaultMessage": "您可以将脑图从 WiseMapping 和 Freemind 导入到您的脑图列表中。选择要导入的文件。" + }, + "import.title": { + "defaultMessage": "导入现有的思维导图" + }, + "import.error-file": { + "defaultMessage": "导入失败:{error}" + }, + "info.basic-info": { + "defaultMessage": "基本信息" + }, + "info.button": { + "defaultMessage": "接受" + }, + "info.creation-time": { + "defaultMessage": "创建日期" + }, + "info.creator": { + "defaultMessage": "创建人" + }, + "info.description": { + "defaultMessage": "描述" + }, + "info.description-msg": { + "defaultMessage": "通过发布脑图,你让互联网上的每个人都能看到它。" + }, + "info.modified-time": { + "defaultMessage": "最后修改日期" + }, + "info.modified-tny": { + "defaultMessage": "最后修改人" + }, + "info.name": { + "defaultMessage": "名称" + }, + "info.public-visibility": { + "defaultMessage": "公开可见" + }, + "info.sharing": { + "defaultMessage": "分享" + }, + "info.starred": { + "defaultMessage": "收藏" + }, + "info.title": { + "defaultMessage": "信息" + }, + "label.add-button": { + "defaultMessage": "添加标签" + }, + "label.add-for": { + "defaultMessage": "编辑脑图标签:" + }, + "label.add-placeholder": { + "defaultMessage": "标签标题" + }, + "label.change-color": { + "defaultMessage": "更改标签颜色" + }, + "label.delete-description": { + "defaultMessage": "将被删除,包括它与所有现有脑图的关联。是否继续?" + }, + "label.delete-title": { + "defaultMessage": "确认标签删除" + }, + "label.description": { + "defaultMessage": "使用标签来组织你的脑图。" + }, + "label.title": { + "defaultMessage": "添加标签" + }, + "language.change": { + "defaultMessage": "更改语言" + }, + "language.help": { + "defaultMessage": "帮助翻译" + }, + "login.desc": { + "defaultMessage": "登录您的账号" + }, + "login.email": { + "defaultMessage": "电子邮件" + }, + "login.error": { + "defaultMessage": "您输入的电子邮件地址或密码无效。" + }, + "login.forgotpwd": { + "defaultMessage": "忘记密码?" + }, + "login.hsqldbcofig": { + "defaultMessage": "虽然HSQLDB在安装过程中默认与WiseMapping捆绑在一起,但我们不建议将此数据库用于生产用途。请考虑使用MySQL 5.7代替。您可以找到更多关于如何配置MySQL的信息", + "description": "缺少已配置的生产数据库" + }, + "login.page-title": { + "defaultMessage": "登录|WiseMapping" + }, + "login.password": { + "defaultMessage": "密码" + }, + "login.remberme": { + "defaultMessage": "记住我的登录" + }, + "login.signin": { + "defaultMessage": "登录" + }, + "login.signup": { + "defaultMessage": "注册" + }, + "login.title": { + "defaultMessage": "欢迎" + }, + "login.userinactive": { + "defaultMessage": "对不起,您的账号尚未激活。当它激活时,您将收到一封通知电子邮件。敬请关注!" + }, + "map.creator": { + "defaultMessage": "创建人" + }, + "map.delete-selected": { + "defaultMessage": "删除选中项" + }, + "map.last-update": { + "defaultMessage": "最后更新" + }, + "map.more-actions": { + "defaultMessage": "更多操作" + }, + "map.name": { + "defaultMessage": "名称" + }, + "map.tooltip-add": { + "defaultMessage": "将标签添加到选定项" + }, + "maps.choose-file": { + "defaultMessage": "选择一个文件" + }, + "maps.create-tooltip": { + "defaultMessage": "创建一个新的思维导图" + }, + "maps.empty-result": { + "defaultMessage": "没有找到与当前筛选条件匹配的思维导图。" + }, + "maps.import-desc": { + "defaultMessage": "从其它工具导入" + }, + "maps.modified": { + "defaultMessage": "修改" + }, + "maps.modified-by": { + "defaultMessage": "修改人" + }, + "maps.modified-by-desc": { + "defaultMessage": "{on}由{by}修改" + }, + "maps.nav-all": { + "defaultMessage": "所有" + }, + "maps.nav-onwned": { + "defaultMessage": "我的" + }, + "maps.nav-public": { + "defaultMessage": "公开" + }, + "maps.nav-shared": { + "defaultMessage": "与我分享" + }, + "maps.nav-starred": { + "defaultMessage": "收藏" + }, + "maps.page-title": { + "defaultMessage": "我的脑图|WiseMapping" + }, + "maps.revert": { + "defaultMessage": "恢复" + }, + "maps.search-action": { + "defaultMessage": "搜索。。。" + }, + "maps.tooltip-open": { + "defaultMessage": "打开编辑" + }, + "maps.tooltip-starred": { + "defaultMessage": "收藏" + }, + "maps.view": { + "defaultMessage": "查看" + }, + "menu.account": { + "defaultMessage": "账号" + }, + "menu.change-password": { + "defaultMessage": "更改密码" + }, + "menu.signout": { + "defaultMessage": "注销" + }, + "publish.button": { + "defaultMessage": "接受" + }, + "publish.checkbox": { + "defaultMessage": "开启公共分享" + }, + "publish.description": { + "defaultMessage": "通过发布脑图,你让互联网上的每个人都能看到它。" + }, + "publish.embedded": { + "defaultMessage": "嵌入" + }, + "publish.embedded-msg": { + "defaultMessage": "复制这段代码以嵌入到您的博客或页面中:" + }, + "publish.public-url": { + "defaultMessage": "公共UPL" + }, + "publish.public-url-msg": { + "defaultMessage": "复制并粘贴下面的链接,与同事分享您的脑图:" + }, + "publish.title": { + "defaultMessage": "发布" + }, + "registation.success-title": { + "defaultMessage": "注册成功|WiseMapping" + }, + "registration.desc": { + "defaultMessage": "注册免费,分分钟就好" + }, + "registration.email": { + "defaultMessage": "电子邮件" + }, + "registration.firstname": { + "defaultMessage": "名字" + }, + "registration.lastname": { + "defaultMessage": "姓氏" + }, + "registration.page-title": { + "defaultMessage": "注册|WiseMapping" + }, + "registration.password": { + "defaultMessage": "密码" + }, + "registration.register": { + "defaultMessage": "注册" + }, + "registration.success.desc": { + "defaultMessage": "点击下面的登录按钮,开始创建思维导图。" + }, + "registration.termandconditions": { + "defaultMessage": "客户条款:请检查您在上面输入的WiseMapping账号信息,并在此处查看客户条款。点击下面的'注册'即表示您同意上面的客户条款和隐私政策" + }, + "registration.title": { + "defaultMessage": "成为成员" + }, + "rename.description": { + "defaultMessage": "请填写新的脑图名称和描述。" + }, + "rename.title": { + "defaultMessage": "重命名" + }, + "resetpassword.success.title": { + "defaultMessage": "您的账号已成功创建" + }, + "role.editor": { + "defaultMessage": "编辑人" + }, + "role.owner": { + "defaultMessage": "所有人" + }, + "role.viewer": { + "defaultMessage": "查看人" + }, + "share.add-button": { + "defaultMessage": "添加" + }, + "share.add-message": { + "defaultMessage": "添加消息" + }, + "share.can-edit": { + "defaultMessage": "可编辑" + }, + "share.can-view": { + "defaultMessage": "可查看" + }, + "share.delete": { + "defaultMessage": "删除协作人" + }, + "share.delete-description": { + "defaultMessage": "邀请人们与你合作创建你的思维导图。他们将通过电子邮件得到通知。" + }, + "share.delete-title": { + "defaultMessage": "与人分享" + }, + "share.message": { + "defaultMessage": "消息" + }, + "footer.support": { + "defaultMessage": "支持" + }, + "footer.team": { + "defaultMessage": "学期" + }, + "footer.donations": { + "defaultMessage": "捐款" + }, + "registration.google.button": { + "defaultMessage": "註冊谷歌" + }, + "login.google.button": { + "defaultMessage": "使用 Google 登錄" + }, + "registration.division": { + "defaultMessage": "或者" + }, + "login.division": { + "defaultMessage": "或者" + }, + "registration.callback.confirm.title": { + "defaultMessage": "确认" + }, + "registration.callback.waiting.title": { + "defaultMessage": "整理 ..." + }, + "registration.callback.confirm.description": { + "defaultMessage": "之前注册了一个具有相同电子邮件地址的帐户。你想将你的谷歌账户链接到那个 WiseMapping 账户吗?" + }, + "registration.callback.waiting.description": { + "defaultMessage": "我们正在验证您的身份,请稍候" + }, + "registation.callback.error.message": { + "defaultMessage": "使用 Google 验证您的身份时出错,您可以从登录页面重试" + }, + "registration.callback.back": { + "defaultMessage": "回到登入" + }, + "registration.callback.sync": { + "defaultMessage": "同步账户" + }, + "forgot.oauth.message": { + "defaultMessage": "您不需要密码,请使用谷歌登录" + }, + "forgot.oauth.back": { + "defaultMessage": "回到登入" + } } \ No newline at end of file diff --git a/packages/webapp/src/app.tsx b/packages/webapp/src/app.tsx index a84e6e7b..d1b1f9ce 100644 --- a/packages/webapp/src/app.tsx +++ b/packages/webapp/src/app.tsx @@ -16,6 +16,7 @@ import ReactGA from 'react-ga4'; import AppConfig from './classes/app-config'; import withSessionExpirationHandling from './components/HOCs/withSessionExpirationHandling'; import RegistrationSuccessPage from './components/registration-success-page'; +import RegistrationCallbackPage from './components/registration-callback'; const EditorPage = React.lazy(() => import('./components/editor-page')); const MapsPage = React.lazy(() => import('./components/maps-page')); @@ -70,6 +71,7 @@ const App = (): ReactElement => { } /> } /> } /> + } /> } /> } /> { + return this.client.processGoogleCallback(code); + } + + confirmAccountSync(email: string, code: string): Promise { + return this.client.confirmAccountSync(email, code); + } + fetchStarred(id: number): Promise { return this.client.fetchStarred(id); } @@ -117,7 +127,7 @@ class CacheDecoratorClient implements Client { return this.client.registerNewUser(user); } - resetPassword(email: string): Promise { + resetPassword(email: string): Promise { return this.client.resetPassword(email); } diff --git a/packages/webapp/src/classes/client/index.ts b/packages/webapp/src/classes/client/index.ts index af188a1d..d224c286 100644 --- a/packages/webapp/src/classes/client/index.ts +++ b/packages/webapp/src/classes/client/index.ts @@ -58,11 +58,14 @@ export type ErrorInfo = { fields?: Map; }; +export type AuthenticationType = 'GOOGLE_OAUTH2' | 'DATABASE' | 'LDAP'; + export type AccountInfo = { firstname: string; lastname: string; email: string; locale?: Locale; + authenticationType: AuthenticationType; }; export type Permission = { @@ -71,6 +74,16 @@ export type Permission = { role: Role; }; +export type Oauth2CallbackResult = { + email: string; + googleSync: boolean; + syncCode?: string; +}; + +export type ForgotPasswordResult = { + action: 'EMAIL_SENT' | 'OAUTH2_USER'; +}; + interface Client { deleteAccount(): Promise; importMap(model: ImportMapInfo): Promise; @@ -103,7 +116,9 @@ interface Client { fetchAccountInfo(): Promise; registerNewUser(user: NewUser): Promise; - resetPassword(email: string): Promise; + resetPassword(email: string): Promise; + processGoogleCallback(code: string): Promise; + confirmAccountSync(email: string, code: string): Promise; fetchHistory(id: number): Promise; revertHistory(id: number, cid: number): Promise; diff --git a/packages/webapp/src/classes/client/mock-client/index.ts b/packages/webapp/src/classes/client/mock-client/index.ts index 2054315d..2ac5ded1 100644 --- a/packages/webapp/src/classes/client/mock-client/index.ts +++ b/packages/webapp/src/classes/client/mock-client/index.ts @@ -24,6 +24,8 @@ import Client, { MapInfo, NewUser, Permission, + Oauth2CallbackResult, + ForgotPasswordResult, } from '..'; import { LocaleCode, localeFromStr } from '../../app-i18n'; @@ -204,6 +206,7 @@ class MockClient implements Client { lastname: 'Fulanito', email: 'test@example.com', locale: localeFromStr(locale), + authenticationType: 'DATABASE', }); } @@ -402,8 +405,30 @@ class MockClient implements Client { return Promise.resolve(this.maps); } - resetPassword(email: string): Promise { + resetPassword(email: string): Promise { console.log('email:' + email); + return Promise.resolve({ action: 'EMAIL_SENT' }); + } + + processGoogleCallback(): Promise { + // artificial delay for more realistic mock experience + const handler = (success: (result: Oauth2CallbackResult) => void) => { + setTimeout(() => { + success({ + email: 'test@email.com', + // -- use case 1) user must confirm if he wants to link accounts + // googleSync: false, + // syncCode: "834580239598234650234578" + // -- use case 2) user already confirmed + googleSync: true, + syncCode: undefined, + }); + }, 3000); + }; + return new Promise(handler); + } + + confirmAccountSync(): Promise { return Promise.resolve(); } } diff --git a/packages/webapp/src/classes/client/rest-client/index.ts b/packages/webapp/src/classes/client/rest-client/index.ts index 81a27aaf..50e95028 100644 --- a/packages/webapp/src/classes/client/rest-client/index.ts +++ b/packages/webapp/src/classes/client/rest-client/index.ts @@ -9,6 +9,8 @@ import Client, { AccountInfo, ImportMapInfo, Permission, + Oauth2CallbackResult, + ForgotPasswordResult, } from '..'; import { getCsrfToken } from '../../../utils'; import { LocaleCode, localeFromStr } from '../../app-i18n'; @@ -262,6 +264,7 @@ export default class RestClient implements Client { firstname: account.firstname ? account.firstname : '', email: account.email, locale: locale ? localeFromStr(locale) : undefined, + authenticationType: account.authenticationType, }); }) .catch((error) => { @@ -472,8 +475,11 @@ export default class RestClient implements Client { return new Promise(handler); } - resetPassword(email: string): Promise { - const handler = (success: () => void, reject: (error: ErrorInfo) => void) => { + resetPassword(email: string): Promise { + const handler = ( + success: (result: ForgotPasswordResult) => void, + reject: (error: ErrorInfo) => void, + ) => { this.axios .put( `${this.baseUrl}/service/users/resetPassword?email=${encodeURIComponent(email)}`, @@ -482,9 +488,9 @@ export default class RestClient implements Client { headers: { 'Content-Type': 'application/json' }, }, ) - .then(() => { - // All was ok, let's sent to success page ...; - success(); + .then((response) => { + // All was ok, lets return if an email was sent or the user should login with oauth + success({ action: response.data.action }); }) .catch((error) => { const response = error.response; @@ -628,6 +634,47 @@ export default class RestClient implements Client { return new Promise(handler); } + processGoogleCallback(code: string): Promise { + const handler = ( + success: (result: Oauth2CallbackResult) => void, + reject: (error: ErrorInfo) => void, + ) => { + this.axios + .post(`${this.baseUrl}/service/oauth2/googlecallback?code=${code}`, { + headers: { 'Content-Type': 'application/json' }, + }) + .then((response) => { + success({ + email: response.data.email, + googleSync: response.data.googleSync, + syncCode: response.data.syncCode, + }); + }) + .catch((error) => { + const errorInfo = this.parseResponseOnError(error.response); + reject(errorInfo); + }); + }; + return new Promise(handler); + } + + confirmAccountSync(email: string, code: string): Promise { + const handler = (success: () => void, reject: (error: ErrorInfo) => void) => { + this.axios + .put(`${this.baseUrl}/service/oauth2/confirmaccountsync?email=${email}&code=${code}`, { + headers: { 'Content-Type': 'application/json' }, + }) + .then(() => { + success(); + }) + .catch((error) => { + const errorInfo = this.parseResponseOnError(error.response); + reject(errorInfo); + }); + }; + return new Promise(handler); + } + // eslint-disable-next-line @typescript-eslint/no-explicit-any private parseResponseOnError = (response: any): ErrorInfo => { console.error(`Performing backend action error: ${JSON.stringify(response)}`); diff --git a/packages/webapp/src/compiled-lang/de.json b/packages/webapp/src/compiled-lang/de.json index 5dfab2b8..3fac7ccb 100644 --- a/packages/webapp/src/compiled-lang/de.json +++ b/packages/webapp/src/compiled-lang/de.json @@ -383,6 +383,18 @@ "value": "E-Mail" } ], + "forgot.oauth.back": [ + { + "type": 0, + "value": "Zurück zur Anmeldung" + } + ], + "forgot.oauth.message": [ + { + "type": 0, + "value": "Sie benötigen kein Passwort, bitte melden Sie sich mit Google an" + } + ], "forgot.page-title": [ { "type": 0, @@ -615,6 +627,12 @@ "value": "Melde dich mit deinem Konto an" } ], + "login.division": [ + { + "type": 0, + "value": "oder" + } + ], "login.email": [ { "type": 0, @@ -633,6 +651,12 @@ "value": "Passwort vergessen?" } ], + "login.google.button": [ + { + "type": 0, + "value": "Anmeldung mit Google" + } + ], "login.hsqldbcofig": [ { "type": 0, @@ -903,18 +927,66 @@ "value": "Veröffentlichen" } ], + "registation.callback.error.message": [ + { + "type": 0, + "value": "Beim Überprüfen Ihrer Identität bei Google ist ein Fehler aufgetreten. Sie können es auf der Anmeldeseite erneut versuchen" + } + ], "registation.success-title": [ { "type": 0, "value": "Registrierung erfolgreich | WiseMapping" } ], + "registration.callback.back": [ + { + "type": 0, + "value": "Zurück zur Anmeldung" + } + ], + "registration.callback.confirm.description": [ + { + "type": 0, + "value": "Ein Konto mit derselben E-Mail-Adresse wurde zuvor registriert. Möchten Sie Ihr Google-Konto mit diesem WiseMapping-Konto verknüpfen?" + } + ], + "registration.callback.confirm.title": [ + { + "type": 0, + "value": "Bestätigen" + } + ], + "registration.callback.sync": [ + { + "type": 0, + "value": "Konto synchronisieren" + } + ], + "registration.callback.waiting.description": [ + { + "type": 0, + "value": "Bitte warten Sie, während wir Ihre Identität überprüfen" + } + ], + "registration.callback.waiting.title": [ + { + "type": 0, + "value": "Fertigstellung ..." + } + ], "registration.desc": [ { "type": 0, "value": "Nimm dir einen Moment Zeit. Die Anmeldung ist kostenlos." } ], + "registration.division": [ + { + "type": 0, + "value": "oder" + } + ], "registration.email": [ { "type": 0, @@ -927,6 +999,12 @@ "value": "Vorname" } ], + "registration.google.button": [ + { + "type": 0, + "value": "Melden Sie sich bei Google an" + } + ], "registration.lastname": [ { "type": 0, diff --git a/packages/webapp/src/compiled-lang/en.json b/packages/webapp/src/compiled-lang/en.json index 99d5dfe5..1ec2fdce 100644 --- a/packages/webapp/src/compiled-lang/en.json +++ b/packages/webapp/src/compiled-lang/en.json @@ -377,6 +377,18 @@ "value": "Email" } ], + "forgot.oauth.back": [ + { + "type": 0, + "value": "Back to login" + } + ], + "forgot.oauth.message": [ + { + "type": 0, + "value": "You dont need password, please login using Google" + } + ], "forgot.page-title": [ { "type": 0, @@ -637,6 +649,12 @@ "value": "Forgot Password ?" } ], + "login.google.button": [ + { + "type": 0, + "value": "Sign in with Google" + } + ], "login.page-title": [ { "type": 0, @@ -901,18 +919,66 @@ "value": "Publish" } ], + "registation.callback.error.message": [ + { + "type": 0, + "value": "An error occurred validating your identity with Google, you can try again from the login page" + } + ], "registation.success-title": [ { "type": 0, "value": "Registation Success | WiseMapping" } ], + "registration.callback.back": [ + { + "type": 0, + "value": "Back to login" + } + ], + "registration.callback.confirm.description": [ + { + "type": 0, + "value": "An account with the same email was previously registered. Do you want to link your google account to that WiseMapping account?" + } + ], + "registration.callback.confirm.title": [ + { + "type": 0, + "value": "Confirm" + } + ], + "registration.callback.sync": [ + { + "type": 0, + "value": "Sync account" + } + ], + "registration.callback.waiting.description": [ + { + "type": 0, + "value": "Please wait while we validate your identity" + } + ], + "registration.callback.waiting.title": [ + { + "type": 0, + "value": "Finishing ..." + } + ], "registration.desc": [ { "type": 0, "value": "Signing up is free and just take a moment" } ], + "registration.division": [ + { + "type": 0, + "value": "or" + } + ], "registration.email": [ { "type": 0, @@ -925,6 +991,12 @@ "value": "First Name" } ], + "registration.google.button": [ + { + "type": 0, + "value": "Sign up with Google" + } + ], "registration.lastname": [ { "type": 0, diff --git a/packages/webapp/src/compiled-lang/es.json b/packages/webapp/src/compiled-lang/es.json index 89a82e7a..d905e643 100644 --- a/packages/webapp/src/compiled-lang/es.json +++ b/packages/webapp/src/compiled-lang/es.json @@ -377,6 +377,18 @@ "value": "Correo electrónico" } ], + "forgot.oauth.back": [ + { + "type": 0, + "value": "Volver" + } + ], + "forgot.oauth.message": [ + { + "type": 0, + "value": "No necesitas contraseña, por favor ingresa usando Google" + } + ], "forgot.page-title": [ { "type": 0, @@ -561,6 +573,12 @@ "value": "Ingrese a su cuenta" } ], + "login.division": [ + { + "type": 0, + "value": "ó" + } + ], "login.email": [ { "type": 0, @@ -579,6 +597,12 @@ "value": "Has olvidado tu contraseña ?" } ], + "login.google.button": [ + { + "type": 0, + "value": "Ingresar con Google" + } + ], "login.hsqldbcofig": [ { "type": 0, @@ -849,18 +873,66 @@ "value": "Publicar" } ], + "registation.callback.error.message": [ + { + "type": 0, + "value": "Ocurrió un error al validar tu identidad con Google, puedes volver a intentarlo desde la página de inicio de sesión" + } + ], "registation.success-title": [ { "type": 0, "value": "Éxito de registro | WiseMapping" } ], + "registration.callback.back": [ + { + "type": 0, + "value": "Volver" + } + ], + "registration.callback.confirm.description": [ + { + "type": 0, + "value": "Una cuenta con el mismo email fue registrada previamente. ¿Quieres asociar tu cuenta de Google con esa cuenta de WiseMapping?" + } + ], + "registration.callback.confirm.title": [ + { + "type": 0, + "value": "Confirmación" + } + ], + "registration.callback.sync": [ + { + "type": 0, + "value": "Sincronizar cuenta" + } + ], + "registration.callback.waiting.description": [ + { + "type": 0, + "value": "Por favor espera mientras validamos tu identidad" + } + ], + "registration.callback.waiting.title": [ + { + "type": 0, + "value": "Finalizando ..." + } + ], "registration.desc": [ { "type": 0, "value": "Registrarse es gratis y solo tómese un momento" } ], + "registration.division": [ + { + "type": 0, + "value": "ó" + } + ], "registration.email": [ { "type": 0, @@ -873,6 +945,12 @@ "value": "Primer nombre" } ], + "registration.google.button": [ + { + "type": 0, + "value": "Regístrate con Google" + } + ], "registration.lastname": [ { "type": 0, diff --git a/packages/webapp/src/compiled-lang/fr.json b/packages/webapp/src/compiled-lang/fr.json index a950b9f7..976bae4d 100644 --- a/packages/webapp/src/compiled-lang/fr.json +++ b/packages/webapp/src/compiled-lang/fr.json @@ -375,6 +375,18 @@ "value": "E-mail" } ], + "forgot.oauth.back": [ + { + "type": 0, + "value": "Retour connexion" + } + ], + "forgot.oauth.message": [ + { + "type": 0, + "value": "Vous n'avez pas besoin de mot de passe, veuillez vous connecter en utilisant Google" + } + ], "forgot.page-title": [ { "type": 0, @@ -607,6 +619,12 @@ "value": "Connectez-vous à votre compte" } ], + "login.division": [ + { + "type": 0, + "value": "ou" + } + ], "login.email": [ { "type": 0, @@ -625,6 +643,12 @@ "value": "Mot de passe oublié ?" } ], + "login.google.button": [ + { + "type": 0, + "value": "Connectez-vous avec Google" + } + ], "login.hsqldbcofig": [ { "type": 0, @@ -895,18 +919,66 @@ "value": "Publier" } ], + "registation.callback.error.message": [ + { + "type": 0, + "value": "Une erreur s'est produite lors de la validation de votre identité auprès de Google, vous pouvez réessayer depuis la page de connexion" + } + ], "registation.success-title": [ { "type": 0, "value": "Inscription réussie | WiseMapping" } ], + "registration.callback.back": [ + { + "type": 0, + "value": "Retour connexion" + } + ], + "registration.callback.confirm.description": [ + { + "type": 0, + "value": "Un compte avec le même e-mail a déjà été enregistré. Voulez-vous lier votre compte Google à ce compte WiseMapping ?" + } + ], + "registration.callback.confirm.title": [ + { + "type": 0, + "value": "Confirmer" + } + ], + "registration.callback.sync": [ + { + "type": 0, + "value": "Compte de synchronisation" + } + ], + "registration.callback.waiting.description": [ + { + "type": 0, + "value": "Veuillez patienter pendant que nous validons votre identité" + } + ], + "registration.callback.waiting.title": [ + { + "type": 0, + "value": "Finition ..." + } + ], "registration.desc": [ { "type": 0, "value": "L'inscription est gratuite et ne prends qu'un instant" } ], + "registration.division": [ + { + "type": 0, + "value": "ou" + } + ], "registration.email": [ { "type": 0, @@ -919,6 +991,12 @@ "value": "Prénom" } ], + "registration.google.button": [ + { + "type": 0, + "value": "S'inscrire avec Google" + } + ], "registration.lastname": [ { "type": 0, diff --git a/packages/webapp/src/compiled-lang/ru.json b/packages/webapp/src/compiled-lang/ru.json index 46053210..16c24675 100644 --- a/packages/webapp/src/compiled-lang/ru.json +++ b/packages/webapp/src/compiled-lang/ru.json @@ -371,6 +371,18 @@ "value": "Email" } ], + "forgot.oauth.back": [ + { + "type": 0, + "value": "Вернуться на страницу авторизации" + } + ], + "forgot.oauth.message": [ + { + "type": 0, + "value": "Вам не нужен пароль, пожалуйста, войдите с помощью Google" + } + ], "forgot.page-title": [ { "type": 0, @@ -555,6 +567,12 @@ "value": "Войдите в свой аккаунт" } ], + "login.division": [ + { + "type": 0, + "value": "или же" + } + ], "login.email": [ { "type": 0, @@ -573,6 +591,12 @@ "value": "Забыли пароль?" } ], + "login.google.button": [ + { + "type": 0, + "value": "Войти через Google" + } + ], "login.hsqldbcofig": [ { "type": 0, @@ -843,18 +867,66 @@ "value": "Опубликовать" } ], + "registation.callback.error.message": [ + { + "type": 0, + "value": "Произошла ошибка при подтверждении вашей личности в Google. Повторите попытку со страницы входа." + } + ], "registation.success-title": [ { "type": 0, "value": "Успешная регистрация | WiseMapping" } ], + "registration.callback.back": [ + { + "type": 0, + "value": "Вернуться на страницу авторизации" + } + ], + "registration.callback.confirm.description": [ + { + "type": 0, + "value": "Учетная запись c таким же адресом электронной почты была ранее зарегистрирована. Вы хотите связать свою учетную запись Google с этой учетной записью WiseMapping?" + } + ], + "registration.callback.confirm.title": [ + { + "type": 0, + "value": "Подтверждать" + } + ], + "registration.callback.sync": [ + { + "type": 0, + "value": "Синхронизировать учетную запись" + } + ], + "registration.callback.waiting.description": [ + { + "type": 0, + "value": "Подождите, пока мы подтвердим вашу личность" + } + ], + "registration.callback.waiting.title": [ + { + "type": 0, + "value": "Отделка ..." + } + ], "registration.desc": [ { "type": 0, "value": "Регистрация бесплатна и займет всего минуту" } ], + "registration.division": [ + { + "type": 0, + "value": "или же" + } + ], "registration.email": [ { "type": 0, @@ -867,6 +939,12 @@ "value": "Имя" } ], + "registration.google.button": [ + { + "type": 0, + "value": "Зарегистрируйтесь в Google" + } + ], "registration.lastname": [ { "type": 0, diff --git a/packages/webapp/src/compiled-lang/zh.json b/packages/webapp/src/compiled-lang/zh.json index a9202075..fb85151b 100644 --- a/packages/webapp/src/compiled-lang/zh.json +++ b/packages/webapp/src/compiled-lang/zh.json @@ -371,6 +371,18 @@ "value": "电子邮件" } ], + "forgot.oauth.back": [ + { + "type": 0, + "value": "回到登入" + } + ], + "forgot.oauth.message": [ + { + "type": 0, + "value": "您不需要密码,请使用谷歌登录" + } + ], "forgot.page-title": [ { "type": 0, @@ -603,6 +615,12 @@ "value": "登录您的账号" } ], + "login.division": [ + { + "type": 0, + "value": "或者" + } + ], "login.email": [ { "type": 0, @@ -621,6 +639,12 @@ "value": "忘记密码?" } ], + "login.google.button": [ + { + "type": 0, + "value": "使用 Google 登錄" + } + ], "login.hsqldbcofig": [ { "type": 0, @@ -891,18 +915,66 @@ "value": "发布" } ], + "registation.callback.error.message": [ + { + "type": 0, + "value": "使用 Google 验证您的身份时出错,您可以从登录页面重试" + } + ], "registation.success-title": [ { "type": 0, "value": "注册成功|WiseMapping" } ], + "registration.callback.back": [ + { + "type": 0, + "value": "回到登入" + } + ], + "registration.callback.confirm.description": [ + { + "type": 0, + "value": "之前注册了一个具有相同电子邮件地址的帐户。你想将你的谷歌账户链接到那个 WiseMapping 账户吗?" + } + ], + "registration.callback.confirm.title": [ + { + "type": 0, + "value": "确认" + } + ], + "registration.callback.sync": [ + { + "type": 0, + "value": "同步账户" + } + ], + "registration.callback.waiting.description": [ + { + "type": 0, + "value": "我们正在验证您的身份,请稍候" + } + ], + "registration.callback.waiting.title": [ + { + "type": 0, + "value": "整理 ..." + } + ], "registration.desc": [ { "type": 0, "value": "注册免费,分分钟就好" } ], + "registration.division": [ + { + "type": 0, + "value": "或者" + } + ], "registration.email": [ { "type": 0, @@ -915,6 +987,12 @@ "value": "名字" } ], + "registration.google.button": [ + { + "type": 0, + "value": "註冊谷歌" + } + ], "registration.lastname": [ { "type": 0, diff --git a/packages/webapp/src/components/common/google-button/index.tsx b/packages/webapp/src/components/common/google-button/index.tsx new file mode 100644 index 00000000..25a2cd0d --- /dev/null +++ b/packages/webapp/src/components/common/google-button/index.tsx @@ -0,0 +1,31 @@ +import React from 'react'; +import { css } from '@emotion/react'; +import { Button } from '@mui/material'; +import GoogleIcon from '../google-icon'; + +const googleButtonStyle = css({ + color: '#000000', + fontWeight: '300', + border: '1px solid black', + '&:hover': { + border: '1px solid black', + }, +}); + +type GoogleButtonProps = { + text: string; + onClick: React.MouseEventHandler; +}; + +const GoogleButton: React.FunctionComponent = ({ + text, + onClick, +}: GoogleButtonProps) => { + return ( + + ); +}; + +export default GoogleButton; diff --git a/packages/webapp/src/components/common/google-icon/index.tsx b/packages/webapp/src/components/common/google-icon/index.tsx new file mode 100644 index 00000000..fe0ebdc2 --- /dev/null +++ b/packages/webapp/src/components/common/google-icon/index.tsx @@ -0,0 +1,31 @@ +import React from 'react'; +import { SvgIcon } from '@mui/material'; + +const GoogleIconSvg = () => { + return ( + + + + + + + + + ); +}; + +const GoogleIcon = ; + +export default GoogleIcon; diff --git a/packages/webapp/src/components/common/separator/index.tsx b/packages/webapp/src/components/common/separator/index.tsx new file mode 100644 index 00000000..a04c9a7e --- /dev/null +++ b/packages/webapp/src/components/common/separator/index.tsx @@ -0,0 +1,29 @@ +import React from 'react'; +import { useTheme } from '@mui/material/styles'; +import { containerStyle, lineStyle, textStyle } from './style'; + +type SeparatorProps = { + responsive: boolean; + text: string; + maxWidth?: number; +}; + +const Separator: React.FunctionComponent = ({ + responsive, + text, + maxWidth = undefined, +}: SeparatorProps) => { + const theme = useTheme(); + + return ( + // eslint-disable-next-line react/no-unknown-property +
+ {/* eslint-disable-next-line react/no-unknown-property */} +
+ {/* eslint-disable-next-line react/no-unknown-property */} +
{text}
+
+ ); +}; + +export default Separator; diff --git a/packages/webapp/src/components/common/separator/style.ts b/packages/webapp/src/components/common/separator/style.ts new file mode 100644 index 00000000..cb95f61a --- /dev/null +++ b/packages/webapp/src/components/common/separator/style.ts @@ -0,0 +1,73 @@ +import { css, SerializedStyles } from '@emotion/react'; + +export const containerStyle = ( + responsive: boolean, + maxWidth: number, + breakPointDownMd: string, +): SerializedStyles => { + return css([ + { + position: 'relative', + width: '100%', + height: '90%', + top: '5%', + display: 'inline-block', + }, + responsive && { + [breakPointDownMd]: { + paddingTop: '25px', + paddingBottom: '25px', + }, + }, + !responsive && { + paddingTop: '25px', + paddingBottom: '25px', + }, + maxWidth && { + maxWidth: maxWidth, + }, + ]); +}; + +export const lineStyle = (responsive: boolean, breakPointUpMd: string): SerializedStyles => { + return css([ + { + backgroundColor: '#dce2e6', + position: 'absolute', + left: '50%', + height: '1px', + width: '100%', + transform: 'translateX(-50%)', + }, + responsive && { + [breakPointUpMd]: { + height: '100%', + width: '1px', + transform: 'translateX(0%) translateY(0%)', + }, + }, + ]); +}; + +export const textStyle = (responsive: boolean, breakPointUpMd: string): SerializedStyles => { + return css([ + { + backgroundColor: '#DCE2E6', + padding: '5px 10px', + minWidth: '36px', + borderRadius: '18px', + fontSize: '18px', + color: 'white', + textAlign: 'center', + display: 'inline-block', + position: 'absolute', + transform: 'translateX(-50%) translateY(-50%)', + left: '50%', + }, + responsive && { + [breakPointUpMd]: { + top: '15%', + }, + }, + ]); +}; diff --git a/packages/webapp/src/components/forgot-password-page/index.tsx b/packages/webapp/src/components/forgot-password-page/index.tsx index 1eae86a8..3840086c 100644 --- a/packages/webapp/src/components/forgot-password-page/index.tsx +++ b/packages/webapp/src/components/forgot-password-page/index.tsx @@ -1,6 +1,6 @@ import React, { useState, useEffect } from 'react'; import { FormattedMessage, useIntl } from 'react-intl'; -import Client, { ErrorInfo } from '../../classes/client'; +import Client, { ErrorInfo, ForgotPasswordResult } from '../../classes/client'; import Header from '../layout/header'; import Footer from '../layout/footer'; @@ -12,22 +12,28 @@ import Input from '../form/input'; import GlobalError from '../form/global-error'; import SubmitButton from '../form/submit-button'; import ReactGA from 'react-ga4'; +import { Link as RouterLink } from 'react-router-dom'; import Typography from '@mui/material/Typography'; import { getCsrfToken, getCsrfTokenParameter } from '../../utils'; import { useNavigate } from 'react-router-dom'; +import { Button } from '@mui/material'; const ForgotPassword = () => { const [email, setEmail] = useState(''); const [error, setError] = useState(); + const [showOauthMessage, setShowOauthMessage] = useState(false); const navigate = useNavigate(); const intl = useIntl(); const service: Client = useSelector(activeInstance); - const mutation = useMutation( + const mutation = useMutation( (email: string) => service.resetPassword(email), { - onSuccess: () => navigate('/c/forgot-password-success'), + onSuccess: (result) => { + if (result.action === 'EMAIL_SENT') navigate('/c/forgot-password-success'); + if (result.action === 'OAUTH2_USER') setShowOauthMessage(true); + }, onError: (error) => { setError(error); }, @@ -39,6 +45,29 @@ const ForgotPassword = () => { mutation.mutate(email); }; + if (showOauthMessage) { + return ( + + + + + + + ); + } + return ( diff --git a/packages/webapp/src/components/form/submit-button/index.tsx b/packages/webapp/src/components/form/submit-button/index.tsx index 03566a74..96e56082 100644 --- a/packages/webapp/src/components/form/submit-button/index.tsx +++ b/packages/webapp/src/components/form/submit-button/index.tsx @@ -24,7 +24,7 @@ const SubmitButton = (props: SubmitButton): React.ReactElement => { disableElevation={true} disabled={disabled} style={{ - width: '350px', + width: '300px', height: '53px', padding: '0px 20px', margin: '7px 0px', diff --git a/packages/webapp/src/components/layout/footer/styled.ts b/packages/webapp/src/components/layout/footer/styled.ts index aa716d12..e2a12b02 100644 --- a/packages/webapp/src/components/layout/footer/styled.ts +++ b/packages/webapp/src/components/layout/footer/styled.ts @@ -8,6 +8,7 @@ export const StyledFooter = styled.footer` background-color: #f9a826; display: grid; grid-template-columns: 200px 1fr 1fr 1fr 3fr; + overflow: hidden; & a { font-size: 14px; diff --git a/packages/webapp/src/components/login-page/index.tsx b/packages/webapp/src/components/login-page/index.tsx index ce608f8b..cafb915b 100644 --- a/packages/webapp/src/components/login-page/index.tsx +++ b/packages/webapp/src/components/login-page/index.tsx @@ -12,6 +12,9 @@ import FormControl from '@mui/material/FormControl'; import Link from '@mui/material/Link'; import ReactGA from 'react-ga4'; import { getCsrfToken, getCsrfTokenParameter } from '../../utils'; +import Separator from '../common/separator'; +import GoogleButton from '../common/google-button'; +import AppConfig from '../../classes/app-config'; const LoginError = () => { // @Todo: This must be reviewed to be based on navigation state. @@ -32,7 +35,7 @@ const LoginError = () => { default: msg = intl.formatMessage({ id: 'login.error', - defaultMessage: 'The email address or password you entered is not valid.', + defaultMessage: 'The email address or password you entered is not valid.', }); } } @@ -54,7 +57,7 @@ const LoginPage = (): React.ReactElement => {
- + @@ -102,10 +105,25 @@ const LoginPage = (): React.ReactElement => { /> - + + { + window.location.href = AppConfig.getGoogleOauth2Url(); + }} + />