Implement Password Grant Flow for Authentication and Enhance User Experience

- Introduced Password Grant Flow for user authentication, allowing direct login with email and password.
- Updated `useAuth` composable to manage login and logout processes, including Single Sign-Out from Cidaas.
- Enhanced user interface with a new `UserMenu` component displaying user information and logout functionality.
- Updated homepage to show personalized greetings for logged-in users and a login prompt for guests.
- Added logout confirmation page with a countdown redirect to the homepage.
- Documented the implementation details and future enhancements for OAuth2 flows in CLAUDE.md and other relevant documentation.
- Added test credentials and guidelines for automated testing in the new TESTING.md file.
This commit is contained in:
Bastian Masanek
2025-11-01 15:23:08 +01:00
parent 83ba708023
commit cc35636d1a
40 changed files with 1843 additions and 31 deletions

View File

@@ -0,0 +1,22 @@
<script setup lang="ts">
import type { HTMLAttributes } from "vue"
import type { AvatarVariants } from "."
import { AvatarRoot } from "reka-ui"
import { cn } from '~/lib/utils'
import { avatarVariant } from "."
const props = withDefaults(defineProps<{
class?: HTMLAttributes["class"]
size?: AvatarVariants["size"]
shape?: AvatarVariants["shape"]
}>(), {
size: "sm",
shape: "circle",
})
</script>
<template>
<AvatarRoot :class="cn(avatarVariant({ size, shape }), props.class)">
<slot />
</AvatarRoot>
</template>

View File

@@ -0,0 +1,12 @@
<script setup lang="ts">
import type { AvatarFallbackProps } from "reka-ui"
import { AvatarFallback } from "reka-ui"
const props = defineProps<AvatarFallbackProps>()
</script>
<template>
<AvatarFallback v-bind="props">
<slot />
</AvatarFallback>
</template>

View File

@@ -0,0 +1,12 @@
<script setup lang="ts">
import type { AvatarImageProps } from "reka-ui"
import { AvatarImage } from "reka-ui"
const props = defineProps<AvatarImageProps>()
</script>
<template>
<AvatarImage v-bind="props" class="h-full w-full object-cover">
<slot />
</AvatarImage>
</template>

View File

@@ -0,0 +1,25 @@
import type { VariantProps } from "class-variance-authority"
import { cva } from "class-variance-authority"
export { default as Avatar } from "./Avatar.vue"
export { default as AvatarFallback } from "./AvatarFallback.vue"
export { default as AvatarImage } from "./AvatarImage.vue"
export const avatarVariant = cva(
"inline-flex items-center justify-center font-normal text-foreground select-none shrink-0 bg-secondary overflow-hidden",
{
variants: {
size: {
sm: "h-10 w-10 text-xs",
base: "h-16 w-16 text-2xl",
lg: "h-32 w-32 text-5xl",
},
shape: {
circle: "rounded-full",
square: "rounded-md",
},
},
},
)
export type AvatarVariants = VariantProps<typeof avatarVariant>