package pkg import ( "github.com/julienschmidt/httprouter" "mime" "net/http" ) func NewRouter(db *Db, demo bool) http.Handler { companyRouter := httprouter.New() companyRouter.GET("/profile", GetProfileForm) companyRouter.POST("/profile", HandleProfileForm) companyRouter.GET("/tax-details", GetCompanyTaxDetailsForm) companyRouter.POST("/tax-details", HandleCompanyTaxDetailsForm) companyRouter.GET("/invoicing", serveCompanyInvoicingForm) companyRouter.POST("/invoicing", handleCompanyInvoicingForm) companyRouter.GET("/switch-company", GetCompanySwitcher) companyRouter.GET("/taxes", serveCompanyTaxes) companyRouter.POST("/taxes", HandleAddCompanyTax) companyRouter.DELETE("/taxes/:taxId", HandleDeleteCompanyTax) companyRouter.GET("/payment-methods", servePaymentMethods) companyRouter.POST("/payment-methods", HandleAddPaymentMethod) companyRouter.DELETE("/payment-methods/:paymentMethodId", HandleDeletePaymentMethod) companyRouter.GET("/contacts", IndexContacts) companyRouter.POST("/contacts", HandleAddContact) companyRouter.POST("/contacts/import", HandleImportContacts) companyRouter.GET("/contacts/:slug", GetContactForm) companyRouter.PUT("/contacts/:slug", HandleUpdateContact) companyRouter.PUT("/contacts/:slug/tags", HandleUpdateContactTags) companyRouter.GET("/contacts/:slug/tags/edit", ServeEditContactTags) companyRouter.GET("/products", IndexProducts) companyRouter.POST("/products", HandleAddProduct) companyRouter.GET("/products/:slug", GetProductForm) companyRouter.PUT("/products/:slug", HandleUpdateProduct) companyRouter.PUT("/products/:slug/tags", HandleUpdateProductTags) companyRouter.GET("/products/:slug/tags/edit", ServeEditProductTags) companyRouter.GET("/invoices", IndexInvoices) companyRouter.POST("/invoices", HandleAddInvoice) companyRouter.GET("/invoices/:slug", ServeInvoice) companyRouter.PUT("/invoices/:slug", HandleUpdateInvoice) companyRouter.POST("/invoices/:slug", HandleNewInvoiceAction) companyRouter.GET("/invoices/:slug/edit", ServeEditInvoice) companyRouter.POST("/invoices/:slug/edit", HandleEditInvoiceAction) companyRouter.PUT("/invoices/:slug/tags", HandleUpdateInvoiceTags) companyRouter.GET("/invoices/:slug/tags/edit", ServeEditInvoiceTags) companyRouter.GET("/invoices/:slug/download/:filename", ServeInvoiceAttachment) companyRouter.GET("/invoices/:slug/collections", serveInvoiceCollectionIndex) companyRouter.POST("/invoices/:slug/collections", handleAddInvoiceCollection) companyRouter.GET("/invoices/:slug/collections/:slug", serveInvoiceCollectionForm) companyRouter.PUT("/invoices/:slug/collections/:slug", handleEditInvoiceCollection) companyRouter.DELETE("/invoices/:slug/collections/:slug", handleRemoveInvoiceCollection) companyRouter.GET("/quotes", IndexQuotes) companyRouter.POST("/quotes", HandleAddQuote) companyRouter.GET("/quotes/:slug", ServeQuote) companyRouter.PUT("/quotes/:slug", HandleUpdateQuote) companyRouter.POST("/quotes/:slug", HandleNewQuoteAction) companyRouter.GET("/quotes/:slug/edit", ServeEditQuote) companyRouter.POST("/quotes/:slug/edit", HandleEditQuoteAction) companyRouter.PUT("/quotes/:slug/tags", HandleUpdateQuoteTags) companyRouter.GET("/quotes/:slug/tags/edit", ServeEditQuoteTags) companyRouter.GET("/search/products", HandleProductSearch) companyRouter.GET("/expenses", IndexExpenses) companyRouter.POST("/expenses", HandleNewExpenseAction) companyRouter.GET("/expenses/:slug", ServeExpenseForm) companyRouter.POST("/expenses/:slug", HandleEditExpenseAction) companyRouter.PUT("/expenses/:slug", HandleUpdateExpense) companyRouter.PUT("/expenses/:slug/tags", HandleUpdateExpenseTags) companyRouter.GET("/expenses/:slug/tags/edit", ServeEditExpenseTags) companyRouter.GET("/expenses/:slug/download/:filename", ServeExpenseAttachment) companyRouter.GET("/expenses/:slug/payments", serveExpensePaymentIndex) companyRouter.POST("/expenses/:slug/payments", handleAddExpensePayment) companyRouter.GET("/expenses/:slug/payments/:slug", serveExpensePaymentForm) companyRouter.PUT("/expenses/:slug/payments/:slug", handleEditExpensePayment) companyRouter.DELETE("/expenses/:slug/payments/:slug", handleRemoveExpensePayment) companyRouter.GET("/payments", servePaymentIndex) companyRouter.POST("/payments", handleAddPayment) companyRouter.GET("/payments/:slug", servePaymentForm) companyRouter.PUT("/payments/:slug", handleEditPayment) companyRouter.DELETE("/payments/:slug", handleRemovePayment) companyRouter.PUT("/payments/:slug/tags", handleUpdatePaymentTags) companyRouter.GET("/payments/:slug/tags/edit", servePaymentTagsEditForm) companyRouter.GET("/payments/:slug/download/:filename", servePaymentAttachment) companyRouter.GET("/payment-accounts", servePaymentAccountIndex) companyRouter.POST("/payment-accounts", handleAddPaymentAccount) companyRouter.GET("/payment-accounts/:slug", servePaymentAccountForm) companyRouter.PUT("/payment-accounts/:slug", handleEditPaymentAccount) companyRouter.GET("/", ServeDashboard) router := httprouter.New() router.ServeFiles("/static/*filepath", http.Dir("web/static")) router.GET("/login", func(w http.ResponseWriter, r *http.Request, _ httprouter.Params) { GetLoginForm(w, r, demo) }) router.POST("/login", func(w http.ResponseWriter, r *http.Request, _ httprouter.Params) { HandleLoginForm(w, r, demo) }) router.POST("/logout", Authenticated(HandleLogout)) companyHandler := Authenticated(CompanyHandler(companyRouter)) router.GET("/company/:slug/*rest", companyHandler) router.POST("/company/:slug/*rest", companyHandler) router.PUT("/company/:slug/*rest", companyHandler) router.DELETE("/company/:slug/*rest", companyHandler) router.GET("/legal", func(w http.ResponseWriter, r *http.Request, _ httprouter.Params) { mustRenderWebTemplate(w, r, "legal.gohtml", nil) }) router.GET("/privacy", func(w http.ResponseWriter, r *http.Request, _ httprouter.Params) { mustRenderWebTemplate(w, r, "privacy.gohtml", nil) }) router.GET("/cookies", func(w http.ResponseWriter, r *http.Request, _ httprouter.Params) { mustRenderWebTemplate(w, r, "cookies.gohtml", nil) }) router.GET("/", func(w http.ResponseWriter, r *http.Request, _ httprouter.Params) { user := getUser(r) if user.LoggedIn { conn := getConn(r) company := &Company{ Slug: conn.MustGetText(r.Context(), "", "select slug::text from company order by company_id limit 1"), } http.Redirect(w, r, companyURI(company, "/"), http.StatusFound) } else { mustRenderWebTemplate(w, r, "home.gohtml", nil) } }) var handler http.Handler = router handler = MethodOverrider(handler) handler = LocaleSetter(db, handler) handler = LoginChecker(db, handler) handler = Recoverer(handler) handler = Logger(handler) return handler } func MethodOverrider(next http.Handler) http.Handler { return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { if r.Method == http.MethodPost { contentType := r.Header.Get("Content-Type") contentType, _, err := mime.ParseMediaType(contentType) if err != nil { http.Error(w, err.Error(), http.StatusBadRequest) return } if contentType == "multipart/form-data" { if err := r.ParseMultipartForm(20 << 20); err != nil { http.Error(w, err.Error(), http.StatusBadRequest) return } } else { if err := r.ParseForm(); err != nil { http.Error(w, err.Error(), http.StatusBadRequest) return } } override := r.FormValue(overrideMethodName) if override == http.MethodDelete || override == http.MethodPut { r2 := new(http.Request) *r2 = *r r2.Method = override r = r2 } } next.ServeHTTP(w, r) }) }