From eb15df3e58f8b77d0519f486088e01f7c4a40875 Mon Sep 17 00:00:00 2001 From: eoate Date: Sat, 27 Jun 2026 13:33:16 +0900 Subject: [PATCH 01/15] =?UTF-8?q?POST=20/api/me/likes=20=E3=82=92=E5=AE=9F?= =?UTF-8?q?=E8=A3=85?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Qpid/handler/me.go | 26 +++++++++++++++++++++++++- 1 file changed, 25 insertions(+), 1 deletion(-) diff --git a/Qpid/handler/me.go b/Qpid/handler/me.go index b59ee51..a77adc7 100644 --- a/Qpid/handler/me.go +++ b/Qpid/handler/me.go @@ -99,9 +99,33 @@ func (h *handler) listMyLikes(c echo.Context) error { return c.JSON(http.StatusOK, result) } +type userActionRequest struct { + Username string `json:"username"` +} + // POST /api/me/likes func (h *handler) likeUser(c echo.Context) error { - return unauthorized(c) + if !h.loginUserRetriever.IsUserLoggedIn() { + return unauthorized(c) + } + + username, err := h.loginUserRetriever.GetLoginUser() + if err != nil { + return c.JSON(http.StatusInternalServerError, errorResponse{Message: "failed to get login user"}) + } + + toUser := &userActionRequest{} + err = c.Bind(toUser) + if err != nil { + return c.JSON(http.StatusBadRequest, errorResponse{Message: "invalid request body"}) + } + + err = h.repository.Like(username, toUser.Username) + if err != nil { + return c.JSON(http.StatusInternalServerError, errorResponse{Message: "failed to like user"}) + } + + return c.NoContent(http.StatusNoContent) } // GET /api/me/liked-by From 6417e4b0af726cf23a7523fdbee8b48e1bd1ab4c Mon Sep 17 00:00:00 2001 From: eoate Date: Sat, 27 Jun 2026 13:53:55 +0900 Subject: [PATCH 02/15] =?UTF-8?q?toUser=E3=81=AE=E5=AD=98=E5=9C=A8?= =?UTF-8?q?=E7=A2=BA=E8=AA=8D=E3=82=92=E8=BF=BD=E5=8A=A0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Qpid/handler/me.go | 16 +++++++++++++--- 1 file changed, 13 insertions(+), 3 deletions(-) diff --git a/Qpid/handler/me.go b/Qpid/handler/me.go index a77adc7..00c9680 100644 --- a/Qpid/handler/me.go +++ b/Qpid/handler/me.go @@ -115,13 +115,23 @@ func (h *handler) likeUser(c echo.Context) error { } toUser := &userActionRequest{} - err = c.Bind(toUser) - if err != nil { + if err := c.Bind(toUser); err != nil { return c.JSON(http.StatusBadRequest, errorResponse{Message: "invalid request body"}) } - err = h.repository.Like(username, toUser.Username) + if toUser.Username == "" { + return c.JSON(http.StatusBadRequest, errorResponse{Message: "username is required"}) + } + + isExist, err := h.repository.Exists(toUser.Username) if err != nil { + return c.JSON(http.StatusInternalServerError, errorResponse{Message: "failed to check user existence"}) + } + if !isExist { + return c.JSON(http.StatusBadRequest, errorResponse{Message: "user does not exist"}) + } + + if err = h.repository.Like(username, toUser.Username); err != nil { return c.JSON(http.StatusInternalServerError, errorResponse{Message: "failed to like user"}) } From 4b37feb7c02a5273ba8d4b04cdb9c083b1454ff6 Mon Sep 17 00:00:00 2001 From: YuHima03 <67862122+YuHima03@users.noreply.github.com> Date: Sat, 27 Jun 2026 13:55:06 +0900 Subject: [PATCH 03/15] =?UTF-8?q?feat:=20=E8=AA=8D=E8=A8=BC=E3=82=92?= =?UTF-8?q?=E5=85=A5=E3=82=8C=E3=82=8B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Qpid/env/env.go | 33 +++++++++++++++++++ Qpid/handler/auth.go | 15 --------- Qpid/handler/handler.go | 54 +++++++++++++++---------------- Qpid/handler/me.go | 13 +++++--- Qpid/handler/middleware/auth.go | 56 ++++++++++++++++++++++++++++---- openapi.yml | 57 --------------------------------- 6 files changed, 118 insertions(+), 110 deletions(-) create mode 100644 Qpid/env/env.go diff --git a/Qpid/env/env.go b/Qpid/env/env.go new file mode 100644 index 0000000..7f3b9ff --- /dev/null +++ b/Qpid/env/env.go @@ -0,0 +1,33 @@ +package env + +import ( + "cmp" + "os" +) + +type Env struct { + Environment string +} + +const ( + EnvironmentLocal = "local" + EnvironmentProduction = "production" +) + +func (e *Env) IsLocal() bool { + return e.Environment == EnvironmentLocal +} + +func (e *Env) IsProduction() bool { + return e.Environment == EnvironmentProduction +} + +func GetEnv() Env { + environment := cmp.Or(os.Getenv("ENVIRONMENT"), EnvironmentLocal) + if environment != EnvironmentLocal && environment != EnvironmentProduction { + environment = EnvironmentLocal + } + return Env{ + Environment: environment, + } +} diff --git a/Qpid/handler/auth.go b/Qpid/handler/auth.go index 6bb8a60..f9e2031 100644 --- a/Qpid/handler/auth.go +++ b/Qpid/handler/auth.go @@ -2,22 +2,7 @@ package handler import "github.com/labstack/echo/v4" -// GET /api/login -func (h *handler) startLogin(c echo.Context) error { - return notImplemented(c) -} - -// POST /api/login/callback -func (h *handler) loginCallback(c echo.Context) error { - return notImplemented(c) -} - // POST /api/signup func (h *handler) signup(c echo.Context) error { return notImplemented(c) } - -// POST /api/logout -func (h *handler) logout(c echo.Context) error { - return notImplemented(c) -} diff --git a/Qpid/handler/handler.go b/Qpid/handler/handler.go index 35579f5..978d8ac 100644 --- a/Qpid/handler/handler.go +++ b/Qpid/handler/handler.go @@ -6,36 +6,35 @@ import ( "github.com/gorilla/sessions" "github.com/labstack/echo/v4" - "github.com/traP-jp/hackathon26spring_05/Qpid/domain" + "github.com/traP-jp/hackathon26spring_05/Qpid/env" "github.com/traP-jp/hackathon26spring_05/Qpid/handler/middleware" + "github.com/traP-jp/hackathon26spring_05/Qpid/infrastructure" "github.com/traP-jp/hackathon26spring_05/Qpid/repository" "github.com/traP-jp/hackathon26spring_05/Qpid/repository/mock" ) type handler struct { + env env.Env repository repository.Repository sessions sessions.Store - // middlewares - loginUserRetriever domain.LoginUserRetriever } func Serve() { e := echo.New() - // _, err := infrastructure.NewDB() - // if err != nil { - // e.Logger.Fatal(err) - // return - // } - + _, err := infrastructure.NewDB() + if err != nil { + e.Logger.Fatal(err) + return + } repo := mock.NewMockRepository() h := &handler{ + env: env.GetEnv(), repository: repo, sessions: sessions.NewCookieStore([]byte( cmp.Or(os.Getenv("SESSION_SECRET"), "secret"), )), - loginUserRetriever: middleware.GetLoginUserRetriever(), } h.mapRoutes(e) @@ -45,26 +44,25 @@ func Serve() { func (h *handler) mapRoutes(e *echo.Echo) { api := e.Group("/api") { - login := api.Group("/login") - { - login.GET("", h.startLogin) - login.POST("/callback", h.loginCallback) - } api.POST("/signup", h.signup) - api.POST("/logout", h.logout) - me := api.Group("/me") - { - me.GET("", h.getMe) - me.PUT("", h.updateMe) - me.GET("/likes", h.listMyLikes) - me.POST("/likes", h.likeUser) - me.GET("/liked-by", h.listUsersWhoLikedMe) - me.POST("/nopes", h.nopeUser) - } - users := api.Group("/users") + + // 認証が必要な API 群 + authenticated := api.Group("", middleware.AuthenticationMiddleware(&h.env, h.repository)) { - users.GET("/:id", h.getUser) + me := authenticated.Group("/me") + { + me.GET("", h.getMe) + me.PUT("", h.updateMe) + me.GET("/likes", h.listMyLikes) + me.POST("/likes", h.likeUser) + me.GET("/liked-by", h.listUsersWhoLikedMe) + me.POST("/nopes", h.nopeUser) + } + users := authenticated.Group("/users") + { + users.GET("/:id", h.getUser) + } + authenticated.GET("/suggestions", h.listSuggestions) } - api.GET("/suggestions", h.listSuggestions) } } diff --git a/Qpid/handler/me.go b/Qpid/handler/me.go index b59ee51..c132624 100644 --- a/Qpid/handler/me.go +++ b/Qpid/handler/me.go @@ -5,6 +5,7 @@ import ( "github.com/labstack/echo/v4" "github.com/traP-jp/hackathon26spring_05/Qpid/domain" + "github.com/traP-jp/hackathon26spring_05/Qpid/handler/middleware" ) type tag struct { @@ -25,11 +26,13 @@ type meResponse struct { // GET /api/me func (h *handler) getMe(c echo.Context) error { - if !h.loginUserRetriever.IsUserLoggedIn() { + loginUserRetriever := middleware.GetLoginUserRetriever(c) + + if !loginUserRetriever.IsUserLoggedIn() { return unauthorized(c) } - username, err := h.loginUserRetriever.GetLoginUser() + username, err := loginUserRetriever.GetLoginUser() if err != nil { return c.JSON(http.StatusInternalServerError, errorResponse{Message: "failed to get login user"}) } @@ -77,11 +80,13 @@ type userSummaryResponse struct { // GET /api/me/likes func (h *handler) listMyLikes(c echo.Context) error { - if !h.loginUserRetriever.IsUserLoggedIn() { + loginUserRetriever := middleware.GetLoginUserRetriever(c) + + if !loginUserRetriever.IsUserLoggedIn() { return unauthorized(c) } - username, err := h.loginUserRetriever.GetLoginUser() + username, err := loginUserRetriever.GetLoginUser() if err != nil { return c.JSON(http.StatusInternalServerError, errorResponse{Message: "failed to get login user"}) } diff --git a/Qpid/handler/middleware/auth.go b/Qpid/handler/middleware/auth.go index 514256a..e9c978b 100644 --- a/Qpid/handler/middleware/auth.go +++ b/Qpid/handler/middleware/auth.go @@ -1,17 +1,61 @@ package middleware -import "github.com/traP-jp/hackathon26spring_05/Qpid/domain" +import ( + "github.com/labstack/echo/v4" + "github.com/traP-jp/hackathon26spring_05/Qpid/domain" + "github.com/traP-jp/hackathon26spring_05/Qpid/env" + "github.com/traP-jp/hackathon26spring_05/Qpid/repository" +) -type loginUserRetrieverImpl struct{} +func AuthenticationMiddleware(env *env.Env, repo repository.Repository) echo.MiddlewareFunc { + if env == nil { + panic("env is nil") + } + if repo == nil { + panic("repo is nil") + } + return func(next echo.HandlerFunc) echo.HandlerFunc { + return func(c echo.Context) error { + if env.IsProduction() { + username := c.Request().Header.Get("X-Forwarded-User") + if username == "" { + return echo.ErrUnauthorized + } + + exists, err := repo.Exists(username) + if err != nil { + return echo.ErrInternalServerError + } + if !exists { + return echo.ErrUnauthorized + } + + setLoginUserRetriever(c, &loginUserRetrieverImpl{username: username}) + return next(c) + } + // ローカル環境では常にログイン済みユーザーとして扱う + setLoginUserRetriever(c, &loginUserRetrieverImpl{username: "test-user"}) + return nil + } + } +} + +type loginUserRetrieverImpl struct { + username string +} func (r *loginUserRetrieverImpl) IsUserLoggedIn() bool { - return true + return r.username != "" } func (r *loginUserRetrieverImpl) GetLoginUser() (string, error) { - return "test-user", nil + return r.username, nil +} + +func setLoginUserRetriever(ctx echo.Context, retriever domain.LoginUserRetriever) { + ctx.Set("loginUserRetriever", retriever) } -func GetLoginUserRetriever() domain.LoginUserRetriever { - return &loginUserRetrieverImpl{} +func GetLoginUserRetriever(ctx echo.Context) domain.LoginUserRetriever { + return ctx.Get("loginUserRetriever").(domain.LoginUserRetriever) } diff --git a/openapi.yml b/openapi.yml index bec9b5a..931bd55 100644 --- a/openapi.yml +++ b/openapi.yml @@ -16,40 +16,6 @@ tags: - name: suggestions description: Recommended users paths: - /login: - get: - security: [] - tags: - - auth - summary: ログイン開始 - operationId: startLogin - responses: - '302': - description: OAuth2 providerへリダイレクトする - headers: - Location: - description: OAuth2 authorization URL - schema: - type: string - format: uri - /login/callback: - post: - security: [] - tags: - - auth - summary: OAuth2 コールバック - operationId: loginCallback - requestBody: - required: true - content: - application/json: - schema: - $ref: '#/components/schemas/OAuth2CallbackRequest' - responses: - '204': - description: ログイン成功 - '400': - $ref: '#/components/responses/BadRequest' /signup: post: security: [] @@ -72,16 +38,6 @@ paths: $ref: '#/components/schemas/User' '400': $ref: '#/components/responses/BadRequest' - /logout: - post: - security: [] - tags: - - auth - summary: ログアウト - operationId: logout - responses: - '204': - description: ログアウト成功 /me: get: tags: @@ -240,19 +196,6 @@ components: name: session description: 認証用セッションCookie schemas: - OAuth2CallbackRequest: - type: object - required: - - code - - state - properties: - code: - type: string - description: OAuth2 authorization code - state: - type: string - description: CSRF対策用state - additionalProperties: false SignupRequest: type: object required: From 7eb4586f7d14dcb7b2b4d502f01558427e747ab0 Mon Sep 17 00:00:00 2001 From: eoate Date: Sat, 27 Jun 2026 13:58:29 +0900 Subject: [PATCH 04/15] =?UTF-8?q?=E8=87=AA=E8=BA=AB=E3=81=B8=E3=81=AELike?= =?UTF-8?q?=E3=82=92=E9=98=B2=E6=AD=A2?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Qpid/handler/me.go | 3 +++ 1 file changed, 3 insertions(+) diff --git a/Qpid/handler/me.go b/Qpid/handler/me.go index 00c9680..6229057 100644 --- a/Qpid/handler/me.go +++ b/Qpid/handler/me.go @@ -122,6 +122,9 @@ func (h *handler) likeUser(c echo.Context) error { if toUser.Username == "" { return c.JSON(http.StatusBadRequest, errorResponse{Message: "username is required"}) } + if toUser.Username == username { + return c.JSON(http.StatusBadRequest, errorResponse{Message: "cannot like yourself"}) + } isExist, err := h.repository.Exists(toUser.Username) if err != nil { From e026db7a3227b1f54bdcf5d1fa16c5e52b4896e4 Mon Sep 17 00:00:00 2001 From: genMira <{weilianzhuantongyin@gmail.com}> Date: Sat, 27 Jun 2026 14:07:17 +0900 Subject: [PATCH 05/15] =?UTF-8?q?cokerfile=E8=BF=BD=E5=8A=A0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Qpid-UI/Dockerfile | 9 +++++++++ 1 file changed, 9 insertions(+) create mode 100644 Qpid-UI/Dockerfile diff --git a/Qpid-UI/Dockerfile b/Qpid-UI/Dockerfile new file mode 100644 index 0000000..6914145 --- /dev/null +++ b/Qpid-UI/Dockerfile @@ -0,0 +1,9 @@ +FROM node:20-alpine AS builder +WORKDIR /app +COPY . . +RUN cd Qpid-UI && npm ci && npm run build + +FROM nginx:alpine +COPY --from=builder /app/Qpid-UI/dist /usr/share/nginx/html +EXPOSE 80 +CMD ["nginx", "-g", "daemon off;"] \ No newline at end of file From 46494492e4d48fa4b87a19e7e0a7035bdec7b73b Mon Sep 17 00:00:00 2001 From: genMira <{weilianzhuantongyin@gmail.com}> Date: Sat, 27 Jun 2026 14:11:07 +0900 Subject: [PATCH 06/15] =?UTF-8?q?=E8=BF=BD=E5=8A=A0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Qpid-UI/Dockerfile | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/Qpid-UI/Dockerfile b/Qpid-UI/Dockerfile index 6914145..16d7a28 100644 --- a/Qpid-UI/Dockerfile +++ b/Qpid-UI/Dockerfile @@ -1,9 +1,10 @@ FROM node:20-alpine AS builder WORKDIR /app COPY . . -RUN cd Qpid-UI && npm ci && npm run build + +RUN npm ci && npm run build FROM nginx:alpine -COPY --from=builder /app/Qpid-UI/dist /usr/share/nginx/html +COPY --from=builder /app/dist /usr/share/nginx/html EXPOSE 80 CMD ["nginx", "-g", "daemon off;"] \ No newline at end of file From 25cf0c416c450776c0dbe7718f9ae53287c9deca Mon Sep 17 00:00:00 2001 From: genMira <{weilianzhuantongyin@gmail.com}> Date: Sat, 27 Jun 2026 14:17:08 +0900 Subject: [PATCH 07/15] =?UTF-8?q?=E3=82=B3=E3=83=94=E3=83=BC=E5=85=88?= =?UTF-8?q?=E5=A4=89=E6=9B=B4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Qpid-UI/Dockerfile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Qpid-UI/Dockerfile b/Qpid-UI/Dockerfile index 16d7a28..5a67d87 100644 --- a/Qpid-UI/Dockerfile +++ b/Qpid-UI/Dockerfile @@ -5,6 +5,6 @@ COPY . . RUN npm ci && npm run build FROM nginx:alpine -COPY --from=builder /app/dist /usr/share/nginx/html +COPY --from=builder /app/Qpid-UI/dist /usr/share/nginx/html EXPOSE 80 CMD ["nginx", "-g", "daemon off;"] \ No newline at end of file From c11ef232912513794f94d1c02e88869b5cafda77 Mon Sep 17 00:00:00 2001 From: YuHima03 <67862122+YuHima03@users.noreply.github.com> Date: Sat, 27 Jun 2026 14:19:48 +0900 Subject: [PATCH 08/15] feat: logger, recover middleware --- Qpid/go.mod | 1 + Qpid/go.sum | 2 ++ Qpid/handler/handler.go | 5 ++++- Qpid/handler/me.go | 4 ++-- Qpid/handler/middleware/auth.go | 2 +- 5 files changed, 10 insertions(+), 4 deletions(-) diff --git a/Qpid/go.mod b/Qpid/go.mod index d65c2f6..b35b829 100644 --- a/Qpid/go.mod +++ b/Qpid/go.mod @@ -23,4 +23,5 @@ require ( golang.org/x/net v0.56.0 // indirect golang.org/x/sys v0.46.0 // indirect golang.org/x/text v0.38.0 // indirect + golang.org/x/time v0.15.0 // indirect ) diff --git a/Qpid/go.sum b/Qpid/go.sum index eee8ab5..9665220 100644 --- a/Qpid/go.sum +++ b/Qpid/go.sum @@ -44,5 +44,7 @@ golang.org/x/sys v0.46.0 h1:noSf2Fq6F8DBgS+LysIkx7rIExoNHJsxOAtPp4rthXw= golang.org/x/sys v0.46.0/go.mod h1:4GL1E5IUh+htKOUEOaiffhrAeqysfVGipDYzABqnCmw= golang.org/x/text v0.38.0 h1:sXmwo9DwP3OK9EZ7PqAdaooSGozfl/3a6/xJcbzPRhE= golang.org/x/text v0.38.0/go.mod h1:YXZt3QhHUKYT53r2lLKFIVi6Ao1jdzrTR/KQ09qyxF4= +golang.org/x/time v0.15.0 h1:bbrp8t3bGUeFOx08pvsMYRTCVSMk89u4tKbNOZbp88U= +golang.org/x/time v0.15.0/go.mod h1:Y4YMaQmXwGQZoFaVFk4YpCt4FLQMYKZe9oeV/f4MSno= gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= diff --git a/Qpid/handler/handler.go b/Qpid/handler/handler.go index 978d8ac..2479b2e 100644 --- a/Qpid/handler/handler.go +++ b/Qpid/handler/handler.go @@ -6,6 +6,7 @@ import ( "github.com/gorilla/sessions" "github.com/labstack/echo/v4" + echoMiddleware "github.com/labstack/echo/v4/middleware" "github.com/traP-jp/hackathon26spring_05/Qpid/env" "github.com/traP-jp/hackathon26spring_05/Qpid/handler/middleware" "github.com/traP-jp/hackathon26spring_05/Qpid/infrastructure" @@ -42,7 +43,9 @@ func Serve() { } func (h *handler) mapRoutes(e *echo.Echo) { - api := e.Group("/api") + api := e.Group("/api", + echoMiddleware.RequestLogger(), + echoMiddleware.Recover()) { api.POST("/signup", h.signup) diff --git a/Qpid/handler/me.go b/Qpid/handler/me.go index c132624..cec18a2 100644 --- a/Qpid/handler/me.go +++ b/Qpid/handler/me.go @@ -48,7 +48,7 @@ func (h *handler) getMe(c echo.Context) error { return c.JSON(http.StatusOK, toMeResponse(*user)) } -func toMeResponse(user domain.User) meResponse { //FindByUsernameで取得したデータをuserをjsonにして返す用 +func toMeResponse(user domain.User) *meResponse { //FindByUsernameで取得したデータをuserをjsonにして返す用 tags := make(map[string]tag, len(user.Tags)) for name, userTag := range user.Tags { tags[name] = tag{ @@ -58,7 +58,7 @@ func toMeResponse(user domain.User) meResponse { //FindByUsernameで取得した } } - return meResponse{ + return &meResponse{ Username: user.Username, IconFileID: user.IconFileID, Major: user.Major, diff --git a/Qpid/handler/middleware/auth.go b/Qpid/handler/middleware/auth.go index e9c978b..d343550 100644 --- a/Qpid/handler/middleware/auth.go +++ b/Qpid/handler/middleware/auth.go @@ -35,7 +35,7 @@ func AuthenticationMiddleware(env *env.Env, repo repository.Repository) echo.Mid } // ローカル環境では常にログイン済みユーザーとして扱う setLoginUserRetriever(c, &loginUserRetrieverImpl{username: "test-user"}) - return nil + return next(c) } } } From 51a76f80720a18084a0103c8f5c32fe0f79b237c Mon Sep 17 00:00:00 2001 From: Arina Date: Sat, 27 Jun 2026 14:19:49 +0900 Subject: [PATCH 09/15] =?UTF-8?q?lives=E3=81=AEid=E3=81=A8name=E3=82=92?= =?UTF-8?q?=E6=96=B0=E3=81=97=E3=81=84=E3=82=82=E3=81=AE=E3=81=AB=E5=A4=89?= =?UTF-8?q?=E6=9B=B4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Qpid-UI/src/components/Likes.vue | 48 ++++++++++++++++---------------- 1 file changed, 24 insertions(+), 24 deletions(-) diff --git a/Qpid-UI/src/components/Likes.vue b/Qpid-UI/src/components/Likes.vue index 0db9d06..4447ad5 100644 --- a/Qpid-UI/src/components/Likes.vue +++ b/Qpid-UI/src/components/Likes.vue @@ -6,60 +6,60 @@ import { ref, computed } from 'vue' // タブの切り替え状態を管理 ('liked' = Likeした人, 'likedBy' = Likeされた人) const activeTab = ref<'liked' | 'likedBy'>('liked') -// Likeした人一覧のダミーデータ +// Likeした人一覧のダミーデータ(バックエンドのスペルに合わせました!) const dummyLikedUsers = [ { - id: 1, - name: 'n3', + username: 'n3', + displayName: 'エヌさん', bio: '明日晴れますよ(断定)\nうにお願いします。(注文)' }, { - id: 2, - name: 'Jiro', + username: 'Jiro', + displayName: 'Jiro', bio: 'バックエンドエンジニアです。\nGo言語が好きです。' }, { - id: 3, - name: 'Saburo', + username: 'Saburo', + displayName: 'Saburo', bio: 'デザイナー兼フロントエンド。\nUI/UXにこだわりがあります!' }, { - id: 4, - name: 'Shiro', + username: 'Shiro', + displayName: 'Shiro', bio: 'AIに興味があります。\nよろしくお願いします。' }, { - id: 5, - name: 'Goro', + username: 'Goro', + displayName: 'Goro', bio: 'これは自己紹介文のサンプルです、パイソンはいいぞよりも長くこのままだとタブ一覧からはみ出すかもしれないので、先ほどのCSSでしっかり「...」になるかテストするための長い文章です。' }, { - id: 6, - name: 'Rokuro', + username: 'Rokuro', + displayName: 'Rokuro', bio: 'プログラミング初心者です!\n楽しく開発したいです。' } ] -// Likeされた人一覧のダミーデータ(こちらも4人に設定) +// Likeされた人一覧のダミーデータ(こちらもバックエンドのスペルに合わせました!) const dummyLikedByUsers = [ { - id: 101, - name: 'Hanako', + username: 'Hanako', + displayName: 'Hanako', bio: 'React派ですがVueも触ってみてます!\n仲良くしてください。' }, { - id: 102, - name: 'Keiko', + username: 'Keiko', + displayName: 'Keiko', bio: '趣味はカフェ巡りです。\n休日はもくもく会によく行きます。' }, { - id: 103, - name: 'Mari', + username: 'Mari', + displayName: 'Mari', bio: 'TypeScript最高!\n型がないと不安になります。' }, { - id: 104, - name: 'Yumi', + username: 'Yumi', + displayName: 'Yumi', bio: 'インフラエンジニア。\nAWSメインで触ってます。' } ] @@ -90,9 +90,9 @@ const displayUsers = computed(() => {
-
+
-

{{ user.name }}

+

{{ user.displayName }}

{{ user.bio }}

From b64fc04e8120f5edddcba43247a51939ea3b4875 Mon Sep 17 00:00:00 2001 From: genMira <{weilianzhuantongyin@gmail.com}> Date: Sat, 27 Jun 2026 14:24:53 +0900 Subject: [PATCH 10/15] =?UTF-8?q?=E5=A4=89=E6=9B=B4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Qpid-UI/Dockerfile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Qpid-UI/Dockerfile b/Qpid-UI/Dockerfile index 5a67d87..16d7a28 100644 --- a/Qpid-UI/Dockerfile +++ b/Qpid-UI/Dockerfile @@ -5,6 +5,6 @@ COPY . . RUN npm ci && npm run build FROM nginx:alpine -COPY --from=builder /app/Qpid-UI/dist /usr/share/nginx/html +COPY --from=builder /app/dist /usr/share/nginx/html EXPOSE 80 CMD ["nginx", "-g", "daemon off;"] \ No newline at end of file From eacae5699aea39988057623cab93d5a6189ba0b2 Mon Sep 17 00:00:00 2001 From: Yusuke Toyoda <67862122+YuHima03@users.noreply.github.com> Date: Sat, 27 Jun 2026 14:26:39 +0900 Subject: [PATCH 11/15] Potential fix for pull request finding Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com> --- Qpid/handler/middleware/auth.go | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/Qpid/handler/middleware/auth.go b/Qpid/handler/middleware/auth.go index d343550..9b3e3ad 100644 --- a/Qpid/handler/middleware/auth.go +++ b/Qpid/handler/middleware/auth.go @@ -57,5 +57,10 @@ func setLoginUserRetriever(ctx echo.Context, retriever domain.LoginUserRetriever } func GetLoginUserRetriever(ctx echo.Context) domain.LoginUserRetriever { - return ctx.Get("loginUserRetriever").(domain.LoginUserRetriever) + v := ctx.Get("loginUserRetriever") + if retriever, ok := v.(domain.LoginUserRetriever); ok && retriever != nil { + return retriever + } + // Middleware 未適用などの場合は未ログイン扱いにする + return &loginUserRetrieverImpl{} } From 5372fb7373ab59ae5ed26f9ad2c2491b9acecd16 Mon Sep 17 00:00:00 2001 From: YuHima03 <67862122+YuHima03@users.noreply.github.com> Date: Sat, 27 Jun 2026 14:30:36 +0900 Subject: [PATCH 12/15] Update OpenAPI auth header Co-authored-by: Codex --- openapi.yml | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/openapi.yml b/openapi.yml index 931bd55..1d4bbde 100644 --- a/openapi.yml +++ b/openapi.yml @@ -5,7 +5,7 @@ info: servers: - url: http://localhost:8080/api security: - - cookieAuth: [] + - forwardedUserAuth: [] tags: - name: auth description: Authentication and account lifecycle @@ -190,11 +190,11 @@ paths: $ref: '#/components/responses/Unauthorized' components: securitySchemes: - cookieAuth: + forwardedUserAuth: type: apiKey - in: cookie - name: session - description: 認証用セッションCookie + in: header + name: X-Forwarded-User + description: 認証済みユーザー名を表すリバースプロキシ由来のヘッダー schemas: SignupRequest: type: object From 2cf3d4bf830237ad5c0092f06f0a515fca513ae1 Mon Sep 17 00:00:00 2001 From: Arina Date: Sat, 27 Jun 2026 15:03:04 +0900 Subject: [PATCH 13/15] =?UTF-8?q?lives.vue=E3=81=8Capenapi=20.yml=E3=81=8B?= =?UTF-8?q?=E3=82=89=E3=83=87=E3=83=BC=E3=82=BF=E3=82=92=E5=85=A5=E6=89=8B?= =?UTF-8?q?=E5=87=BA=E6=9D=A5=E3=82=8B=E3=82=88=E3=81=86=E3=81=AB=E5=A4=89?= =?UTF-8?q?=E6=9B=B4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Qpid-UI/src/components/Likes.vue | 132 +++++++++++++------------------ 1 file changed, 55 insertions(+), 77 deletions(-) diff --git a/Qpid-UI/src/components/Likes.vue b/Qpid-UI/src/components/Likes.vue index 4447ad5..d4281dd 100644 --- a/Qpid-UI/src/components/Likes.vue +++ b/Qpid-UI/src/components/Likes.vue @@ -1,72 +1,40 @@ @@ -89,11 +57,15 @@ const displayUsers = computed(() => {
-
+
+ まだユーザーがいません。 +
+ +
-

{{ user.displayName }}

-

{{ user.bio }}

+

{{ user.displayName || user.username }}

+

{{ user.bio || '自己紹介文はまだありません。' }}

@@ -102,12 +74,20 @@ const displayUsers = computed(() => {