Merged in feature/VBV-370-dev-live-loginpage (pull request #114)

Feature/VBV-370 Separate local and SSO login page

* Implement local and SSO login pages

* Add translations

* Fix typechecks

* Fix env detection


Approved-by: Christian Cueni
This commit is contained in:
Elia Bieri 2023-05-31 06:55:00 +00:00
parent ded684ecc2
commit 1a0a431768
6 changed files with 50 additions and 6 deletions

View File

@ -1,5 +1,9 @@
{ {
"Benutzername": "Benutzername",
"Klicke auf den Button, um dich über SSO anzumelden oder zu registrieren.": "Klicke auf den Button, um dich über SSO anzumelden oder zu registrieren.",
"Nächste Termine": "Nächste Termine", "Nächste Termine": "Nächste Termine",
"Passwort": "Passwort",
"SSO Login/Registration": "SSO Login/Registration",
"Zur Zeit sind keine Termine vorhanden": "Zur Zeit sind keine Termine vorhanden", "Zur Zeit sind keine Termine vorhanden": "Zur Zeit sind keine Termine vorhanden",
"assignment": { "assignment": {
"acceptConditionsDisclaimer": "Bedingungen akzeptieren und Ergebnisse abgeben", "acceptConditionsDisclaimer": "Bedingungen akzeptieren und Ergebnisse abgeben",

View File

@ -1,4 +1,10 @@
{ {
"Benutzername": "Nom d'utilisateur",
"Klicke auf den Button, um dich über SSO anzumelden oder zu registrieren.": "Clique sur le bouton pour te connecter ou t'inscrire via SSO.",
"Nächste Termine": "Prochains rendez-vous",
"Passwort": "Mot de passe",
"SSO Login/Registration": "Connexion/enregistrement SSO",
"Zur Zeit sind keine Termine vorhanden": "Il n'y a pas de rendez-vous pour le moment",
"circlePage": { "circlePage": {
"circleContentBoxTitle": "C'est ce que tu apprends dans ce Cercle.", "circleContentBoxTitle": "C'est ce que tu apprends dans ce Cercle.",
"contactExpertButton": "Contacter l'expert", "contactExpertButton": "Contacter l'expert",

View File

@ -1,11 +1,16 @@
<script setup lang="ts"> <script setup lang="ts">
import { useUserStore } from "@/stores/user"; import { useUserStore } from "@/stores/user";
import type { LoginMethod } from "@/types";
import * as log from "loglevel"; import * as log from "loglevel";
import { reactive } from "vue"; import { reactive } from "vue";
import { useRoute } from "vue-router"; import { useRoute } from "vue-router";
const route = useRoute(); const route = useRoute();
defineProps<{
loginMethod: LoginMethod;
}>();
log.debug("LoginView.vue created"); log.debug("LoginView.vue created");
log.debug(route.query); log.debug(route.query);
@ -23,6 +28,7 @@ const userStore = useUserStore();
<h1 class="mb-8">Login</h1> <h1 class="mb-8">Login</h1>
<form <form
v-if="loginMethod === 'local'"
class="bg-white p-4 lg:p-8" class="bg-white p-4 lg:p-8"
@submit.prevent=" @submit.prevent="
userStore.handleLogin( userStore.handleLogin(
@ -33,22 +39,24 @@ const userStore = useUserStore();
" "
> >
<div class="mb-4"> <div class="mb-4">
<label class="mb-1 block" for="email">Username</label> <label class="mb-1 block" for="email">{{ $t("Benutzername") }}</label>
<input <input
id="username" id="username"
v-model="state.username" v-model="state.username"
type="text" type="text"
name="username" name="username"
autocomplete="username"
class="mt-1 block w-96 max-w-full border px-3 py-2" class="mt-1 block w-96 max-w-full border px-3 py-2"
/> />
</div> </div>
<div class="mb-4"> <div class="mb-4">
<label class="mb-1 block" for="password">Password</label> <label class="mb-1 block" for="password">{{ $t("Passwort") }}</label>
<input <input
id="password" id="password"
v-model="state.password" v-model="state.password"
type="password" type="password"
name="password" name="password"
autocomplete="current-password"
class="mt-1 block w-96 max-w-full border px-3 py-2" class="mt-1 block w-96 max-w-full border px-3 py-2"
/> />
</div> </div>
@ -62,9 +70,21 @@ const userStore = useUserStore();
/> />
</div> </div>
</form> </form>
<p class="pt-8">
<a :href="`/sso/login/?lang=${userStore.language}`">Login mit SSO</a> <div v-if="loginMethod === 'sso'" class="bg-white p-4 lg:p-8">
</p> <p>
{{
$t(
"Klicke auf den Button, um dich über SSO anzumelden oder zu registrieren."
)
}}
</p>
<p class="btn-primary mt-8">
<a :href="`/sso/login/?lang=${userStore.language}`">
{{ $t("SSO Login/Registration") }}
</a>
</p>
</div>
</div> </div>
</main> </main>
</template> </template>

View File

@ -15,7 +15,9 @@ export const updateLoggedIn: NavigationGuard = async () => {
export const redirectToLoginIfRequired: NavigationGuard = (to) => { export const redirectToLoginIfRequired: NavigationGuard = (to) => {
const userStore = useUserStore(); const userStore = useUserStore();
if (loginRequired(to) && !userStore.loggedIn) { if (loginRequired(to) && !userStore.loggedIn) {
return `/login?next=${to.fullPath}`; const sentryEnv = import.meta.env.VITE_SENTRY_ENV;
const ssoLogin = sentryEnv === "production" || sentryEnv === "staging";
return ssoLogin ? `/login?next=${to.fullPath}` : `/login-local?next=${to.fullPath}`;
} }
}; };

View File

@ -20,6 +20,16 @@ const router = createRouter({
{ {
path: "/login", path: "/login",
component: LoginPage, component: LoginPage,
props: { loginMethod: "sso" },
meta: {
// no login required -> so `public === true`
public: true,
},
},
{
path: "/login-local",
component: LoginPage,
props: { loginMethod: "local" },
meta: { meta: {
// no login required -> so `public === true` // no login required -> so `public === true`
public: true, public: true,

View File

@ -1,6 +1,8 @@
import type { Circle } from "@/services/circle"; import type { Circle } from "@/services/circle";
import type { Component } from "vue"; import type { Component } from "vue";
export type LoginMethod = "local" | "sso";
export type CourseCompletionStatus = "unknown" | "fail" | "success"; export type CourseCompletionStatus = "unknown" | "fail" | "success";
export interface BaseCourseWagtailPage { export interface BaseCourseWagtailPage {