From 69b110e36bc56a7ae4d7697d20d1c035e6909e17 Mon Sep 17 00:00:00 2001 From: Ksinia Date: Tue, 17 Aug 2021 22:02:08 +0200 Subject: [PATCH] Add telegram auth to frontend --- frontend/app/common/types.ts | 16 +++- frontend/app/components/auth/auth.api.ts | 17 +++- frontend/app/components/auth/auth.hooks.ts | 8 +- .../app/components/auth/auth.messsages.ts | 24 +++++ frontend/app/components/auth/auth.module.css | 5 + frontend/app/components/auth/auth.tsx | 95 +++++++++++++++++-- .../auth/components/assets/telegram.svg | 1 + .../auth/components/oauth.consts.ts | 1 + .../app/components/auth/components/oauth.tsx | 55 ++++++++--- frontend/app/locales/be.json | 6 ++ frontend/app/locales/bg.json | 6 ++ frontend/app/locales/bp.json | 6 ++ frontend/app/locales/de.json | 6 ++ frontend/app/locales/en.json | 6 ++ frontend/app/locales/es.json | 6 ++ frontend/app/locales/fi.json | 6 ++ frontend/app/locales/fr.json | 6 ++ frontend/app/locales/it.json | 8 +- frontend/app/locales/ja.json | 6 ++ frontend/app/locales/ko.json | 6 ++ frontend/app/locales/pl.json | 6 ++ frontend/app/locales/ru.json | 6 ++ frontend/app/locales/tr.json | 6 ++ frontend/app/locales/ua.json | 6 ++ frontend/app/locales/vi.json | 6 ++ frontend/app/locales/zh.json | 6 ++ frontend/app/store/user/actions.ts | 11 ++- frontend/app/store/user/reducers.ts | 17 +++- frontend/app/store/user/types.ts | 9 +- frontend/package.json | 2 + 30 files changed, 338 insertions(+), 27 deletions(-) create mode 100644 frontend/app/components/auth/components/assets/telegram.svg diff --git a/frontend/app/common/types.ts b/frontend/app/common/types.ts index 69097e9e..bb5a9c52 100644 --- a/frontend/app/common/types.ts +++ b/frontend/app/common/types.ts @@ -95,7 +95,16 @@ export interface Tree { info: PostInfo; } -export type OAuthProvider = 'facebook' | 'twitter' | 'google' | 'yandex' | 'github' | 'microsoft' | 'patreon' | 'dev'; +export type OAuthProvider = + | 'facebook' + | 'twitter' + | 'google' + | 'yandex' + | 'github' + | 'microsoft' + | 'patreon' + | 'telegram' + | 'dev'; export type FormProvider = 'email' | 'anonymous'; export type Provider = OAuthProvider | FormProvider; @@ -158,3 +167,8 @@ export interface ApiError { /** in-depth explanation */ error: string; } + +export interface TelegramParams { + bot: string; + token: string; +} diff --git a/frontend/app/components/auth/auth.api.ts b/frontend/app/components/auth/auth.api.ts index 8b0b7a25..b7decf72 100644 --- a/frontend/app/components/auth/auth.api.ts +++ b/frontend/app/components/auth/auth.api.ts @@ -1,9 +1,10 @@ -import type { User } from 'common/types'; +import type { User, TelegramParams } from 'common/types'; import { authFetcher } from 'common/fetcher'; import { siteId } from 'common/settings'; const EMAIL_SIGNIN_ENDPOINT = '/email/login'; +const TELEGRAM_SIGNIN_ENDPOINT = '/telegram/login'; export function anonymousSignin(user: string): Promise { return authFetcher.get('/anonymous/login', { user, aud: siteId }); @@ -23,6 +24,20 @@ export function verifyEmailSignin(token: string): Promise { return authFetcher.get(EMAIL_SIGNIN_ENDPOINT, { token }); } +/** + * First step of two of `telegram` authorization + */ +export function getTelegramSigninParams(): Promise { + return authFetcher.get(TELEGRAM_SIGNIN_ENDPOINT); +} + +/** + * Second step of two of `telegram` authorization + */ +export function verifyTelegramSignin(token: string): Promise { + return authFetcher.get(TELEGRAM_SIGNIN_ENDPOINT, { token }); +} + export function logout(): Promise { return authFetcher.get('/logout'); } diff --git a/frontend/app/components/auth/auth.hooks.ts b/frontend/app/components/auth/auth.hooks.ts index 5384d072..49da72b9 100644 --- a/frontend/app/components/auth/auth.hooks.ts +++ b/frontend/app/components/auth/auth.hooks.ts @@ -33,7 +33,13 @@ export function useDropdown(disableClosing?: boolean) { } function handleClickOutside(evt: MouseEvent) { - if (disableClosing || dropdownElement?.contains(evt.target as HTMLDivElement)) { + if ( + disableClosing || + dropdownElement?.contains(evt.target as HTMLDivElement) || + (evt.target as Element).classList?.contains('telegram-auth') + // telegram button is gone from dropdown render by the time of this check + // without that condition click on telegram button considered as outside click + ) { return; } diff --git a/frontend/app/components/auth/auth.messsages.ts b/frontend/app/components/auth/auth.messsages.ts index de97e803..263a726c 100644 --- a/frontend/app/components/auth/auth.messsages.ts +++ b/frontend/app/components/auth/auth.messsages.ts @@ -57,6 +57,30 @@ export const messages = defineMessages({ id: 'auth.submit', defaultMessage: 'Submit', }, + telegramLink: { + id: 'auth.telegram-link', + defaultMessage: 'by the link', + }, + telegramCheck: { + id: 'auth.telegram-check', + defaultMessage: 'Check', + }, + telegramMessage1: { + id: 'auth.telegram-message-1', + defaultMessage: 'Open the Telegram', + }, + telegramOptionalQR: { + id: 'auth.telegram-optional-qr', + defaultMessage: 'or by scanning the QR code', + }, + telegramMessage2: { + id: 'auth.telegram-message-2', + defaultMessage: 'and click “Start” there.', + }, + telegramMessage3: { + id: 'auth.telegram-message-3', + defaultMessage: 'Afterwards, click “Check” below.', + }, openProfile: { id: 'auth.open-profile', defaultMessage: 'Open My Profile', diff --git a/frontend/app/components/auth/auth.module.css b/frontend/app/components/auth/auth.module.css index 594b4042..6c05d2ce 100644 --- a/frontend/app/components/auth/auth.module.css +++ b/frontend/app/components/auth/auth.module.css @@ -195,3 +195,8 @@ color: var(--error-color); line-height: 1.2; } + +.qr { + display: block; + margin: 0 auto 1.5rem auto; +} diff --git a/frontend/app/components/auth/auth.tsx b/frontend/app/components/auth/auth.tsx index 4eefbb69..f237e325 100644 --- a/frontend/app/components/auth/auth.tsx +++ b/frontend/app/components/auth/auth.tsx @@ -2,9 +2,10 @@ import clsx from 'clsx'; import { h, Fragment } from 'preact'; import { useState } from 'preact/hooks'; import { useIntl } from 'react-intl'; -import { useDispatch } from 'react-redux'; +import { useSelector, useDispatch } from 'react-redux'; +import QRCode from 'qrcode.react'; -import { setUser } from 'store/user/actions'; +import { setTelegramParams, setUser } from 'store/user/actions'; import { Input } from 'components/input'; import { CrossIcon } from 'components/icons/cross'; import { TextareaAutosize } from 'components/textarea-autosize'; @@ -16,19 +17,22 @@ import { OAuth } from './components/oauth'; import { messages } from './auth.messsages'; import { useDropdown } from './auth.hooks'; import { getProviders, getTokenInvalidReason } from './auth.utils'; -import { emailSignin, verifyEmailSignin, anonymousSignin } from './auth.api'; +import { emailSignin, verifyEmailSignin, anonymousSignin, verifyTelegramSignin } from './auth.api'; +import { StoreState } from 'store'; import styles from './auth.module.css'; export function Auth() { const intl = useIntl(); const dispatch = useDispatch(); + const telegramParams = useSelector((s: StoreState) => s.telegramParams); const [oauthProviders, formProviders] = getProviders(); // UI State const [isLoading, setLoading] = useState(false); const [view, setView] = useState(formProviders[0]); - const [ref, isDropdownShown, toggleDropdownState] = useDropdown(view === 'token'); + const [isTelegramShown, toggleTelegram] = useState(false); + const [ref, isDropdownShown, toggleDropdownState] = useDropdown(view === 'token' || isTelegramShown); // Errors const [invalidReason, setInvalidReason] = useState(null); @@ -42,6 +46,7 @@ export function Auth() { evt.preventDefault(); setView(formProviders[0]); toggleDropdownState(); + toggleTelegram(false); } function handleProviderChange(evt: Event) { @@ -96,6 +101,23 @@ export function Auth() { setLoading(false); } + async function handleTelegramSubmit(evt: Event) { + evt.preventDefault(); + setLoading(true); + setInvalidReason(null); + if (telegramParams) { + try { + const user = await verifyTelegramSignin(telegramParams.token); + dispath(setUser(user)); + toggleTelegram(false); + dispath(setTelegramParams(null)); + } catch (e) { + setInvalidReason(e.message || e.error); + } + setLoading(false); + } + } + function handleShowEmailStep(evt: Event) { evt.preventDefault(); setView('email'); @@ -122,7 +144,68 @@ export function Auth() { {isDropdownShown && (
- {isTokenView ? ( + {isTelegramShown && telegramParams ? ( + <> +
+
+ +
+ +
+

+ {intl.formatMessage(messages.telegramMessage1)}{' '} + + {intl.formatMessage(messages.telegramLink)} + + {window.screen.width >= 768 && ` ${intl.formatMessage(messages.telegramOptionalQR)}`}{' '} + {intl.formatMessage(messages.telegramMessage2)} +
+ {intl.formatMessage(messages.telegramMessage3)} +

+ {window.screen.width >= 768 && ( + + )} + + {errorMessage &&
{errorMessage}
} + + ) : isTokenView ? ( <>
@@ -171,7 +254,7 @@ export function Auth() {
{intl.formatMessage(messages.oauthSource)}
- + )} {hasOAuthProviders && hasFormProviders && ( diff --git a/frontend/app/components/auth/components/assets/telegram.svg b/frontend/app/components/auth/components/assets/telegram.svg new file mode 100644 index 00000000..080818fa --- /dev/null +++ b/frontend/app/components/auth/components/assets/telegram.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/frontend/app/components/auth/components/oauth.consts.ts b/frontend/app/components/auth/components/oauth.consts.ts index ac39dff9..e10e80b8 100644 --- a/frontend/app/components/auth/components/oauth.consts.ts +++ b/frontend/app/components/auth/components/oauth.consts.ts @@ -13,6 +13,7 @@ export const OAUTH_DATA = { dark: require('./assets/github-dark.svg').default as string, }, }, + telegram: require('./assets/telegram.svg').default as string, } as const; export const OAUTH_PROVIDERS = Object.keys(OAUTH_DATA); diff --git a/frontend/app/components/auth/components/oauth.tsx b/frontend/app/components/auth/components/oauth.tsx index d48466a7..1e0709ac 100644 --- a/frontend/app/components/auth/components/oauth.tsx +++ b/frontend/app/components/auth/components/oauth.tsx @@ -1,12 +1,13 @@ import { h, JSX } from 'preact'; -import { useDispatch } from 'react-redux'; +import { useDispatch, useSelector } from 'react-redux'; import clsx from 'clsx'; import { useIntl } from 'react-intl'; import type { OAuthProvider } from 'common/types'; import { siteId } from 'common/settings'; import { useTheme } from 'hooks/useTheme'; -import { setUser } from 'store/user/actions'; +import { setUser, setTelegramParams } from 'store/user/actions'; +import { StoreState } from 'store'; import { messages } from 'components/auth/auth.messsages'; @@ -14,16 +15,19 @@ import { oauthSignin } from './oauth.api'; import { BASE_URL } from 'common/constants.config'; import { getButtonVariant, getProviderData } from './oauth.utils'; import styles from './oauth.module.css'; +import { getTelegramSigninParams } from '../auth.api'; const location = encodeURIComponent(`${window.location.origin}${window.location.pathname}?selfClose`); type Props = { providers: OAuthProvider[]; + toggleTelegram?: (showTelegram: boolean) => void; }; -export function OAuth({ providers }: Props) { +export function OAuth({ providers, toggleTelegram }: Props) { const intl = useIntl(); const dispatch = useDispatch(); + const telegramParams = useSelector((s: StoreState) => s.telegramParams); const theme = useTheme(); const buttonVariant = getButtonVariant(providers.length); const handleOauthClick: JSX.GenericEventHandler = async (evt) => { @@ -39,6 +43,18 @@ export function OAuth({ providers }: Props) { dispatch(setUser(user)); }; + const handleTelegramClick: JSX.EventHandler> = async (evt) => { + evt.preventDefault(); + if (!telegramParams) { + const params = await getTelegramSigninParams(); + if (params === null) { + return; + } + dispath(setTelegramParams(params)); + } + toggleTelegram && toggleTelegram(true); + }; + return (
    {providers.map((p) => { @@ -46,17 +62,28 @@ export function OAuth({ providers }: Props) { return (
  • - - - + {name === 'Telegram' ? ( + + ) : ( + + + + )}
  • ); })} diff --git a/frontend/app/locales/be.json b/frontend/app/locales/be.json index 9c999869..d0485a69 100644 --- a/frontend/app/locales/be.json +++ b/frontend/app/locales/be.json @@ -10,6 +10,12 @@ "auth.signout": "Выйсці?", "auth.submit": "Адправіць", "auth.symbols-restriction": "імя карыстальніка мусіць пачынацца з літары і ўтрымоўваць толькі лацінскія літары, лічбы, знакі падкрэслівання і прабелы(?)", + "auth.telegram-check": "Check", + "auth.telegram-link": "Telegram bot", + "auth.telegram-message-1": "You need to authorize your account in the", + "auth.telegram-message-2": "by clicking “Start” there.", + "auth.telegram-message-3": "Click “Check” below after authorization in the Telegram bot.", + "auth.telegram-optional-qr": "or by scanning the QR code", "auth.user-not-found": "Карыстальнік не знойдзены", "auth.username": "Імя карыстальніка", "authPanel.disable-comments": "Адключыць каментары", diff --git a/frontend/app/locales/bg.json b/frontend/app/locales/bg.json index 7685c329..86b3668c 100644 --- a/frontend/app/locales/bg.json +++ b/frontend/app/locales/bg.json @@ -10,6 +10,12 @@ "auth.signout": "Изход", "auth.submit": "Изпрати", "auth.symbols-restriction": "Потребителското име трябва да започва с буква и да бъде само от латински букви, цифри, подчертавки или разтояния", + "auth.telegram-check": "Check", + "auth.telegram-link": "Telegram bot", + "auth.telegram-message-1": "You need to authorize your account in the", + "auth.telegram-message-2": "by clicking “Start” there.", + "auth.telegram-message-3": "Click “Check” below after authorization in the Telegram bot.", + "auth.telegram-optional-qr": "or by scanning the QR code", "auth.user-not-found": "Не бе намерен потребител", "auth.username": "Потребителско име", "authPanel.disable-comments": "Забрани коментарите", diff --git a/frontend/app/locales/bp.json b/frontend/app/locales/bp.json index 9e41d8e6..14128b4a 100644 --- a/frontend/app/locales/bp.json +++ b/frontend/app/locales/bp.json @@ -10,6 +10,12 @@ "auth.signout": "Fazer logout", "auth.submit": "Enviar", "auth.symbols-restriction": "O nome de usuário deve conter apenas letras, números, sublinhados ou espaços", + "auth.telegram-check": "Check", + "auth.telegram-link": "Telegram bot", + "auth.telegram-message-1": "You need to authorize your account in the", + "auth.telegram-message-2": "by clicking “Start” there.", + "auth.telegram-message-3": "Click “Check” below after authorization in the Telegram bot.", + "auth.telegram-optional-qr": "or by scanning the QR code", "auth.user-not-found": "Nenhum usuário encontrado", "auth.username": "Nome do usuário", "authPanel.disable-comments": "Desabilitar comentários", diff --git a/frontend/app/locales/de.json b/frontend/app/locales/de.json index d641f528..8b931514 100644 --- a/frontend/app/locales/de.json +++ b/frontend/app/locales/de.json @@ -10,6 +10,12 @@ "auth.signout": "Abmelden", "auth.submit": "Absenden", "auth.symbols-restriction": "Der Benutzername darf nur Buchstaben, Zahlen, Unterstriche oder Leerzeichen enthalten", + "auth.telegram-check": "Check", + "auth.telegram-link": "Telegram bot", + "auth.telegram-message-1": "You need to authorize your account in the", + "auth.telegram-message-2": "by clicking “Start” there.", + "auth.telegram-message-3": "Click “Check” below after authorization in the Telegram bot.", + "auth.telegram-optional-qr": "or by scanning the QR code", "auth.user-not-found": "Benutzer konnte nicht gefunden werden", "auth.username": "Benutzername", "authPanel.disable-comments": "Kommentarfunktion deaktivieren", diff --git a/frontend/app/locales/en.json b/frontend/app/locales/en.json index 9d7a76aa..3a61b421 100644 --- a/frontend/app/locales/en.json +++ b/frontend/app/locales/en.json @@ -10,6 +10,12 @@ "auth.signout": "Sign Out", "auth.submit": "Submit", "auth.symbols-restriction": "Username must contain only letters, numbers, underscores or spaces", + "auth.telegram-check": "Check", + "auth.telegram-link": "by the link", + "auth.telegram-message-1": "Open the Telegram", + "auth.telegram-message-2": "and click “Start” there.", + "auth.telegram-message-3": "Afterwards, click “Check” below.", + "auth.telegram-optional-qr": "or by scanning the QR code", "auth.user-not-found": "No user was found", "auth.username": "Username", "authPanel.disable-comments": "Disable comments", diff --git a/frontend/app/locales/es.json b/frontend/app/locales/es.json index 7d72e06e..68110025 100644 --- a/frontend/app/locales/es.json +++ b/frontend/app/locales/es.json @@ -10,6 +10,12 @@ "auth.signout": "¿Salir?", "auth.submit": "Enviar", "auth.symbols-restriction": "El nombre de usuario debe comenzar con una letra y contener solamente letras latinas, números, guión bajo o espacio", + "auth.telegram-check": "Check", + "auth.telegram-link": "Telegram bot", + "auth.telegram-message-1": "You need to authorize your account in the", + "auth.telegram-message-2": "by clicking “Start” there.", + "auth.telegram-message-3": "Click “Check” below after authorization in the Telegram bot.", + "auth.telegram-optional-qr": "or by scanning the QR code", "auth.user-not-found": "No se encontró el usuario", "auth.username": "Nombre de usuario", "authPanel.disable-comments": "Deshabilitar comentarios", diff --git a/frontend/app/locales/fi.json b/frontend/app/locales/fi.json index 88944c13..84c99fad 100644 --- a/frontend/app/locales/fi.json +++ b/frontend/app/locales/fi.json @@ -10,6 +10,12 @@ "auth.signout": "Kirjaudu ulos", "auth.submit": "Lähetä", "auth.symbols-restriction": "Käyttäjätunnuksen tulee alkaa kirjaimella ja sisältää vain latinalaisia kirjaimia, numeroita, alaviivoja ja välilyöntejä", + "auth.telegram-check": "Check", + "auth.telegram-link": "Telegram bot", + "auth.telegram-message-1": "You need to authorize your account in the", + "auth.telegram-message-2": "by clicking “Start” there.", + "auth.telegram-message-3": "Click “Check” below after authorization in the Telegram bot.", + "auth.telegram-optional-qr": "or by scanning the QR code", "auth.user-not-found": "Käyttäjää ei löytynyt", "auth.username": "Käyttäjätunnus", "authPanel.disable-comments": "Poista kommentit käytöstä", diff --git a/frontend/app/locales/fr.json b/frontend/app/locales/fr.json index c0080a1b..02ca17eb 100644 --- a/frontend/app/locales/fr.json +++ b/frontend/app/locales/fr.json @@ -10,6 +10,12 @@ "auth.signout": "Se déconnecter", "auth.submit": "Valider", "auth.symbols-restriction": "Le nom d'utilisateur ne doit contenir que des lettres, nombres, tirets bas et espaces.", + "auth.telegram-check": "Check", + "auth.telegram-link": "Telegram bot", + "auth.telegram-message-1": "You need to authorize your account in the", + "auth.telegram-message-2": "by clicking “Start” there.", + "auth.telegram-message-3": "Click “Check” below after authorization in the Telegram bot.", + "auth.telegram-optional-qr": "or by scanning the QR code", "auth.user-not-found": "Aucun utilisateur n'a été trouvé", "auth.username": "Nom d'utilisateur", "authPanel.disable-comments": "Désactiver les commentaires", diff --git a/frontend/app/locales/it.json b/frontend/app/locales/it.json index 350f908f..8bfa077b 100644 --- a/frontend/app/locales/it.json +++ b/frontend/app/locales/it.json @@ -10,6 +10,12 @@ "auth.signout": "Esci", "auth.submit": "Invia", "auth.symbols-restriction": "L'username deve contenere solo lettere, numberi, trattini bassi o spazi", + "auth.telegram-check": "Check", + "auth.telegram-link": "Telegram bot", + "auth.telegram-message-1": "You need to authorize your account in the", + "auth.telegram-message-2": "by clicking “Start” there.", + "auth.telegram-message-3": "Click “Check” below after authorization in the Telegram bot.", + "auth.telegram-optional-qr": "or by scanning the QR code", "auth.user-not-found": "Nessun utente trovato", "auth.username": "Username", "authPanel.disable-comments": "Disabilita commenti", @@ -157,8 +163,8 @@ "toolbar.ordered-list": "Aggiungi lista numerata", "toolbar.quote": "Inserisci citazione", "toolbar.unordered-list": "Aggiungi lista a pallini", - "user.my-comments": "My comments", "user.comments": "Comments", + "user.my-comments": "My comments", "vote.anonymous": "Gli utenti anonimi non possono votare", "vote.deleted": "Non puoi votare per un commento eliminato", "vote.guest": "Accedi per votare", diff --git a/frontend/app/locales/ja.json b/frontend/app/locales/ja.json index 1c58f916..56c90a59 100644 --- a/frontend/app/locales/ja.json +++ b/frontend/app/locales/ja.json @@ -10,6 +10,12 @@ "auth.signout": "ログアウトしますか", "auth.submit": "送信", "auth.symbols-restriction": "ユーザー名には英数字、アンダースコア、またはスペースのみを指定してください", + "auth.telegram-check": "Check", + "auth.telegram-link": "Telegram bot", + "auth.telegram-message-1": "You need to authorize your account in the", + "auth.telegram-message-2": "by clicking “Start” there.", + "auth.telegram-message-3": "Click “Check” below after authorization in the Telegram bot.", + "auth.telegram-optional-qr": "or by scanning the QR code", "auth.user-not-found": "ユーザーが見つかりませんでした", "auth.username": "ユーザー名", "authPanel.disable-comments": "コメントの無効化", diff --git a/frontend/app/locales/ko.json b/frontend/app/locales/ko.json index 82714a0a..b3edd76e 100644 --- a/frontend/app/locales/ko.json +++ b/frontend/app/locales/ko.json @@ -10,6 +10,12 @@ "auth.signout": "로그아웃하시겠어요", "auth.submit": "확인", "auth.symbols-restriction": "사용자 이름에는 문자, 숫자, 밑줄 또는 공백만 포함되어야 합니다", + "auth.telegram-check": "Check", + "auth.telegram-link": "Telegram bot", + "auth.telegram-message-1": "You need to authorize your account in the", + "auth.telegram-message-2": "by clicking “Start” there.", + "auth.telegram-message-3": "Click “Check” below after authorization in the Telegram bot.", + "auth.telegram-optional-qr": "or by scanning the QR code", "auth.user-not-found": "사용자를 찾을 수 없습니다", "auth.username": "사용자 이름", "authPanel.disable-comments": "댓글 비활성화", diff --git a/frontend/app/locales/pl.json b/frontend/app/locales/pl.json index ad459bb3..a359621f 100644 --- a/frontend/app/locales/pl.json +++ b/frontend/app/locales/pl.json @@ -10,6 +10,12 @@ "auth.signout": "Wyloguj", "auth.submit": "Potwierdź", "auth.symbols-restriction": "Nazwa użytkownika powinna składać się z liter, numerów, podkreślinków lub spacji", + "auth.telegram-check": "Check", + "auth.telegram-link": "Telegram bot", + "auth.telegram-message-1": "You need to authorize your account in the", + "auth.telegram-message-2": "by clicking “Start” there.", + "auth.telegram-message-3": "Click “Check” below after authorization in the Telegram bot.", + "auth.telegram-optional-qr": "or by scanning the QR code", "auth.user-not-found": "Żaden użytkownik nie został znaleziony", "auth.username": "Nazwa użytkownika", "authPanel.disable-comments": "Wyłącz komentarze", diff --git a/frontend/app/locales/ru.json b/frontend/app/locales/ru.json index 0109750e..89bf46c8 100644 --- a/frontend/app/locales/ru.json +++ b/frontend/app/locales/ru.json @@ -10,6 +10,12 @@ "auth.signout": "Выйти", "auth.submit": "Отправить", "auth.symbols-restriction": "Имя пользователя должно начинаться с буквы и содержать только латинские буквы, цифры, знаки подчеркивания и пробелы", + "auth.telegram-check": "Проверить", + "auth.telegram-link": "по ссылке", + "auth.telegram-message-1": "Откройте Телеграм", + "auth.telegram-message-2": "и нажмите там кнопку “Start”/“Начать”.", + "auth.telegram-message-3": "Затем нажмите кнопку “Проверить”.", + "auth.telegram-optional-qr": "или по QR-коду", "auth.user-not-found": "Пользователь не найден", "auth.username": "Имя пользователя", "authPanel.disable-comments": "Отключить комментарии", diff --git a/frontend/app/locales/tr.json b/frontend/app/locales/tr.json index a52c0cb4..e7b9d0b1 100644 --- a/frontend/app/locales/tr.json +++ b/frontend/app/locales/tr.json @@ -10,6 +10,12 @@ "auth.signout": "Çıkış yap", "auth.submit": "Gönder", "auth.symbols-restriction": "Kullanıcı adı harf ile başlayıp; yalnızca harf, rakam, alt çizgi veya boşluk içerebilir", + "auth.telegram-check": "Check", + "auth.telegram-link": "Telegram bot", + "auth.telegram-message-1": "You need to authorize your account in the", + "auth.telegram-message-2": "by clicking “Start” there.", + "auth.telegram-message-3": "Click “Check” below after authorization in the Telegram bot.", + "auth.telegram-optional-qr": "or by scanning the QR code", "auth.user-not-found": "Kullanıcı bulunamadı", "auth.username": "Kullanıcı adı", "authPanel.disable-comments": "Yorumları devre dışı bırak", diff --git a/frontend/app/locales/ua.json b/frontend/app/locales/ua.json index 29417178..de10ebbf 100644 --- a/frontend/app/locales/ua.json +++ b/frontend/app/locales/ua.json @@ -10,6 +10,12 @@ "auth.signout": "Вийти", "auth.submit": "Відправити", "auth.symbols-restriction": "Ім’я користувача повинно починатися з літери та містити тільки символи латинського алфавіту, цифри, знаки підкреслення або пробіли", + "auth.telegram-check": "Check", + "auth.telegram-link": "Telegram bot", + "auth.telegram-message-1": "You need to authorize your account in the", + "auth.telegram-message-2": "by clicking “Start” there.", + "auth.telegram-message-3": "Click “Check” below after authorization in the Telegram bot.", + "auth.telegram-optional-qr": "or by scanning the QR code", "auth.user-not-found": "Користувач не знайдений", "auth.username": "Ім’я користувача", "authPanel.disable-comments": "Вимкнути коментарі", diff --git a/frontend/app/locales/vi.json b/frontend/app/locales/vi.json index e5dc6782..a3613932 100644 --- a/frontend/app/locales/vi.json +++ b/frontend/app/locales/vi.json @@ -10,6 +10,12 @@ "auth.signout": "Thoát", "auth.submit": "Gửi đi", "auth.symbols-restriction": "Tên người dùng chỉ được chứa các chữ cái, số, dấu gạch dưới hoặc dấu cách", + "auth.telegram-check": "Check", + "auth.telegram-link": "Telegram bot", + "auth.telegram-message-1": "You need to authorize your account in the", + "auth.telegram-message-2": "by clicking “Start” there.", + "auth.telegram-message-3": "Click “Check” below after authorization in the Telegram bot.", + "auth.telegram-optional-qr": "or by scanning the QR code", "auth.user-not-found": "Không tìm thấy người dùng nào", "auth.username": "Tên người dùng", "authPanel.disable-comments": "Tắt bình luận", diff --git a/frontend/app/locales/zh.json b/frontend/app/locales/zh.json index 8b3e7891..341847ef 100644 --- a/frontend/app/locales/zh.json +++ b/frontend/app/locales/zh.json @@ -10,6 +10,12 @@ "auth.signout": "登出", "auth.submit": "提交", "auth.symbols-restriction": "用户名只能包含字母、数字、下划线或空格", + "auth.telegram-check": "Check", + "auth.telegram-link": "Telegram bot", + "auth.telegram-message-1": "You need to authorize your account in the", + "auth.telegram-message-2": "by clicking “Start” there.", + "auth.telegram-message-3": "Click “Check” below after authorization in the Telegram bot.", + "auth.telegram-optional-qr": "or by scanning the QR code", "auth.user-not-found": "未找到用户", "auth.username": "用户名", "authPanel.disable-comments": "禁用评论", diff --git a/frontend/app/store/user/actions.ts b/frontend/app/store/user/actions.ts index 73780ad3..dd581199 100644 --- a/frontend/app/store/user/actions.ts +++ b/frontend/app/store/user/actions.ts @@ -1,6 +1,6 @@ import * as api from 'common/api'; import { logout } from 'components/auth/auth.api'; -import { User, BlockedUser, BlockTTL } from 'common/types'; +import { User, BlockedUser, BlockTTL, TelegramParams } from 'common/types'; import { ttlToTime } from 'utils/ttl-to-time'; import { getHiddenUsers } from 'utils/get-hidden-users'; import { LS_EMAIL_KEY, LS_HIDDEN_USERS_KEY } from 'common/constants'; @@ -17,6 +17,8 @@ import { USER_UNHIDE, USER_SUBSCRIPTION_SET, USER_SET_ACTION, + TELEGRAM_PARAMS_SET, + TELEGRAM_PARAMS_SET_ACTION, } from './types'; import { fetchComments, unsetCommentMode } from '../comments/actions'; import { COMMENTS_PATCH } from '../comments/types'; @@ -28,6 +30,13 @@ export function setUser(user: User | null = null): USER_SET_ACTION { }; } +export function setTelegramParams(telegramParams: TelegramParams | null = null): TELEGRAM_PARAMS_SET_ACTION { + return { + type: TELEGRAM_PARAMS_SET, + telegramParams, + }; +} + export function signout(cleanSession = true): StoreAction> { return async (dispatch) => { if (cleanSession) { diff --git a/frontend/app/store/user/reducers.ts b/frontend/app/store/user/reducers.ts index f45f48ff..3a7ddacd 100644 --- a/frontend/app/store/user/reducers.ts +++ b/frontend/app/store/user/reducers.ts @@ -1,4 +1,4 @@ -import type { User, BlockedUser } from 'common/types'; +import type { User, BlockedUser, TelegramParams } from 'common/types'; import { USER_SET, @@ -10,6 +10,8 @@ import { USER_HIDE, USER_UNHIDE, USER_SUBSCRIPTION_SET, + TELEGRAM_PARAMS_SET, + TELEGRAM_PARAMS_SET_ACTION, } from './types'; export const user = (state: User | null = null, action: USER_ACTIONS): User | null => { @@ -73,3 +75,16 @@ export const hiddenUsers = (state: { [id: string]: User } = {}, action: USER_ACT return state; } }; + +export const telegramParams = ( + state: TelegramParams | null = null, + action: TELEGRAM_PARAMS_SET_ACTION +): TelegramParams | null => { + switch (action.type) { + case TELEGRAM_PARAMS_SET: { + return action.telegramParams; + } + default: + return state; + } +}; diff --git a/frontend/app/store/user/types.ts b/frontend/app/store/user/types.ts index 55147401..562a5769 100644 --- a/frontend/app/store/user/types.ts +++ b/frontend/app/store/user/types.ts @@ -1,12 +1,19 @@ -import { User, BlockedUser } from 'common/types'; +import { User, BlockedUser, TelegramParams } from 'common/types'; export const USER_SET = 'USER/SET'; +export const TELEGRAM_PARAMS_SET = 'TELEGRAM_PARAMS/SET'; + export interface USER_SET_ACTION { type: typeof USER_SET; user: User | null; } +export interface TELEGRAM_PARAMS_SET_ACTION { + type: typeof TELEGRAM_PARAMS_SET; + telegramParams: TelegramParams | null; +} + /** * Set list of banned users */ diff --git a/frontend/package.json b/frontend/package.json index e25e4ca6..dbc1f440 100644 --- a/frontend/package.json +++ b/frontend/package.json @@ -36,6 +36,7 @@ "lodash-es": "^4.17.21", "node-emoji": "^1.10.0", "preact": "^10.5.13", + "qrcode.react": "^1.0.1", "react-intl": "^5.17.4", "react-redux": "^7.2.4", "redux": "^4.1.0", @@ -55,6 +56,7 @@ "@types/jest": "^26.0.23", "@types/lodash-es": "^4.17.4", "@types/node-emoji": "^1.8.1", + "@types/qrcode.react": "^1.0.2", "@types/react-redux": "^7.1.16", "@types/redux-mock-store": "^1.0.2", "@types/webpack-env": "^1.16.0",