sozsoft-platform/ui/src/utils/hooks/useAuth.ts
2026-08-12 22:08:14 +03:00

158 lines
4.4 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

import { jwtDecode } from 'jwt-decode'
import { useNavigate } from 'react-router-dom'
import useQuery from './useQuery'
import { useStoreActions, useStoreState } from '../../store/store'
import {
FailedSignInResponse,
SignInCredential,
SignInResponse,
SignUpCredential,
} from '../../proxy/auth/models'
import { signIn, signOut } from '../../services/auth.service'
import { isLoginSuccess } from '../../proxy/account/models'
import { REDIRECT_URL_KEY } from '../../constants/app.constant'
import appConfig from '../../proxy/configs/app.config'
import { register } from '../../services/account.service'
import { hasPendingChangelog } from '@/views/version/swRegistration'
import { ROUTES_ENUM } from '@/routes/route.constant'
type Status = 'success' | 'failed' | 'error'
function useAuth() {
const { signIn: signInStore, signOut: signOutStore } = useStoreActions((actions) => actions.auth)
const navigate = useNavigate()
const query = useQuery()
const { token, refreshToken, signedIn } = useStoreState((state) => state.auth.session)
const handleToken = ({
token,
refreshToken,
expiresIn,
}: {
token: string
refreshToken: string
expiresIn: number
}) => {
const tokenDetails: any = jwtDecode(token)
signInStore({
session: { token, refreshToken, expiresIn, expire: tokenDetails?.exp, signedIn: true },
user: {
id: tokenDetails?.sub,
userName: tokenDetails?.preferred_username,
email: tokenDetails?.email,
authority: [tokenDetails?.role],
name: `${tokenDetails?.given_name} ${tokenDetails?.family_name}`.trim(),
role: 'teacher',
tenantId: tokenDetails?.tenantid,
},
})
}
const _signIn = async (
values: SignInCredential,
): Promise<{
status: Status
message?: string
data?: SignInResponse | FailedSignInResponse
}> => {
try {
const resp = await signIn(values)
if (isLoginSuccess(resp.data)) {
const {
access_token: token,
refresh_token: refreshToken,
expires_in: expiresIn,
} = resp.data
handleToken({ token, refreshToken, expiresIn })
const redirectUrl = query.get(REDIRECT_URL_KEY)
// Uygulama yeni bir sürümle/deploy ile açıldıysa kullanıcı önce
// değişiklikleri görsün. Bayrak ChangeLog ekranında tüketilir.
const target = hasPendingChangelog()
? ROUTES_ENUM.protected.admin.changeLog
: (redirectUrl ?? appConfig.authenticatedEntryPath)
navigate(target)
return {
status: 'success',
message: '',
}
} else {
return {
status: 'failed',
data: resp?.data,
}
}
// eslint-disable-next-line @typescript-eslint/no-explicit-any
} catch (errors: any) {
return {
status: 'error',
message: errors?.response?.data?.message || errors.toString(),
}
}
}
const _signUp = async (values: SignUpCredential) => {
try {
const resp = await register(values)
if (resp.data) {
const {
access_token: token,
refresh_token: refreshToken,
expires_in: expiresIn,
} = resp?.data as any
handleToken({ token, refreshToken, expiresIn })
// if (resp.data.user) {
// setUser(
// resp.data.user || {
// avatar: '',
// userName: 'Anonymous',
// authority: ['USER'],
// email: '',
// name: '',
// },
// )
// }
setTimeout(
() => navigate(query.get(REDIRECT_URL_KEY) ?? appConfig.authenticatedEntryPath),
10000,
)
return {
status: 'success',
message: '',
}
}
// eslint-disable-next-line @typescript-eslint/no-explicit-any
} catch (errors: any) {
const err =
errors?.response?.data?.error?.details ||
errors?.response?.data?.error?.message ||
errors?.response?.data?.message ||
errors.toString()
return {
status: 'error',
message: err,
}
}
}
const _signOut = async () => {
await signOut({ token, refreshToken })
signOutStore()
navigate(appConfig.unAuthenticatedEntryPath)
}
return {
authenticated: token && signedIn,
signIn: _signIn,
signUp: _signUp,
signOut: _signOut,
}
}
export default useAuth