From b57cb700ece7dae7a4c70444fb441d9ff8415b2e Mon Sep 17 00:00:00 2001 From: Maxime Duchene-Savard Date: Mon, 14 Apr 2025 09:48:25 -0400 Subject: [PATCH] travaux --- apis/auth_endpoints.go | 10 ++++++-- apis/auth_endpoints_test.go | 27 ++++++++++++++++++++-- frontend/src/layouts/default.vue | 29 +++++++++++++----------- frontend/src/pages/{ => auth}/signin.vue | 1 - frontend/src/pages/auth/signout.vue | 17 ++++++++++++++ frontend/src/pages/index.vue | 8 +++++-- frontend/src/router/index.ts | 4 +++- frontend/src/stores/app.ts | 8 ++++++- frontend/src/typed-router.d.ts | 3 ++- 9 files changed, 84 insertions(+), 23 deletions(-) rename frontend/src/pages/{ => auth}/signin.vue (98%) create mode 100644 frontend/src/pages/auth/signout.vue diff --git a/apis/auth_endpoints.go b/apis/auth_endpoints.go index 0ffb4c3..ce685c1 100644 --- a/apis/auth_endpoints.go +++ b/apis/auth_endpoints.go @@ -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 { diff --git a/apis/auth_endpoints_test.go b/apis/auth_endpoints_test.go index bcfadee..82af324 100644 --- a/apis/auth_endpoints_test.go +++ b/apis/auth_endpoints_test.go @@ -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) { diff --git a/frontend/src/layouts/default.vue b/frontend/src/layouts/default.vue index 61b7c04..8ecc3eb 100644 --- a/frontend/src/layouts/default.vue +++ b/frontend/src/layouts/default.vue @@ -12,22 +12,25 @@ - - - {{ item.title }} - - +
+ {{ appStore.user.displayName }} + + + {{ item.title }} + + +
@@ -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"}] } } diff --git a/frontend/src/pages/signin.vue b/frontend/src/pages/auth/signin.vue similarity index 98% rename from frontend/src/pages/signin.vue rename to frontend/src/pages/auth/signin.vue index 43e0881..80f7a2e 100644 --- a/frontend/src/pages/signin.vue +++ b/frontend/src/pages/auth/signin.vue @@ -65,7 +65,6 @@ + + diff --git a/frontend/src/pages/index.vue b/frontend/src/pages/index.vue index a352702..ce3e0f5 100644 --- a/frontend/src/pages/index.vue +++ b/frontend/src/pages/index.vue @@ -1,7 +1,11 @@ diff --git a/frontend/src/router/index.ts b/frontend/src/router/index.ts index 244a804..807cc2e 100644 --- a/frontend/src/router/index.ts +++ b/frontend/src/router/index.ts @@ -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() } diff --git a/frontend/src/stores/app.ts b/frontend/src/stores/app.ts index 84b6d23..a2693e7 100644 --- a/frontend/src/stores/app.ts +++ b/frontend/src/stores/app.ts @@ -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 } diff --git a/frontend/src/typed-router.d.ts b/frontend/src/typed-router.d.ts index 16e50ee..dfb6a26 100644 --- a/frontend/src/typed-router.d.ts +++ b/frontend/src/typed-router.d.ts @@ -19,6 +19,7 @@ declare module 'vue-router/auto-routes' { */ export interface RouteNamedMap { '/': RouteRecordInfo<'/', '/', Record, Record>, - '/signin': RouteRecordInfo<'/signin', '/signin', Record, Record>, + '/auth/signin': RouteRecordInfo<'/auth/signin', '/auth/signin', Record, Record>, + '/auth/signout': RouteRecordInfo<'/auth/signout', '/auth/signout', Record, Record>, } }