1
1
'use client' // Ensures this runs only on the client-side
2
2
3
- import type { PropsWithChildren } from 'react'
4
- import { createContext , useContext , useEffect , useState } from 'react'
5
- import Cookies from 'js-cookie '
3
+ import type { ComponentType , PropsWithChildren } from 'react'
4
+ import { useEffect } from 'react'
5
+ import { createContext , useContext , useState } from 'react '
6
6
import { tw } from '@twind/core'
7
7
import { LoadingAnimation } from '@helpwave/common/components/LoadingAnimation'
8
- import type { LoginData } from '@/components/pages/login'
9
8
import { LoginPage } from '@/components/pages/login'
10
-
11
- type Identity = {
12
- token : string ,
13
- name : string ,
14
- }
9
+ import { login , logout , restoreSession } from '@/api/auth/authService'
10
+ import type { User } from 'oidc-client-ts'
11
+ import { REDIRECT_URI } from '@/api/auth/config'
15
12
16
13
type AuthContextType = {
17
- identity : Identity ,
14
+ identity : User ,
18
15
logout : ( ) => void ,
19
16
}
20
17
21
18
const AuthContext = createContext < AuthContextType | undefined > ( undefined )
22
19
23
20
type AuthState = {
24
- identity ?: Identity ,
21
+ identity ?: User ,
25
22
isLoading : boolean ,
26
23
}
27
24
28
- const cookieName = 'authToken'
29
-
30
25
export const AuthProvider = ( { children } : PropsWithChildren ) => {
31
26
const [ { isLoading, identity } , setAuthState ] = useState < AuthState > ( { isLoading : true } )
32
27
33
- const checkIdentity = ( ) => {
34
- setAuthState ( { isLoading : true } )
35
- const token = Cookies . get ( cookieName )
36
- const newAuthState = ! ! token
37
- if ( newAuthState ) {
38
- const identity : Identity = { token : 'test-token' , name : 'Max Mustermann' }
39
- setAuthState ( { identity, isLoading : false } )
40
- } else {
41
- setAuthState ( { isLoading : false } )
42
- }
43
- }
44
-
45
- // Check authentication state on first load
46
28
useEffect ( ( ) => {
47
- checkIdentity ( )
29
+ restoreSession ( ) . then ( identity => {
30
+ setAuthState ( {
31
+ identity,
32
+ isLoading : false ,
33
+ } )
34
+ } )
48
35
} , [ ] )
49
36
50
- const login = async ( _ : LoginData ) => {
51
- // TODO do real login
52
- Cookies . set ( cookieName , 'testdata' , { expires : 1 } )
53
- checkIdentity ( )
54
- return true
55
- }
56
-
57
- const logout = ( ) => {
58
- Cookies . remove ( cookieName )
59
- checkIdentity ( )
60
- }
61
-
62
37
if ( ! identity && isLoading ) {
63
38
return (
64
39
< div className = { tw ( 'flex flex-col items-center justify-center w-screen h-screen' ) } >
@@ -68,7 +43,12 @@ export const AuthProvider = ({ children }: PropsWithChildren) => {
68
43
}
69
44
70
45
if ( ! identity ) {
71
- return ( < LoginPage login = { login } /> )
46
+ return (
47
+ < LoginPage login = { async ( ) => {
48
+ await login ( REDIRECT_URI + `?redirect_uri=${ encodeURIComponent ( window . location . href ) } ` )
49
+ return true
50
+ } } />
51
+ )
72
52
}
73
53
74
54
return (
@@ -78,11 +58,27 @@ export const AuthProvider = ({ children }: PropsWithChildren) => {
78
58
)
79
59
}
80
60
61
+ export const withAuth = < P extends object > ( Component : ComponentType < P > ) => {
62
+ const WrappedComponent = ( props : P ) => (
63
+ < AuthProvider >
64
+ < Component { ...props } />
65
+ </ AuthProvider >
66
+ )
67
+ WrappedComponent . displayName = `withAuth(${ Component . displayName || Component . name || 'Component' } )`
68
+
69
+ return WrappedComponent
70
+ }
71
+
72
+
81
73
// Custom hook for using AuthContext
82
74
export const useAuth = ( ) => {
83
75
const context = useContext ( AuthContext )
84
76
if ( ! context ) {
85
77
throw new Error ( 'useAuth must be used within an AuthProvider' )
86
78
}
87
- return context
79
+ const authHeader = {
80
+ 'Content-Type' : 'application/json' ,
81
+ 'Authorization' : `Bearer ${ context . identity . access_token } ` ,
82
+ }
83
+ return { ...context , authHeader }
88
84
}
0 commit comments