From a82b6812e3a0c69f79e2d9a98d19f3d9868dd1d8 Mon Sep 17 00:00:00 2001 From: Diana Date: Sat, 28 Sep 2024 17:40:42 -0500 Subject: [PATCH 01/12] get body request, validator fix --- context.go | 30 ++++++++++++++++++++++++++++++ validator.go | 12 ++++-------- 2 files changed, 34 insertions(+), 8 deletions(-) diff --git a/context.go b/context.go index 30c750b..3d21cbc 100644 --- a/context.go +++ b/context.go @@ -68,6 +68,36 @@ func (c *Context) RequestParamExists(key string) bool { return c.Request.httpRequest.Form.Has(key) } +func (c *Context) GetRequesForm() interface{} { + return c.Request.httpRequest.Form +} + +func (c *Context) GetRequesBodyMap() map[string]interface{} { + var dat map[string]any + body := c.Request.httpRequest.Body + if body != nil { + if content, err := io.ReadAll(body); err == nil { + json.Unmarshal(content, &dat) + } + } + return dat +} + +// get json body and bind to dest interface +func (c *Context) GetRequesBodyStruct(dest interface{}) error { + body := c.Request.httpRequest.Body + if body != nil { + value := reflect.ValueOf(dest) + if value.Kind() != reflect.Ptr { + fmt.Println("dest is not a pointer") + return errors.New("dest is not a pointer") + } + err := json.NewDecoder(body).Decode(dest) + return err + } + return nil +} + func (c *Context) GetHeader(key string) string { return c.Request.httpRequest.Header.Get(key) } diff --git a/validator.go b/validator.go index 7d8eac8..ba4d8a2 100644 --- a/validator.go +++ b/validator.go @@ -33,18 +33,14 @@ func (v *Validator) Validate(data map[string]interface{}, rules map[string]inter vr = validationResult{} vr.hasFailed = false res := map[string]string{} - for key, val := range data { - _, ok := rules[key] - if !ok { - continue - } - rls, err := parseRules(rules[key]) + for rule_key, rule_val := range rules { + rls, err := parseRules(rule_val) if err != nil { panic(err.Error()) } - err = validation.Validate(val, rls...) + err = validation.Validate(data[rule_key], rls...) if err != nil { - res[key] = fmt.Sprintf("%v: %v", key, err.Error()) + res[rule_key] = fmt.Sprintf("%v: %v", rule_key, err.Error()) } } From 2bffdcdcf7e40eb432cf26c0451ea18b2292561b Mon Sep 17 00:00:00 2001 From: Zeni Kim Date: Mon, 30 Sep 2024 09:12:38 -0500 Subject: [PATCH 02/12] start cookie session --- context.go | 9 ++ cookies.go | 238 ++++++++++++++++++++++++++++++++++ core.go | 8 +- template/components/head.html | 10 +- template/components/page.html | 17 +++ 5 files changed, 275 insertions(+), 7 deletions(-) create mode 100644 cookies.go create mode 100644 template/components/page.html diff --git a/context.go b/context.go index 30c750b..cc622be 100644 --- a/context.go +++ b/context.go @@ -72,6 +72,15 @@ func (c *Context) GetHeader(key string) string { return c.Request.httpRequest.Header.Get(key) } +func (c *Context) GetCookie() (UserCookie, error) { + + user, err := GetCookie(c.Request.httpRequest) + if err != nil { + return user, err + } + return user, nil +} + func (c *Context) GetUploadedFile(name string) *UploadedFileInfo { file, fileHeader, err := c.Request.httpRequest.FormFile(name) if err != nil { diff --git a/cookies.go b/cookies.go new file mode 100644 index 0000000..87503e7 --- /dev/null +++ b/cookies.go @@ -0,0 +1,238 @@ +// Copyright (c) 2024 Zeni Kim +// Use of this source code is governed by MIT-style +// license that can be found in the LICENSE file. + +package core + +import ( + "crypto/aes" + "crypto/cipher" + + "bytes" + "crypto/rand" + "encoding/base64" + "encoding/gob" + "encoding/hex" + "errors" + "fmt" + "io" + "net/http" + "strings" +) + +var ( + ErrValueTooLong = errors.New("cookie value too long") + ErrInvalidValue = errors.New("invalid cookie value") +) + +// Declare the User type. +type UserCookie struct { + Email string + Token string +} + +var secretcookie []byte + +func GetCookie(r *http.Request) (UserCookie, error) { + + var err error + // Create a new instance of a User type. + var user UserCookie + + secretcookie, err = hex.DecodeString("13d6b4dff8f84a10851021ec8608f814570d562c92fe6b5ec4c9f595bcb3234b") + if err != nil { + return user, err + } + + gobEncodedValue, err := CookieReadEncrypted(r, "goffee", secretcookie) + if err != nil { + return user, err + } + + // Create an strings.Reader containing the gob-encoded value. + reader := strings.NewReader(gobEncodedValue) + + // Decode it into the User type. Notice that we need to pass a *pointer* to + // the Decode() target here? + if err := gob.NewDecoder(reader).Decode(&user); err != nil { + return user, err + } + + return user, nil + +} + +func SetCookie(w http.ResponseWriter, email string, token string) error { + // Initialize a User struct containing the data that we want to store in the + // cookie. + var err error + + secretcookie, err = hex.DecodeString("13d6b4dff8f84a10851021ec8608f814570d562c92fe6b5ec4c9f595bcb3234b") + if err != nil { + return err + } + + user := UserCookie{Email: email, Token: token} + + // Initialize a buffer to hold the gob-encoded data. + var buf bytes.Buffer + + // Gob-encode the user data, storing the encoded output in the buffer. + err = gob.NewEncoder(&buf).Encode(&user) + if err != nil { + return err + } + + // Call buf.String() to get the gob-encoded value as a string and set it as + // the cookie value. + cookie := http.Cookie{ + Name: "goffee", + Value: buf.String(), + Path: "/", + MaxAge: 3600, + HttpOnly: true, + Secure: true, + SameSite: http.SameSiteLaxMode, + } + + // Write an encrypted cookie containing the gob-encoded data as normal. + err = CookieWriteEncrypted(w, cookie, secretcookie) + if err != nil { + return err + } + + fmt.Printf("Cookie set %v\n", email) + + return nil +} + +func CookieWrite(w http.ResponseWriter, cookie http.Cookie) error { + // Encode the cookie value using base64. + cookie.Value = base64.URLEncoding.EncodeToString([]byte(cookie.Value)) + + // Check the total length of the cookie contents. Return the ErrValueTooLong + // error if it's more than 4096 bytes. + if len(cookie.String()) > 4096 { + return ErrValueTooLong + } + + // Write the cookie as normal. + http.SetCookie(w, &cookie) + + return nil +} + +func CookieRead(r *http.Request, name string) (string, error) { + // Read the cookie as normal. + cookie, err := r.Cookie(name) + if err != nil { + return "", err + } + + // Decode the base64-encoded cookie value. If the cookie didn't contain a + // valid base64-encoded value, this operation will fail and we return an + // ErrInvalidValue error. + value, err := base64.URLEncoding.DecodeString(cookie.Value) + if err != nil { + return "", ErrInvalidValue + } + + // Return the decoded cookie value. + return string(value), nil +} + +func CookieWriteEncrypted(w http.ResponseWriter, cookie http.Cookie, secretKey []byte) error { + // Create a new AES cipher block from the secret key. + block, err := aes.NewCipher(secretKey) + if err != nil { + return err + } + + // Wrap the cipher block in Galois Counter Mode. + aesGCM, err := cipher.NewGCM(block) + if err != nil { + return err + } + + // Create a unique nonce containing 12 random bytes. + nonce := make([]byte, aesGCM.NonceSize()) + _, err = io.ReadFull(rand.Reader, nonce) + if err != nil { + return err + } + + // Prepare the plaintext input for encryption. Because we want to + // authenticate the cookie name as well as the value, we make this plaintext + // in the format "{cookie name}:{cookie value}". We use the : character as a + // separator because it is an invalid character for cookie names and + // therefore shouldn't appear in them. + plaintext := fmt.Sprintf("%s:%s", cookie.Name, cookie.Value) + + // Encrypt the data using aesGCM.Seal(). By passing the nonce as the first + // parameter, the encrypted data will be appended to the nonce — meaning + // that the returned encryptedValue variable will be in the format + // "{nonce}{encrypted plaintext data}". + encryptedValue := aesGCM.Seal(nonce, nonce, []byte(plaintext), nil) + + // Set the cookie value to the encryptedValue. + cookie.Value = string(encryptedValue) + + // Write the cookie as normal. + return CookieWrite(w, cookie) +} + +func CookieReadEncrypted(r *http.Request, name string, secretKey []byte) (string, error) { + // Read the encrypted value from the cookie as normal. + encryptedValue, err := CookieRead(r, name) + if err != nil { + return "", err + } + + // Create a new AES cipher block from the secret key. + block, err := aes.NewCipher(secretKey) + if err != nil { + return "", err + } + + // Wrap the cipher block in Galois Counter Mode. + aesGCM, err := cipher.NewGCM(block) + if err != nil { + return "", err + } + + // Get the nonce size. + nonceSize := aesGCM.NonceSize() + + // To avoid a potential 'index out of range' panic in the next step, we + // check that the length of the encrypted value is at least the nonce + // size. + if len(encryptedValue) < nonceSize { + return "", ErrInvalidValue + } + + // Split apart the nonce from the actual encrypted data. + nonce := encryptedValue[:nonceSize] + ciphertext := encryptedValue[nonceSize:] + + // Use aesGCM.Open() to decrypt and authenticate the data. If this fails, + // return a ErrInvalidValue error. + plaintext, err := aesGCM.Open(nil, []byte(nonce), []byte(ciphertext), nil) + if err != nil { + return "", ErrInvalidValue + } + + // The plaintext value is in the format "{cookie name}:{cookie value}". We + // use strings.Cut() to split it on the first ":" character. + expectedName, value, ok := strings.Cut(string(plaintext), ":") + if !ok { + return "", ErrInvalidValue + } + + // Check that the cookie name is the expected one and hasn't been changed. + if expectedName != name { + return "", ErrInvalidValue + } + + // Return the plaintext cookie value. + return value, nil +} diff --git a/core.go b/core.go index ba208d3..59691c6 100644 --- a/core.go +++ b/core.go @@ -98,9 +98,7 @@ func (app *App) Run(router *httprouter.Router) { TemplateEnable, _ := strconv.ParseBool(TemplateEnableStr) // if enabled, if TemplateEnable { - // add public path - publicPath := os.Getenv("TEMPLATE_PUBLIC") - router.ServeFiles("/public/*filepath", http.Dir(publicPath)) + router.ServeFiles("/public/*filepath", http.Dir("storage/public")) } useHttpsStr := os.Getenv("App_USE_HTTPS") @@ -183,6 +181,7 @@ func (app *App) RegisterRoutes(routes []Route, router *httprouter.Router) *httpr func (app *App) makeHTTPRouterHandlerFunc(h Controller, ms []Hook) httprouter.Handle { return func(w http.ResponseWriter, r *http.Request, ps httprouter.Params) { + ctx := &Context{ Request: &Request{ httpRequest: r, @@ -206,11 +205,13 @@ func (app *App) makeHTTPRouterHandlerFunc(h Controller, ms []Hook) httprouter.Ha GetEventsManager: resolveEventsManager(), GetLogger: resolveLogger(), } + ctx.prepare(ctx) rhs := app.combHandlers(h, ms) app.prepareChain(rhs) app.t = 0 app.chain.execute(ctx) + for _, header := range ctx.Response.headers { w.Header().Add(header.key, header.val) } @@ -223,6 +224,7 @@ func (app *App) makeHTTPRouterHandlerFunc(h Controller, ms []Hook) httprouter.Ha } else { ct = CONTENT_TYPE_HTML } + w.Header().Add(CONTENT_TYPE, ct) if ctx.Response.statusCode != 0 { w.WriteHeader(ctx.Response.statusCode) diff --git a/template/components/head.html b/template/components/head.html index cecc5ed..68aaca8 100644 --- a/template/components/head.html +++ b/template/components/head.html @@ -1,8 +1,10 @@ {{define "head"}} - - - {{.}} | Goffee - + + + + {{.}} | Goffee + + {{end}} \ No newline at end of file diff --git a/template/components/page.html b/template/components/page.html new file mode 100644 index 0000000..636487b --- /dev/null +++ b/template/components/page.html @@ -0,0 +1,17 @@ + + + + + + + My Website + + + + +
+

Welcome to My Website

+
+ + + \ No newline at end of file From 015e85bf7b20a56381449cbf1ba1b580d3d1d360 Mon Sep 17 00:00:00 2001 From: Zeni Kim Date: Mon, 7 Oct 2024 18:10:04 -0500 Subject: [PATCH 03/12] start theme core templates --- .../components/{button.go => form_button.go} | 2 +- .../{button.html => form_button.html} | 9 +++------ template/components/form_input.go | 12 ++++++++++++ template/components/form_input.html | 15 +++++++++++++++ template/components/page.html | 17 ----------------- template/components/page_card.go | 8 ++++++++ template/components/page_card.html | 11 +++++++++++ template/components/page_footer.html | 6 ++++++ .../components/{head.html => page_head.html} | 3 ++- template/components/page_page.html | 14 ++++++++++++++ template/components/title.go | 5 ----- template/components/title.html | 5 ----- 12 files changed, 72 insertions(+), 35 deletions(-) rename template/components/{button.go => form_button.go} (83%) rename template/components/{button.html => form_button.html} (89%) create mode 100644 template/components/form_input.go create mode 100644 template/components/form_input.html delete mode 100644 template/components/page.html create mode 100644 template/components/page_card.go create mode 100644 template/components/page_card.html create mode 100644 template/components/page_footer.html rename template/components/{head.html => page_head.html} (75%) create mode 100644 template/components/page_page.html delete mode 100644 template/components/title.go delete mode 100644 template/components/title.html diff --git a/template/components/button.go b/template/components/form_button.go similarity index 83% rename from template/components/button.go rename to template/components/form_button.go index 0c52a38..2cfee00 100644 --- a/template/components/button.go +++ b/template/components/form_button.go @@ -1,6 +1,6 @@ package components -type Button struct { +type FormButton struct { Text string Link string Icon string diff --git a/template/components/button.html b/template/components/form_button.html similarity index 89% rename from template/components/button.html rename to template/components/form_button.html index 6590905..5e1d68c 100644 --- a/template/components/button.html +++ b/template/components/form_button.html @@ -1,7 +1,6 @@ -{{define "button"}} - {{if eq .Icon "gear"}} @@ -17,6 +16,4 @@ {{end}} - - {{end}} \ No newline at end of file diff --git a/template/components/form_input.go b/template/components/form_input.go new file mode 100644 index 0000000..0ce7ce4 --- /dev/null +++ b/template/components/form_input.go @@ -0,0 +1,12 @@ +package components + +type FormInput struct { + ID string + Label string + Type string + Placeholder string + Value string + Hint string + Error string + IsDisabled bool +} diff --git a/template/components/form_input.html b/template/components/form_input.html new file mode 100644 index 0000000..b79ae87 --- /dev/null +++ b/template/components/form_input.html @@ -0,0 +1,15 @@ +{{define "form_input"}} +
+ + + {{if ne .Hint ""}}{{.Hint}}{{end}} + {{if ne .Error ""}}
{{.Error}}
{{end}} +
+{{end}} \ No newline at end of file diff --git a/template/components/page.html b/template/components/page.html deleted file mode 100644 index 636487b..0000000 --- a/template/components/page.html +++ /dev/null @@ -1,17 +0,0 @@ - - - - - - - My Website - - - - -
-

Welcome to My Website

-
- - - \ No newline at end of file diff --git a/template/components/page_card.go b/template/components/page_card.go new file mode 100644 index 0000000..7f9b504 --- /dev/null +++ b/template/components/page_card.go @@ -0,0 +1,8 @@ +package components + +type PageCard struct { + CardTitle string + CardSubTitle string + CardBody string + CardLink string +} diff --git a/template/components/page_card.html b/template/components/page_card.html new file mode 100644 index 0000000..9ef8821 --- /dev/null +++ b/template/components/page_card.html @@ -0,0 +1,11 @@ +{{define "page_card"}} +
+
+ {{if .CardTitle}}
{{.CardTitle}}
{{end}} + {{if .CardSubTitle}}
{{.CardSubTitle}}
{{end}} + {{if .CardBody}}

{{.CardBody}}

{{end}} + {{block "page_card_content" .}}{{end}} + {{if .CardLink}}Card link{{end}} +
+
+{{end}} \ No newline at end of file diff --git a/template/components/page_footer.html b/template/components/page_footer.html new file mode 100644 index 0000000..20b7f38 --- /dev/null +++ b/template/components/page_footer.html @@ -0,0 +1,6 @@ +{{define "page_footer"}} +
+ +
+ +{{end}} \ No newline at end of file diff --git a/template/components/head.html b/template/components/page_head.html similarity index 75% rename from template/components/head.html rename to template/components/page_head.html index 68aaca8..e589e84 100644 --- a/template/components/head.html +++ b/template/components/page_head.html @@ -1,4 +1,4 @@ -{{define "head"}} +{{define "page_head"}} @@ -6,5 +6,6 @@ {{.}} | Goffee + {{end}} \ No newline at end of file diff --git a/template/components/page_page.html b/template/components/page_page.html new file mode 100644 index 0000000..2c83582 --- /dev/null +++ b/template/components/page_page.html @@ -0,0 +1,14 @@ + + + {{template "page_head" "Goffee"}} + +
+ {{block "page_content" .}} +
+

Use this file as base inside cup application

+
+ {{end}} + {{template "page_footer"}} +
+ + \ No newline at end of file diff --git a/template/components/title.go b/template/components/title.go deleted file mode 100644 index 0e68b6a..0000000 --- a/template/components/title.go +++ /dev/null @@ -1,5 +0,0 @@ -package components - -type Title struct { - Label string -} diff --git a/template/components/title.html b/template/components/title.html deleted file mode 100644 index eef5bf3..0000000 --- a/template/components/title.html +++ /dev/null @@ -1,5 +0,0 @@ -{{define "title"}} -
-

{{.Label}}

-
-{{end}} \ No newline at end of file From 8f17bf6a8c879a514a2029c4c8c65fce141f6aac Mon Sep 17 00:00:00 2001 From: Zeni Kim Date: Tue, 8 Oct 2024 07:58:42 -0500 Subject: [PATCH 04/12] add form components --- template/components/form_checkbox.go | 14 ++++++++++++++ template/components/form_checkbox.html | 11 +++++++++++ template/components/form_radio.go | 15 +++++++++++++++ template/components/form_radio.html | 11 +++++++++++ template/components/form_select.go | 13 +++++++++++++ template/components/form_select.html | 10 ++++++++++ template/components/form_textarea.go | 7 +++++++ template/components/form_textarea.html | 6 ++++++ 8 files changed, 87 insertions(+) create mode 100644 template/components/form_checkbox.go create mode 100644 template/components/form_checkbox.html create mode 100644 template/components/form_radio.go create mode 100644 template/components/form_radio.html create mode 100644 template/components/form_select.go create mode 100644 template/components/form_select.html create mode 100644 template/components/form_textarea.go create mode 100644 template/components/form_textarea.html diff --git a/template/components/form_checkbox.go b/template/components/form_checkbox.go new file mode 100644 index 0000000..819da82 --- /dev/null +++ b/template/components/form_checkbox.go @@ -0,0 +1,14 @@ +package components + +type FormCheckbox struct { + Label string + AllCheckbox []FormCheckboxItem +} + +type FormCheckboxItem struct { + ID string + Name string + Value string + Label string + IsChecked bool +} diff --git a/template/components/form_checkbox.html b/template/components/form_checkbox.html new file mode 100644 index 0000000..9a8d845 --- /dev/null +++ b/template/components/form_checkbox.html @@ -0,0 +1,11 @@ +{{define "form_checkbox"}} +
+ + {{range $options := .AllCheckbox}} +
+ + +
+ {{end}} +
+{{end}} \ No newline at end of file diff --git a/template/components/form_radio.go b/template/components/form_radio.go new file mode 100644 index 0000000..e8e923c --- /dev/null +++ b/template/components/form_radio.go @@ -0,0 +1,15 @@ +package components + +type FormRadio struct { + Label string + AllRadios []FormRadioItem +} + +type FormRadioItem struct { + ID string + Name string + Value string + Label string + IsDisabled bool + IsChecked bool +} diff --git a/template/components/form_radio.html b/template/components/form_radio.html new file mode 100644 index 0000000..a0c26cd --- /dev/null +++ b/template/components/form_radio.html @@ -0,0 +1,11 @@ +{{define "form_radio"}} +
+ + {{range $options := .AllRadios}} +
+ + +
+ {{end}} +
+{{end}} \ No newline at end of file diff --git a/template/components/form_select.go b/template/components/form_select.go new file mode 100644 index 0000000..db94fe3 --- /dev/null +++ b/template/components/form_select.go @@ -0,0 +1,13 @@ +package components + +type FormSelect struct { + ID string + SelectedOption FormSelectOption + Label string + AllOptions []FormSelectOption +} + +type FormSelectOption struct { + Value string + Caption string +} diff --git a/template/components/form_select.html b/template/components/form_select.html new file mode 100644 index 0000000..6317e6b --- /dev/null +++ b/template/components/form_select.html @@ -0,0 +1,10 @@ +{{define "form_select"}} +
+ + +
+{{end}} \ No newline at end of file diff --git a/template/components/form_textarea.go b/template/components/form_textarea.go new file mode 100644 index 0000000..8fbaf51 --- /dev/null +++ b/template/components/form_textarea.go @@ -0,0 +1,7 @@ +package components + +type FormTextarea struct { + ID string + Label string + AllOptions []FormSelectOption +} diff --git a/template/components/form_textarea.html b/template/components/form_textarea.html new file mode 100644 index 0000000..5372a42 --- /dev/null +++ b/template/components/form_textarea.html @@ -0,0 +1,6 @@ +{{define "form_textarea"}} +
+ + +
+{{end}} \ No newline at end of file From 7073cd1c21913816445c2fc9a6e0294a5429122c Mon Sep 17 00:00:00 2001 From: Diana Date: Sat, 12 Oct 2024 13:01:52 -0500 Subject: [PATCH 05/12] components: buttons, dropdown, href, nav --- template/components/form_button.go | 3 +-- template/components/form_button.html | 35 +++++++++++++------------- template/components/form_dropdown.go | 15 +++++++++++ template/components/form_dropdown.html | 16 ++++++++++++ template/components/form_href.go | 10 ++++++++ template/components/form_href.html | 6 +++++ template/components/page_footer.html | 1 + template/components/page_nav.go | 16 ++++++++++++ template/components/page_nav.html | 23 +++++++++++++++++ 9 files changed, 106 insertions(+), 19 deletions(-) create mode 100644 template/components/form_dropdown.go create mode 100644 template/components/form_dropdown.html create mode 100644 template/components/form_href.go create mode 100644 template/components/form_href.html create mode 100644 template/components/page_nav.go create mode 100644 template/components/page_nav.html diff --git a/template/components/form_button.go b/template/components/form_button.go index 2cfee00..658306e 100644 --- a/template/components/form_button.go +++ b/template/components/form_button.go @@ -2,9 +2,8 @@ package components type FormButton struct { Text string - Link string Icon string IsSubmit bool - IsPrimary bool + TypeClass string // type primary, secondary, success, danger, warning, info, light, dark, link, outline-primary IsDisabled bool } diff --git a/template/components/form_button.html b/template/components/form_button.html index 5e1d68c..7594613 100644 --- a/template/components/form_button.html +++ b/template/components/form_button.html @@ -1,19 +1,20 @@ {{define "form_button"}} - - - {{if eq .Icon "gear"}} - - - - - {{else if eq .Icon "arrow-right"}} - - - - {{else if eq .Icon "plus"}} - - - - {{end}} + + + {{if eq .Icon "gear"}} + + + + + {{else if eq .Icon "arrow-right"}} + + + + {{else if eq .Icon "plus"}} + + + + {{end}} {{end}} \ No newline at end of file diff --git a/template/components/form_dropdown.go b/template/components/form_dropdown.go new file mode 100644 index 0000000..b80d8f1 --- /dev/null +++ b/template/components/form_dropdown.go @@ -0,0 +1,15 @@ +package components + +type FormDropdown struct { + Label string + TypeClass string + IsDisabled bool + Items []FormDropdownItem +} + +type FormDropdownItem struct { + Text string + Link string + IsDisabled bool + IsActive bool +} diff --git a/template/components/form_dropdown.html b/template/components/form_dropdown.html new file mode 100644 index 0000000..2c6827b --- /dev/null +++ b/template/components/form_dropdown.html @@ -0,0 +1,16 @@ +{{define "form_dropdown_item"}} +
  • {{.Text}}
  • +{{end}} + +{{define "form_dropdown"}} + +{{end}} \ No newline at end of file diff --git a/template/components/form_href.go b/template/components/form_href.go new file mode 100644 index 0000000..25dbee3 --- /dev/null +++ b/template/components/form_href.go @@ -0,0 +1,10 @@ +package components + +type FormHref struct { + Text string + Link string + Icon string + IsButton bool + TypeClass string // type primary, secondary, success, danger, warning, info, light, dark, link + IsDisabled bool +} diff --git a/template/components/form_href.html b/template/components/form_href.html new file mode 100644 index 0000000..dc9adb3 --- /dev/null +++ b/template/components/form_href.html @@ -0,0 +1,6 @@ +{{define "form_href"}} + + {{.Text}} + +{{end}} \ No newline at end of file diff --git a/template/components/page_footer.html b/template/components/page_footer.html index 20b7f38..6421f3e 100644 --- a/template/components/page_footer.html +++ b/template/components/page_footer.html @@ -2,5 +2,6 @@
    + {{end}} \ No newline at end of file diff --git a/template/components/page_nav.go b/template/components/page_nav.go new file mode 100644 index 0000000..2ed9319 --- /dev/null +++ b/template/components/page_nav.go @@ -0,0 +1,16 @@ +package components + +type PageNav struct { + NavClass string // nav-pills + NavItems []PageNavItem + IsVertical bool + IsTab bool +} + +type PageNavItem struct { + Text string + Link string + IsDisabled bool + IsActive bool + ChildItems []PageNavItem +} diff --git a/template/components/page_nav.html b/template/components/page_nav.html new file mode 100644 index 0000000..5bb0b83 --- /dev/null +++ b/template/components/page_nav.html @@ -0,0 +1,23 @@ +{{define "page_nav"}} + +{{end}} From 1c1740d97b4ce8540434f84f30474c4fc3f98cbe Mon Sep 17 00:00:00 2001 From: Zeni Kim Date: Mon, 14 Oct 2024 12:13:51 -0500 Subject: [PATCH 06/12] base table --- template/components/content_table.go | 17 +++++++++++++++++ template/components/content_table.html | 12 ++++++++++++ 2 files changed, 29 insertions(+) create mode 100644 template/components/content_table.go create mode 100644 template/components/content_table.html diff --git a/template/components/content_table.go b/template/components/content_table.go new file mode 100644 index 0000000..66c7e1f --- /dev/null +++ b/template/components/content_table.go @@ -0,0 +1,17 @@ +package components + +type ContentTable struct { + ID string + AllTH []ContentTableTH + AllTD [][]ContentTableTD +} + +type ContentTableTH struct { + ID string + Value string +} + +type ContentTableTD struct { + ID string + Value string +} diff --git a/template/components/content_table.html b/template/components/content_table.html new file mode 100644 index 0000000..68e34f6 --- /dev/null +++ b/template/components/content_table.html @@ -0,0 +1,12 @@ +{{define "content_table"}} + + + + {{range $index, $col := .AllTH}}{{end}} + + + +{{range .AllTD}}{{range .}}{{end}}{{end}} + +
    {{ $col.Value }}
    {{ .Value }}
    +{{end}} \ No newline at end of file From a904773babab29b9e24d40cf183b8a7a1ee92f0e Mon Sep 17 00:00:00 2001 From: Diana Date: Tue, 15 Oct 2024 16:06:49 -0500 Subject: [PATCH 07/12] Badge --- template/components/content_badge.go | 7 +++++++ template/components/content_badge.html | 7 +++++++ 2 files changed, 14 insertions(+) create mode 100644 template/components/content_badge.go create mode 100644 template/components/content_badge.html diff --git a/template/components/content_badge.go b/template/components/content_badge.go new file mode 100644 index 0000000..7da7147 --- /dev/null +++ b/template/components/content_badge.go @@ -0,0 +1,7 @@ +package components + +type ContentBadge struct { + Text string + TypeClass string // type primary, secondary, success, danger, warning, info, light, dark, (default secondary) + IsOutline bool +} diff --git a/template/components/content_badge.html b/template/components/content_badge.html new file mode 100644 index 0000000..6f72cf7 --- /dev/null +++ b/template/components/content_badge.html @@ -0,0 +1,7 @@ +{{define "content_badge"}} + {{.Text}} +{{end}} \ No newline at end of file From f398ebb02dbc0d9510dab1f2588ffd0b5f6c1405 Mon Sep 17 00:00:00 2001 From: Diana Date: Tue, 15 Oct 2024 16:07:18 -0500 Subject: [PATCH 08/12] dropdown, href is content --- template/components/content_dropdown.go | 15 +++++++++++++++ .../{form_dropdown.html => content_dropdown.html} | 6 +++--- .../components/{form_href.go => content_href.go} | 2 +- .../{form_href.html => content_href.html} | 2 +- template/components/form_dropdown.go | 15 --------------- 5 files changed, 20 insertions(+), 20 deletions(-) create mode 100644 template/components/content_dropdown.go rename template/components/{form_dropdown.html => content_dropdown.html} (79%) rename template/components/{form_href.go => content_href.go} (88%) rename template/components/{form_href.html => content_href.html} (88%) delete mode 100644 template/components/form_dropdown.go diff --git a/template/components/content_dropdown.go b/template/components/content_dropdown.go new file mode 100644 index 0000000..1040060 --- /dev/null +++ b/template/components/content_dropdown.go @@ -0,0 +1,15 @@ +package components + +type ContentDropdown struct { + Label string + TypeClass string // type primary, secondary, success, danger, warning, info, light, dark, link, outline-primary + IsDisabled bool + Items []ContentDropdownItem +} + +type ContentDropdownItem struct { + Text string + Link string + IsDisabled bool + IsActive bool +} diff --git a/template/components/form_dropdown.html b/template/components/content_dropdown.html similarity index 79% rename from template/components/form_dropdown.html rename to template/components/content_dropdown.html index 2c6827b..ce83a26 100644 --- a/template/components/form_dropdown.html +++ b/template/components/content_dropdown.html @@ -1,15 +1,15 @@ -{{define "form_dropdown_item"}} +{{define "content_dropdown_item"}}
  • {{.Text}}
  • {{end}} -{{define "form_dropdown"}} +{{define "content_dropdown"}} diff --git a/template/components/form_href.go b/template/components/content_href.go similarity index 88% rename from template/components/form_href.go rename to template/components/content_href.go index 25dbee3..143ca80 100644 --- a/template/components/form_href.go +++ b/template/components/content_href.go @@ -1,6 +1,6 @@ package components -type FormHref struct { +type ContentHref struct { Text string Link string Icon string diff --git a/template/components/form_href.html b/template/components/content_href.html similarity index 88% rename from template/components/form_href.html rename to template/components/content_href.html index dc9adb3..f4980ac 100644 --- a/template/components/form_href.html +++ b/template/components/content_href.html @@ -1,4 +1,4 @@ -{{define "form_href"}} +{{define "content_href"}} {{.Text}} diff --git a/template/components/form_dropdown.go b/template/components/form_dropdown.go deleted file mode 100644 index b80d8f1..0000000 --- a/template/components/form_dropdown.go +++ /dev/null @@ -1,15 +0,0 @@ -package components - -type FormDropdown struct { - Label string - TypeClass string - IsDisabled bool - Items []FormDropdownItem -} - -type FormDropdownItem struct { - Text string - Link string - IsDisabled bool - IsActive bool -} From 458ad520ca19f7301741fcc02b9c6a6306157837 Mon Sep 17 00:00:00 2001 From: Diana Date: Tue, 15 Oct 2024 16:09:17 -0500 Subject: [PATCH 09/12] Input required, table (class, href, badge) --- template/components/content_table.go | 15 +++++++++------ template/components/content_table.html | 19 ++++++++++++++++--- template/components/form_input.go | 1 + template/components/form_input.html | 3 +++ template/components/page_nav.go | 2 +- template/components/page_nav.html | 2 +- 6 files changed, 31 insertions(+), 11 deletions(-) diff --git a/template/components/content_table.go b/template/components/content_table.go index 66c7e1f..1cb7024 100644 --- a/template/components/content_table.go +++ b/template/components/content_table.go @@ -1,17 +1,20 @@ package components type ContentTable struct { - ID string - AllTH []ContentTableTH - AllTD [][]ContentTableTD + ID string + TableClass string // table-primary, table-secondary,.. table-striped table-bordered + HeadClass string // table-dark table-light + AllTH []ContentTableTH + AllTD [][]ContentTableTD } type ContentTableTH struct { - ID string - Value string + ID string + ValueType string // -> default string, href, badge + Value string } type ContentTableTD struct { ID string - Value string + Value interface{} // string or component struct according ValueType } diff --git a/template/components/content_table.html b/template/components/content_table.html index 68e34f6..ce19344 100644 --- a/template/components/content_table.html +++ b/template/components/content_table.html @@ -1,12 +1,25 @@ {{define "content_table"}} - - +
    + {{range $index, $col := .AllTH}}{{end}} -{{range .AllTD}}{{range .}}{{end}}{{end}} + {{range .AllTD}} + {{range $index, $item := .}} + {{end}} + {{end}}
    {{ $col.Value }}
    {{ .Value }}
    + {{ with $x := index $.AllTH $index }} + {{ if eq $x.ValueType "href"}} + {{template "content_href" $item.Value}} + {{ else if eq $x.ValueType "badge"}} + {{template "content_badge" $item.Value}} + {{ else }} + {{ $item.Value }} + {{end}} + {{end}} +
    {{end}} \ No newline at end of file diff --git a/template/components/form_input.go b/template/components/form_input.go index 0ce7ce4..e27910f 100644 --- a/template/components/form_input.go +++ b/template/components/form_input.go @@ -9,4 +9,5 @@ type FormInput struct { Hint string Error string IsDisabled bool + IsRequired bool } diff --git a/template/components/form_input.html b/template/components/form_input.html index b79ae87..8159896 100644 --- a/template/components/form_input.html +++ b/template/components/form_input.html @@ -5,6 +5,9 @@ {{if eq .IsDisabled true}} disabled {{end}} + {{if eq .IsRequired true}} + required + {{end}} {{if ne .Value ""}} value="{{.Value}}" {{end}} diff --git a/template/components/page_nav.go b/template/components/page_nav.go index 2ed9319..862d1c8 100644 --- a/template/components/page_nav.go +++ b/template/components/page_nav.go @@ -1,7 +1,7 @@ package components type PageNav struct { - NavClass string // nav-pills + NavClass string // nav-pills, nav-underline NavItems []PageNavItem IsVertical bool IsTab bool diff --git a/template/components/page_nav.html b/template/components/page_nav.html index 5bb0b83..08faaf4 100644 --- a/template/components/page_nav.html +++ b/template/components/page_nav.html @@ -8,7 +8,7 @@ class="nav-link dropdown-toggle {{if eq .IsActive true}}active{{end}} {{if eq .IsDisabled true}}disabled{{end}}">{{$item.Text}}
    From bf84e14bb12060a12d9e6581a39b26547823a92c Mon Sep 17 00:00:00 2001 From: Diana Date: Tue, 15 Oct 2024 16:09:31 -0500 Subject: [PATCH 10/12] component list --- template/components/content_list.go | 19 +++++++++++++++++++ template/components/content_list.html | 14 ++++++++++++++ 2 files changed, 33 insertions(+) create mode 100644 template/components/content_list.go create mode 100644 template/components/content_list.html diff --git a/template/components/content_list.go b/template/components/content_list.go new file mode 100644 index 0000000..34bfb49 --- /dev/null +++ b/template/components/content_list.go @@ -0,0 +1,19 @@ +package components + +type ContentList struct { + Items []ContentListItem +} + +type ContentListItem struct { + Text string + Description string + EndElement string + //Link string + TypeClass string // primary, secondary, success, danger, warning, info, light, dark + IsDisabled bool + //IsActive bool +} + +//link +//border +// badge diff --git a/template/components/content_list.html b/template/components/content_list.html new file mode 100644 index 0000000..31af60b --- /dev/null +++ b/template/components/content_list.html @@ -0,0 +1,14 @@ +{{define "content_list"}} +
      + {{ range .Items}} +
    • {{.Text}}

      {{.EndElement}}
      + {{.Description}} +
    • + {{end}} +
    + + + +{{end}} \ No newline at end of file From cc74165659377ebef96443030f33fbeafb9774ff Mon Sep 17 00:00:00 2001 From: Zeni Kim Date: Tue, 15 Oct 2024 22:00:46 -0500 Subject: [PATCH 11/12] add cookie secret as env, fix components --- cookies.go | 49 +++++++++++++++++++++----- template/components/content_table.html | 2 +- template/components/form_textarea.go | 6 ++-- template/components/form_textarea.html | 2 +- 4 files changed, 46 insertions(+), 13 deletions(-) diff --git a/cookies.go b/cookies.go index 87503e7..8c03c10 100644 --- a/cookies.go +++ b/cookies.go @@ -5,10 +5,9 @@ package core import ( + "bytes" "crypto/aes" "crypto/cipher" - - "bytes" "crypto/rand" "encoding/base64" "encoding/gob" @@ -17,6 +16,8 @@ import ( "fmt" "io" "net/http" + "os" + "strconv" "strings" ) @@ -39,9 +40,24 @@ func GetCookie(r *http.Request) (UserCookie, error) { // Create a new instance of a User type. var user UserCookie - secretcookie, err = hex.DecodeString("13d6b4dff8f84a10851021ec8608f814570d562c92fe6b5ec4c9f595bcb3234b") - if err != nil { - return user, err + // check if template engine is enable + TemplateEnableStr := os.Getenv("TEMPLATE_ENABLE") + if TemplateEnableStr == "" { + TemplateEnableStr = "false" + } + TemplateEnable, _ := strconv.ParseBool(TemplateEnableStr) + // if enabled, + if TemplateEnable { + cookie_secret := os.Getenv("COOKIE_SECRET") + if cookie_secret == "" { + panic("cookie secret key is not set") + } + secretcookie, err = hex.DecodeString(cookie_secret) + if err != nil { + return user, err + } + } else { + panic("Templates are disabled") } gobEncodedValue, err := CookieReadEncrypted(r, "goffee", secretcookie) @@ -67,7 +83,26 @@ func SetCookie(w http.ResponseWriter, email string, token string) error { // cookie. var err error - secretcookie, err = hex.DecodeString("13d6b4dff8f84a10851021ec8608f814570d562c92fe6b5ec4c9f595bcb3234b") + // check if template engine is enable + TemplateEnableStr := os.Getenv("TEMPLATE_ENABLE") + if TemplateEnableStr == "" { + TemplateEnableStr = "false" + } + TemplateEnable, _ := strconv.ParseBool(TemplateEnableStr) + // if enabled, + if TemplateEnable { + cookie_secret := os.Getenv("COOKIE_SECRET") + if cookie_secret == "" { + panic("cookie secret key is not set") + } + secretcookie, err = hex.DecodeString(cookie_secret) + if err != nil { + return err + } + } else { + panic("Templates are disabled") + } + if err != nil { return err } @@ -101,8 +136,6 @@ func SetCookie(w http.ResponseWriter, email string, token string) error { return err } - fmt.Printf("Cookie set %v\n", email) - return nil } diff --git a/template/components/content_table.html b/template/components/content_table.html index 68e34f6..f7c2f89 100644 --- a/template/components/content_table.html +++ b/template/components/content_table.html @@ -6,7 +6,7 @@ -{{range .AllTD}}{{range .}}{{ .Value }}{{end}}{{end}} +{{- range .AllTD}}{{range .}}{{ .Value }}{{end}}{{- end}} {{end}} \ No newline at end of file diff --git a/template/components/form_textarea.go b/template/components/form_textarea.go index 8fbaf51..818ae02 100644 --- a/template/components/form_textarea.go +++ b/template/components/form_textarea.go @@ -1,7 +1,7 @@ package components type FormTextarea struct { - ID string - Label string - AllOptions []FormSelectOption + ID string + Label string + Value string } diff --git a/template/components/form_textarea.html b/template/components/form_textarea.html index 5372a42..23559ab 100644 --- a/template/components/form_textarea.html +++ b/template/components/form_textarea.html @@ -1,6 +1,6 @@ {{define "form_textarea"}}
    - +
    {{end}} \ No newline at end of file From be138b2fb4b5e983a35129a598e3a11a8c01e337 Mon Sep 17 00:00:00 2001 From: Zeni Kim Date: Tue, 15 Oct 2024 22:15:20 -0500 Subject: [PATCH 12/12] add middle line --- template/components/content_table.html | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/template/components/content_table.html b/template/components/content_table.html index ce19344..2bf559d 100644 --- a/template/components/content_table.html +++ b/template/components/content_table.html @@ -6,7 +6,7 @@ - {{range .AllTD}} + {{- range .AllTD}} {{range $index, $item := .}} {{ with $x := index $.AllTH $index }} {{ if eq $x.ValueType "href"}} @@ -19,7 +19,7 @@ {{end}} {{end}} - {{end}} + {{- end}} -{{end}} \ No newline at end of file +{{end}}