From e61b684759bf8cd42e7b65f037a64d94afed04d5 Mon Sep 17 00:00:00 2001 From: Gowtham M Date: Wed, 20 Aug 2025 11:59:35 +0530 Subject: [PATCH] Custom api key security and added env file : GWM --- .env | 3 + go.mod | 1 + go.sum | 2 + main.go | 179 ++++++++++++++++++++++++++++++++++++++++++++++-- pb_data/logs.db | Bin 40960 -> 45056 bytes 5 files changed, 179 insertions(+), 6 deletions(-) create mode 100644 .env diff --git a/.env b/.env new file mode 100644 index 0000000..d789efe --- /dev/null +++ b/.env @@ -0,0 +1,3 @@ +APP_SIGNATURE = super-secret-key + +BASE_URL = https://pb.venbait.in \ No newline at end of file diff --git a/go.mod b/go.mod index f8ea9db..9a2f857 100755 --- a/go.mod +++ b/go.mod @@ -60,6 +60,7 @@ require ( github.com/googleapis/gax-go/v2 v2.14.1 // indirect github.com/hashicorp/golang-lru/v2 v2.0.7 // indirect github.com/inconshreveable/mousetrap v1.1.0 // indirect + github.com/joho/godotenv v1.5.1 // indirect github.com/kballard/go-shellquote v0.0.0-20180428030007-95032a82bc51 // indirect github.com/mattn/go-colorable v0.1.13 // indirect github.com/mattn/go-isatty v0.0.20 // indirect diff --git a/go.sum b/go.sum index 84afc4f..57ab244 100755 --- a/go.sum +++ b/go.sum @@ -161,6 +161,8 @@ github.com/inconshreveable/mousetrap v1.1.0 h1:wN+x4NVGpMsO7ErUn/mUI3vEoE6Jt13X2 github.com/inconshreveable/mousetrap v1.1.0/go.mod h1:vpF70FUmC8bwa3OWnCshd2FqLfsEA9PFc4w1p2J65bw= github.com/jmespath/go-jmespath v0.4.0 h1:BEgLn5cpjn8UN1mAw4NjwDrS35OdebyEtFe+9YPoQUg= github.com/jmespath/go-jmespath v0.4.0/go.mod h1:T8mJZnbsbmF+m6zOOFylbeCJqk5+pHWvzYPziyZiYoo= +github.com/joho/godotenv v1.5.1 h1:7eLL/+HRGLY0ldzfGMeQkb7vMd0as4CfYvUVzLqw0N0= +github.com/joho/godotenv v1.5.1/go.mod h1:f4LDr5Voq0i2e/R5DDNOoa2zzDfwtkZa6DnEwAbqwq4= github.com/kballard/go-shellquote v0.0.0-20180428030007-95032a82bc51 h1:Z9n2FFNUXsshfwJMBgNA0RU6/i7WVaAegv3PtuIHPMs= github.com/kballard/go-shellquote v0.0.0-20180428030007-95032a82bc51/go.mod h1:CzGEWj7cYgsdH8dAjBGEr58BoE7ScuLd+fwFZ44+/x8= github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE= diff --git a/main.go b/main.go index 6913d1e..82817f3 100755 --- a/main.go +++ b/main.go @@ -20,6 +20,7 @@ import ( firebase "firebase.google.com/go" "firebase.google.com/go/messaging" + "github.com/joho/godotenv" "github.com/labstack/echo/v5" "github.com/pocketbase/dbx" "github.com/pocketbase/pocketbase" @@ -34,7 +35,7 @@ import ( "google.golang.org/api/option" ) -const baseUrl = "https://pb.venbait.in" +var baseUrl = os.Getenv("BASE_URL") type EmailConfigurationResponse struct { Page int `json:"page"` @@ -463,7 +464,14 @@ func generateToken() string { var app *pocketbase.PocketBase func main() { - const baseUrl = "https://pb.venbait.in" + + // load .env file + err := godotenv.Load() + if err != nil { + log.Println("No .env file found") + } + + var baseUrl = os.Getenv("BASE_URL") app = pocketbase.New() @@ -584,6 +592,12 @@ func main() { }) e.Router.GET("/api/auth/request-password-reset", func(c echo.Context) error { + + apiKey := c.Request().Header.Get("APP_SIGNATURE") + if apiKey != os.Getenv("APP_SIGNATURE") { + return c.JSON(http.StatusForbidden, map[string]string{"error": "Invalid API Key"}) + } + email := c.QueryParam("email") if email == "" { return c.JSON(http.StatusBadRequest, map[string]string{"error": "Email is required"}) @@ -710,6 +724,12 @@ func main() { }) e.Router.GET("/api/auth/reset-password", func(c echo.Context) error { + + apiKey := c.Request().Header.Get("APP_SIGNATURE") + if apiKey != os.Getenv("APP_SIGNATURE") { + return c.JSON(http.StatusForbidden, map[string]string{"error": "Invalid API Key"}) + } + token := c.QueryParam("token") if token == "" { return c.JSON(http.StatusBadRequest, map[string]string{"error": "Token is required"}) @@ -738,6 +758,11 @@ func main() { e.Router.GET("/api/login_success", func(c echo.Context) error { + apiKey := c.Request().Header.Get("APP_SIGNATURE") + if apiKey != os.Getenv("APP_SIGNATURE") { + return c.JSON(http.StatusForbidden, map[string]string{"error": "Invalid API Key"}) + } + userID := c.QueryParam("id") if userID == "" { return c.JSON(http.StatusBadRequest, map[string]string{"error": "User ID is required"}) @@ -778,6 +803,11 @@ func main() { e.Router.GET("/api/getNotification", func(c echo.Context) error { + apiKey := c.Request().Header.Get("APP_SIGNATURE") + if apiKey != os.Getenv("APP_SIGNATURE") { + return c.JSON(http.StatusForbidden, map[string]string{"error": "Invalid API Key"}) + } + language := c.QueryParam("language") if language == "" { return c.JSON(http.StatusBadRequest, map[string]string{"error": "language is required"}) @@ -837,6 +867,12 @@ func main() { }) e.Router.GET("/api/removeNotification", func(c echo.Context) error { + + apiKey := c.Request().Header.Get("APP_SIGNATURE") + if apiKey != os.Getenv("APP_SIGNATURE") { + return c.JSON(http.StatusForbidden, map[string]string{"error": "Invalid API Key"}) + } + userID := c.QueryParam("user_id") notificationID := c.QueryParam("notification_id") @@ -890,6 +926,11 @@ func main() { e.Router.GET("/api/pushNotification", func(c echo.Context) error { + apiKey := c.Request().Header.Get("APP_SIGNATURE") + if apiKey != os.Getenv("APP_SIGNATURE") { + return c.JSON(http.StatusForbidden, map[string]string{"error": "Invalid API Key"}) + } + // type Request struct { // DeviceToken string `json:"device_token"` // } @@ -943,6 +984,11 @@ func main() { e.Router.POST("/api/getDataSet", func(c echo.Context) error { + apiKey := c.Request().Header.Get("APP_SIGNATURE") + if apiKey != os.Getenv("APP_SIGNATURE") { + return c.JSON(http.StatusForbidden, map[string]string{"error": "Invalid API Key"}) + } + type RequestData struct { Dataset string `json:"dataset"` KPI string `json:"kpi"` @@ -1268,6 +1314,11 @@ func main() { e.Router.GET("/api/getHomePageData", func(c echo.Context) error { + apiKey := c.Request().Header.Get("APP_SIGNATURE") + if apiKey != os.Getenv("APP_SIGNATURE") { + return c.JSON(http.StatusForbidden, map[string]string{"error": "Invalid API Key"}) + } + language := c.QueryParam("language") colorMode := c.QueryParam("color_mode") @@ -1284,10 +1335,10 @@ func main() { // Execute the query query := fmt.Sprintf(` - SELECT - main_topic_en, - main_topic_ar, - main_topic_list_order, + SELECT + main_topic_en, + main_topic_ar, + main_topic_list_order, %s AS color_pattern FROM home_screen GROUP BY main_topic_en, main_topic_ar, main_topic_list_order, %s @@ -1362,8 +1413,119 @@ func main() { }) + // e.Router.GET("/api/getHomePageData", func(c echo.Context) error { + + // language := c.QueryParam("language") + // colorMode := c.QueryParam("color_mode") + + // var colorPatternColumn string + // if colorMode == "dark" { + // colorPatternColumn = "color_pattern_dark" + // } else { + // colorPatternColumn = "color_pattern_light" + // } + + // var languageSpecificColumn string + // if language == "en" { + // languageSpecificColumn = "data_set_tile_heading_en" + // } else { + // languageSpecificColumn = "data_set_tile_heading_ar" + // } + + // // Define the struct for holding the query results + // mainTopics := []struct { + // MainTopicEn string `db:"main_topic_en" json:"main_topic_en"` + // MainTopicAr string `db:"main_topic_ar" json:"main_topic_ar"` + // MainTopicListOrder string `db:"main_topic_list_order" json:"main_topic_list_order"` + // ColorPattern string `db:"color_pattern" json:"color_pattern"` + // }{} + + // // Execute the query + // query := fmt.Sprintf(` + // SELECT + // main_topic_en, + // main_topic_ar, + // main_topic_list_order, + // %s AS color_pattern + // FROM home_screen + // GROUP BY main_topic_en, main_topic_ar, main_topic_list_order, %s + // ORDER BY main_topic_list_order ASC + // `, colorPatternColumn, colorPatternColumn) + + // err := app.DB().NewQuery(query).All(&mainTopics) + + // // err := app.DB(). + // // Select("main_topic_en", "main_topic_ar", "main_topic_list_order", "color_pattern"). + // // From("home_screen"). + // // GroupBy("main_topic_en", "main_topic_ar", "color_pattern"). + // // OrderBy("main_topic_list_order ASC"). + // // All(&mainTopics) + + // if err != nil { + // log.Printf("Failed to fetch home_screen data: %v", err) + // return c.JSON(http.StatusInternalServerError, map[string]string{"error": "Failed to fetch records"}) + // } + + // // If no records are found + // if len(mainTopics) == 0 { + // return c.JSON(http.StatusNotFound, map[string]string{"error": "No records found for home screen"}) + // } + + // // Final result structure + // result := []map[string]interface{}{} + + // // Loop through main topics and fetch sub-topic data for each + // for _, mainTopic := range mainTopics { + + // dataSets := []struct { + // DataSet string `db:"data_set" json:"data_set"` + // DataSetTileHeading string `db:"data_set_tile_heading" json:"data_set_tile_heading"` + // ValueSource string `db:"value_source" json:"value_source"` + // Value string `db:"value" json:"value"` + // DataSetListOrder string `db:"data_set_list_order" json:"data_set_list_order"` + // }{} + + // query := ` SELECT data_set,` + languageSpecificColumn + ` AS data_set_tile_heading,value_source,value, data_set_list_order FROM home_screen WHERE main_topic_en = {:topic}` + // err := app.DB(). + // NewQuery(query). + // Bind(dbx.Params{ + // "topic": mainTopic.MainTopicEn, + // }). + // All(&dataSets) + + // if err != nil { + // log.Printf("Error fetching data sets: %v", err) + // continue + // } + + // var MainTopic string + // if language == "en" { + // MainTopic = mainTopic.MainTopicEn + // } else { + // MainTopic = mainTopic.MainTopicAr + // } + + // // Add the main topic and its sub-topics to the result + // result = append(result, map[string]interface{}{ + // "main_topic": MainTopic, + // "main_topic_list_order": mainTopic.MainTopicListOrder, + // "color_pattern": mainTopic.ColorPattern, + // "tile_data": dataSets, + // }) + // } + + // // Send the combined result as JSON + // return c.JSON(http.StatusOK, result) + + // }) + e.Router.GET("/api/getUAENumbersData", func(c echo.Context) error { + apiKey := c.Request().Header.Get("APP_SIGNATURE") + if apiKey != os.Getenv("APP_SIGNATURE") { + return c.JSON(http.StatusForbidden, map[string]string{"error": "Invalid API Key"}) + } + language := c.QueryParam("language") colorMode := c.QueryParam("color_mode") @@ -1509,6 +1671,11 @@ func main() { e.Router.GET("/api/getUserBookmark", func(c echo.Context) error { + apiKey := c.Request().Header.Get("APP_SIGNATURE") + if apiKey != os.Getenv("APP_SIGNATURE") { + return c.JSON(http.StatusForbidden, map[string]string{"error": "Invalid API Key"}) + } + language := c.QueryParam("language") user_id := c.QueryParam("user_id") colorMode := c.QueryParam("color_mode") diff --git a/pb_data/logs.db b/pb_data/logs.db index 21dcf3e0560890b9ee8eccbb4a4032dc038cfb45..63d3b5cb6db18911823a2afbf2f2d4cf43e66e54 100644 GIT binary patch literal 45056 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 M`fndRtK8Kff}B%?4p@kMr|*m0c1 zeW+vN6b9``Ia%}21=>Dj59=O`8EmkJ<{=E)!5HjiTL~+B*%*09VT{o{>>Q_LNr?Y| z!36s0oR6gMPdbIRQpK6Zz` zPp#Lh%T!}sC@|<-p&i|}G;|6EIY9_(iYCh%8iZFcg{V)yLrcOK+K@X=;cG3ya3NRK zyd2l{ax^(ECK9vLv*mQLtRZSLkDj_7q5E&GZRK`T27==afo_W!VVb