rooting authorizer
This commit is contained in:
parent
dfbbb075e8
commit
a59cc9c28e
|
@ -4,6 +4,7 @@ import { Meta, MetaProvider } from '@solidjs/meta'
|
|||
import { Component, createEffect, createMemo } from 'solid-js'
|
||||
import { Dynamic } from 'solid-js/web'
|
||||
|
||||
import { AuthorizerProvider } from '../context/authorizer'
|
||||
import { ConfirmProvider } from '../context/confirm'
|
||||
import { ConnectProvider } from '../context/connect'
|
||||
import { EditorProvider } from '../context/editor'
|
||||
|
@ -41,7 +42,6 @@ import { SearchPage } from '../pages/search.page'
|
|||
import { TopicPage } from '../pages/topic.page'
|
||||
import { ROUTES, useRouter } from '../stores/router'
|
||||
import { hideModal, MODALS, showModal } from '../stores/ui'
|
||||
import { AuthorizerProvider } from '../context/authorizer'
|
||||
|
||||
// TODO: lazy load
|
||||
// const SomePage = lazy(() => import('./Pages/SomePage'))
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
import type { Author, Shout } from '../../graphql/schema/core.gen'
|
||||
import type { Author, Shout, Topic } from '../../graphql/schema/core.gen'
|
||||
|
||||
import { getPagePath } from '@nanostores/router'
|
||||
import { createPopper } from '@popperjs/core'
|
||||
|
@ -12,6 +12,7 @@ import { useReactions } from '../../context/reactions'
|
|||
import { useSession } from '../../context/session'
|
||||
import { MediaItem } from '../../pages/types'
|
||||
import { DEFAULT_HEADER_OFFSET, router, useRouter } from '../../stores/router'
|
||||
import { capitalize } from '../../utils/capitalize'
|
||||
import { getImageUrl } from '../../utils/getImageUrl'
|
||||
import { getDescription } from '../../utils/meta'
|
||||
import { Icon } from '../_shared/Icon'
|
||||
|
@ -33,7 +34,6 @@ import { ShoutRatingControl } from './ShoutRatingControl'
|
|||
|
||||
import styles from './Article.module.scss'
|
||||
import stylesHeader from '../Nav/Header/Header.module.scss'
|
||||
import { capitalize } from '../../utils/capitalize'
|
||||
|
||||
type Props = {
|
||||
article: Shout
|
||||
|
@ -73,7 +73,7 @@ export const FullArticle = (props: Props) => {
|
|||
|
||||
const mainTopic = createMemo(() => {
|
||||
const main_topic_slug = props.article.topics.length > 0 ? props.article.main_topic : null
|
||||
const mt = props.article.topics.find((t) => t.slug === main_topic_slug)
|
||||
const mt = props.article.topics.find((tpc: Topic) => tpc.slug === main_topic_slug)
|
||||
if (mt) {
|
||||
mt.title = lang() == 'en' ? capitalize(mt.slug.replace('-', ' ')) : mt.title
|
||||
return mt
|
||||
|
|
|
@ -32,7 +32,7 @@ export const AuthorBadge = (props: Props) => {
|
|||
const { changeSearchParam } = useRouter()
|
||||
const { t, formatDate } = useLocalize()
|
||||
const subscribed = createMemo(() =>
|
||||
subscriptions().authors.some((author) => author.slug === props.author.slug),
|
||||
subscriptions().authors.some((a: Author) => a.slug === props.author.slug),
|
||||
)
|
||||
|
||||
const subscribe = async (really = true) => {
|
||||
|
|
|
@ -43,7 +43,7 @@ export const AuthorCard = (props: Props) => {
|
|||
const [subscriptionFilter, setSubscriptionFilter] = createSignal<SubscriptionFilter>('all')
|
||||
|
||||
const subscribed = createMemo<boolean>(() =>
|
||||
subscriptions().authors.some((author) => author.slug === props.author.slug),
|
||||
subscriptions().authors.some((a: Author) => a.slug === props.author.slug),
|
||||
)
|
||||
|
||||
const subscribe = async (really = true) => {
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
import type { Author, Shout } from '../../../graphql/schema/core.gen'
|
||||
import type { Author, Shout, Topic } from '../../../graphql/schema/core.gen'
|
||||
|
||||
import { getPagePath, openPage } from '@nanostores/router'
|
||||
import { clsx } from 'clsx'
|
||||
|
@ -87,7 +87,7 @@ export const ArticleCard = (props: ArticleCardProps) => {
|
|||
const { t, lang, formatDate } = useLocalize()
|
||||
const { author } = useSession()
|
||||
const mainTopicSlug = props.article.main_topic
|
||||
const mainTopic = props.article.topics.find((t) => t.slug === mainTopicSlug)
|
||||
const mainTopic = props.article.topics.find((tpc: Topic) => tpc.slug === mainTopicSlug)
|
||||
const mainTopicTitle =
|
||||
lang() === 'ru' && mainTopic?.title ? mainTopic.title : mainTopicSlug.replace('-', ' ')
|
||||
|
||||
|
|
|
@ -3,6 +3,7 @@ import type { ConfirmEmailSearchParams } from './types'
|
|||
import { clsx } from 'clsx'
|
||||
import { createMemo, createSignal, onMount, Show } from 'solid-js'
|
||||
|
||||
import { useAuthorizer } from '../../../context/authorizer'
|
||||
import { useLocalize } from '../../../context/localize'
|
||||
import { useSession } from '../../../context/session'
|
||||
import { ApiError } from '../../../graphql/error'
|
||||
|
@ -14,14 +15,14 @@ import styles from './AuthModal.module.scss'
|
|||
export const EmailConfirm = () => {
|
||||
const { t } = useLocalize()
|
||||
const {
|
||||
session,
|
||||
actions: { confirmEmail },
|
||||
} = useSession()
|
||||
const [{ user }] = useAuthorizer()
|
||||
|
||||
const [isTokenExpired, setIsTokenExpired] = createSignal(false)
|
||||
const [isTokenInvalid, setIsTokenInvalid] = createSignal(false)
|
||||
|
||||
const confirmedEmail = createMemo(() => session()?.user?.email || '')
|
||||
const confirmedEmail = createMemo(() => user?.email || '')
|
||||
|
||||
const { searchParams } = useRouter<ConfirmEmailSearchParams>()
|
||||
|
||||
|
|
|
@ -4,10 +4,10 @@ import deepEqual from 'fast-deep-equal'
|
|||
import { createEffect, createSignal, For, lazy, Match, onCleanup, onMount, Show, Switch } from 'solid-js'
|
||||
import { createStore } from 'solid-js/store'
|
||||
|
||||
import { useAuthorizer } from '../../context/authorizer'
|
||||
import { useConfirm } from '../../context/confirm'
|
||||
import { useLocalize } from '../../context/localize'
|
||||
import { useProfileForm } from '../../context/profile'
|
||||
import { useSession } from '../../context/session'
|
||||
import { useSnackbar } from '../../context/snackbar'
|
||||
import { clone } from '../../utils/clone'
|
||||
import { getImageUrl } from '../../utils/getImageUrl'
|
||||
|
@ -49,9 +49,7 @@ export const ProfileSettings = () => {
|
|||
actions: { showSnackbar },
|
||||
} = useSnackbar()
|
||||
|
||||
const {
|
||||
actions: { loadSession },
|
||||
} = useSession()
|
||||
const [, { setUser, authorizer }] = useAuthorizer()
|
||||
|
||||
const {
|
||||
actions: { showConfirm },
|
||||
|
@ -101,7 +99,10 @@ export const ProfileSettings = () => {
|
|||
}
|
||||
showSnackbar({ type: 'error', body: t('Error') })
|
||||
}
|
||||
loadSession()
|
||||
const profile = await authorizer().getProfile()
|
||||
if (profile) {
|
||||
setUser(profile)
|
||||
}
|
||||
}
|
||||
|
||||
const handleCancel = async () => {
|
||||
|
|
|
@ -84,7 +84,7 @@ export const TopicCard = (props: TopicProps) => {
|
|||
}
|
||||
|
||||
const title = createMemo(() =>
|
||||
capitalize(lang() == 'en' ? props.topic.slug.replace(/-/g, ' ') : props.topic.title || ''),
|
||||
capitalize(lang() == 'en' ? props.topic.slug.replaceAll('-', ' ') : props.topic.title || ''),
|
||||
)
|
||||
|
||||
return (
|
||||
|
|
|
@ -5,12 +5,12 @@ import { useLocalize } from '../../../context/localize'
|
|||
import { useSession } from '../../../context/session'
|
||||
import { FollowingEntity, Topic } from '../../../graphql/schema/core.gen'
|
||||
import { follow, unfollow } from '../../../stores/zine/common'
|
||||
import { capitalize } from '../../../utils/capitalize'
|
||||
import { getImageUrl } from '../../../utils/getImageUrl'
|
||||
import { Button } from '../../_shared/Button'
|
||||
import { CheckButton } from '../../_shared/CheckButton'
|
||||
|
||||
import styles from './TopicBadge.module.scss'
|
||||
import { capitalize } from '../../../utils/capitalize'
|
||||
|
||||
type Props = {
|
||||
topic: Topic
|
||||
|
@ -54,7 +54,7 @@ export const TopicBadge = (props: Props) => {
|
|||
/>
|
||||
<a href={`/topic/${props.topic.slug}`} class={styles.info}>
|
||||
<span class={styles.title}>
|
||||
{lang() == 'en' ? capitalize(props.topic.slug.replace(/-/g, ' ')) : props.topic.title}
|
||||
{lang() == 'en' ? capitalize(props.topic.slug.replaceAll('-', ' ')) : props.topic.title}
|
||||
</span>
|
||||
<Show
|
||||
when={props.topic.body}
|
||||
|
|
|
@ -7,13 +7,13 @@ import { useLocalize } from '../../context/localize'
|
|||
import { useSession } from '../../context/session'
|
||||
import { useRouter } from '../../stores/router'
|
||||
import { setTopicsSort, useTopicsStore } from '../../stores/zine/topics'
|
||||
import { capitalize } from '../../utils/capitalize'
|
||||
import { dummyFilter } from '../../utils/dummyFilter'
|
||||
import { scrollHandler } from '../../utils/scroll'
|
||||
import { SearchField } from '../_shared/SearchField'
|
||||
import { TopicCard } from '../Topic/Card'
|
||||
|
||||
import styles from './AllTopics.module.scss'
|
||||
import { capitalize } from '../../utils/capitalize'
|
||||
|
||||
type AllTopicsPageSearchParams = {
|
||||
by: 'shouts' | 'authors' | 'title' | ''
|
||||
|
@ -147,7 +147,9 @@ export const AllTopicsView = (props: AllTopicsViewProps) => {
|
|||
{(topic) => (
|
||||
<div class={clsx(styles.topic, 'topic col-sm-12 col-md-8')}>
|
||||
<a href={`/topic/${topic.slug}`}>
|
||||
{lang() == 'en' ? capitalize(topic.slug.replace(/-/g, ' ')) : topic.title}
|
||||
{lang() == 'en'
|
||||
? capitalize(topic.slug.replaceAll('-', ' '))
|
||||
: topic.title}
|
||||
</a>
|
||||
<span class={styles.articlesCounter}>{topic.stat.shouts}</span>
|
||||
</div>
|
||||
|
|
|
@ -409,7 +409,7 @@ export const EditView = (props: Props) => {
|
|||
</form>
|
||||
</div>
|
||||
<Show when={page().route === 'editSettings'}>
|
||||
<PublishSettings shoutId={props.shout.id} form={form}></PublishSettings>
|
||||
<PublishSettings shoutId={props.shout.id} form={form} />
|
||||
</Show>
|
||||
<Panel shoutId={props.shout.id} />
|
||||
</>
|
||||
|
|
|
@ -228,7 +228,7 @@ export const FeedView = (props: Props) => {
|
|||
{(topic) => (
|
||||
<span class={clsx(stylesTopic.shoutTopic, styles.topic)}>
|
||||
<a href={`/topic/${topic.slug}`}>
|
||||
{lang() == 'en' ? topic.slug.replace(/-/g, ' ') : topic.title}
|
||||
{lang() == 'en' ? topic.slug.replaceAll('-', ' ') : topic.title}
|
||||
</a>{' '}
|
||||
</span>
|
||||
)}
|
||||
|
|
|
@ -20,7 +20,7 @@ import stylesSettings from '../../../styles/FeedSettings.module.scss'
|
|||
|
||||
export const ProfileSubscriptions = () => {
|
||||
const { t, lang } = useLocalize()
|
||||
const { session } = useSession()
|
||||
const { author } = useSession()
|
||||
const [following, setFollowing] = createSignal<Array<Author | Topic>>([])
|
||||
const [filtered, setFiltered] = createSignal<Array<Author | Topic>>([])
|
||||
const [subscriptionFilter, setSubscriptionFilter] = createSignal<SubscriptionFilter>('all')
|
||||
|
@ -29,8 +29,8 @@ export const ProfileSubscriptions = () => {
|
|||
const fetchSubscriptions = async () => {
|
||||
try {
|
||||
const [getAuthors, getTopics] = await Promise.all([
|
||||
apiClient.getAuthorFollowingUsers({ slug: session()?.author.slug }),
|
||||
apiClient.getAuthorFollowingTopics({ slug: session()?.author.slug }),
|
||||
apiClient.getAuthorFollowingUsers({ slug: author()?.slug }),
|
||||
apiClient.getAuthorFollowingTopics({ slug: author()?.slug }),
|
||||
])
|
||||
setFollowing([...getAuthors, ...getTopics])
|
||||
setFiltered([...getAuthors, ...getTopics])
|
||||
|
|
|
@ -10,6 +10,7 @@ import { Topic } from '../../../graphql/schema/core.gen'
|
|||
import { UploadedFile } from '../../../pages/types'
|
||||
import { router } from '../../../stores/router'
|
||||
import { hideModal, showModal } from '../../../stores/ui'
|
||||
import { useTopicsStore } from '../../../stores/zine/topics'
|
||||
import { Button } from '../../_shared/Button'
|
||||
import { Icon } from '../../_shared/Icon'
|
||||
import { Image } from '../../_shared/Image'
|
||||
|
@ -19,7 +20,6 @@ import { EMPTY_TOPIC } from '../Edit'
|
|||
|
||||
import styles from './PublishSettings.module.scss'
|
||||
import stylesBeside from '../../Feed/Beside.module.scss'
|
||||
import { useTopicsStore } from '../../../stores/zine/topics'
|
||||
|
||||
const SimplifiedEditor = lazy(() => import('../../Editor/SimplifiedEditor'))
|
||||
const GrowingTextarea = lazy(() => import('../../_shared/GrowingTextarea/GrowingTextarea'))
|
||||
|
|
|
@ -1,15 +1,7 @@
|
|||
import type { ParentComponent } from 'solid-js'
|
||||
|
||||
import { Authorizer, User, AuthToken, ConfigType } from '@authorizerdev/authorizer-js'
|
||||
import {
|
||||
createContext,
|
||||
createEffect,
|
||||
createMemo,
|
||||
createSignal,
|
||||
onCleanup,
|
||||
onMount,
|
||||
useContext,
|
||||
} from 'solid-js'
|
||||
import { createContext, createEffect, createMemo, onMount, useContext } from 'solid-js'
|
||||
import { createStore } from 'solid-js/store'
|
||||
|
||||
export type AuthorizerState = {
|
||||
|
@ -83,18 +75,6 @@ export const AuthorizerProvider: ParentComponent<AuthorizerProviderProps> = (pro
|
|||
|
||||
const handleTokenChange = (token: AuthToken | null) => {
|
||||
setState('token', token)
|
||||
|
||||
// If we have an access_token, then we clear the interval and create a new interval
|
||||
// to the token expires_in, so we can retrieve the token again before it expires
|
||||
if (token?.access_token) {
|
||||
if (interval) {
|
||||
clearInterval(interval)
|
||||
}
|
||||
|
||||
interval = setInterval(() => {
|
||||
getToken()
|
||||
}, token.expires_in * 1000) as any
|
||||
}
|
||||
}
|
||||
|
||||
const setUser = (user: User | null) => {
|
||||
|
@ -110,53 +90,17 @@ export const AuthorizerProvider: ParentComponent<AuthorizerProviderProps> = (pro
|
|||
setState('user', null)
|
||||
}
|
||||
|
||||
let interval: number | null = null
|
||||
const interval: number | null = null
|
||||
|
||||
const getToken = async () => {
|
||||
setState('loading', true)
|
||||
const metaRes = await authorizer().getMetaData()
|
||||
|
||||
try {
|
||||
const res = await authorizer().getSession()
|
||||
if (res.access_token && res.user) {
|
||||
setState((prev) => ({
|
||||
...prev,
|
||||
token: {
|
||||
access_token: res.access_token,
|
||||
expires_in: res.expires_in,
|
||||
id_token: res.id_token,
|
||||
refresh_token: res.refresh_token || '',
|
||||
},
|
||||
user: res.user,
|
||||
}))
|
||||
|
||||
if (interval) {
|
||||
clearInterval(interval)
|
||||
}
|
||||
|
||||
interval = setInterval(() => {
|
||||
getToken()
|
||||
}, res.expires_in * 1000) as any
|
||||
} else {
|
||||
setState((prev) => ({ ...prev, user: null, token: null }))
|
||||
}
|
||||
} catch {
|
||||
setState((prev) => ({ ...prev, user: null, token: null }))
|
||||
} finally {
|
||||
setState('config', (cfg) => ({ ...cfg, ...metaRes }))
|
||||
setState('loading', false)
|
||||
}
|
||||
setState('config', (cfg) => ({ ...cfg, ...metaRes }))
|
||||
setState('loading', false)
|
||||
}
|
||||
|
||||
onMount(() => {
|
||||
setState('config', { ...config, redirectURL: window.location.origin + '/?modal=auth' })
|
||||
!state.token && getToken()
|
||||
})
|
||||
|
||||
onCleanup(() => {
|
||||
if (interval) {
|
||||
clearInterval(interval)
|
||||
}
|
||||
})
|
||||
|
||||
return (
|
||||
|
|
|
@ -3,8 +3,8 @@ import type { Accessor, JSX } from 'solid-js'
|
|||
import { fetchEventSource } from '@microsoft/fetch-event-source'
|
||||
import { createContext, useContext, createSignal, createEffect } from 'solid-js'
|
||||
|
||||
import { useSession } from './session'
|
||||
import { useAuthorizer } from './authorizer'
|
||||
import { useSession } from './session'
|
||||
|
||||
export interface SSEMessage {
|
||||
id: string
|
||||
|
|
|
@ -12,6 +12,7 @@ import { slugify } from '../utils/slugify'
|
|||
|
||||
import { useLocalize } from './localize'
|
||||
import { useSnackbar } from './snackbar'
|
||||
import { useSession } from './session'
|
||||
|
||||
type WordCounter = {
|
||||
characters: number
|
||||
|
@ -82,10 +83,13 @@ const removeDraftFromLocalStorage = (shoutId: number) => {
|
|||
|
||||
export const EditorProvider = (props: { children: JSX.Element }) => {
|
||||
const { t } = useLocalize()
|
||||
|
||||
const {
|
||||
actions: { getToken },
|
||||
} = useSession()
|
||||
const { page } = useRouter()
|
||||
const apiClient = createMemo(() => {
|
||||
if (!coreClient.private) coreClient.connect()
|
||||
const token = getToken()
|
||||
if (!coreClient.private) coreClient.connect(token)
|
||||
return coreClient
|
||||
})
|
||||
const {
|
||||
|
|
|
@ -7,6 +7,7 @@ import { inboxClient } from '../graphql/client/chat'
|
|||
import { loadMessages } from '../stores/inbox'
|
||||
|
||||
import { SSEMessage, useConnect } from './connect'
|
||||
import { useSession } from './session'
|
||||
|
||||
type InboxContextType = {
|
||||
chats: Accessor<Chat[]>
|
||||
|
@ -40,8 +41,12 @@ export const InboxProvider = (props: { children: JSX.Element }) => {
|
|||
setChats((prev) => [...prev, relivedChat])
|
||||
}
|
||||
}
|
||||
const {
|
||||
actions: { getToken },
|
||||
} = useSession()
|
||||
const apiClient = createMemo(() => {
|
||||
if (!inboxClient.private) inboxClient.connect()
|
||||
const token = getToken()
|
||||
if (!inboxClient.private) inboxClient.connect(token)
|
||||
return inboxClient
|
||||
})
|
||||
const { addHandler } = useConnect()
|
||||
|
|
|
@ -39,9 +39,13 @@ export const NotificationsProvider = (props: { children: JSX.Element }) => {
|
|||
const [unreadNotificationsCount, setUnreadNotificationsCount] = createSignal(0)
|
||||
const [totalNotificationsCount, setTotalNotificationsCount] = createSignal(0)
|
||||
const [notificationEntities, setNotificationEntities] = createStore<Record<number, Notification>>({})
|
||||
const { isAuthenticated } = useSession()
|
||||
const {
|
||||
isAuthenticated,
|
||||
actions: { getToken },
|
||||
} = useSession()
|
||||
const apiClient = createMemo(() => {
|
||||
if (!notifierClient.private && isAuthenticated()) notifierClient.connect()
|
||||
const token = getToken()
|
||||
if (!notifierClient.private && isAuthenticated()) notifierClient.connect(token)
|
||||
return notifierClient
|
||||
})
|
||||
const { addHandler } = useConnect()
|
||||
|
|
|
@ -30,13 +30,17 @@ const userpicUrl = (userpic: string) => {
|
|||
return userpic
|
||||
}
|
||||
export const ProfileFormProvider = (props: { children: JSX.Element }) => {
|
||||
const { author: currentAuthor } = useSession()
|
||||
const {
|
||||
author,
|
||||
actions: { getToken },
|
||||
} = useSession()
|
||||
const [form, setForm] = createStore<ProfileInput>({})
|
||||
|
||||
const currentSlug = createMemo(() => session()?.user?.slug)
|
||||
const currentSlug = createMemo(() => author()?.slug)
|
||||
|
||||
const apiClient = createMemo(() => {
|
||||
if (!coreClient.private) coreClient.connect()
|
||||
const token = getToken()
|
||||
if (!coreClient.private) coreClient.connect(token)
|
||||
return coreClient
|
||||
})
|
||||
|
||||
|
|
|
@ -6,6 +6,8 @@ import { createStore, reconcile } from 'solid-js/store'
|
|||
import { apiClient as coreClient } from '../graphql/client/core'
|
||||
import { Reaction, ReactionBy, ReactionInput, ReactionKind } from '../graphql/schema/core.gen'
|
||||
|
||||
import { useSession } from './session'
|
||||
|
||||
type ReactionsContextType = {
|
||||
reactionEntities: Record<number, Reaction>
|
||||
actions: {
|
||||
|
@ -32,9 +34,13 @@ export function useReactions() {
|
|||
|
||||
export const ReactionsProvider = (props: { children: JSX.Element }) => {
|
||||
const [reactionEntities, setReactionEntities] = createStore<Record<number, Reaction>>({})
|
||||
const {
|
||||
actions: { getToken },
|
||||
} = useSession()
|
||||
|
||||
const apiClient = createMemo(() => {
|
||||
if (!coreClient.private) coreClient.connect()
|
||||
const token = getToken()
|
||||
if (!coreClient.private) coreClient.connect(token)
|
||||
return coreClient
|
||||
})
|
||||
|
||||
|
|
|
@ -3,7 +3,6 @@ import type { Author, Result } from '../graphql/schema/core.gen'
|
|||
import type { Accessor, JSX, Resource } from 'solid-js'
|
||||
|
||||
import { VerifyEmailInput, LoginInput, AuthToken, User } from '@authorizerdev/authorizer-js'
|
||||
import { cookieStorage, createStorage } from '@solid-primitives/storage'
|
||||
import { createContext, createMemo, createResource, createSignal, onMount, useContext } from 'solid-js'
|
||||
|
||||
import { apiClient } from '../graphql/client/core'
|
||||
|
@ -12,13 +11,11 @@ import { showModal } from '../stores/ui'
|
|||
import { useAuthorizer } from './authorizer'
|
||||
import { useLocalize } from './localize'
|
||||
import { useSnackbar } from './snackbar'
|
||||
import { getToken, resetToken, setToken } from '../stores/token'
|
||||
|
||||
export type SessionContextType = {
|
||||
session: Resource<AuthToken>
|
||||
isSessionLoaded: Accessor<boolean>
|
||||
subscriptions: Accessor<Result>
|
||||
user: Accessor<User>
|
||||
author: Resource<Author | null>
|
||||
isAuthenticated: Accessor<boolean>
|
||||
actions: {
|
||||
|
@ -53,8 +50,8 @@ export const SessionProvider = (props: { children: JSX.Element }) => {
|
|||
const {
|
||||
actions: { showSnackbar },
|
||||
} = useSnackbar()
|
||||
const [, { authorizer }] = useAuthorizer()
|
||||
|
||||
const [{ token }, { setUser, setToken, authorizer }] = useAuthorizer()
|
||||
const getToken = () => token.access_token
|
||||
const loadSubscriptions = async (): Promise<void> => {
|
||||
const result = await apiClient.getMySubscriptions()
|
||||
if (result) {
|
||||
|
@ -66,14 +63,12 @@ export const SessionProvider = (props: { children: JSX.Element }) => {
|
|||
|
||||
const getSession = async (): Promise<AuthToken> => {
|
||||
try {
|
||||
const token = getToken()
|
||||
if (token) {
|
||||
const authResult = await authorizer().getSession({
|
||||
Authorization: token,
|
||||
})
|
||||
const authResult = await authorizer().getSession()
|
||||
if (authResult && authResult.access_token) {
|
||||
console.log(authResult)
|
||||
setToken(authResult.access_token)
|
||||
setToken(authResult)
|
||||
if (authResult.user) setUser(authResult.user)
|
||||
loadSubscriptions()
|
||||
return authResult
|
||||
}
|
||||
|
@ -81,7 +76,8 @@ export const SessionProvider = (props: { children: JSX.Element }) => {
|
|||
return null
|
||||
} catch (error) {
|
||||
console.error('getSession error:', error)
|
||||
resetToken()
|
||||
setToken(null)
|
||||
setUser(null)
|
||||
return null
|
||||
} finally {
|
||||
setTimeout(() => {
|
||||
|
@ -95,8 +91,6 @@ export const SessionProvider = (props: { children: JSX.Element }) => {
|
|||
initialValue: null,
|
||||
})
|
||||
|
||||
const user = createMemo(() => session()?.user)
|
||||
|
||||
const [author, { refetch: loadAuthor }] = createResource<Author | null>(
|
||||
async () => {
|
||||
const u = session()?.user
|
||||
|
@ -117,7 +111,7 @@ export const SessionProvider = (props: { children: JSX.Element }) => {
|
|||
const authResult: AuthToken | void = await authorizer().login(params)
|
||||
|
||||
if (authResult && authResult.access_token) {
|
||||
setToken(authResult.access_token)
|
||||
setToken(authResult)
|
||||
mutate(authResult)
|
||||
loadSubscriptions()
|
||||
console.debug('signed in')
|
||||
|
@ -131,7 +125,7 @@ export const SessionProvider = (props: { children: JSX.Element }) => {
|
|||
const requireAuthentication = async (callback: () => void, modalSource: AuthModalSource) => {
|
||||
setIsAuthWithCallback(() => callback)
|
||||
|
||||
await loadSession()
|
||||
await authorizer().getProfile()
|
||||
|
||||
if (!isAuthenticated()) {
|
||||
showModal('auth', modalSource)
|
||||
|
@ -147,7 +141,8 @@ export const SessionProvider = (props: { children: JSX.Element }) => {
|
|||
const signOut = async () => {
|
||||
await authorizer().logout()
|
||||
mutate(null)
|
||||
resetToken()
|
||||
setToken(null)
|
||||
setUser(null)
|
||||
setSubscriptions(EMPTY_SUBSCRIPTIONS)
|
||||
showSnackbar({ body: t("You've successfully logged out") })
|
||||
}
|
||||
|
@ -155,7 +150,7 @@ export const SessionProvider = (props: { children: JSX.Element }) => {
|
|||
const confirmEmail = async (input: VerifyEmailInput) => {
|
||||
const at: void | AuthToken = await authorizer().verifyEmail(input)
|
||||
if (at) {
|
||||
setToken(at.access_token)
|
||||
setToken(at)
|
||||
mutate(at)
|
||||
}
|
||||
}
|
||||
|
@ -174,7 +169,6 @@ export const SessionProvider = (props: { children: JSX.Element }) => {
|
|||
subscriptions,
|
||||
isSessionLoaded,
|
||||
author,
|
||||
user,
|
||||
isAuthenticated,
|
||||
actions,
|
||||
}
|
||||
|
|
|
@ -26,7 +26,7 @@ import {
|
|||
|
||||
export const inboxClient = {
|
||||
private: null,
|
||||
connect: () => (inboxClient.private = createGraphQLClient('chat')),
|
||||
connect: (token: string) => (inboxClient.private = createGraphQLClient('chat', token)),
|
||||
|
||||
loadChats: async (options: QueryLoad_ChatsArgs): Promise<Chat[]> => {
|
||||
const resp = await inboxClient.private.query(myChats, options).toPromise()
|
||||
|
|
|
@ -29,8 +29,8 @@ import draftsLoad from '../query/core/articles-load-drafts'
|
|||
import myFeed from '../query/core/articles-load-feed'
|
||||
import shoutsLoadSearch from '../query/core/articles-load-search'
|
||||
import authorBy from '../query/core/author-by'
|
||||
import authorId from '../query/core/author-id'
|
||||
import authorFollowers from '../query/core/author-followers'
|
||||
import authorId from '../query/core/author-id'
|
||||
import authorsAll from '../query/core/authors-all'
|
||||
import authorFollowed from '../query/core/authors-followed-by'
|
||||
import authorsLoadBy from '../query/core/authors-load-by'
|
||||
|
@ -45,7 +45,7 @@ const publicGraphQLClient = createGraphQLClient('core')
|
|||
|
||||
export const apiClient = {
|
||||
private: null,
|
||||
connect: () => (apiClient.private = createGraphQLClient('core')), // NOTE: use it after token appears
|
||||
connect: (token: string) => (apiClient.private = createGraphQLClient('core', token)), // NOTE: use it after token appears
|
||||
|
||||
getRandomTopics: async ({ amount }: { amount: number }) => {
|
||||
const response = await publicGraphQLClient.query(topicsRandomQuery, { amount }).toPromise()
|
||||
|
|
|
@ -1,12 +1,12 @@
|
|||
import { createGraphQLClient } from '../createGraphQLClient'
|
||||
import markAllNotificationsAsRead from '../mutation/notifier/mark-all-notifications-as-read'
|
||||
import markNotificationAsRead from '../mutation/notifier/mark-notification-as-read'
|
||||
import { createGraphQLClient } from '../createGraphQLClient'
|
||||
import loadNotifications from '../query/notifier/notifications-load'
|
||||
import { NotificationsResult, QueryLoad_NotificationsArgs } from '../schema/notifier.gen'
|
||||
|
||||
export const notifierClient = {
|
||||
private: null,
|
||||
connect: () => (notifierClient.private = createGraphQLClient('notifier')),
|
||||
connect: (token: string) => (notifierClient.private = createGraphQLClient('notifier', token)),
|
||||
|
||||
getNotifications: async (params: QueryLoad_NotificationsArgs): Promise<NotificationsResult> => {
|
||||
const resp = await notifierClient.private.query(loadNotifications, params).toPromise()
|
||||
|
|
|
@ -2,7 +2,6 @@ import { ClientOptions, dedupExchange, fetchExchange, Exchange, createClient } f
|
|||
import { devtoolsExchange } from '@urql/devtools'
|
||||
|
||||
import { isDev } from '../utils/config'
|
||||
import { getToken } from '../stores/token'
|
||||
|
||||
const exchanges: Exchange[] = [dedupExchange, fetchExchange]
|
||||
|
||||
|
@ -10,8 +9,7 @@ if (isDev) {
|
|||
exchanges.unshift(devtoolsExchange)
|
||||
}
|
||||
|
||||
export const createGraphQLClient = (serviceName: string) => {
|
||||
const token = getToken()
|
||||
export const createGraphQLClient = (serviceName: string, token: string = '') => {
|
||||
const options: ClientOptions = {
|
||||
url: `https://${serviceName}.discours.io`,
|
||||
maskTypename: true,
|
||||
|
|
|
@ -44,8 +44,8 @@ export const ArticlePage = (props: PageProps) => {
|
|||
script.dataset.ackeeDomainId = '1004abeb-89b2-4e85-ad97-74f8d2c8ed2d'
|
||||
try {
|
||||
document.body.appendChild(script)
|
||||
} catch (err) {
|
||||
console.warn(err)
|
||||
} catch (error) {
|
||||
console.warn(error)
|
||||
}
|
||||
})
|
||||
const [scrollToComments, setScrollToComments] = createSignal<boolean>(false)
|
||||
|
|
|
@ -1,10 +0,0 @@
|
|||
import { cookieStorage, createStorage } from '@solid-primitives/storage'
|
||||
|
||||
// https://start.solidjs.com/api/createCookieSessionStorage
|
||||
export const [store, setStore, { remove }] = createStorage({
|
||||
api: cookieStorage,
|
||||
prefix: 'discoursio',
|
||||
})
|
||||
export const getToken = () => store.token
|
||||
export const setToken = (value) => setStore('token', value)
|
||||
export const resetToken = () => remove('token')
|
Loading…
Reference in New Issue
Block a user