diff --git a/static/canvas.js b/static/canvas.js index 236e9cb..ab521a2 100644 --- a/static/canvas.js +++ b/static/canvas.js @@ -17,6 +17,9 @@ let image = new ImageData(DATA_SIZE, DATA_SIZE); let bitmap = null; window.addEventListener("load", async (e) => { + for (let x = 0; x < DATA_SIZE * DATA_SIZE * 4; x++) { + image.data[x] = 255; + } // Create drawable image, update it every half second await redraw(); setInterval(redraw, 500); @@ -46,17 +49,28 @@ function draw() { ctx.setTransform(1, 0, 0, 1, 0, 0); } +function mousePosition(e) { + let x = e.clientX - canvas.getBoundingClientRect().left; + let y = e.clientY - canvas.getBoundingClientRect().top; + let cx = Math.round(x / (CANVAS_SIZE * scale) * DATA_SIZE - offx - 0.5); + let cy = Math.round(y / (CANVAS_SIZE * scale) * DATA_SIZE - offy - 0.5); + return {x: cx, y: cy}; +} + canvas.addEventListener("wheel", async (e) => { + let mouse = mousePosition(e); + console.log(mouse); let oldScale = scale; if (e.deltaY < 0) { scale += 0.1; } else if (e.deltaY > 0) { scale -= 0.1; } - /* - offX += (DATA_SIZE * scale - DATA_SIZE * oldScale) / 2; - offY += (DATA_SIZE * scale - DATA_SIZE * oldScale) / 2; - */ + let diff = (CANVAS_SIZE / oldScale) - (CANVAS_SIZE / scale); + let ratiox = (mouse.x - (CANVAS_SIZE / 2)) / CANVAS_SIZE; + let ratioy = (mouse.y - (CANVAS_SIZE / 2)) / CANVAS_SIZE; + offx += diff * ratiox; + offy += diff * ratioy; draw(image); }); @@ -77,17 +91,12 @@ canvas.addEventListener("mousedown", async (e) => { canvas.addEventListener("mouseup", async (e) => { if (e.button == 0 && mouseClicked) { mouseClicked = false; - clickx = e.clientX; clicky = e.clientY; - - let x = e.clientX - canvas.getBoundingClientRect().left; - let y = e.clientY - canvas.getBoundingClientRect().top; - - let cx = Math.round(x / (CANVAS_SIZE * scale) * DATA_SIZE - offx); - let cy = Math.round(y / (CANVAS_SIZE * scale) * DATA_SIZE - offy); + let mouse = mousePosition(e); + let cx = mouse.x; + let cy = mouse.y; - console.log(cx, cy); if (cx < 0 || cx > CANVAS_SIZE || cy < 0 || cy > CANVAS_SIZE) { return; } diff --git a/static/contact.css b/static/contact.css new file mode 100644 index 0000000..4106807 --- /dev/null +++ b/static/contact.css @@ -0,0 +1,55 @@ +body { + margin: 0; + } + + html { + box-sizing: border-box; + } + + *, *:before, *:after { + box-sizing: inherit; + } + + .column { + float: left; + width: 33.3%; + margin-bottom: 16px; + padding: 0 8px; + } + + .card { + box-shadow: 0 4px 8px 0 rgba(0, 0, 0, 0.2); + margin: 8px; + } + + .about-section { + padding: 30px; + text-align: center; + background-color: #bf7016; + color: white; + } + + .container { + padding: 0 16px; + } + + .container::after, .row::after { + content: ""; + clear: both; + display: table; + } + + .title { + color: grey; + } + + .button:hover { + background-color: #555; + } + + @media screen and (max-width: 650px) { + .column { + width: 100%; + display: block; + } + } \ No newline at end of file diff --git a/static/contact.html b/static/contact.html new file mode 100644 index 0000000..1ba69a1 --- /dev/null +++ b/static/contact.html @@ -0,0 +1,95 @@ + + + + + + Contact + + + + + +
+

About Us / Contact Page

+

Who are we??

+
+ +

Team

+ +
+
+
+ Joe +
+

Joe

+

back-end

+

Lorem ipsum dolor sit amet.

+

joe@Placeholders.com

+
+
+
+ +
+
+ Joe2 +
+

Joe 2

+

front-end

+

Lorem ipsum dolor sit amet.

+

joe2@Placeholders.com

+
+
+
+ +
+
+ Joe3 +
+

Joe 3

+

stinky

+

Lorem ipsum dolor sit amet.

+

joe3@Placeholders.com

+
+
+
+
+ +
+
+
+ Joe4 +
+

Joe4

+

back-end

+

Lorem ipsum dolor sit amet.

+

joe@Placeholders.com

+
+
+
+ +
+
+ Joe5 +
+

Joe 5

+

front-end

+

Lorem ipsum dolor sit amet.

+

joe2@Placeholders.com

+
+
+
+ +
+
+ Joe6 +
+

Joe 6

+

stinky

+

Lorem ipsum dolor sit amet.

+

joe3@Placeholders.com

+
+
+
+
+ + \ No newline at end of file diff --git a/static/index.html b/static/index.html index 21eff23..c48741e 100644 --- a/static/index.html +++ b/static/index.html @@ -16,7 +16,6 @@
  • Register
  • -
  • Login
  • @@ -37,6 +36,9 @@ Secret +
  • + Contact +
  • - + \ No newline at end of file diff --git a/users.go b/users.go index 8df9f2b..6048f13 100644 --- a/users.go +++ b/users.go @@ -11,10 +11,9 @@ import ( ) const SESSION_COOKIE_NAME = "utsa-place-session" +const SESSION_EMAIL = "email" const SESSION_AUTH = "auth" const SESSION_STARTED = "age" -const SESSION_CONFIRMED = "confirmed" -const SESSION_CONFIRM_KEY = "confirm-key" const ENCRYPTION_STRENGTH = 14 @@ -23,11 +22,13 @@ type UserData struct { Password string AccountCreated time.Time LastLogin time.Time + EmailCode string + Verified bool } func validate_email(email string) (string, bool) { email = strings.ToLower(email) - regex := regexp.MustCompile("^[a-z]+.[a-z]+@(my.)?utsa.edu") + regex := regexp.MustCompile("^[a-z0-9]+.[a-z0-9]+@(my.)?utsa.edu") ok := regex.MatchString(email) return email, ok } @@ -51,7 +52,7 @@ func (s *Server) handle_login(w http.ResponseWriter, r *http.Request) { http.ServeFile(w, r, "./static/login.html") case http.MethodPost: // Get data from form - email := r.FormValue("email") + email := strings.ToLower(r.FormValue("email")) password := r.FormValue("password") // Get user from database user, ok := s.Users[email] @@ -75,9 +76,15 @@ func (s *Server) handle_login(w http.ResponseWriter, r *http.Request) { now := time.Now() session.Values[SESSION_AUTH] = true session.Values[SESSION_STARTED] = now.String() + session.Values[SESSION_EMAIL] = user.Email session.Save(r, w) // Update last-login on DB user.LastLogin = now + // If email not verified, go to verified page + if user.Verified { + s.handle_confirmation(w, r) + return + } s.Users[email] = user // Redirect to index.html fmt.Println("Logged in user: ", email) @@ -124,12 +131,13 @@ func (s *Server) handle_register(w http.ResponseWriter, r *http.Request) { Password: hash_password(password), AccountCreated: now, LastLogin: now, + EmailCode: "123456", + Verified: false, } // Make session valid session.Values[SESSION_AUTH] = true session.Values[SESSION_STARTED] = now.String() - session.Values[SESSION_CONFIRMED] = false - session.Values[SESSION_CONFIRM_KEY] = "asdf" + session.Values[SESSION_EMAIL] = email // Send session token to browser session.Save(r, w) // Redirect to index.html @@ -147,17 +155,26 @@ func (s *Server) handle_confirmation(w http.ResponseWriter, r *http.Request) { http.Redirect(w, r, "/register", http.StatusFound) return } + email := session.Values[SESSION_EMAIL].(string) + user, ok := s.Users[email] + if !ok { + return + } switch r.Method { case http.MethodGet: - confirmed := session.Values[SESSION_CONFIRMED].(bool) - fmt.Println("User email confirmed: ", confirmed) - if confirmed { + fmt.Println("User email confirmed: ", user.Verified) + if user.Verified { http.Redirect(w, r, "/", http.StatusFound) } else { http.ServeFile(w, r, "./static/confirmation.html") } case http.MethodPost: - default: + code := r.FormValue("code") + if user.EmailCode == code { + http.Redirect(w, r, "/", http.StatusAccepted) + } else { + http.Redirect(w, r, "/confirm-email", http.StatusForbidden) + } } }