From e4357070af9e7bd879675aadaee559fc5fdcc55b Mon Sep 17 00:00:00 2001 From: vchikalkin Date: Mon, 27 May 2024 12:02:05 +0300 Subject: [PATCH] apps/web: add FormStateContext apps/api: add methods ldap-tfa/login-telegram --- apps/api/src/ldap-tfa/ldap-tfa.controller.ts | 16 +++++-- apps/web/components/Form.tsx | 46 ++++---------------- apps/web/context/form-state.tsx | 45 +++++++++++++++++++ apps/web/pages/telegram.jsx | 7 ++- apps/web/types/user.ts | 9 ++++ 5 files changed, 80 insertions(+), 43 deletions(-) create mode 100644 apps/web/context/form-state.tsx create mode 100644 apps/web/types/user.ts diff --git a/apps/api/src/ldap-tfa/ldap-tfa.controller.ts b/apps/api/src/ldap-tfa/ldap-tfa.controller.ts index 5691bc5..8aa2f83 100644 --- a/apps/api/src/ldap-tfa/ldap-tfa.controller.ts +++ b/apps/api/src/ldap-tfa/ldap-tfa.controller.ts @@ -4,6 +4,7 @@ import { ApiResponse, ApiTags } from '@nestjs/swagger'; import { FastifyReply, FastifyRequest } from 'fastify'; import { cookieOptions } from 'src/config/cookie'; import { env } from 'src/config/env'; +import { AuthToken } from 'src/decorators/token.decorator'; import { Credentials } from 'src/dto/credentials'; import { LdapController } from 'src/ldap/ldap.controller'; @@ -20,10 +21,7 @@ export class LdapTfaController extends LdapController { @Res() reply: FastifyReply ) { try { - const token = await this.ldapService.login(credentials, { - audience: 'auth', - }); - + const token = await this.ldapService.login(credentials, { audience: 'auth' }); const user = await this.ldapService.getUser(token); return reply.setCookie(env.COOKIE_TOKEN_NAME, token, cookieOptions).status(200).send(user); @@ -31,4 +29,14 @@ export class LdapTfaController extends LdapController { throw new HttpException('Unauthorized', HttpStatus.UNAUTHORIZED); } } + + @Post('/login-telegram') + @ApiResponse({ + status: HttpStatus.OK, + }) + async loginTelegram(@AuthToken() token: string, @Res() reply: FastifyReply) { + const user = await this.ldapService.getUser(token); + + return reply.status(200).send(user); + } } diff --git a/apps/web/components/Form.tsx b/apps/web/components/Form.tsx index 6210daa..1b17b9a 100644 --- a/apps/web/components/Form.tsx +++ b/apps/web/components/Form.tsx @@ -4,9 +4,11 @@ import TelegramIcon from '../public/assets/images/telegram.svg'; import styles from './Form.module.scss'; import { publicRuntimeConfig } from '@/config/runtime'; import { AuthModeContext } from '@/context/auth-mode'; +import { FormStateContext } from '@/context/form-state'; +import type { LdapUser } from '@/types/user'; import axios from 'axios'; import Image from 'next/image'; -import { useContext, useReducer, useState } from 'react'; +import { useContext, useState } from 'react'; import { useForm } from 'react-hook-form'; const { APP_BASE_PATH } = publicRuntimeConfig; @@ -16,16 +18,6 @@ type FormData = { readonly password: string; }; -type User = { - department: string; - displayName: string; - domain: string; - domainName: string; - mail: string; - position: string; - username: string; -}; - function handleDefaultLogin(data: FormData) { const redirectUrl = (window.location.pathname.replace(APP_BASE_PATH, '') || '/') + (window.location.search || ''); @@ -36,37 +28,17 @@ function handleDefaultLogin(data: FormData) { } function handleTelegramLogin(data: FormData) { - return axios.post('/login', data); + return axios.post('/login', data); } -type State = { - step: 'login' | 'telegram'; - user: User | undefined; -}; - -type Action = { - payload: State; - type: 'set-step'; -}; - -const reducer = (state: State, action: Action): State => { - switch (action.type) { - case 'set-step': - return { - ...state, - ...action.payload, - }; - - default: - return state; - } -}; - export function Form() { const [hasError, setHasError] = useState(false); const { handleSubmit, register } = useForm(); const { tfa } = useContext(AuthModeContext); - const [{ step, user }, dispatch] = useReducer(reducer, { step: 'login', user: undefined }); + const { + dispatch, + state: { step, user }, + } = useContext(FormStateContext); return (
{ + switch (action.type) { + case 'set-step': + return { + ...state, + ...action.payload, + }; + + default: + return state; + } +}; + +type Context = { + dispatch: React.Dispatch; + state: State; +}; + +export const FormStateContext = createContext({} as Context); + +export function FormStateProvider({ children }: PropsWithChildren) { + const [state, dispatch] = useReducer(reducer, { + step: 'login', + user: undefined, + }); + + const value = useMemo(() => ({ dispatch, state }), [state]); + + return {children}; +} diff --git a/apps/web/pages/telegram.jsx b/apps/web/pages/telegram.jsx index 6c8a6a2..da86683 100644 --- a/apps/web/pages/telegram.jsx +++ b/apps/web/pages/telegram.jsx @@ -1,6 +1,7 @@ import { Login } from '@/components'; import { publicRuntimeConfig } from '@/config/runtime'; import { AuthModeContext } from '@/context/auth-mode'; +import { FormStateProvider } from '@/context/form-state'; import Head from 'next/head'; import { useMemo } from 'react'; @@ -20,8 +21,10 @@ export default function Page() { return ( - - + + + + ); } diff --git a/apps/web/types/user.ts b/apps/web/types/user.ts new file mode 100644 index 0000000..fe0abd0 --- /dev/null +++ b/apps/web/types/user.ts @@ -0,0 +1,9 @@ +export type LdapUser = { + department: string; + displayName: string; + domain: string; + domainName: string; + mail: string; + position: string; + username: string; +};