This commit is contained in:
Maxime Duchene-Savard 2025-04-14 09:48:25 -04:00
parent 5aa5520e4c
commit b57cb700ec
9 changed files with 84 additions and 23 deletions

View File

@ -8,7 +8,8 @@ import (
func InitAuthEndpoints(r *gin.RouterGroup) {
group := r.Group("/auth")
group.POST("/login", authLogin)
group.POST("/signin", authSignin)
group.POST("/signout", authSignout)
group.GET("/me", getMe)
}
@ -17,7 +18,7 @@ type loginRequest struct {
Password string `json:"password"`
}
func authLogin(c *gin.Context) {
func authSignin(c *gin.Context) {
var loginRequest loginRequest
err := c.BindJSON(&loginRequest)
if err != nil {
@ -48,6 +49,11 @@ func authLogin(c *gin.Context) {
c.JSON(200, gin.H{"valid": true})
}
func authSignout(c *gin.Context) {
c.SetCookie("CLORTHO_AUTH", "", -1, "/", "", true, true)
c.JSON(200, gin.H{})
}
func getMe(c *gin.Context) {
session, hasSession := c.Get("session")
if !hasSession {

View File

@ -31,7 +31,7 @@ func TestMain(m *testing.M) {
os.Exit(exitCode)
}
func TestInitAuthEndpoints_authLogin(t *testing.T) {
func TestInitAuthEndpoints_authSignin(t *testing.T) {
adminPass, err := users.InitAdminUser()
if err != nil {
t.Fatal(err)
@ -43,11 +43,34 @@ func TestInitAuthEndpoints_authLogin(t *testing.T) {
reqBody := loginRequest{Username: "admin", Password: *adminPass}
strReqBody, _ := json.Marshal(reqBody)
w := httptest.NewRecorder()
req, _ := http.NewRequest("POST", "/gui/auth/login", strings.NewReader(string(strReqBody)))
req, _ := http.NewRequest("POST", "/gui/auth/signin", strings.NewReader(string(strReqBody)))
r.ServeHTTP(w, req)
assert.Equal(t, 200, w.Code)
assert.JSONEq(t, `{"valid": true}`, w.Body.String())
setCookie := w.Header().Get("Set-Cookie")
assert.True(t, strings.Contains(setCookie, "CLORTHO_AUTH="))
}
func TestInitAuthEndpoints_authSignout(t *testing.T) {
adminPass, err := users.InitAdminUser()
if err != nil {
t.Fatal(err)
}
r := gin.Default()
SetupRouter(r, nil)
reqBody := loginRequest{Username: "admin", Password: *adminPass}
strReqBody, _ := json.Marshal(reqBody)
w := httptest.NewRecorder()
req, _ := http.NewRequest("POST", "/gui/auth/signout", strings.NewReader(string(strReqBody)))
r.ServeHTTP(w, req)
assert.Equal(t, 200, w.Code)
assert.JSONEq(t, `{}`, w.Body.String())
setCookie := w.Header().Get("Set-Cookie")
assert.True(t, strings.Contains(setCookie, "CLORTHO_AUTH="))
}
func TestInitAuthEndpoints_getMe(t *testing.T) {

View File

@ -12,12 +12,14 @@
<v-menu>
<template #activator="{ props }">
<v-avatar
class="hidden-sm-and-down mr-3"
class="mr-3"
color="grey-darken-1"
size="32"
v-bind="props"
/>
</template>
<div>
{{ appStore.user.displayName }}
<v-list>
<v-list-item
v-for="(item, index) in items"
@ -28,6 +30,7 @@
<v-list-item-title>{{ item.title }}</v-list-item-title>
</v-list-item>
</v-list>
</div>
</v-menu>
</v-app-bar>
@ -51,9 +54,9 @@ watch(() => appStore.user, initMenu)
function initMenu() {
if (appStore.user) {
items.value = [{title: "Log out", link: "/logout"}]
items.value = [{title: "Log out", link: "/auth/signout"}]
} else {
items.value = [{title: "Sign In", link: "/signin"}]
items.value = [{title: "Sign In", link: "/auth/signin"}]
}
}
</script>

View File

@ -65,7 +65,6 @@
<script lang="ts" setup>
import {ref} from 'vue'
import {useRouter} from 'vue-router'
const router = useRouter()
const valid = ref(false)

View File

@ -0,0 +1,17 @@
<template>
</template>
<script setup lang="ts">
onMounted(async () => {
await fetch('/gui/auth/signout', {
method: 'POST',
})
const router = useRouter();
await router.replace("/")
})
</script>
<style scoped lang="sass">
</style>

View File

@ -1,7 +1,11 @@
<template>
<div style="min-height: 3000px"></div>
<div style="min-height: 3000px" />
</template>
<script lang="ts" setup>
//
/**
* @route
* @meta public true
* @meta title "Home"
*/
</script>

View File

@ -38,13 +38,15 @@ router.beforeEach(async (to, from, next) => {
const appStore = useAppStore();
await appStore.updateUser()
console.log("to", to)
if (to.meta.public) {
next()
return
}
if (!appStore.user) {
next('/signin')
next('/auth/signin')
} else {
next()
}

View File

@ -9,7 +9,13 @@ export const useAppStore = defineStore('app', {
async updateUser() {
const res = await fetch('/gui/auth/me')
if (res.status === 200) {
this.user = await res.json()
const data = await res.json()
if (data.loggedIn) {
this.user = data.user
} else {
this.user = null
}
} else if (res.status === 401) {
this.user = null
}

View File

@ -19,6 +19,7 @@ declare module 'vue-router/auto-routes' {
*/
export interface RouteNamedMap {
'/': RouteRecordInfo<'/', '/', Record<never, never>, Record<never, never>>,
'/signin': RouteRecordInfo<'/signin', '/signin', Record<never, never>, Record<never, never>>,
'/auth/signin': RouteRecordInfo<'/auth/signin', '/auth/signin', Record<never, never>, Record<never, never>>,
'/auth/signout': RouteRecordInfo<'/auth/signout', '/auth/signout', Record<never, never>, Record<never, never>>,
}
}