Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
37 commits
Select commit Hold shift + click to select a range
73e26b9
linting
crumbowl Jul 23, 2025
220185f
doc: update for ProductBarcode
crumbowl Jul 20, 2025
6199d08
Barcode: improve consistency by moving logic into a BarcodeRepository…
crumbowl Sep 26, 2025
3573e87
Barcode: rename source files
crumbowl Jul 21, 2025
d0c6ee0
Barcode: refactoring: separate DB item database functions
crumbowl Jul 21, 2025
69c1630
Barcode: refactoring: prepare code for future APIs with generic funct…
crumbowl Jul 21, 2025
95037e4
Barcode: add testing function
crumbowl Jul 21, 2025
f200b96
Barcode: add SearchEngineURL and SearchEngineProductURL + minor refac…
crumbowl Jul 21, 2025
68f71b2
Barcode: add manufacturer & modelNumber filling in database
crumbowl Jul 22, 2025
6f10a6a
Barcode: add new 'barcode' field to database
crumbowl Jul 23, 2025
3cecdf8
Barcode: display a real barcode image in item details (add JsBarcode
crumbowl Sep 26, 2025
2f2366c
fix: manufacturer & modelNumber were not filled properly
crumbowl Sep 26, 2025
dfc0954
Barcode: properly copy barcode on duplicate item
crumbowl Sep 26, 2025
f4cc216
BarcodeModal: redirect URL to product instead of DB website
crumbowl Jul 24, 2025
5b257b7
Barcode: use of ItemCreate's field instead of custom ones
crumbowl Jul 25, 2025
e7b7540
Barcode: refactor using Table.vu (WIP - preference still broken)
crumbowl Sep 26, 2025
24e3db4
Barcode: rework of Table to use a itemType field
crumbowl Jul 25, 2025
f1381ff
BarcodeModal: fix onSelectedItemChange() call
crumbowl Jul 25, 2025
5586c23
Barcode: add BarcodeCard component
crumbowl Jul 25, 2025
c327715
Barcode: add card support
crumbowl Jul 25, 2025
22dd1dd
BarcodeModal: derive from BaseModal instead of Dialog
crumbowl Jul 26, 2025
d79bf08
BarcodeModal: make use of base class App/CreateModal
crumbowl Jul 26, 2025
561ff77
BarcodeModal: fix Separator issue on smartphones
crumbowl Jul 27, 2025
7979230
Input: better handling of numeric values
crumbowl Jul 28, 2025
d7faf34
BarcodeModal: trigger numeric keyboard on barcode field
crumbowl Jul 28, 2025
cea0473
App/CreateModal: add the possibility to hide shortcuts
crumbowl Jul 28, 2025
4a7e55b
BarcodeModal: hide shortcut
crumbowl Jul 28, 2025
8037c84
BarcodeModal: disable Tablesettings
crumbowl Jul 28, 2025
35df00b
Selectable: properly reset selecteditem when changing view
crumbowl Jul 28, 2025
c39c8e0
BarcodeModal: fix bottom margin on smartphones
crumbowl Jul 28, 2025
3ab06d0
Scanner: display complete error in GUI (useful for smartphone debug)
crumbowl Jul 28, 2025
dd9220a
Barcode: return proper error from the backend to the frontend
crumbowl Aug 24, 2025
5c48c81
Barcode: properly encode barcode in URL to avoid injection
crumbowl Aug 24, 2025
c5ea4d1
Barcode: add comment on UPCDBITEM unmarshalling
crumbowl Aug 24, 2025
4caa41f
Barcode: properly mock test to avoid remote API limitations
crumbowl Sep 26, 2025
d9487ab
Barcode: prevent empty response from BarcodeSpider
crumbowl Sep 26, 2025
7d8617b
Barcode: Make use of translation in Item/CreateModal
crumbowl Sep 26, 2025
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion backend/app/api/demo.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ import (
)

func (a *app) SetupDemo() error {
csvText := `HB.import_ref,HB.location,HB.labels,HB.quantity,HB.name,HB.description,HB.insured,HB.serial_number,HB.model_number,HB.manufacturer,HB.notes,HB.purchase_from,HB.purchase_price,HB.purchase_time,HB.lifetime_warranty,HB.warranty_expires,HB.warranty_details,HB.sold_to,HB.sold_price,HB.sold_time,HB.sold_notes
csvText := `HB.import_ref,HB.location,HB.labels,HB.quantity,HB.name,HB.description,HB.insured,HB.serial_number,HB.model_number,HB.manufacturer,HB.barcode,HB.notes,HB.purchase_from,HB.purchase_price,HB.purchase_time,HB.lifetime_warranty,HB.warranty_expires,HB.warranty_details,HB.sold_to,HB.sold_price,HB.sold_time,HB.sold_notes
,Garage,IOT;Home Assistant; Z-Wave,1,Zooz Universal Relay ZEN17,"Zooz 700 Series Z-Wave Universal Relay ZEN17 for Awnings, Garage Doors, Sprinklers, and More | 2 NO-C-NC Relays (20A, 10A) | Signal Repeater | Hub Required (Compatible with SmartThings and Hubitat)",,,ZEN17,Zooz,,Amazon,39.95,10/13/2021,,,,,,,
,Living Room,IOT;Home Assistant; Z-Wave,1,Zooz Motion Sensor,"Zooz Z-Wave Plus S2 Motion Sensor ZSE18 with Magnetic Mount, Works with Vera and SmartThings",,,ZSE18,Zooz,,Amazon,29.95,10/15/2021,,,,,,,
,Office,IOT;Home Assistant; Z-Wave,1,Zooz 110v Power Switch,"Zooz Z-Wave Plus Power Switch ZEN15 for 110V AC Units, Sump Pumps, Humidifiers, and More",,,ZEN15,Zooz,,Amazon,39.95,10/13/2021,,,,,,,
Expand Down
44 changes: 44 additions & 0 deletions backend/app/api/handlers/v1/v1_ctrl_barcodes.go
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"`
}
Comment on lines +21 to +24
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major

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
In backend/app/api/handlers/v1/v1_ctrl_barcodes.go around lines 21-24 (and
similarly lines 26-31), the barcode field currently only checks required and max
length; add a server-side numeric-only validation so non-digit EANs are rejected
before external calls. Update the query struct validation to include a
digits-only rule (e.g. a regex like ^\d+$) or wire in the validator's
numeric/digits validator, adjust any parsing logic to rely on that validation,
and ensure the handler returns a 400 Bad Request with a clear validation error
when the EAN contains non-digits.


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
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major

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

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
products, err := ctrl.repo.Barcode.RetrieveProductsFromBarcode(ctrl.config.Barcode, q.EAN)
if err != nil {
return server.JSON(w, http.StatusInternalServerError, err.Error())
}
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"
)
// ...
products, err := ctrl.repo.Barcode.RetrieveProductsFromBarcode(ctrl.config.Barcode, q.EAN)
if err != nil {
log.Error().Err(err).Str("ean", q.EAN).Msg("barcode product search failed")
return server.JSON(w, http.StatusInternalServerError, nil)
}
🤖 Prompt for AI Agents
In backend/app/api/handlers/v1/v1_ctrl_barcodes.go around lines 32 to 36, the
handler currently returns err.Error() to the client exposing internal details;
instead, log the detailed error server-side and return a generic 500 response
body. Update the error branch to send a non-revealing message (e.g. "internal
server error") to the client and use the controller's logger (or standard
logger) to record the full err with context (including barcode and any other
useful request identifiers) before returning the generic response.


if len(products) != 0 {
return server.JSON(w, http.StatusOK, products)
}

return server.JSON(w, http.StatusNoContent, nil)
}
}
332 changes: 0 additions & 332 deletions backend/app/api/handlers/v1/v1_ctrl_product_search.go

This file was deleted.

2 changes: 1 addition & 1 deletion backend/app/api/routes.go
Original file line number Diff line number Diff line change
Expand Up @@ -158,7 +158,7 @@ func (a *app) mountRoutes(r *chi.Mux, chain *errchain.ErrChain, repos *repo.AllR
a.mwRoles(RoleModeOr, authroles.RoleUser.String(), authroles.RoleAttachments.String()),
}

r.Get("/products/search-from-barcode", chain.ToHandlerFunc(v1Ctrl.HandleProductSearchFromBarcode(a.conf.Barcode), userMW...))
r.Get("/products/search-from-barcode", chain.ToHandlerFunc(v1Ctrl.HandleProductSearchFromBarcode(), userMW...))

r.Get("/qrcode", chain.ToHandlerFunc(v1Ctrl.HandleGenerateQRCode(), assetMW...))
r.Get(
Expand Down
Loading