Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

merge(develop): implemented jwt authorization on server and client #16

Merged
merged 11 commits into from
Aug 1, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 0 additions & 1 deletion .eslintignore

This file was deleted.

5 changes: 3 additions & 2 deletions .eslintrc.js
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ module.exports = configure({
extend: {
root: true,
ignorePatterns: ["**/*"],
plugins: ["@nx"],
plugins: ["@nx", "prefer-arrow"],
// My custom config
extends: ["gearonix"],
rules: {
Expand All @@ -35,7 +35,8 @@ module.exports = configure({
"react-hooks/exhaustive-deps": "warn",
"react/no-array-index-key": "warn",
"@typescript-eslint/no-explicit-any": "warn",
"dot-notation": "off"
"dot-notation": "off",
"prefer-arrow/prefer-arrow-functions": "error"
}
}
})
2 changes: 2 additions & 0 deletions .nxignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
# Added to avoid causing additional problems when serving nestjs applications.
_schema.gql
3 changes: 0 additions & 3 deletions .prettierignore

This file was deleted.

4 changes: 4 additions & 0 deletions _templates/fsd-module/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,3 +6,7 @@ This generator creates a module using the
---

- new (General case)

### Run

`hygen fsd-module [method]`
2 changes: 1 addition & 1 deletion apps/client/src/app/app.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import { StoreProvider } from './providers/store'

import 'normalize.css'

function App() {
const App = () => {
return (
<StoreProvider>
<ThemeProvider>
Expand Down
2 changes: 1 addition & 1 deletion apps/client/src/app/entry.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,11 @@
import App from './app'

const updateSW = registerSW({
onNeedRefresh() {
onNeedRefresh: () => {
if (confirm('New content available. Reload?')) {
updateSW(true)
}
}
})

render(<App />, document.querySelector('#root')!)

Check warning on line 14 in apps/client/src/app/entry.tsx

View workflow job for this annotation

GitHub Actions / Linting project

Forbidden non-null assertion

Check warning on line 14 in apps/client/src/app/entry.tsx

View workflow job for this annotation

GitHub Actions / Linting project

Forbidden non-null assertion
1 change: 1 addition & 0 deletions apps/client/src/app/index.ts
Original file line number Diff line number Diff line change
@@ -1 +1,2 @@
export { default as App } from './app'
export { RootStore, StoreContext } from './providers/store'
15 changes: 7 additions & 8 deletions apps/client/src/app/providers/router/config/router.tsx
Original file line number Diff line number Diff line change
@@ -1,13 +1,12 @@
import { Suspense } from 'react'
import { createBrowserRouter } from 'react-router-dom'

import { About } from '@/pages/about'
import { EditPage } from '@/pages/edit'
import { Main } from '@/pages/main'
import { NotFound } from '@/pages/not-found'
import { SignInModal } from '@/widgets/sign-in-modal'
import { ProfilePage } from '@/pages/profile'

import { RoutePaths } from '$/client-shared'
import { Editor } from '$/editor'

const router = createBrowserRouter([
{
Expand All @@ -16,16 +15,16 @@ const router = createBrowserRouter([
},
{
path: RoutePaths.EDITOR,
element: (
<Suspense fallback={null}>
<Editor SignIn={SignInModal} />
</Suspense>
)
element: <EditPage />
},
{
path: RoutePaths.ABOUT,
element: <About />
},
{
path: `${RoutePaths.PROFILE}/:username`,
element: <ProfilePage />
},
{
path: '*',
element: <NotFound />
Expand Down
4 changes: 4 additions & 0 deletions apps/client/src/app/providers/store/config/store.ts
Original file line number Diff line number Diff line change
@@ -1,13 +1,17 @@
import { makeAutoObservable } from 'mobx'

import { AuthStore } from '@/widgets/sign-in-modal'

import { EditorStore } from '$/editor'

class RootStore {
editor: EditorStore
auth: AuthStore

constructor() {
makeAutoObservable(this)
this.editor = new EditorStore()
this.auth = new AuthStore()
}
}

Expand Down
3 changes: 2 additions & 1 deletion apps/client/src/app/providers/store/index.ts
Original file line number Diff line number Diff line change
@@ -1 +1,2 @@
export { default as StoreProvider } from './ui/store-provider'
export { default as RootStore } from './config/store'
export { StoreContext, default as StoreProvider } from './ui/store-provider'
1 change: 1 addition & 0 deletions apps/client/src/app/styles/app.styles.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ export const GlobalStyles = createGlobalStyle`
margin: 0;
}


${customScrollbar('body')}

.ant-popconfirm {
Expand Down
Empty file removed apps/client/src/entities/.gitkeep
Empty file.
1 change: 1 addition & 0 deletions apps/client/src/entities/sign-in-modal-template/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export { SignInModalTemplate } from './ui/sign-in-modal-template'
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export const getFormItemRules = () => [{ required: true, min: 6, max: 14 }]
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
import { Form } from 'antd'
import styled from 'styled-components'

import { wh } from '$/styles'

export const SignInModalStyles = styled(Form)`
width: 84%;
margin: 0 auto;
`

export const SubmitButton = styled.button`
height: 40px;
width: 100%;
cursor: pointer;
font-size: ${({ theme }) => theme.fz7};
margin: 0 auto;
margin-top: 80px;
display: block;
`

export const LogoWrapper = styled.img`
${wh('68px', '92px')}
margin: 10px auto;
display: block;
`
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
import { Form, Input } from 'antd'

import { getFormItemRules } from '../lib/helpers'

import {
LogoWrapper,
SignInModalStyles,
SubmitButton
} from './sign-in-modal-template.styles'

import { Logo } from '$/assets'
import { ColoredButton, ModalTitle } from '$/client-shared'

interface SignInModalTemplateProps<T> {
onSubmit: (data: T) => void
}

export const SignInModalTemplate = <T,>({
onSubmit
}: SignInModalTemplateProps<T>) => {
return (
<SignInModalStyles
name="sign-in-form"
autoComplete="off"
onFinish={onSubmit}>
<LogoWrapper src={Logo} />
<ModalTitle>CodeGear</ModalTitle>

<Form.Item name="username" rules={getFormItemRules()}>
<Input placeholder="Username" size="large" />
</Form.Item>

<Form.Item name="password" rules={getFormItemRules()}>
<Input.Password
placeholder="Password"
size="large"
style={{ marginTop: '10px' }}
/>
</Form.Item>

<SubmitButton
override="#38a886"
type="primary"
htmlType="submit"
as={ColoredButton}>
Sign In
</SubmitButton>
</SignInModalStyles>
)
}
4 changes: 3 additions & 1 deletion apps/client/src/pages/about/ui/about.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
import { Page } from '@/shared/lib'

const About = () => {
return <div>about page</div>
return <Page>about page</Page>
}

export default About
1 change: 1 addition & 0 deletions apps/client/src/pages/edit/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export { default as EditPage } from './ui/edit-page'
18 changes: 18 additions & 0 deletions apps/client/src/pages/edit/ui/edit-page.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
import { Suspense } from 'react'

import { Page } from '@/shared/lib'
import { SignInModal } from '@/widgets/sign-in-modal'

import { Editor } from '$/editor'

const EditPage = () => {
return (
<Page>
<Suspense fallback={null}>
<Editor SignIn={SignInModal} />
</Suspense>
</Page>
)
}

export default EditPage
4 changes: 3 additions & 1 deletion apps/client/src/pages/main/ui/main.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
import { Link } from 'react-router-dom'

import { Page, RoutePaths } from '$/client-shared'
import { Page } from '@/shared/lib'

import { RoutePaths } from '$/client-shared'

const Main = () => {
return (
Expand Down
4 changes: 3 additions & 1 deletion apps/client/src/pages/not-found/ui/not-found.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
import { Page } from '@/shared/lib'

const NotFound = () => {
return <div>not found</div>
return <Page>not found</Page>
}

export default NotFound
1 change: 1 addition & 0 deletions apps/client/src/pages/profile/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export { default as ProfilePage } from './ui/profile-page'
7 changes: 7 additions & 0 deletions apps/client/src/pages/profile/ui/profile-page.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
import { Page } from '@/shared/lib'

const ProfilePage = () => {
return <Page>profile</Page>
}

export default ProfilePage
1 change: 1 addition & 0 deletions apps/client/src/shared/hooks/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export { useStore } from './useStore'
7 changes: 7 additions & 0 deletions apps/client/src/shared/hooks/useStore.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
import { useContext } from 'react'

import { RootStore, StoreContext } from '@/app'

export const useStore = <T extends keyof RootStore>(name: T) => {
return useContext(StoreContext)[name]
}
42 changes: 42 additions & 0 deletions apps/client/src/shared/lib/components/page/auth-guard.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
import { useEffect } from 'react'
import { observer } from 'mobx-react-lite'
import { useLocation, useNavigate } from 'react-router-dom'

import { useStore } from '@/shared/hooks'

import {
PrivatePaths,
RoutePaths,
useAsyncEffect,
useBooleanState,
WithChildren
} from '$/client-shared'

const AuthGuard = observer(({ children }: WithChildren) => {
const { isAuthorized, services } = useStore('auth')
const location = useLocation()
const navigate = useNavigate()
const loader = useBooleanState()

useAsyncEffect(async () => {
await services.getProfile()
loader.on()
}, [])

useEffect(() => {
if (!loader.val) {
return
}

const currentPath = location.pathname.split('/')[1]
const isPrivatePath = PrivatePaths.includes(`/${currentPath}`)

if (isPrivatePath && !isAuthorized) {
navigate(RoutePaths.EDITOR)
}
}, [location, loader.val])

Check warning on line 37 in apps/client/src/shared/lib/components/page/auth-guard.tsx

View workflow job for this annotation

GitHub Actions / Linting project

React Hook useEffect has missing dependencies: 'isAuthorized' and 'navigate'. Either include them or remove the dependency array

Check warning on line 37 in apps/client/src/shared/lib/components/page/auth-guard.tsx

View workflow job for this annotation

GitHub Actions / Linting project

React Hook useEffect has missing dependencies: 'isAuthorized' and 'navigate'. Either include them or remove the dependency array

return children
})

export default AuthGuard
1 change: 1 addition & 0 deletions apps/client/src/shared/lib/components/page/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export { default as Page } from './page'
13 changes: 13 additions & 0 deletions apps/client/src/shared/lib/components/page/page.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
import AuthGuard from '@/shared/lib/components/page/auth-guard'

import { ErrorBoundary, WithChildren } from '$/client-shared'

const Page = ({ children }: WithChildren) => {
return (
<ErrorBoundary>
<AuthGuard>{children}</AuthGuard>
</ErrorBoundary>
)
}

export default Page
1 change: 1 addition & 0 deletions apps/client/src/shared/lib/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export * from './components/page'
15 changes: 15 additions & 0 deletions apps/client/src/widgets/sign-in-modal/graphql/get-profile.query.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
import { gql } from '@apollo/react-hooks'

import { ApolloOperation } from '$/client-shared'

export const getProfileQuery: ApolloOperation = {
gql: gql`
query {
getProfile {
username
avatarUrl
}
}
`,
method: 'getProfile'
}
14 changes: 14 additions & 0 deletions apps/client/src/widgets/sign-in-modal/graphql/sign-in.mutation.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
import { gql } from '@apollo/react-hooks'

import { ApolloOperation } from '$/client-shared'

export const SignInMutation: ApolloOperation = {
gql: gql`
mutation SignIn($payload: SignIn!) {
signIn(_graphql: $payload) {
accessToken
}
}
`,
method: 'signIn'
}
Empty file.
3 changes: 2 additions & 1 deletion apps/client/src/widgets/sign-in-modal/index.ts
Original file line number Diff line number Diff line change
@@ -1 +1,2 @@
export { SignInModal } from './ui/sign-in-modal'
export { AuthStore } from './store/auth.store'
export { default as SignInModal } from './ui/sign-in-modal'
1 change: 1 addition & 0 deletions apps/client/src/widgets/sign-in-modal/lib/exceptions.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export const WrongPassword = 'You entered the wrong password.'
Empty file.
Empty file.
Loading
Loading