test-job-ci

This commit is contained in:
Untone 2023-11-28 21:04:51 +03:00
parent b6f9251350
commit ed3360d92b
17 changed files with 68 additions and 100 deletions

View File

@ -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 }}
ssh_private_key: ${{ secrets.SSH_PRIVATE_KEY }}

View File

@ -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'

View File

@ -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<Record<keyof FormFields, string | JSX.Element>>
export const ForgotPasswordForm = () => {
const { changeSearchParam } = useRouter<AuthModalSearchParams>()
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<ValidationErrors>({})
@ -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)

View File

@ -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<Record<keyof FormFields, string>>
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) => {

View File

@ -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<AuthModalSearchParams>()
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)

View File

@ -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 <></>
}

View File

@ -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) {

View File

@ -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) => {
})}
>
<For each={displayedAvatars}>
{(user) => (
<Userpic size={avatarSize()} name={user.name} userpic={user.userpic} class={styles.item} />
{(author: Author) => (
<Userpic size={avatarSize()} name={author.name} userpic={author.pic} class={styles.item} />
)}
</For>
{props.authors.length > 4 && <div class={styles.moreUsers}>+{props.authors?.length - 3}</div>}

View File

@ -142,7 +142,7 @@ export const AuthorizerProvider: ParentComponent<AuthorizerProviderProps> = (pro
} catch {
setState((prev) => ({ ...prev, user: null, token: null }))
} finally {
setState('config', (config) => ({ ...config, ...metaRes }))
setState('config', (cfg) => ({ ...cfg, ...metaRes }))
setState('loading', false)
}
}

View File

@ -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<string>()
const submit = async (profile: ProfileInput) => {

View File

@ -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<Author | null>(
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)
}
}

View File

@ -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')

View File

@ -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: () => {

View File

@ -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,

View File

@ -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)
}

View File

@ -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'

View File

@ -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