From 9a42086f080cd652c1d996d01f7c62b22c1558d8 Mon Sep 17 00:00:00 2001 From: Untone Date: Fri, 24 May 2024 17:59:15 +0300 Subject: [PATCH] auth-minor-fixes --- biome.json | 35 +----- package.json | 8 +- public/locales/en/translation.json | 2 +- public/locales/ru/translation.json | 2 +- .../Author/AuthorCard/AuthorCard.tsx | 6 +- .../Views/DraftsView/DraftsView.tsx | 6 +- src/components/Views/EditView/EditView.tsx | 3 +- .../Views/PublishSettings/PublishSettings.tsx | 30 +++-- src/context/connect.tsx | 6 +- src/context/session.tsx | 113 ++++++++++-------- src/pages/create.page.tsx | 2 +- src/pages/edit.page.tsx | 21 ++-- src/utils/config.ts | 8 +- 13 files changed, 128 insertions(+), 114 deletions(-) diff --git a/biome.json b/biome.json index 90e9f754..df4c1e92 100644 --- a/biome.json +++ b/biome.json @@ -1,21 +1,8 @@ { "$schema": "https://biomejs.dev/schemas/1.7.2/schema.json", "files": { - "include": [ - "*.tsx", - "*.ts", - "*.js", - "*.json" - ], - "ignore": [ - "./dist", - "./node_modules", - ".husky", - "docs", - "gen", - "*.gen.ts", - "*.d.ts" - ] + "include": ["*.tsx", "*.ts", "*.js", "*.json"], + "ignore": ["./dist", "./node_modules", ".husky", "docs", "gen", "*.gen.ts", "*.d.ts"] }, "vcs": { "defaultBranch": "dev", @@ -23,19 +10,13 @@ }, "organizeImports": { "enabled": true, - "ignore": [ - "./api", - "./gen" - ] + "ignore": ["./api", "./gen"] }, "formatter": { "indentStyle": "space", "indentWidth": 2, "lineWidth": 108, - "ignore": [ - "./src/graphql/schema", - "./gen" - ] + "ignore": ["./src/graphql/schema", "./gen"] }, "javascript": { "formatter": { @@ -48,13 +29,7 @@ } }, "linter": { - "ignore": [ - "*.scss", - "*.md", - ".DS_Store", - "*.svg", - "*.d.ts" - ], + "ignore": ["*.scss", "*.md", ".DS_Store", "*.svg", "*.d.ts"], "enabled": true, "rules": { "all": true, diff --git a/package.json b/package.json index 92e8236a..318c4564 100644 --- a/package.json +++ b/package.json @@ -95,7 +95,7 @@ "fast-deep-equal": "3.1.3", "ga-gtag": "1.2.0", "graphql": "16.8.1", - "graphql-tag": "2.12.6", + "graphql-tag": "^2.12.6", "i18next": "22.4.15", "i18next-http-backend": "2.2.0", "i18next-icu": "2.3.0", @@ -137,5 +137,7 @@ "y-prosemirror": "1.2.5", "yjs": "13.6.15" }, - "trustedDependencies": ["@biomejs/biome"] -} + "trustedDependencies": [ + "@biomejs/biome" + ] +} \ No newline at end of file diff --git a/public/locales/en/translation.json b/public/locales/en/translation.json index d3abe54e..aab672da 100644 --- a/public/locales/en/translation.json +++ b/public/locales/en/translation.json @@ -541,4 +541,4 @@ "You've reached a non-existed page": "You've reached a non-existed page", "Your email": "Your email", "Your name will appear on your profile page and as your signature in publications, comments and responses.": "Your name will appear on your profile page and as your signature in publications, comments and responses" -} \ No newline at end of file +} diff --git a/public/locales/ru/translation.json b/public/locales/ru/translation.json index 8e2a97b3..412d2782 100644 --- a/public/locales/ru/translation.json +++ b/public/locales/ru/translation.json @@ -568,4 +568,4 @@ "You've successfully logged out": "Вы успешно вышли из аккаунта", "Your email": "Ваш email", "Your name will appear on your profile page and as your signature in publications, comments and responses.": "Ваше имя появится на странице вашего профиля и как ваша подпись в публикациях, комментариях и откликах" -} \ No newline at end of file +} diff --git a/src/components/Author/AuthorCard/AuthorCard.tsx b/src/components/Author/AuthorCard/AuthorCard.tsx index 58d2b8ac..ca643e0b 100644 --- a/src/components/Author/AuthorCard/AuthorCard.tsx +++ b/src/components/Author/AuthorCard/AuthorCard.tsx @@ -197,8 +197,10 @@ export const AuthorCard = (props: Props) => { 0}> - {(f) => ( - + {(f: Author) => ( + + + )}
diff --git a/src/components/Views/DraftsView/DraftsView.tsx b/src/components/Views/DraftsView/DraftsView.tsx index 957f7ffe..7c904691 100644 --- a/src/components/Views/DraftsView/DraftsView.tsx +++ b/src/components/Views/DraftsView/DraftsView.tsx @@ -15,20 +15,24 @@ import styles from './DraftsView.module.scss' export const DraftsView = () => { const { author, loadSession } = useSession() const [drafts, setDrafts] = createSignal([]) + const [loading, setLoading] = createSignal(false) createEffect( on( () => author(), async (a) => { if (a) { + setLoading(true) const { shouts: loadedDrafts, error } = await apiClient.getDrafts() if (error) { console.warn(error) await loadSession() } setDrafts(loadedDrafts || []) + setLoading(false) } }, + { defer: true }, ), ) @@ -50,7 +54,7 @@ export const DraftsView = () => { return (
- }> + }>
diff --git a/src/components/Views/EditView/EditView.tsx b/src/components/Views/EditView/EditView.tsx index 2148a3e4..5910ba4d 100644 --- a/src/components/Views/EditView/EditView.tsx +++ b/src/components/Views/EditView/EditView.tsx @@ -28,6 +28,7 @@ import { EditorSwiper } from '../../_shared/SolidSwiper' import { PublishSettings } from '../PublishSettings' import styles from './EditView.module.scss' +import { Loading } from '../../_shared/Loading' const SimplifiedEditor = lazy(() => import('../../Editor/SimplifiedEditor')) const GrowingTextarea = lazy(() => import('../../_shared/GrowingTextarea/GrowingTextarea')) @@ -403,7 +404,7 @@ export const EditView = (props: Props) => {
- + }> { } }) - const [settingsForm, setSettingsForm] = createStore(emptyConfig) + const [settingsForm, setSettingsForm] = createStore(emptyConfig) onMount(() => { setSettingsForm(initialData()) @@ -96,12 +107,12 @@ export const PublishSettings = (props: Props) => { setSettingsForm('coverImageUrl', '') } - const handleTopicSelectChange = (newSelectedTopics) => { + const handleTopicSelectChange = (newSelectedTopics: Topic[]) => { if ( props.form.selectedTopics.length === 0 || - newSelectedTopics.every((topic) => topic.id !== props.form.mainTopic?.id) + newSelectedTopics.every((topic: Topic) => topic.id !== props.form.mainTopic?.id) ) { - setSettingsForm((prev) => { + setSettingsForm((prev: Topic) => { return { ...prev, mainTopic: newSelectedTopics[0], @@ -193,7 +204,8 @@ export const PublishSettings = (props: Props) => { fieldName={t('Header')} placeholder={t('Come up with a title for your story')} initialValue={settingsForm.title} - value={(value) => setSettingsForm('title', value)} + // biome-ignore lint/suspicious/noExplicitAny: + value={(value: any) => setSettingsForm('title', value)} allowEnterKey={false} maxLength={100} /> @@ -203,7 +215,8 @@ export const PublishSettings = (props: Props) => { fieldName={t('Subheader')} placeholder={t('Come up with a subtitle for your story')} initialValue={settingsForm.subtitle || ''} - value={(value) => setSettingsForm('subtitle', value)} + // biome-ignore lint/suspicious/noExplicitAny: + value={(value: any) => setSettingsForm('subtitle', value)} allowEnterKey={false} maxLength={100} /> @@ -214,7 +227,8 @@ export const PublishSettings = (props: Props) => { placeholder={t('Write a short introduction')} label={t('Description')} initialContent={composeDescription()} - onChange={(value) => setForm('description', value)} + // biome-ignore lint/suspicious/noExplicitAny: + onChange={(value: any) => setForm('description', value)} maxLength={DESCRIPTION_MAX_LENGTH} />
diff --git a/src/context/connect.tsx b/src/context/connect.tsx index facd0ae5..ef3553e6 100644 --- a/src/context/connect.tsx +++ b/src/context/connect.tsx @@ -42,7 +42,7 @@ export const ConnectProvider = (props: { children: JSX.Element }) => { createEffect( on( () => session()?.access_token, - async ([tkn]) => { + async (tkn) => { if (!sseUrl) return if (!tkn) return if (!connected() && retried() <= RECONNECT_TIMES) { @@ -67,7 +67,7 @@ export const ConnectProvider = (props: { children: JSX.Element }) => { return Promise.resolve() } return Promise.reject( - `SSE: cannot connect to real-time updates, status: ${response.status}`, + `SSE: cannot connect to real-time updates: ${response.status}`, ) }, onclose() { @@ -75,7 +75,7 @@ export const ConnectProvider = (props: { children: JSX.Element }) => { setConnected(false) if (retried() < RECONNECT_TIMES) { setRetried((r) => r + 1) - } + } else throw Error('closed by server') }, onerror(err) { console.error('[context.connect] SSE connection error:', err) diff --git a/src/context/session.tsx b/src/context/session.tsx index 9d8199db..e4dc15d3 100644 --- a/src/context/session.tsx +++ b/src/context/session.tsx @@ -34,13 +34,14 @@ import { useRouter } from '../stores/router' import { showModal } from '../stores/ui' import { addAuthors } from '../stores/zine/authors' +import { authApiUrl } from '../utils/config' import { useLocalize } from './localize' import { useSnackbar } from './snackbar' const defaultConfig: ConfigType = { - authorizerURL: 'https://auth.discours.io', + authorizerURL: authApiUrl.replace('/graphql', ''), redirectURL: 'https://testing.discours.io', - clientID: 'b9038a34-ca59-41ae-a105-c7fbea603e24', // FIXME: use env? + clientID: '', } export type SessionContextType = { @@ -73,9 +74,32 @@ export type SessionContextType = { resendVerifyEmail: (params: ResendVerifyEmailInput) => Promise } -// biome-ignore lint/suspicious/noEmptyBlockStatements: -const noop = () => {} - +const noop = () => null +const metaRes = { + data: { + meta: { + version: 'latest', + // client_id: 'b9038a34-ca59-41ae-a105-c7fbea603e24', + is_google_login_enabled: true, + is_facebook_login_enabled: true, + is_github_login_enabled: true, + is_linkedin_login_enabled: false, + is_apple_login_enabled: false, + is_twitter_login_enabled: true, + is_microsoft_login_enabled: false, + is_twitch_login_enabled: false, + is_roblox_login_enabled: false, + is_email_verification_enabled: true, + is_basic_authentication_enabled: true, + is_magic_link_login_enabled: true, + is_sign_up_enabled: true, + is_strong_password_enabled: false, + is_multi_factor_auth_enabled: true, + is_mobile_basic_authentication_enabled: true, + is_phone_verification_enabled: false, + }, + }, +} const SessionContext = createContext() export function useSession() { @@ -212,44 +236,41 @@ export const SessionProvider = (props: { }) // when session is loaded - createEffect(() => { - if (session()) { - const token = session()?.access_token - if (token) { - if (!inboxClient.private) { - apiClient.connect(token) - inboxClient.connect(token) - } - - try { - const appdata = session()?.user.app_data - if (appdata) { - const { profile } = appdata - if (profile?.id) { - setAuthor(profile) - addAuthors([profile]) - } else { - setTimeout(loadAuthor, 15) + createEffect( + on( + session, + (s: AuthToken) => { + if (s) { + const token = s?.access_token + if (token) { + if (!inboxClient.private) { + apiClient.connect(token) + inboxClient.connect(token) } + + try { + const appdata = session()?.user.app_data + if (appdata) { + const { profile } = appdata + if (profile?.id) { + setAuthor(profile) + addAuthors([profile]) + } else { + setTimeout(loadAuthor, 15) + } + } + } catch (e) { + console.error(e) + } + setIsSessionLoaded(true) + } else { + reset() } - } catch (e) { - console.error(e) } - - setIsSessionLoaded(true) - } - } - }) - - // when author is loaded - createEffect(() => { - if (author()) { - addAuthors([author()]) - } else { - reset() - } - }) - + }, + { defer: true }, + ), + ) const reset = () => { setIsSessionLoaded(true) setSession(null) @@ -257,20 +278,13 @@ export const SessionProvider = (props: { } // initial effect - onMount(async () => { - const metaRes = await authorizer().getMetaData() + onMount(() => { setConfig({ ...defaultConfig, ...metaRes, redirectURL: window.location.origin, }) - let s: AuthToken - try { - s = await loadSession() - } catch (error) { - console.warn('[context.session] load session failed', error) - } - if (!s) reset() + loadSession() }) // callback state updater @@ -318,6 +332,7 @@ export const SessionProvider = (props: { console.debug(authResult) reset() showSnackbar({ body: t("You've successfully logged out") }) + console.debug(session()) } const changePassword = async (password: string, token: string) => { diff --git a/src/pages/create.page.tsx b/src/pages/create.page.tsx index e5b7e8a1..137121f5 100644 --- a/src/pages/create.page.tsx +++ b/src/pages/create.page.tsx @@ -17,7 +17,7 @@ import styles from '../styles/Create.module.scss' const handleCreate = async (layout: LayoutType) => { const shout = await apiClient.createArticle({ article: { layout: layout } }) - redirectPage(router, 'edit', { + shout?.id && redirectPage(router, 'edit', { shoutId: shout?.id.toString(), }) } diff --git a/src/pages/edit.page.tsx b/src/pages/edit.page.tsx index aaa08eee..f7dfbb59 100644 --- a/src/pages/edit.page.tsx +++ b/src/pages/edit.page.tsx @@ -7,7 +7,7 @@ import { useLocalize } from '../context/localize' import { useSession } from '../context/session' import { apiClient } from '../graphql/client/core' import { Shout } from '../graphql/schema/core.gen' -import { router, useRouter } from '../stores/router' +import { router } from '../stores/router' import { redirectPage } from '@nanostores/router' import { useSnackbar } from '../context/snackbar' @@ -33,7 +33,6 @@ const getContentTypeTitle = (layout: LayoutType) => { export const EditPage = () => { const { t } = useLocalize() const { session } = useSession() - const { page } = useRouter() const snackbar = useSnackbar() const fail = async (error: string) => { @@ -48,15 +47,17 @@ export const EditPage = () => { createEffect( on( - () => page(), + () => window?.location.pathname, (p) => { - if (p?.path) { - console.debug(p?.path) - const shoutId = p?.path.split('/').pop() - const shoutIdFromUrl = Number.parseInt(shoutId ?? '0', 10) - console.debug(`editing shout ${shoutIdFromUrl}`) - if (shoutIdFromUrl) { - setShoutId(shoutIdFromUrl) + if (p) { + console.debug(p) + const shoutId = p.split('/').pop() + if (shoutId) { + const shoutIdFromUrl = Number.parseInt(shoutId ?? '0', 10) + console.debug(`editing shout ${shoutIdFromUrl}`) + if (shoutIdFromUrl) { + setShoutId(shoutIdFromUrl) + } } } }, diff --git a/src/utils/config.ts b/src/utils/config.ts index dc16a516..d192278d 100644 --- a/src/utils/config.ts +++ b/src/utils/config.ts @@ -2,7 +2,7 @@ export const isDev = import.meta.env.MODE === 'development' export const cdnUrl = 'https://cdn.discours.io' export const thumborUrl = import.meta.env.PUBLIC_THUMBOR_URL || 'https://images.discours.io' export const errorsReportingDsn = import.meta.env.PUBLIC_GLITCHTIP_DSN || import.meta.env.PUBLIC_SENTRY_DSN || '' -export const coreApiUrl = 'https://coretest.discours.io' -export const chatApiUrl = 'https://inboxtest.discours.io' -export const authApiUrl = 'https://authtest.discours.io/graphql' -export const sseUrl = 'https://presencetest.discours.io' +export const coreApiUrl = import.meta.env.PUBLIC_API_BASE || 'https://coretest.discours.io' +export const chatApiUrl = import.meta.env.PUBLIC_CHAT_API || 'https://inboxtest.discours.io' +export const authApiUrl = import.meta.env.PUBLIC_AUTH_API || 'https://authtest.discours.io/graphql' +export const sseUrl = import.meta.env.PUBLIC_REALTIME_EVENTS || 'https://presencetest.discours.io'