-
-
Notifications
You must be signed in to change notification settings - Fork 251
Feat/barcode refactoring #920
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Changes from all commits
73e26b9
220185f
6199d08
3573e87
d0c6ee0
69c1630
95037e4
f200b96
68f71b2
6f10a6a
3cecdf8
2f2366c
dfc0954
f4cc216
5b257b7
e7b7540
24e3db4
f1381ff
5586c23
c327715
22dd1dd
d79bf08
561ff77
7979230
d7faf34
cea0473
4a7e55b
8037c84
35df00b
c39c8e0
3ab06d0
dd9220a
5c48c81
c5ea4d1
4caa41f
d9487ab
7d8617b
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change | ||||||||||||||||||||||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| @@ -0,0 +1,44 @@ | ||||||||||||||||||||||||||||||||||||||||||||
| package v1 | ||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||
| import ( | ||||||||||||||||||||||||||||||||||||||||||||
| "net/http" | ||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||
| "github.com/hay-kot/httpkit/errchain" | ||||||||||||||||||||||||||||||||||||||||||||
| "github.com/hay-kot/httpkit/server" | ||||||||||||||||||||||||||||||||||||||||||||
| "github.com/sysadminsmedia/homebox/backend/internal/web/adapters" | ||||||||||||||||||||||||||||||||||||||||||||
| ) | ||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||
| // HandleGenerateQRCode godoc | ||||||||||||||||||||||||||||||||||||||||||||
| // | ||||||||||||||||||||||||||||||||||||||||||||
| // @Summary Search EAN from Barcode | ||||||||||||||||||||||||||||||||||||||||||||
| // @Tags Items | ||||||||||||||||||||||||||||||||||||||||||||
| // @Produce json | ||||||||||||||||||||||||||||||||||||||||||||
| // @Param data query string false "barcode to be searched" | ||||||||||||||||||||||||||||||||||||||||||||
| // @Success 200 {object} []repo.BarcodeProduct | ||||||||||||||||||||||||||||||||||||||||||||
| // @Router /v1/products/search-from-barcode [GET] | ||||||||||||||||||||||||||||||||||||||||||||
| // @Security Bearer | ||||||||||||||||||||||||||||||||||||||||||||
| func (ctrl *V1Controller) HandleProductSearchFromBarcode() errchain.HandlerFunc { | ||||||||||||||||||||||||||||||||||||||||||||
| type query struct { | ||||||||||||||||||||||||||||||||||||||||||||
| // 80 characters is the longest non-2D barcode length (GS1-128) | ||||||||||||||||||||||||||||||||||||||||||||
| EAN string `schema:"productEAN" validate:"required,max=80"` | ||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||
| return func(w http.ResponseWriter, r *http.Request) error { | ||||||||||||||||||||||||||||||||||||||||||||
| q, err := adapters.DecodeQuery[query](r) | ||||||||||||||||||||||||||||||||||||||||||||
| if err != nil { | ||||||||||||||||||||||||||||||||||||||||||||
| return err | ||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||
| products, err := ctrl.repo.Barcode.RetrieveProductsFromBarcode(ctrl.config.Barcode, q.EAN) | ||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||
| if err != nil { | ||||||||||||||||||||||||||||||||||||||||||||
| return server.JSON(w, http.StatusInternalServerError, err.Error()) | ||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||
|
Comment on lines
+32
to
+36
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Don’t leak internal errors; log and return generic 500 Return a generic 500 body and log the detailed error instead of sending err.Error() to clients. Apply these diffs: @@
-import (
+import (
"net/http"
"github.com/hay-kot/httpkit/errchain"
"github.com/hay-kot/httpkit/server"
"github.com/sysadminsmedia/homebox/backend/internal/web/adapters"
+ "github.com/rs/zerolog/log"
)
@@
- if err != nil {
- return server.JSON(w, http.StatusInternalServerError, err.Error())
- }
+ if err != nil {
+ log.Error().Err(err).Str("ean", q.EAN).Msg("barcode product search failed")
+ return server.JSON(w, http.StatusInternalServerError, nil)
+ }Security: Avoid exposing upstream provider errors or config hints in responses. Based on learnings. 📝 Committable suggestion
Suggested change
🤖 Prompt for AI Agents |
||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||
| if len(products) != 0 { | ||||||||||||||||||||||||||||||||||||||||||||
| return server.JSON(w, http.StatusOK, products) | ||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||
| return server.JSON(w, http.StatusNoContent, nil) | ||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||
This file was deleted.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Enforce numeric-only barcode server-side
Frontend restriction is good; add backend validation to reject non-digits to prevent unnecessary external calls.
Apply this diff:
type query struct { // 80 characters is the longest non-2D barcode length (GS1-128) EAN string `schema:"productEAN" validate:"required,max=80"` } return func(w http.ResponseWriter, r *http.Request) error { q, err := adapters.DecodeQuery[query](r) if err != nil { return err } + // Backend guard: digits only + for _, ch := range q.EAN { + if ch < '0' || ch > '9' { + return server.JSON(w, http.StatusBadRequest, "invalid barcode") + } + }Security: Input validation should be enforced server-side as well.
Also applies to: 26-31
🤖 Prompt for AI Agents