1
- import { ref } from "vue" ;
2
- import { useRoute , useRouter } from "vue-router" ;
3
- import { useSecurityStore } from "../../store/securityStore" ;
4
- import { usePlatformConfig } from "../../store/platformConfig" ;
5
- import securityService from "../../services/securityService" ;
6
- import { useNotification } from "../notification" ;
1
+ import { ref } from "vue"
2
+ import { useRoute , useRouter } from "vue-router"
3
+ import { useSecurityStore } from "../../store/securityStore"
4
+ import { usePlatformConfig } from "../../store/platformConfig"
5
+ import securityService from "../../services/securityService"
6
+ import { useNotification } from "../notification"
7
7
8
8
function isValidHttpUrl ( string ) {
9
9
try {
10
- const url = new URL ( string ) ;
11
- return url . protocol === "http:" || url . protocol === "https:" ;
10
+ const url = new URL ( string )
11
+ return url . protocol === "http:" || url . protocol === "https:"
12
12
} catch ( _ ) {
13
- return false ;
13
+ return false
14
14
}
15
15
}
16
16
17
17
export function useLogin ( ) {
18
- const route = useRoute ( ) ;
19
- const router = useRouter ( ) ;
20
- const securityStore = useSecurityStore ( ) ;
21
- const platformConfigurationStore = usePlatformConfig ( ) ;
22
- const { showErrorNotification } = useNotification ( ) ;
18
+ const route = useRoute ( )
19
+ const router = useRouter ( )
20
+ const securityStore = useSecurityStore ( )
21
+ const platformConfigurationStore = usePlatformConfig ( )
22
+ const { showErrorNotification } = useNotification ( )
23
23
24
- const isLoading = ref ( false ) ;
25
- const requires2FA = ref ( false ) ;
24
+ const isLoading = ref ( false )
25
+ const requires2FA = ref ( false )
26
26
27
- async function performLogin ( payload ) {
28
- isLoading . value = true ;
29
- requires2FA . value = false ;
27
+ async function performLogin ( { login , password , _remember_me , totp = null } ) {
28
+ isLoading . value = true
29
+ requires2FA . value = false
30
30
31
31
try {
32
- const responseData = await securityService . login ( payload ) ;
32
+ // Prepare payload as expected by securityService
33
+ const payload = {
34
+ login,
35
+ password,
36
+ _remember_me,
37
+ totp,
38
+ }
39
+
40
+ // Add returnUrl if exists in query param
41
+ const returnUrl = route . query . redirect ?. toString ( ) || null
42
+ if ( returnUrl ) {
43
+ payload . returnUrl = returnUrl
44
+ }
33
45
34
- // Check if the backend demands 2FA and no TOTP was provided yet
46
+ const responseData = await securityService . login ( payload )
47
+
48
+ // Handle 2FA flow
35
49
if ( responseData . requires2FA && ! payload . totp ) {
36
- requires2FA . value = true ;
37
- return { success : false , requires2FA : true } ;
50
+ requires2FA . value = true
51
+ return { success : false , requires2FA : true }
38
52
}
39
53
40
- // Check rotate password flow
54
+ // Handle forced password rotation
41
55
if ( responseData . rotate_password && responseData . redirect ) {
42
- window . location . href = responseData . redirect ;
43
- return { success : true , rotate : true } ;
56
+ window . location . href = responseData . redirect
57
+ return { success : true , rotate : true }
44
58
}
45
59
46
- // Handle explicit backend error message
60
+ // Handle backend explicit error
47
61
if ( responseData . error ) {
48
- showErrorNotification ( responseData . error ) ;
49
- return { success : false , error : responseData . error } ;
62
+ showErrorNotification ( responseData . error )
63
+ return { success : false , error : responseData . error }
50
64
}
51
65
52
- // Special flow for terms acceptance
66
+ // Handle terms and conditions redirect
53
67
if ( responseData . load_terms && responseData . redirect ) {
54
- window . location . href = responseData . redirect ;
55
- return { success : true , redirect : responseData . redirect } ;
68
+ window . location . href = responseData . redirect
69
+ return { success : true , redirect : responseData . redirect }
56
70
}
57
71
58
72
// Handle external redirect param
59
- const redirectParam = route . query . redirect ?. toString ( ) ;
60
- if ( redirectParam ) {
73
+ if ( route . query . redirect ) {
74
+ const redirectParam = route . query . redirect . toString ( )
61
75
if ( isValidHttpUrl ( redirectParam ) ) {
62
- window . location . href = redirectParam ;
76
+ window . location . href = redirectParam
63
77
} else {
64
- await router . replace ( { path : redirectParam } ) ;
78
+ await router . replace ( { path : redirectParam } )
65
79
}
66
- return { success : true } ;
80
+ return { success : true }
67
81
}
68
82
83
+ // Fallback redirect from backend
69
84
if ( responseData . redirect ) {
70
- window . location . href = responseData . redirect ;
71
- return { success : true } ;
85
+ window . location . href = responseData . redirect
86
+ return { success : true }
72
87
}
73
88
74
- securityStore . setUser ( responseData ) ;
75
- await platformConfigurationStore . initialize ( ) ;
89
+ // Save user info
90
+ securityStore . setUser ( responseData )
91
+ await platformConfigurationStore . initialize ( )
76
92
77
- // Handle redirect param again after login
93
+ // Redirect again if redirect param still exists
78
94
if ( route . query . redirect ) {
79
- await router . replace ( { path : route . query . redirect . toString ( ) } ) ;
80
- return { success : true } ;
95
+ await router . replace ( { path : route . query . redirect . toString ( ) } )
96
+ return { success : true }
81
97
}
82
98
83
- // Determine post-login route from settings
84
- const setting = platformConfigurationStore . getSetting ( "registration.redirect_after_login" ) ;
85
- let target = "/" ;
99
+ // Default platform redirect after login
100
+ const setting = platformConfigurationStore . getSetting ( "registration.redirect_after_login" )
101
+ let target = "/"
86
102
87
103
if ( setting && typeof setting === "string" ) {
88
104
try {
89
- const map = JSON . parse ( setting ) ;
90
- const roles = responseData . roles || [ ] ;
105
+ const map = JSON . parse ( setting )
106
+ const roles = responseData . roles || [ ]
91
107
92
108
const getProfile = ( ) => {
93
- if ( roles . includes ( "ROLE_ADMIN" ) ) return "ADMIN" ;
94
- if ( roles . includes ( "ROLE_SESSION_MANAGER" ) ) return "SESSIONADMIN" ;
95
- if ( roles . includes ( "ROLE_TEACHER" ) ) return "COURSEMANAGER" ;
96
- if ( roles . includes ( "ROLE_STUDENT_BOSS" ) ) return "STUDENT_BOSS" ;
97
- if ( roles . includes ( "ROLE_DRH" ) ) return "DRH" ;
98
- if ( roles . includes ( "ROLE_INVITEE" ) ) return "INVITEE" ;
99
- if ( roles . includes ( "ROLE_STUDENT" ) ) return "STUDENT" ;
100
- return null ;
101
- } ;
102
-
103
- const profile = getProfile ( ) ;
104
- const value = profile && map [ profile ] ? map [ profile ] : "" ;
109
+ if ( roles . includes ( "ROLE_ADMIN" ) ) return "ADMIN"
110
+ if ( roles . includes ( "ROLE_SESSION_MANAGER" ) ) return "SESSIONADMIN"
111
+ if ( roles . includes ( "ROLE_TEACHER" ) ) return "COURSEMANAGER"
112
+ if ( roles . includes ( "ROLE_STUDENT_BOSS" ) ) return "STUDENT_BOSS"
113
+ if ( roles . includes ( "ROLE_DRH" ) ) return "DRH"
114
+ if ( roles . includes ( "ROLE_INVITEE" ) ) return "INVITEE"
115
+ if ( roles . includes ( "ROLE_STUDENT" ) ) return "STUDENT"
116
+ return null
117
+ }
118
+
119
+ const profile = getProfile ( )
120
+ const value = profile && map [ profile ] ? map [ profile ] : ""
105
121
106
122
switch ( value ) {
107
123
case "user_portal.php" :
108
124
case "index.php" :
109
- target = "/home" ;
110
- break ;
125
+ target = "/home"
126
+ break
111
127
case "main/auth/courses.php" :
112
- target = "/courses" ;
113
- break ;
128
+ target = "/courses"
129
+ break
114
130
case "" :
115
131
case null :
116
- target = "/" ;
117
- break ;
132
+ target = "/"
133
+ break
118
134
default :
119
- target = `/${ value . replace ( / ^ \/ + / , "" ) } ` ;
135
+ target = `/${ value . replace ( / ^ \/ + / , "" ) } `
120
136
}
121
137
} catch ( e ) {
122
- console . warn ( "[redirect_after_login] Malformed JSON:" , e ) ;
138
+ console . warn ( "[redirect_after_login] Malformed JSON:" , e )
123
139
}
124
140
}
125
141
126
- await router . replace ( { path : target } ) ;
127
- return { success : true } ;
142
+ await router . replace ( { path : target } )
143
+
144
+ return { success : true }
128
145
} catch ( error ) {
129
146
const errorMessage =
130
- error . response ?. data ?. error || "An error occurred during login." ;
131
- showErrorNotification ( errorMessage ) ;
132
- return { success : false , error : errorMessage } ;
147
+ error . response ?. data ?. error || "An error occurred during login."
148
+ showErrorNotification ( errorMessage )
149
+ return { success : false , error : errorMessage }
133
150
} finally {
134
- isLoading . value = false ;
151
+ isLoading . value = false
135
152
}
136
153
}
137
154
138
155
async function redirectNotAuthenticated ( ) {
139
156
if ( ! securityStore . isAuthenticated ) {
140
- return ;
157
+ return
141
158
}
142
159
143
- const redirectParam = route . query . redirect ?. toString ( ) ;
160
+ const redirectParam = route . query . redirect ?. toString ( )
144
161
if ( redirectParam ) {
145
- await router . push ( { path : redirectParam } ) ;
162
+ await router . push ( { path : redirectParam } )
146
163
} else {
147
- await router . replace ( { name : "Home" } ) ;
164
+ await router . replace ( { name : "Home" } )
148
165
}
149
166
}
150
167
@@ -153,5 +170,5 @@ export function useLogin() {
153
170
requires2FA,
154
171
performLogin,
155
172
redirectNotAuthenticated,
156
- } ;
173
+ }
157
174
}
0 commit comments