diff --git a/api/routes.go b/api/routes.go index fc23222a..bb9ac89a 100644 --- a/api/routes.go +++ b/api/routes.go @@ -47,6 +47,11 @@ func AddRoutes(r *mux.Router) { r.Handle("/mailer/{id}", authenticatedHandlerJSONPost(mailer.ByIDGet)).Methods("GET").Name("mailer.ByIDGet") r.Handle("/mosquito-source", auth.NewEnsureAuth(apiMosquitoSource)).Methods("GET") + qrcode := resource.QRCode(router) + r.Handle("/qr-code/mailer/{code}", handlerBasic(qrcode.Mailer)).Methods("GET") + r.Handle("/qr-code/marketing", handlerBasic(qrcode.Marketing)).Methods("GET") + r.Handle("/qr-code/report/{code}", handlerBasic(qrcode.Report)).Methods("GET") + r.Handle("/publicreport/invalid", authenticatedHandlerJSONPost(postPublicreportInvalid)).Methods("POST") r.Handle("/publicreport/signal", authenticatedHandlerJSONPost(postPublicreportSignal)).Methods("POST") r.Handle("/publicreport/message", authenticatedHandlerJSONPost(postPublicreportMessage)).Methods("POST") diff --git a/html/template/sync/mock/report.html b/html/template/sync/mock/report.html index ba8cf231..baeaae69 100644 --- a/html/template/sync/mock/report.html +++ b/html/template/sync/mock/report.html @@ -163,7 +163,7 @@
IMPORTANT NOTICE

We visited regarding a potential mosquito breeding site.

- +

Scan this code with your phone camera to report diff --git a/resource/qrcode.go b/resource/qrcode.go new file mode 100644 index 00000000..aec194e0 --- /dev/null +++ b/resource/qrcode.go @@ -0,0 +1,97 @@ +package resource + +import ( + "context" + "net/http" + "strconv" + + "github.com/Gleipnir-Technology/nidus-sync/config" + nhttp "github.com/Gleipnir-Technology/nidus-sync/http" + "github.com/gorilla/mux" + "github.com/skip2/go-qrcode" +) + +type qrcodeR struct { + router *router +} + +func QRCode(r *router) *qrcodeR { + return &qrcodeR{ + router: r, + } +} + +func (res *qrcodeR) Mailer(ctx context.Context, w http.ResponseWriter, r *http.Request) *nhttp.ErrorWithStatus { + vars := mux.Vars(r) + code := vars["code"] + if code == "" { + return nhttp.NewBadRequest("There should always be a id") + } + content := config.MakeURLReport("/mailer/%s", code) + return writeQRCode(w, r, content) +} +func (res *qrcodeR) Marketing(w http.ResponseWriter, r *http.Request) *nhttp.ErrorWithStatus { + content := "https://nidus.cloud" + return writeQRCode(w, r, content) +} + +func (res *qrcodeR) Report(w http.ResponseWriter, r *http.Request) *nhttp.ErrorWithStatus { + vars := mux.Vars(r) + code := vars["code"] + if code == "" { + return nhttp.NewBadRequest("There should always be a code") + } + content := config.MakeURLNidus("/report/%s", code) + return writeQRCode(w, r, content) +} +func writeQRCode(w http.ResponseWriter, r *http.Request, content string) *nhttp.ErrorWithStatus { + // Get optional size parameter (default to 256) + size := 256 + if sizeStr := r.URL.Query().Get("size"); sizeStr != "" { + var err error + size, err = strconv.Atoi(sizeStr) + if err != nil { + return nhttp.NewBadRequest("Invalid 'size' parameter, must be an integer") + } + } + + // Get optional error correction level (default to Medium) + level := qrcode.Medium + if levelStr := r.URL.Query().Get("level"); levelStr != "" { + switch levelStr { + case "L", "l": + level = qrcode.Low + case "M", "m": + level = qrcode.Medium + case "Q", "q": + level = qrcode.High + case "H", "h": + level = qrcode.Highest + default: + return nhttp.NewBadRequest("Invalid 'level' parameter, must be L, M, Q, or H") + } + } + + // Generate the QR code + var qr *qrcode.QRCode + var err error + qr, err = qrcode.New(content, level) + if err != nil { + return nhttp.NewError("Error generating QR code: %w", err) + } + + // Set the appropriate content type + w.Header().Set("Content-Type", "image/png") + + // Generate PNG and write directly to the response writer + png, err := qr.PNG(size) + if err != nil { + return nhttp.NewError("Error encoding QR code to PNG: %w", err) + } + + _, err = w.Write(png) + if err != nil { + return nhttp.NewError("Error writing response: %w", err) + } + return nil +} diff --git a/sync/mailer.go b/sync/mailer.go index 1999b46c..240775dc 100644 --- a/sync/mailer.go +++ b/sync/mailer.go @@ -98,7 +98,7 @@ func getMailer2Preview(w http.ResponseWriter, r *http.Request) { LogoURL: config.MakeURLNidus("/api/district/delta-mvcd/logo"), Organization: org, PoolImageURL: config.MakeURLNidus("/mailer/pool/random"), - QRCodeURL: config.MakeURLNidus("/qr-code/marketing"), + QRCodeURL: config.MakeURLNidus("/api/qr-code/marketing"), ReportURL: "https://nidus.cloud", }) } @@ -133,7 +133,7 @@ func getMailer3Preview(w http.ResponseWriter, r *http.Request) { LogoURL: config.MakeURLNidus("/api/district/%s/logo", org.Slug.GetOr("unset")), Organization: org, PoolImageURL: config.MakeURLNidus("/api/compliance-request/image/pool/%s", code), - QRCodeURL: config.MakeURLNidus("/qr-code/mailer/%s", code), + QRCodeURL: config.MakeURLNidus("/api/qr-code/mailer/%s", code), ReportURL: config.MakeURLReport("/mailer/%s", code), }) } diff --git a/sync/qr.go b/sync/qr.go index 807a9889..1ca2a85e 100644 --- a/sync/qr.go +++ b/sync/qr.go @@ -1,88 +1 @@ package sync - -import ( - "github.com/skip2/go-qrcode" - "net/http" - "strconv" - - "github.com/Gleipnir-Technology/nidus-sync/config" - "github.com/gorilla/mux" -) - -func getQRCodeMailer(w http.ResponseWriter, r *http.Request) { - vars := mux.Vars(r) - code := vars["code"] - if code == "" { - respondError(w, "There should always be a id", nil, http.StatusBadRequest) - } - content := config.MakeURLReport("/mailer/%s", code) - writeQRCode(w, r, content) -} -func getQRCodeMarketing(w http.ResponseWriter, r *http.Request) { - content := "https://nidus.cloud" - writeQRCode(w, r, content) -} - -func getQRCodeReport(w http.ResponseWriter, r *http.Request) { - vars := mux.Vars(r) - code := vars["code"] - if code == "" { - respondError(w, "There should always be a code", nil, http.StatusBadRequest) - } - content := config.MakeURLNidus("/report/%s", code) - writeQRCode(w, r, content) -} -func writeQRCode(w http.ResponseWriter, r *http.Request, content string) { - // Get optional size parameter (default to 256) - size := 256 - if sizeStr := r.URL.Query().Get("size"); sizeStr != "" { - var err error - size, err = strconv.Atoi(sizeStr) - if err != nil { - http.Error(w, "Invalid 'size' parameter, must be an integer", http.StatusBadRequest) - return - } - } - - // Get optional error correction level (default to Medium) - level := qrcode.Medium - if levelStr := r.URL.Query().Get("level"); levelStr != "" { - switch levelStr { - case "L", "l": - level = qrcode.Low - case "M", "m": - level = qrcode.Medium - case "Q", "q": - level = qrcode.High - case "H", "h": - level = qrcode.Highest - default: - respondError(w, "Invalid 'level' parameter, must be L, M, Q, or H", nil, http.StatusBadRequest) - return - } - } - - // Generate the QR code - var qr *qrcode.QRCode - var err error - qr, err = qrcode.New(content, level) - if err != nil { - respondError(w, "Error generating QR code", err, http.StatusInternalServerError) - return - } - - // Set the appropriate content type - w.Header().Set("Content-Type", "image/png") - - // Generate PNG and write directly to the response writer - png, err := qr.PNG(size) - if err != nil { - respondError(w, "Error encoding QR code to PNG", err, http.StatusInternalServerError) - return - } - - _, err = w.Write(png) - if err != nil { - respondError(w, "Error writing response", err, http.StatusInternalServerError) - } -} diff --git a/sync/routes.go b/sync/routes.go index b0d869ec..75f77e4f 100644 --- a/sync/routes.go +++ b/sync/routes.go @@ -19,9 +19,6 @@ func Router(r *mux.Router) { // Utility endpoints r.HandleFunc("/privacy", getPrivacy) - r.HandleFunc("/qr-code/marketing", getQRCodeMarketing) - r.HandleFunc("/qr-code/report/{code}", getQRCodeReport) - r.HandleFunc("/qr-code/mailer/{code}", getQRCodeMailer) r.HandleFunc("/template-test", getTemplateTest) //r.HandleFunc("/", getRoot) diff --git a/vite/sync/vite.config.js b/vite/sync/vite.config.js index 4ac7b0c2..7822530c 100644 --- a/vite/sync/vite.config.js +++ b/vite/sync/vite.config.js @@ -77,11 +77,11 @@ export default defineConfig({ target: "http://127.0.0.1:9003", changeOrigin: false, }, - "/oauth": { + "/mock": { target: "http://127.0.0.1:9003", changeOrigin: false, }, - "/qr-code": { + "/oauth": { target: "http://127.0.0.1:9003", changeOrigin: false, },