diff --git a/src/components/Views/Feed.tsx b/src/components/Views/Feed.tsx
index 24ad0308..756124cc 100644
--- a/src/components/Views/Feed.tsx
+++ b/src/components/Views/Feed.tsx
@@ -7,9 +7,8 @@ import { TopicCard } from '../Topic/Card'
import { ArticleCard } from '../Feed/Card'
import { AuthorCard } from '../Author/Card'
import { t } from '../../utils/intl'
-import { useStore } from '@nanostores/solid'
import { FeedSidebar } from '../Feed/Sidebar'
-import { session } from '../../stores/auth'
+import { useAuthStore } from '../../stores/auth'
import CommentCard from '../Article/Comment'
import { loadRecentArticles, useArticlesStore } from '../../stores/zine/articles'
import { useReactionsStore } from '../../stores/zine/reactions'
@@ -36,8 +35,7 @@ export const FeedView = (props: FeedProps) => {
const { sortedAuthors } = useAuthorsStore()
const { topTopics } = useTopicsStore()
const { topAuthors } = useTopAuthorsStore()
-
- const auth = useStore(session)
+ const { session } = useAuthStore()
const topReactions = createMemo(() => sortBy(reactions(), byCreated))
@@ -71,7 +69,7 @@ export const FeedView = (props: FeedProps) => {
-
+
-
{t('My feed')}
diff --git a/src/graphql/query/authors-all.ts b/src/graphql/query/authors-all.ts
index c1c4e00b..bbaeac55 100644
--- a/src/graphql/query/authors-all.ts
+++ b/src/graphql/query/authors-all.ts
@@ -1,8 +1,8 @@
import { gql } from '@urql/core'
export default gql`
- query AuthorssAllQuery($limit: Int!, $offset: Int!) {
- authorsAll(limit: $limit, offset: $offset) {
+ query AuthorssAllQuery {
+ authorsAll {
_id: slug
slug
name
diff --git a/src/locales/ru.json b/src/locales/ru.json
index 34258077..90264e81 100644
--- a/src/locales/ru.json
+++ b/src/locales/ru.json
@@ -39,7 +39,7 @@
"Feedback": "Обратная связь",
"Follow": "Подписаться",
"Follow the topic": "Подписаться на тему",
- "Forget password?": "Забыли пароль?",
+ "Forgot password?": "Забыли пароль?",
"Get to know the most intelligent people of our time, edit and discuss the articles, share your expertise, rate and decide what to publish in the magazine": "Познакомитесь с выдающимися людьми нашего времени, участвуйте в редактировании и обсуждении статей, выступайте экспертом, оценивайте материалы других авторов со всего мира и определяйте, какие статьи будут опубликованы в журнале",
"Help to edit": "Помочь редактировать",
"Horizontal collaborative journalistic platform": "Горизонтальная платформа для коллаборативной журналистики",
@@ -141,5 +141,7 @@
"topics": "темы",
"user already exist": "пользователь уже существует",
"view": "просмотр",
- "zine": "журнал"
+ "zine": "журнал",
+ "Please, confirm email": "Пожалуйста, подтвердите электронную почту",
+ "Something went wrong, check email and password": "Что-то пошло не так. Проверьте адрес электронной почты и пароль"
}
diff --git a/src/stores/auth.ts b/src/stores/auth.ts
index 95d9e68b..5cc13fad 100644
--- a/src/stores/auth.ts
+++ b/src/stores/auth.ts
@@ -3,27 +3,28 @@ import type { AuthResult } from '../graphql/types.gen'
import { getLogger } from '../utils/logger'
import { resetToken, setToken } from '../graphql/privateGraphQLClient'
import { apiClient } from '../utils/apiClient'
+import { createSignal } from 'solid-js'
const log = getLogger('auth-store')
-export const session = atom()
+const [session, setSession] = createSignal(null)
export const signIn = async (params) => {
- const s = await apiClient.authLogin(params)
- session.set(s)
- setToken(s.token)
+ const authResult = await apiClient.authLogin(params)
+ setSession(authResult)
+ setToken(authResult.token)
log.debug('signed in')
}
export const signUp = async (params) => {
- const s = await apiClient.authRegiser(params)
- session.set(s)
- setToken(s.token)
+ const authResult = await apiClient.authRegister(params)
+ setSession(authResult)
+ setToken(authResult.token)
log.debug('signed up')
}
export const signOut = () => {
- session.set(null)
+ setSession(null)
resetToken()
log.debug('signed out')
}
@@ -36,6 +37,18 @@ export const signCheck = async (params) => {
export const resetCode = atom()
+export const register = async ({ email, password }: { email: string; password: string }) => {
+ const authResult = await apiClient.authRegister({
+ email,
+ password
+ })
+
+ if (authResult && !authResult.error) {
+ log.debug('register session update', authResult)
+ setSession(authResult)
+ }
+}
+
export const signSendLink = async (params) => {
await apiClient.authSendLink(params) // { email }
resetToken()
@@ -44,11 +57,15 @@ export const signSendLink = async (params) => {
export const signConfirm = async (params) => {
const auth = await apiClient.authConfirmCode(params) // { code }
setToken(auth.token)
- session.set(auth)
+ setSession(auth)
}
export const renewSession = async () => {
- const s = await apiClient.getSession() // token in header
- setToken(s.token)
- session.set(s)
+ const authResult = await apiClient.getSession() // token in header
+ setToken(authResult.token)
+ setSession(authResult)
+}
+
+export const useAuthStore = () => {
+ return { session }
}
diff --git a/src/utils/apiClient.ts b/src/utils/apiClient.ts
index 45e605f1..60a670ef 100644
--- a/src/utils/apiClient.ts
+++ b/src/utils/apiClient.ts
@@ -1,4 +1,4 @@
-import type { Reaction, Shout, FollowingEntity } from '../graphql/types.gen'
+import type { Reaction, Shout, FollowingEntity, AuthResult } from '../graphql/types.gen'
import { publicGraphQLClient } from '../graphql/publicGraphQLClient'
import articleBySlug from '../graphql/query/article-by-slug'
@@ -36,15 +36,43 @@ const log = getLogger('api-client')
const FEED_SIZE = 50
const REACTIONS_PAGE_SIZE = 100
-export const apiClient = {
- // auth
+type ApiErrorCode = 'unknown' | 'email_not_confirmed' | 'user_not_found'
- authLogin: async ({ email, password }) => {
+export class ApiError extends Error {
+ code: ApiErrorCode
+
+ constructor(code: ApiErrorCode, message?: string) {
+ super(message)
+ this.code = code
+ }
+}
+
+export const apiClient = {
+ authLogin: async ({ email, password }): Promise => {
const response = await publicGraphQLClient.query(authLoginQuery, { email, password }).toPromise()
+ // log.debug('authLogin', { response })
+ if (response.error) {
+ if (response.error.message === '[GraphQL] User not found') {
+ throw new ApiError('user_not_found')
+ }
+
+ throw new ApiError('unknown', response.error.message)
+ }
+
+ if (response.data.signIn.error) {
+ if (response.data.signIn.error === 'please, confirm email') {
+ throw new ApiError('email_not_confirmed')
+ }
+
+ throw new ApiError('unknown', response.data.signIn.error)
+ }
+
return response.data.signIn
},
- authRegiser: async ({ email, password }) => {
- const response = await publicGraphQLClient.query(authRegisterMutation, { email, password }).toPromise()
+ authRegister: async ({ email, password }): Promise => {
+ const response = await publicGraphQLClient
+ .mutation(authRegisterMutation, { email, password })
+ .toPromise()
return response.data.registerUser
},
authSignOut: async () => {
@@ -87,9 +115,12 @@ export const apiClient = {
return response.data.recentPublished
},
getRandomTopics: async ({ amount }: { amount: number }) => {
- log.debug('getRandomTopics')
const response = await publicGraphQLClient.query(topicsRandomQuery, { amount }).toPromise()
+ if (!response.data) {
+ log.error('getRandomTopics', response.error)
+ }
+
return response.data.topicsRandom
},
getSearchResults: async ({
@@ -177,7 +208,7 @@ export const apiClient = {
return response.data.unfollow
},
- getSession: async () => {
+ getSession: async (): Promise => {
// renew session with auth token in header (!)
const response = await privateGraphQLClient.mutation(mySession, {}).toPromise()
return response.data.refreshSession
@@ -193,7 +224,7 @@ export const apiClient = {
},
getAllAuthors: async () => {
- const response = await publicGraphQLClient.query(authorsAll, { limit: 9999, offset: 9999 }).toPromise()
+ const response = await publicGraphQLClient.query(authorsAll, {}).toPromise()
return response.data.authorsAll
},
getArticle: async ({ slug }: { slug: string }): Promise => {