diff --git a/back/Makefile b/back/Makefile deleted file mode 100644 index 0077d71..0000000 --- a/back/Makefile +++ /dev/null @@ -1,2 +0,0 @@ -build: - go build -o bin/server cmd/server/main.go \ No newline at end of file diff --git a/back/bin/server b/back/bin/server deleted file mode 100755 index 1ff6ac6..0000000 Binary files a/back/bin/server and /dev/null differ diff --git a/back/cmd/server/main.go b/back/cmd/server/main.go deleted file mode 100644 index c591f8e..0000000 --- a/back/cmd/server/main.go +++ /dev/null @@ -1,35 +0,0 @@ -package main - -import ( - "flag" - "fmt" - "net/http" - "netoik.io/netoik-website/pkg/captcha" - "netoik.io/netoik-website/pkg/conf" - "netoik.io/netoik-website/pkg/contact" - "os" -) - -func main() { - // Parse command line arguments - path := flag.String("c", "server.conf", "Config file") - flag.Parse() - - // Parse config file - if !conf.ParseFile(*path) { - os.Exit(1) - } - - // Setup captcha - captcha.Setup() - - // Declare api routes - http.HandleFunc("/api/contact/send", contact.HandleSend) - http.HandleFunc("/api/captcha/new", captcha.HandleNew) - - // Start listening - if err := http.ListenAndServe(fmt.Sprintf("%s:%d", conf.Conf.BindHost, conf.Conf.BindPort), nil); err != nil { - fmt.Fprintf(os.Stderr, "cannot listen at %s:%d: %s\n", conf.Conf.BindHost, conf.Conf.BindPort, err.Error()) - os.Exit(1) - } -} diff --git a/back/go.mod b/back/go.mod deleted file mode 100644 index 9cfb7a6..0000000 --- a/back/go.mod +++ /dev/null @@ -1,10 +0,0 @@ -module netoik.io/netoik-website - -go 1.18 - -require ( - github.com/dchest/captcha v0.0.0-20200903113550-03f5f0333e1f // indirect - github.com/pelletier/go-toml v1.9.5 // indirect - gopkg.in/alexcesaro/quotedprintable.v3 v3.0.0-20150716171945-2caba252f4dc // indirect - gopkg.in/gomail.v2 v2.0.0-20160411212932-81ebce5c23df // indirect -) diff --git a/back/go.sum b/back/go.sum deleted file mode 100644 index e2d36b8..0000000 --- a/back/go.sum +++ /dev/null @@ -1,8 +0,0 @@ -github.com/dchest/captcha v0.0.0-20200903113550-03f5f0333e1f h1:q/DpyjJjZs94bziQ7YkBmIlpqbVP7yw179rnzoNVX1M= -github.com/dchest/captcha v0.0.0-20200903113550-03f5f0333e1f/go.mod h1:QGrK8vMWWHQYQ3QU9bw9Y9OPNfxccGzfb41qjvVeXtY= -github.com/pelletier/go-toml v1.9.5 h1:4yBQzkHv+7BHq2PQUZF3Mx0IYxG7LsP222s7Agd3ve8= -github.com/pelletier/go-toml v1.9.5/go.mod h1:u1nR/EPcESfeI/szUZKdtJ0xRNbUoANCkoOuaOx1Y+c= -gopkg.in/alexcesaro/quotedprintable.v3 v3.0.0-20150716171945-2caba252f4dc h1:2gGKlE2+asNV9m7xrywl36YYNnBG5ZQ0r/BOOxqPpmk= -gopkg.in/alexcesaro/quotedprintable.v3 v3.0.0-20150716171945-2caba252f4dc/go.mod h1:m7x9LTH6d71AHyAX77c9yqWCCa3UKHcVEj9y7hAtKDk= -gopkg.in/gomail.v2 v2.0.0-20160411212932-81ebce5c23df h1:n7WqCuqOuCbNr617RXOY0AWRXxgwEyPp2z+p0+hgMuE= -gopkg.in/gomail.v2 v2.0.0-20160411212932-81ebce5c23df/go.mod h1:LRQQ+SO6ZHR7tOkpBDuZnXENFzX8qRjMDMyPD6BRkCw= diff --git a/back/pkg/api/api.go b/back/pkg/api/api.go deleted file mode 100644 index 6a76c5f..0000000 --- a/back/pkg/api/api.go +++ /dev/null @@ -1,18 +0,0 @@ -package api - -import ( - "encoding/json" - "net/http" -) - -type Answer struct { - Success bool `json:"success"` - Id string `json:"id,omitempty"` -} - -func Reply(w http.ResponseWriter, code int, answer Answer) { - a, _ := json.Marshal(answer) - w.Header().Set(http.CanonicalHeaderKey("content-type"), "application/json") - w.WriteHeader(code) - w.Write(a) -} diff --git a/back/pkg/captcha/captcha.go b/back/pkg/captcha/captcha.go deleted file mode 100644 index 6fb752b..0000000 --- a/back/pkg/captcha/captcha.go +++ /dev/null @@ -1,60 +0,0 @@ -package captcha - -import ( - "errors" - "fmt" - "github.com/dchest/captcha" - "net/http" - "netoik.io/netoik-website/pkg/api" - "netoik.io/netoik-website/pkg/conf" - "os" - "path/filepath" - "time" -) - -func writeImage(id string) bool { - path := filepath.Join(conf.Conf.CaptchaDirectory, id+".png") - file, err := os.Create(path) - if err != nil { - fmt.Fprintf(os.Stderr, "ERROR: cannot write file %q: %s\n", path, err.Error()) - return false - } - if err = captcha.WriteImage(file, id, conf.Conf.CaptchaWidth, conf.Conf.CaptchaHeight); err != nil { - fmt.Fprintf(os.Stderr, "ERROR: cannot write captcha into file %q: %s\n", path, err.Error()) - return false - } - return true -} - -func HandleNew(w http.ResponseWriter, r *http.Request) { - // Check method - if r.Method != "POST" { - api.Reply(w, 405, api.Answer{}) - return - } - - // Create new captcha - id := captcha.NewLen(conf.Conf.CaptchaLength) - - // Write captcha image - if !writeImage(id) { - api.Reply(w, 500, api.Answer{}) - return - } - - // Remove captcha image after expiration time - go func(id string) { - time.Sleep(conf.Conf.CaptchaExpiration) - path := filepath.Join(conf.Conf.CaptchaDirectory, id+".png") - if err := os.Remove(path); err != nil && !errors.Is(err, os.ErrNotExist) { - fmt.Fprintf(os.Stderr, "ERROR: cannot remove captcha image after expiration %q: %s", path, err.Error()) - } - }(id) - - // Return captcha id - api.Reply(w, 200, api.Answer{Success: true, Id: id}) -} - -func Setup() { - captcha.SetCustomStore(captcha.NewMemoryStore(captcha.CollectNum, conf.Conf.CaptchaExpiration)) -} diff --git a/back/pkg/conf/conf.go b/back/pkg/conf/conf.go deleted file mode 100644 index e6bba03..0000000 --- a/back/pkg/conf/conf.go +++ /dev/null @@ -1,108 +0,0 @@ -package conf - -import ( - "fmt" - "github.com/pelletier/go-toml" - "net" - "os" - "time" -) - -type conf struct { - BindHost string `toml:"bind_host"` - BindPort int `toml:"bind_port"` - - SMTPHost string `toml:"smtp_host"` - SMTPPort int `toml:"smtp_port"` - SMTPUsername string `toml:"smtp_username"` - SMTPPassword string `toml:"smtp_password"` - SMTPReceiver string `toml:"smtp_receiver"` - - CaptchaDirectory string `toml:"captcha_directory"` - CaptchaLength int `toml:"captcha_length"` - CaptchaWidth int `toml:"captcha_width"` - CaptchaHeight int `toml:"captcha_height"` - CaptchaExpiration time.Duration `toml:"captcha_expiration"` -} - -var Conf = conf{ - BindHost: "127.0.0.1", - BindPort: 8000, - CaptchaLength: 6, - CaptchaWidth: 240, - CaptchaHeight: 80, - CaptchaExpiration: time.Hour, -} - -func ParseFile(path string) bool { - var failure bool - - // Open config file - file, err := os.Open(path) - if err != nil { - fmt.Fprintf(os.Stderr, "ERROR: cannot open config file %q: %s\n", path, err.Error()) - return false - } - - // Read data from config file - var data = make([]byte, 10000) - n, err := file.Read(data) - if err != nil { - fmt.Fprintf(os.Stderr, "ERROR: cannot read config file %q: %s\n", path, err.Error()) - return false - } - - // Parse toml from config file - if err = toml.Unmarshal(data[:n], &Conf); err != nil { - fmt.Fprintf(os.Stderr, "ERROR: cannot load toml config from file %q: %s\n", path, err.Error()) - return false - } - - // Check arguments in config file - if net.ParseIP(Conf.BindHost) == nil { - fmt.Fprintf(os.Stderr, "ERROR: bad value for 'bind_host' in config file %q: should be a valid IP address\n", path) - failure = true - } - if Conf.BindPort < 1 || Conf.BindPort > 65535 { - fmt.Fprintf(os.Stderr, "ERROR: bad value for 'bind_port' in config file %q: should be an integer in 1-65535\n", path) - failure = true - } - if Conf.SMTPHost == "" { - fmt.Fprintf(os.Stderr, "ERROR: missing value for 'smtp_host' in config file %q\n", path) - failure = true - } - if Conf.SMTPPort < 1 || Conf.SMTPPort > 65535 { - fmt.Fprintf(os.Stderr, "ERROR: bad value for 'smtp_port' in config file %q: should be an integer in 1-65535\n", path) - failure = true - } - if Conf.SMTPUsername == "" { - fmt.Fprintf(os.Stderr, "ERROR: missing value for 'smtp_username' in config file %q\n", path) - failure = true - } - if Conf.SMTPPassword == "" { - fmt.Fprintf(os.Stderr, "ERROR: missing value for 'smtp_password' in config file %q\n", path) - failure = true - } - if Conf.SMTPReceiver == "" { - fmt.Fprintf(os.Stderr, "ERROR: missing value for 'smtp_receiver' in config file %q\n", path) - failure = true - } - if Conf.CaptchaDirectory == "" { - fmt.Fprintf(os.Stderr, "ERROR: missing value for 'captcha_directory' in config file %q\n", path) - failure = true - } - if Conf.CaptchaLength == 0 { - fmt.Fprintf(os.Stderr, "ERROR: missing value for 'captcha_length' in config file %q\n", path) - failure = true - } - if Conf.CaptchaWidth == 0 { - fmt.Fprintf(os.Stderr, "ERROR: missing value for 'captcha_width' in config file %q\n", path) - failure = true - } - if Conf.CaptchaHeight == 0 { - fmt.Fprintf(os.Stderr, "ERROR: missing value for 'captcha_height' in config file %q\n", path) - failure = true - } - - return !failure -} diff --git a/back/pkg/contact/contact.go b/back/pkg/contact/contact.go deleted file mode 100644 index 49dc240..0000000 --- a/back/pkg/contact/contact.go +++ /dev/null @@ -1,97 +0,0 @@ -package contact - -import ( - "encoding/json" - "errors" - "fmt" - "github.com/dchest/captcha" - "gopkg.in/gomail.v2" - "net/http" - "netoik.io/netoik-website/pkg/api" - "netoik.io/netoik-website/pkg/conf" - "os" - "path/filepath" -) - -type request struct { - Name string `json:"name"` - Email string `json:"email"` - Phone string `json:"phone"` - Company string `json:"company"` - Message string `json:"message"` - CaptchaId string `json:"captchaId"` - CaptchaDigits string `json:"captchaDigits"` -} - -func HandleSend(w http.ResponseWriter, r *http.Request) { - // Check method - if r.Method != "POST" { - api.Reply(w, 405, api.Answer{}) - return - } - - // Parse json from request body - var data request - if err := json.NewDecoder(r.Body).Decode(&data); err != nil { - api.Reply(w, 400, api.Answer{}) - return - } - if data.Name == "" || len(data.Name) > 200 { - api.Reply(w, 400, api.Answer{}) - return - } - if data.Email == "" || len(data.Email) > 200 { - api.Reply(w, 400, api.Answer{}) - return - } - if len(data.Phone) > 200 { - api.Reply(w, 400, api.Answer{}) - return - } - if len(data.Company) > 200 { - api.Reply(w, 400, api.Answer{}) - return - } - if data.Message == "" || len(data.Message) > 10000 { - api.Reply(w, 400, api.Answer{}) - return - } - if data.CaptchaId == "" { - api.Reply(w, 400, api.Answer{}) - return - } - if data.CaptchaDigits == "" { - api.Reply(w, 400, api.Answer{}) - return - } - - // Check captcha digits - if !captcha.VerifyString(data.CaptchaId, data.CaptchaDigits) { - api.Reply(w, 418, api.Answer{}) - return - } - - // Captcha has been verified, so remove image - path := filepath.Join(conf.Conf.CaptchaDirectory, data.CaptchaId+".png") - if err := os.Remove(path); err != nil && !errors.Is(err, os.ErrNotExist) { - fmt.Fprintf(os.Stderr, "ERROR: cannot remove captcha image %q: %s", path, err.Error()) - } - - // Build email - msg := gomail.NewMessage() - msg.SetHeader("From", conf.Conf.SMTPUsername) - msg.SetHeader("To", conf.Conf.SMTPReceiver) - msg.SetHeader("Subject", "Message from www.netoik.io") - msg.SetBody("text/plain", fmt.Sprintf( - "You have received a message from frontend.\nname: %s\nemail: %s\nphone: %s\ncompany: %s\n%s", - data.Name, data.Email, data.Phone, data.Company, data.Message)) - - // Configure SMTP dialer and send email - dialer := gomail.NewDialer(conf.Conf.SMTPHost, conf.Conf.SMTPPort, conf.Conf.SMTPUsername, conf.Conf.SMTPPassword) - if err := dialer.DialAndSend(msg); err != nil { - fmt.Fprintf(os.Stderr, "cannot send email: %s\n", err.Error()) - api.Reply(w, 400, api.Answer{}) - return - } - api.Reply(w, 200, api.Answer{Success: true}) -} diff --git a/front/assets/bootstrap-5.1.3/bootstrap.bundle.min.js b/src/assets/bootstrap-5.1.3/bootstrap.bundle.min.js similarity index 100% rename from front/assets/bootstrap-5.1.3/bootstrap.bundle.min.js rename to src/assets/bootstrap-5.1.3/bootstrap.bundle.min.js diff --git a/front/assets/bootstrap-5.1.3/sb-forms-latest.js b/src/assets/bootstrap-5.1.3/sb-forms-latest.js similarity index 100% rename from front/assets/bootstrap-5.1.3/sb-forms-latest.js rename to src/assets/bootstrap-5.1.3/sb-forms-latest.js diff --git a/front/assets/css/styles.css b/src/assets/css/styles.css similarity index 100% rename from front/assets/css/styles.css rename to src/assets/css/styles.css diff --git a/front/assets/css/vars.css b/src/assets/css/vars.css similarity index 100% rename from front/assets/css/vars.css rename to src/assets/css/vars.css diff --git a/front/assets/docs/cv.pdf b/src/assets/docs/cv.pdf similarity index 100% rename from front/assets/docs/cv.pdf rename to src/assets/docs/cv.pdf diff --git a/front/assets/docs/master-cryptis.pdf b/src/assets/docs/master-cryptis.pdf similarity index 100% rename from front/assets/docs/master-cryptis.pdf rename to src/assets/docs/master-cryptis.pdf diff --git a/front/assets/fontawesome-6.1.1/all.min.css b/src/assets/fontawesome-6.1.1/all.min.css similarity index 100% rename from front/assets/fontawesome-6.1.1/all.min.css rename to src/assets/fontawesome-6.1.1/all.min.css diff --git a/front/assets/fontawesome-6.1.1/all.min.js b/src/assets/fontawesome-6.1.1/all.min.js similarity index 100% rename from front/assets/fontawesome-6.1.1/all.min.js rename to src/assets/fontawesome-6.1.1/all.min.js diff --git a/front/assets/googleapis/roboto b/src/assets/googleapis/roboto similarity index 100% rename from front/assets/googleapis/roboto rename to src/assets/googleapis/roboto diff --git a/front/assets/img/captcha/loading.png b/src/assets/img/captcha/loading.png similarity index 100% rename from front/assets/img/captcha/loading.png rename to src/assets/img/captcha/loading.png diff --git a/front/assets/img/captcha/unavailable.png b/src/assets/img/captcha/unavailable.png similarity index 100% rename from front/assets/img/captcha/unavailable.png rename to src/assets/img/captcha/unavailable.png diff --git a/front/assets/img/codingame-black.png b/src/assets/img/codingame-black.png similarity index 100% rename from front/assets/img/codingame-black.png rename to src/assets/img/codingame-black.png diff --git a/front/assets/img/codingame-white.png b/src/assets/img/codingame-white.png similarity index 100% rename from front/assets/img/codingame-white.png rename to src/assets/img/codingame-white.png diff --git a/front/assets/img/codingame.png b/src/assets/img/codingame.png similarity index 100% rename from front/assets/img/codingame.png rename to src/assets/img/codingame.png diff --git a/front/assets/img/netoik-favicon-white.svg b/src/assets/img/netoik-favicon-white.svg similarity index 100% rename from front/assets/img/netoik-favicon-white.svg rename to src/assets/img/netoik-favicon-white.svg diff --git a/front/assets/img/netoik-linkedin.png b/src/assets/img/netoik-linkedin.png similarity index 100% rename from front/assets/img/netoik-linkedin.png rename to src/assets/img/netoik-linkedin.png diff --git a/front/assets/img/netoik-title.svg b/src/assets/img/netoik-title.svg similarity index 100% rename from front/assets/img/netoik-title.svg rename to src/assets/img/netoik-title.svg diff --git a/front/assets/img/profil.png b/src/assets/img/profil.png similarity index 100% rename from front/assets/img/profil.png rename to src/assets/img/profil.png diff --git a/front/assets/img/services/cybersecurity.svg b/src/assets/img/services/cybersecurity.svg similarity index 100% rename from front/assets/img/services/cybersecurity.svg rename to src/assets/img/services/cybersecurity.svg diff --git a/front/assets/img/services/database.svg b/src/assets/img/services/database.svg similarity index 100% rename from front/assets/img/services/database.svg rename to src/assets/img/services/database.svg diff --git a/front/assets/img/services/programming.svg b/src/assets/img/services/programming.svg similarity index 100% rename from front/assets/img/services/programming.svg rename to src/assets/img/services/programming.svg diff --git a/front/assets/jquery-3.6.0/jquery-3.6.0.min.js b/src/assets/jquery-3.6.0/jquery-3.6.0.min.js similarity index 100% rename from front/assets/jquery-3.6.0/jquery-3.6.0.min.js rename to src/assets/jquery-3.6.0/jquery-3.6.0.min.js diff --git a/front/assets/js/scripts.js b/src/assets/js/scripts.js similarity index 100% rename from front/assets/js/scripts.js rename to src/assets/js/scripts.js diff --git a/front/favicon.ico b/src/favicon.ico similarity index 100% rename from front/favicon.ico rename to src/favicon.ico diff --git a/front/index.html b/src/index.html similarity index 100% rename from front/index.html rename to src/index.html diff --git a/front/share/cg/index.html b/src/share/cg/index.html similarity index 100% rename from front/share/cg/index.html rename to src/share/cg/index.html diff --git a/front/share/in/index.html b/src/share/in/index.html similarity index 100% rename from front/share/in/index.html rename to src/share/in/index.html