Implement OIDC login

This commit is contained in:
2025-07-16 21:44:20 +02:00
parent f0c729cba7
commit 33c1e7278b
11 changed files with 385 additions and 37 deletions

View File

@ -1,70 +1,92 @@
<template>
<div class="min-h-screen bg-gray-100 flex items-center justify-center p-4">
<div v-if="error" class="w-screen absolute top-0 left-0 z-50">
<sl-alert variant="danger" open v-if="error">
<sl-icon slot="icon" name="exclamation-octagon"></sl-icon>
<strong>Login failed.</strong><br />
Please check your username and password, and try again.
</sl-alert>
</div>
<div class="max-w-md w-full bg-white rounded-xl shadow-lg p-8">
<h2 class="text-2xl font-bold text-gray-900 mb-6 text-center">Sign In</h2>
<form @submit.prevent="submitLogin" class="space-y-4">
<div>
<label class="block text-sm font-medium text-gray-400 mb-1">Username</label>
<input
v-model="username"
type="text"
class="w-full px-4 py-2 border border-gray-300 rounded-lg focus:ring-2 focus:ring-indigo-500 focus:border-indigo-500 outline-none transition-all"
<sl-input
label="Username"
class="w-full"
placeholder="Username"
autocomplete="username"
required=""
/>
:value="username"
@input="username = $event.target.value"
></sl-input>
</div>
<div>
<label class="block text-sm font-medium text-gray-700 mb-1">Password</label>
<input
v-model="password"
<sl-input
label="Password"
type="password"
class="w-full px-4 py-2 border border-gray-300 rounded-lg focus:ring-2 focus:ring-indigo-500 focus:border-indigo-500 outline-none transition-all"
class="w-full"
:value="password"
@input="password = $event.target.value"
placeholder="••••••••"
autocomplete="current-password"
/>
required=""
></sl-input>
</div>
<button
type="submit"
class="w-full bg-indigo-600 hover:bg-indigo-700 text-white font-medium py-2.5 rounded-lg transition-colors"
>
Login
</button>
<sl-button type="submit" variant="primary" class="w-full"> Login </sl-button>
</form>
<template v-if="oidcProvider">
<div class="w-full items-center text-center my-4 flex">
<div class="w-full h-[0.125rem] box-border bg-gray-200 dark:bg-gray-700"></div>
<div class="px-4 text-lg text-sm font-medium text-gray-500 dark:text-gray-400">Or</div>
<div class="w-full h-[0.125rem] box-border bg-gray-200 dark:bg-gray-700"></div>
</div>
<div class="w-full text-center my-4">
<sl-button outline variant="neutral" :href="oidcLoginUrl">
Sign in with {{ oidcProvider }}
</sl-button>
</div>
</template>
</div>
</div>
</template>
<script setup lang="ts">
import { ref } from 'vue'
import { onMounted, ref } from 'vue'
import { useAuthTokenStore } from '@/store/auth'
import { useRouter } from 'vue-router'
import { useAlertsStore } from '@/store/useAlertsStore'
import '@shoelace-style/shoelace/dist/components/alert/alert.js'
const username = ref('')
const password = ref('')
const error = ref(false)
const auth = useAuthTokenStore()
const router = useRouter()
const alerts = useAlertsStore()
const oidcProvider = ref<string | null>()
async function checkOidcProvider() {
const provider = await auth.getOidcProvider()
console.log(provider)
if (provider) {
console.log('OIDC Provider: ', provider)
oidcProvider.value = provider
}
}
const baseURL = import.meta.env.SSHECRET_FRONTEND_API_BASE_URL
const oidcLoginUrl = baseURL + '/api/v1/oidc/login'
async function submitLogin() {
error.value = false
const success = await auth.login(username.value, password.value)
if (success) {
router.push('/')
} else {
error.value = true
alerts.showAlert(
'Please check your username and password, and try again.',
'error',
'Login Failed',
)
}
}
onMounted(checkOidcProvider)
</script>