diff --git a/.gitea/workflows/main.yml b/.gitea/workflows/main.yml index c88393d4..644a73f3 100644 --- a/.gitea/workflows/main.yml +++ b/.gitea/workflows/main.yml @@ -1,9 +1,30 @@ name: 'deploy' -on: [push] +on: + push: + branches: + - main jobs: + test: + runs-on: ubuntu-latest + steps: + - name: Checkout code + uses: actions/checkout@v2 + + - name: Set up Node.js + uses: actions/setup-node@v3 + with: + node-version: '18' + + - name: Install dependencies + run: npm install + + - name: Run tests + run: npm run check + deploy: runs-on: ubuntu-latest + needs: test # Ensure 'test' job is completed before deploying steps: - name: Cloning repo uses: actions/checkout@v2 @@ -19,4 +40,4 @@ jobs: with: branch: 'main' git_remote_url: 'ssh://dokku@staging.discours.io:22/${{ steps.repo_name.outputs.repo }}' - ssh_private_key: ${{ secrets.SSH_PRIVATE_KEY }} \ No newline at end of file + ssh_private_key: ${{ secrets.SSH_PRIVATE_KEY }} diff --git a/codegen.yml b/codegen.yml index 9d34e4f4..ec1872d9 100644 --- a/codegen.yml +++ b/codegen.yml @@ -28,7 +28,7 @@ generates: # Generate types for notifier src/graphql/schema/notifier.gen.ts: - schema: 'http://notifier.discours.io' # FIXME: https + schema: 'https://notifier.discours.io' # FIXME: https plugins: - 'typescript' - 'typescript-operations' diff --git a/src/components/Nav/AuthModal/ForgotPasswordForm.tsx b/src/components/Nav/AuthModal/ForgotPasswordForm.tsx index 9efe03fc..dc13fa32 100644 --- a/src/components/Nav/AuthModal/ForgotPasswordForm.tsx +++ b/src/components/Nav/AuthModal/ForgotPasswordForm.tsx @@ -3,9 +3,9 @@ import type { AuthModalSearchParams } from './types' import { clsx } from 'clsx' import { createSignal, JSX, Show } from 'solid-js' +import { useAuthorizer } from '../../../context/authorizer' import { useLocalize } from '../../../context/localize' import { ApiError } from '../../../graphql/error' -import { signSendLink } from '../../../stores/auth' import { useRouter } from '../../../stores/router' import { validateEmail } from '../../../utils/validateEmail' @@ -21,12 +21,12 @@ type ValidationErrors = Partial> export const ForgotPasswordForm = () => { const { changeSearchParam } = useRouter() - const { t, lang } = useLocalize() + const { t } = useLocalize() const handleEmailInput = (newEmail: string) => { setValidationErrors(({ email: _notNeeded, ...rest }) => rest) setEmail(newEmail) } - + const [, { authorizer }] = useAuthorizer() const [submitError, setSubmitError] = createSignal('') const [isSubmitting, setIsSubmitting] = createSignal(false) const [validationErrors, setValidationErrors] = createSignal({}) @@ -63,7 +63,10 @@ export const ForgotPasswordForm = () => { setIsSubmitting(true) try { - await signSendLink({ email: email(), lang: lang(), template: 'forgot_password' }) + const response = await authorizer().forgotPassword({ email: email() }) + if (response) { + console.debug(response) + } } catch (error) { if (error instanceof ApiError && error.code === 'user_not_found') { setIsUserNotFound(true) diff --git a/src/components/Nav/AuthModal/LoginForm.tsx b/src/components/Nav/AuthModal/LoginForm.tsx index ac8914c6..a7e4f994 100644 --- a/src/components/Nav/AuthModal/LoginForm.tsx +++ b/src/components/Nav/AuthModal/LoginForm.tsx @@ -3,11 +3,11 @@ import type { AuthModalSearchParams } from './types' import { clsx } from 'clsx' import { createSignal, Show } from 'solid-js' +import { useAuthorizer } from '../../../context/authorizer' import { useLocalize } from '../../../context/localize' import { useSession } from '../../../context/session' import { useSnackbar } from '../../../context/snackbar' import { ApiError } from '../../../graphql/error' -import { signSendLink } from '../../../stores/auth' import { useRouter } from '../../../stores/router' import { hideModal } from '../../../stores/ui' import { validateEmail } from '../../../utils/validateEmail' @@ -27,7 +27,7 @@ type FormFields = { type ValidationErrors = Partial> export const LoginForm = () => { - const { t, lang } = useLocalize() + const { t } = useLocalize() const [submitError, setSubmitError] = createSignal('') const [isSubmitting, setIsSubmitting] = createSignal(false) @@ -67,9 +67,9 @@ export const LoginForm = () => { setIsLinkSent(true) setIsEmailNotConfirmed(false) setSubmitError('') - - const result = await signSendLink({ email: email(), lang: lang(), template: 'email_confirmation' }) - if (result.error) setSubmitError(result.error) + const [{ token }, { authorizer }] = useAuthorizer() + const result = await authorizer().verifyEmail({ token: token.id_token }) + if (!result) setSubmitError('cant sign send link') // TODO: } const handleSubmit = async (event: Event) => { diff --git a/src/components/Nav/AuthModal/RegisterForm.tsx b/src/components/Nav/AuthModal/RegisterForm.tsx index 165ab715..053edd36 100644 --- a/src/components/Nav/AuthModal/RegisterForm.tsx +++ b/src/components/Nav/AuthModal/RegisterForm.tsx @@ -4,9 +4,9 @@ import type { JSX } from 'solid-js' import { clsx } from 'clsx' import { Show, createSignal } from 'solid-js' +import { useAuthorizer } from '../../../context/authorizer' import { useLocalize } from '../../../context/localize' import { ApiError } from '../../../graphql/error' -import { register } from '../../../stores/auth' import { checkEmail, useEmailChecks } from '../../../stores/emailChecks' import { useRouter } from '../../../stores/router' import { hideModal } from '../../../stores/ui' @@ -35,7 +35,7 @@ export const RegisterForm = () => { const { changeSearchParam } = useRouter() const { t } = useLocalize() const { emailChecks } = useEmailChecks() - + const [, { authorizer }] = useAuthorizer() const [submitError, setSubmitError] = createSignal('') const [fullName, setFullName] = createSignal('') const [password, setPassword] = createSignal('') @@ -127,10 +127,11 @@ export const RegisterForm = () => { setIsSubmitting(true) try { - await register({ - name: cleanName, + await authorizer().signup({ + given_name: cleanName, email: cleanEmail, password: password(), + confirm_password: password(), }) setIsSuccess(true) diff --git a/src/components/NotificationsPanel/NotificationView/NotificationView.tsx b/src/components/NotificationsPanel/NotificationView/NotificationView.tsx index e6fa1ec6..70b60919 100644 --- a/src/components/NotificationsPanel/NotificationView/NotificationView.tsx +++ b/src/components/NotificationsPanel/NotificationView/NotificationView.tsx @@ -6,7 +6,7 @@ import { createMemo, createSignal, onMount, Show } from 'solid-js' import { useLocalize } from '../../../context/localize' import { useNotifications } from '../../../context/notifications' -import { Reaction, Shout } from '../../../graphql/schema/core.gen' +import { Reaction } from '../../../graphql/schema/core.gen' import { Notification } from '../../../graphql/schema/notifier.gen' import { router, useRouter } from '../../../stores/router' import { GroupAvatar } from '../../_shared/GroupAvatar' @@ -111,17 +111,6 @@ export const NotificationView = (props: Props) => { ) } } - case 'update': - - case 'delete': - - case 'follow': - - case 'unfollow': - - case 'invited': - // TODO: invited for collaborative authoring - default: { return <> } diff --git a/src/components/Views/PublishSettings/PublishSettings.tsx b/src/components/Views/PublishSettings/PublishSettings.tsx index 1db8d739..a944701f 100644 --- a/src/components/Views/PublishSettings/PublishSettings.tsx +++ b/src/components/Views/PublishSettings/PublishSettings.tsx @@ -38,7 +38,7 @@ const shorten = (str: string, maxLen: number) => { export const PublishSettings = async (props: Props) => { const { t } = useLocalize() - const { session, author } = useSession() + const { author } = useSession() const composeDescription = () => { if (!props.form.description) { diff --git a/src/components/_shared/GroupAvatar/GroupAvatar.tsx b/src/components/_shared/GroupAvatar/GroupAvatar.tsx index ec456b85..087e9b88 100644 --- a/src/components/_shared/GroupAvatar/GroupAvatar.tsx +++ b/src/components/_shared/GroupAvatar/GroupAvatar.tsx @@ -1,14 +1,14 @@ import { clsx } from 'clsx' import { For } from 'solid-js' +import { Author } from '../../../graphql/schema/core.gen' import { Userpic } from '../../Author/Userpic' -import { NotificationUser } from '../../NotificationsPanel/NotificationView/NotificationView' import styles from './GroupAvatar.module.scss' type Props = { class?: string - authors: NotificationUser[] + authors: Author[] } export const GroupAvatar = (props: Props) => { @@ -35,8 +35,8 @@ export const GroupAvatar = (props: Props) => { })} > - {(user) => ( - + {(author: Author) => ( + )} {props.authors.length > 4 &&
+{props.authors?.length - 3}
} diff --git a/src/context/authorizer.tsx b/src/context/authorizer.tsx index 60d92e55..225aa9d9 100644 --- a/src/context/authorizer.tsx +++ b/src/context/authorizer.tsx @@ -142,7 +142,7 @@ export const AuthorizerProvider: ParentComponent = (pro } catch { setState((prev) => ({ ...prev, user: null, token: null })) } finally { - setState('config', (config) => ({ ...config, ...metaRes })) + setState('config', (cfg) => ({ ...cfg, ...metaRes })) setState('loading', false) } } diff --git a/src/context/profile.tsx b/src/context/profile.tsx index b2201794..a2f8a2cf 100644 --- a/src/context/profile.tsx +++ b/src/context/profile.tsx @@ -1,10 +1,10 @@ import type { ProfileInput } from '../graphql/schema/core.gen' -import { createEffect, createMemo, createSignal } from 'solid-js' +import { createEffect, createSignal } from 'solid-js' import { createStore } from 'solid-js/store' import { apiClient } from '../graphql/client/core' -import { loadAuthor, useAuthorsStore } from '../stores/zine/authors' +import { loadAuthor } from '../stores/zine/authors' import { useSession } from './session' @@ -15,8 +15,7 @@ const userpicUrl = (userpic: string) => { return userpic } const useProfileForm = () => { - const { session } = useSession() - const currentAuthor = createMemo(() => session()?.author) + const { author: currentAuthor } = useSession() const [slugError, setSlugError] = createSignal() const submit = async (profile: ProfileInput) => { diff --git a/src/context/session.tsx b/src/context/session.tsx index 30c2fb35..fe28824f 100644 --- a/src/context/session.tsx +++ b/src/context/session.tsx @@ -3,18 +3,10 @@ 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 { - createEffect, - createContext, - createMemo, - createResource, - createSignal, - onMount, - useContext, -} from 'solid-js' +import { createContext, createMemo, createResource, createSignal, onMount, useContext } from 'solid-js' import { apiClient } from '../graphql/client/core' -import { getToken, resetToken, setToken } from '../graphql/privateGraphQLClient' +import { getToken, resetToken } from '../graphql/privateGraphQLClient' import { showModal } from '../stores/ui' import { useAuthorizer } from './authorizer' @@ -75,7 +67,7 @@ export const SessionProvider = (props: { children: JSX.Element }) => { try { const token = getToken() // FIXME: token in localStorage? const authResult = await authorizer().getSession({ - Authorization: token, + Authorization: token, // authToken() }) if (authResult) { console.log(authResult) @@ -105,9 +97,9 @@ export const SessionProvider = (props: { children: JSX.Element }) => { const [author, { refetch: loadAuthor }] = createResource( async () => { - const user = session()?.user - if (user) { - return (await apiClient.getAuthor({ user: user.id })) ?? null + const u = session()?.user + if (u) { + return (await apiClient.getAuthor({ user: u.id })) ?? null } return null }, @@ -126,7 +118,7 @@ export const SessionProvider = (props: { children: JSX.Element }) => { mutate(authResult) } loadSubscriptions() - // console.debug('signed in') + console.debug('signed in') } const [isAuthWithCallback, setIsAuthWithCallback] = createSignal(null) @@ -156,10 +148,10 @@ export const SessionProvider = (props: { children: JSX.Element }) => { } const confirmEmail = async (input: VerifyEmailInput) => { - const authToken: void | AuthToken = await authorizer().verifyEmail(input) - if (authToken) { - setToken(authToken.access_token) - mutate(authToken) + const at: void | AuthToken = await authorizer().verifyEmail(input) + if (at) { + setToken(at.access_token) + mutate(at) } } diff --git a/src/graphql/client/notifier.ts b/src/graphql/client/notifier.ts index 7986eea9..0e7b10da 100644 --- a/src/graphql/client/notifier.ts +++ b/src/graphql/client/notifier.ts @@ -2,7 +2,7 @@ import markAllNotificationsAsRead from '../mutation/notifier/mark-all-notificati import markNotificationAsRead from '../mutation/notifier/mark-notification-as-read' import { getPrivateClient } from '../privateGraphQLClient' import loadNotifications from '../query/notifier/notifications-load' -import { Notification, NotificationsResult, QueryLoad_NotificationsArgs } from '../schema/notifier.gen' +import { NotificationsResult, QueryLoad_NotificationsArgs } from '../schema/notifier.gen' export const notifierPrivateGraphqlClient = getPrivateClient('notifier') diff --git a/src/graphql/privateGraphQLClient.ts b/src/graphql/privateGraphQLClient.ts index e3d643c8..1a282abf 100644 --- a/src/graphql/privateGraphQLClient.ts +++ b/src/graphql/privateGraphQLClient.ts @@ -1,7 +1,7 @@ import { ClientOptions, dedupExchange, fetchExchange, Exchange, createClient } from '@urql/core' import { devtoolsExchange } from '@urql/devtools' -import { isDev, apiBaseUrl } from '../utils/config' +import { isDev } from '../utils/config' const TOKEN_LOCAL_STORAGE_KEY = 'token' @@ -28,7 +28,7 @@ export const resetToken = () => { } const options: ClientOptions = { - url: apiBaseUrl, + url: '', maskTypename: true, requestPolicy: 'cache-and-network', fetchOptions: () => { diff --git a/src/graphql/publicGraphQLClient.ts b/src/graphql/publicGraphQLClient.ts index 5a5f31ba..e4a0b570 100644 --- a/src/graphql/publicGraphQLClient.ts +++ b/src/graphql/publicGraphQLClient.ts @@ -1,7 +1,7 @@ import { ClientOptions, dedupExchange, fetchExchange, Exchange, createClient } from '@urql/core' import { devtoolsExchange } from '@urql/devtools' -import { isDev, apiBaseUrl } from '../utils/config' +import { isDev } from '../utils/config' // import { cache } from './cache' const exchanges: Exchange[] = [dedupExchange, fetchExchange] //, cache] @@ -11,7 +11,7 @@ if (isDev) { } const options: ClientOptions = { - url: apiBaseUrl, + url: '', maskTypename: true, requestPolicy: 'cache-and-network', exchanges, diff --git a/src/stores/auth.ts b/src/stores/auth.ts deleted file mode 100644 index 2476ba8a..00000000 --- a/src/stores/auth.ts +++ /dev/null @@ -1,33 +0,0 @@ -import { MagicLinkLoginInput, SignupInput } from '@authorizerdev/authorizer-js' -import { useAuthorizer } from '../context/authorizer' - -const [, { authorizer }] = useAuthorizer() - -export const register = async ({ - name, - email, - password, -}: { - name: string - email: string - password: string -}) => { - const signupInput: SignupInput = { - email, - password, - confirm_password: password, - } - await authorizer().signup(signupInput) -} - -export const signSendLink = async ({ - email, - lang, - template, -}: { - email: string - lang: string - template: string -}) => { - return await authorizer().magicLinkLogin({ email } as MagicLinkLoginInput) -} diff --git a/src/stores/zine/authors.ts b/src/stores/zine/authors.ts index 9d43daa9..98a3e416 100644 --- a/src/stores/zine/authors.ts +++ b/src/stores/zine/authors.ts @@ -2,8 +2,8 @@ import { createLazyMemo } from '@solid-primitives/memo' import { createSignal } from 'solid-js' import { apiClient } from '../../graphql/client/core' -import { byStat } from '../../utils/sortby' import { Author } from '../../graphql/schema/core.gen' +import { byStat } from '../../utils/sortby' export type AuthorsSortBy = 'shouts' | 'name' | 'followers' diff --git a/src/utils/config.ts b/src/utils/config.ts index 096c4e8d..ea2e7488 100644 --- a/src/utils/config.ts +++ b/src/utils/config.ts @@ -1,9 +1,5 @@ export const isDev = import.meta.env.MODE === 'development' -const defaultApiUrl = 'https://testapi.discours.io' -// export const apiBaseUrl = import.meta.env.PUBLIC_API_URL || defaultApiUrl -export const apiBaseUrl = 'https://v2.discours.io' - const defaultThumborUrl = 'https://images.discours.io' export const thumborUrl = import.meta.env.PUBLIC_THUMBOR_URL || defaultThumborUrl