Skip to content

Commit c5fe4d0

Browse files
authored
Merge pull request #6468 from christianbeeznest/ofaj-22774
Internal: Terms and Conditions improvements and fixes - refs BT#22774
2 parents 97d0a0a + 03b4368 commit c5fe4d0

File tree

17 files changed

+705
-520
lines changed

17 files changed

+705
-520
lines changed

assets/vue/components/Login.vue

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -66,7 +66,7 @@
6666
v-if="allowRegistration"
6767
v-t="'Sign up'"
6868
class="btn btn--primary-outline"
69-
href="/main/auth/inscription.php"
69+
href="/main/auth/registration.php"
7070
tabindex="3"
7171
/>
7272
</div>

assets/vue/components/layout/TopbarNotLoggedIn.vue

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -59,7 +59,7 @@ const menuItems = computed(() => {
5959
if (allowRegistration.value) {
6060
items.splice(2, 0, {
6161
label: t("Registration"),
62-
url: "/main/auth/inscription.php",
62+
url: "/main/auth/registration.php",
6363
})
6464
}
6565

assets/vue/composables/auth/login.js

Lines changed: 97 additions & 80 deletions
Original file line numberDiff line numberDiff line change
@@ -1,150 +1,167 @@
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"
77

88
function isValidHttpUrl(string) {
99
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:"
1212
} catch (_) {
13-
return false;
13+
return false
1414
}
1515
}
1616

1717
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()
2323

24-
const isLoading = ref(false);
25-
const requires2FA = ref(false);
24+
const isLoading = ref(false)
25+
const requires2FA = ref(false)
2626

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
3030

3131
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+
}
3345

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
3549
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 }
3852
}
3953

40-
// Check rotate password flow
54+
// Handle forced password rotation
4155
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 }
4458
}
4559

46-
// Handle explicit backend error message
60+
// Handle backend explicit error
4761
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 }
5064
}
5165

52-
// Special flow for terms acceptance
66+
// Handle terms and conditions redirect
5367
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 }
5670
}
5771

5872
// 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()
6175
if (isValidHttpUrl(redirectParam)) {
62-
window.location.href = redirectParam;
76+
window.location.href = redirectParam
6377
} else {
64-
await router.replace({ path: redirectParam });
78+
await router.replace({ path: redirectParam })
6579
}
66-
return { success: true };
80+
return { success: true }
6781
}
6882

83+
// Fallback redirect from backend
6984
if (responseData.redirect) {
70-
window.location.href = responseData.redirect;
71-
return { success: true };
85+
window.location.href = responseData.redirect
86+
return { success: true }
7287
}
7388

74-
securityStore.setUser(responseData);
75-
await platformConfigurationStore.initialize();
89+
// Save user info
90+
securityStore.setUser(responseData)
91+
await platformConfigurationStore.initialize()
7692

77-
// Handle redirect param again after login
93+
// Redirect again if redirect param still exists
7894
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 }
8197
}
8298

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 = "/"
86102

87103
if (setting && typeof setting === "string") {
88104
try {
89-
const map = JSON.parse(setting);
90-
const roles = responseData.roles || [];
105+
const map = JSON.parse(setting)
106+
const roles = responseData.roles || []
91107

92108
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] : ""
105121

106122
switch (value) {
107123
case "user_portal.php":
108124
case "index.php":
109-
target = "/home";
110-
break;
125+
target = "/home"
126+
break
111127
case "main/auth/courses.php":
112-
target = "/courses";
113-
break;
128+
target = "/courses"
129+
break
114130
case "":
115131
case null:
116-
target = "/";
117-
break;
132+
target = "/"
133+
break
118134
default:
119-
target = `/${value.replace(/^\/+/, "")}`;
135+
target = `/${value.replace(/^\/+/, "")}`
120136
}
121137
} catch (e) {
122-
console.warn("[redirect_after_login] Malformed JSON:", e);
138+
console.warn("[redirect_after_login] Malformed JSON:", e)
123139
}
124140
}
125141

126-
await router.replace({ path: target });
127-
return { success: true };
142+
await router.replace({ path: target })
143+
144+
return { success: true }
128145
} catch (error) {
129146
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 }
133150
} finally {
134-
isLoading.value = false;
151+
isLoading.value = false
135152
}
136153
}
137154

138155
async function redirectNotAuthenticated() {
139156
if (!securityStore.isAuthenticated) {
140-
return;
157+
return
141158
}
142159

143-
const redirectParam = route.query.redirect?.toString();
160+
const redirectParam = route.query.redirect?.toString()
144161
if (redirectParam) {
145-
await router.push({ path: redirectParam });
162+
await router.push({ path: redirectParam })
146163
} else {
147-
await router.replace({ name: "Home" });
164+
await router.replace({ name: "Home" })
148165
}
149166
}
150167

@@ -153,5 +170,5 @@ export function useLogin() {
153170
requires2FA,
154171
performLogin,
155172
redirectNotAuthenticated,
156-
};
173+
}
157174
}

0 commit comments

Comments
 (0)