diff --git a/backend/internal/server/auth.go b/backend/internal/server/auth.go index 40488a78..1dcbfe68 100644 --- a/backend/internal/server/auth.go +++ b/backend/internal/server/auth.go @@ -23,6 +23,7 @@ func (s *Server) setupAuthRoutes() { auth.Use(s.authLimiter.RateLimit()) // special rate limit for auth routes auth.POST("/signup", s.handleSignup, mw.ValidateRequestBody(reflect.TypeOf(SignupRequest{}))) auth.POST("/signin", s.handleSignin, mw.ValidateRequestBody(reflect.TypeOf(SigninRequest{}))) + auth.GET("/ami-verified", s.handleEmailVerifiedStatus) } func (s *Server) handleSignup(c echo.Context) error { @@ -144,6 +145,26 @@ func (s *Server) handleSignin(c echo.Context) error { }) } +/* +handleEmailVerifiedStatus checks for the email_verified column of the given email. +If the email does not exist in the users table, it returns false. The same goes +for any error encountered. +*/ +func (s *Server) handleEmailVerifiedStatus(c echo.Context) error { + email := c.QueryParam("email") + if email == "" { + return echo.NewHTTPError(http.StatusBadRequest, "Missing email in query param.") + } + + user, err := db.New(s.DBPool).GetUserByEmail(c.Request().Context(), email) + if err != nil { + log.Error().Err(err).Msg("Failed to fetch user when checking email verified status.") + return c.JSON(http.StatusOK, EmailVerifiedStatusResponse{Verified: false}) + } + + return c.JSON(http.StatusOK, EmailVerifiedStatusResponse{Verified: user.EmailVerified}) +} + // helper function to convert pgtype.Text to *string func getStringPtr(t pgtype.Text) *string { if !t.Valid { diff --git a/backend/internal/server/auth_test.go b/backend/internal/server/auth_test.go index f7c8917e..ae8e8ce5 100644 --- a/backend/internal/server/auth_test.go +++ b/backend/internal/server/auth_test.go @@ -116,4 +116,26 @@ func TestAuth(t *testing.T) { s.echoInstance.ServeHTTP(rec, req) assert.Equal(t, http.StatusUnauthorized, rec.Code) }) + + // TODO: re-order this test when the verification for the email tests are merged. + // this tets has to run before it to pass + // Then a new test should be added to cover the status when it is 'true' + t.Run("email verified status", func(t *testing.T) { + req := httptest.NewRequest(http.MethodGet, "/api/v1/auth/ami-verified?email=test@example.com", nil) + rec := httptest.NewRecorder() + s.echoInstance.ServeHTTP(rec, req) + assert.Equal(t, http.StatusOK, rec.Code) + + var response EmailVerifiedStatusResponse + err := json.Unmarshal(rec.Body.Bytes(), &response) + assert.Nil(t, err) + assert.False(t, response.Verified) + }) + + t.Run("email verified status - missing email query param", func(t *testing.T) { + req := httptest.NewRequest(http.MethodGet, "/api/v1/auth/ami-verified", nil) + rec := httptest.NewRecorder() + s.echoInstance.ServeHTTP(rec, req) + assert.Equal(t, http.StatusBadRequest, rec.Code) + }) } diff --git a/backend/internal/server/types.go b/backend/internal/server/types.go index 81811c23..5e5b0d56 100644 --- a/backend/internal/server/types.go +++ b/backend/internal/server/types.go @@ -202,6 +202,10 @@ type UpdateMeetingRequest struct { Notes *string `json:"notes"` } +type EmailVerifiedStatusResponse struct { + Verified bool `json:"verified"` +} + type CreateProjectFileRequest struct { FileType string `json:"file_type" validate:"required"` FileURL string `json:"file_url" validate:"required,url,s3_url"`