From 41f931a075b38ddaa76797b362a1b7939648e93c Mon Sep 17 00:00:00 2001 From: Hamilton Sands Date: Thu, 14 Jun 2018 19:44:23 -0400 Subject: [PATCH 1/7] solution from previous clone --- loginpage/Gemfile | 5 ++- loginpage/Gemfile.lock | 24 +++++++----- loginpage/config.ru | 2 +- loginpage/login_page.rb | 13 ++++--- loginpage/public/css/app.css | 75 ++++++++++++++++++++++++++++++++++++ loginpage/public/js/app.js | 52 +++++++++++++++++++++++++ loginpage/views/index.erb | 69 ++++++++++++++++++++++++++------- 7 files changed, 208 insertions(+), 32 deletions(-) diff --git a/loginpage/Gemfile b/loginpage/Gemfile index 3cd5dc8..4a5df82 100644 --- a/loginpage/Gemfile +++ b/loginpage/Gemfile @@ -1,4 +1,5 @@ source 'https://rubygems.org' -gem 'sinatra', '~> 1.4.5' -gem 'puma' \ No newline at end of file +# gem 'sinatra', '~> 1.4.5' +gem 'sinatra', '2.0.0' +gem 'puma' diff --git a/loginpage/Gemfile.lock b/loginpage/Gemfile.lock index 74471c5..01dc348 100644 --- a/loginpage/Gemfile.lock +++ b/loginpage/Gemfile.lock @@ -1,20 +1,24 @@ GEM remote: https://rubygems.org/ specs: - puma (2.8.2) - rack (>= 1.1, < 2.0) - rack (1.5.2) - rack-protection (1.5.3) + mustermann (1.0.2) + puma (3.11.4) + rack (2.0.5) + rack-protection (2.0.0) rack - sinatra (1.4.5) - rack (~> 1.4) - rack-protection (~> 1.4) - tilt (~> 1.3, >= 1.3.4) - tilt (1.4.1) + sinatra (2.0.0) + mustermann (~> 1.0) + rack (~> 2.0) + rack-protection (= 2.0.0) + tilt (~> 2.0) + tilt (2.0.8) PLATFORMS ruby DEPENDENCIES puma - sinatra (~> 1.4.5) + sinatra (= 2.0.0) + +BUNDLED WITH + 1.15.4 diff --git a/loginpage/config.ru b/loginpage/config.ru index 55975a6..28be456 100644 --- a/loginpage/config.ru +++ b/loginpage/config.ru @@ -1,2 +1,2 @@ require './login_page' -run LoginPage \ No newline at end of file +run LoginPage diff --git a/loginpage/login_page.rb b/loginpage/login_page.rb index cabee89..a07fc41 100644 --- a/loginpage/login_page.rb +++ b/loginpage/login_page.rb @@ -8,13 +8,16 @@ class LoginPage < Sinatra::Base end post('/login') do - puts " Email: #{params[:email]}" - puts "Password: #{params[:password]}" - - if true + if (user_params["email"] == "admin@example.com" && user_params["password"] == "password123") [200, "success"] else [400, "failure"] end end -end \ No newline at end of file + +end + +def user_params + permitted_fields = ["email", "password"] + params["user"].select {|k,v| permitted_fields.include?(k)} +end diff --git a/loginpage/public/css/app.css b/loginpage/public/css/app.css index e69de29..7ddefc1 100644 --- a/loginpage/public/css/app.css +++ b/loginpage/public/css/app.css @@ -0,0 +1,75 @@ +html, body { + height: 100%; + color: #eeeeee; + text-align: center; +} + +body { + display: flex; + flex-direction: column; + justify-content: space-between; + /*pushes footer to bottom */ +} + +.bg { + background: linear-gradient(rgba(0, 0, 0, 0.5), rgba(0, 0, 0, 0.5)), url("/img/Blue_sky_and_green_grass-wide.jpg"); + height: 100%; + background-position: center; + background-attachment: fixed; + background-repeat: no-repeat; + background-size: cover; +} + +.upcase { + text-transform: uppercase; +} + +main { + height: 90%; + max-width: 800px; + display: flex; + flex-direction: column; + justify-content: center; +} + +summary { + font-size: 16px; +} + +#form-box { + margin-top: 40px; +} + +#user-message { + margin-bottom: 10px; +} + +/* Various tweaks to bootsrap for the form */ +.column { + display: flex; + flex-direction: column; +} + +.form-inline .form-group{ + vertical-align: top; +} + +.right { + float: right; +} + +.form-check { + margin-top: 5px; +} + +.hidden { + visibility: hidden; +} + +.red { + color: red; +} + +.green { + color: #00dd00; +} diff --git a/loginpage/public/js/app.js b/loginpage/public/js/app.js index e69de29..602d40f 100644 --- a/loginpage/public/js/app.js +++ b/loginpage/public/js/app.js @@ -0,0 +1,52 @@ +$("#login-form").on("submit", (e)=> { + e.preventDefault(); + let noEmptyFields = true; + + $("#emailInput, #passwordInput").each((index, input) => { + input = $(input); + if (input.val() === "") { + input.parent().addClass("has-error has-feedback"); //use bootsrap error css + $(`#${input.attr("id")}Glyph`).removeClass("hidden"); //make alert glyph visible + input.attr("placeholder", "Field cannot be empty"); //use placeholder to message user + noEmptyFields = false; + } else if (input.attr("id") == "emailInput" && !emailRegex(input.val())) { + input.parent().addClass("has-error has-feedback"); + input.val(""); + $(`#${input.attr("id")}Glyph`).removeClass("hidden"); + input.attr("placeholder", "Must enter a valid email"); + noEmptyFields = false; + } else { + input.parent().removeClass("has-error has-feedback"); + $(`#${input.attr("id")}Glyph`).addClass("hidden"); + input.attr("placeholder", ""); //reset any previous error messages + } + }); + + if (noEmptyFields) { + signIn({ + email: $("#emailInput").val(), + password: $("#passwordInput").val(), + }) + .done(() => messageUser("You have succesfully logged in", ["green","red"])) + .fail(() => messageUser("You have entered an invalid username or password", ["red", "green"])); + } +}); + +const emailRegex = (str) => { + // Borrowed from http://emailregex.com/ + return str.match(/^(([^<>()\[\]\\.,;:\s@"]+(\.[^<>()\[\]\\.,;:\s@"]+)*)|(".+"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/); +}; + +const signIn = (user) => { + return $.ajax({ + method: 'post', + url: "/login", + data: {user} + }); +}; + +const messageUser = (message, classNames) => { + $("#user-message").html(message); + $("#user-message").addClass(classNames[0]); + $("#user-message").removeClass(classNames[1] + " hidden"); +}; diff --git a/loginpage/views/index.erb b/loginpage/views/index.erb index eb04aaa..3642bda 100644 --- a/loginpage/views/index.erb +++ b/loginpage/views/index.erb @@ -19,29 +19,70 @@ - + +
-

Big Title Heading For This Page

+
+
+

Welcome to Micrsoft's Github XP

+
-

Subtitle Goes Here

+

Things Just Got Worse

-

Add Welcome message/instructions here. Cow beef drumstick ball tip. Kielbasa pastrami flank ribeye pig chicken bacon kevin. Prosciutto ham t-bone kielbasa jerky salami pig jowl drumstick tongue bacon biltong pastrami. Pastrami short ribs pancetta, spare ribs swine bacon beef drumstick shankle landjaeger ground round bresaola pig turkey ball tip. Fatback biltong ham hock shoulder.

+ + Please bear with us while we learn latin. Lorem ipsum dolor sit amet, consectetur adipiscing elit. Phasellus non metus eget tellus eleifend convallis ac et eros. Nunc scelerisque pulvinar egestas. Vivamus feugiat nunc placerat, finibus urna non, vehicula purus. + +
-

[Replace this paragraph with the login form]

+
-

Use this image as the background:

+ +
+
+ + + +
+
+
+ + + +
+ +
+
+
+ + +
+
+
+ +
+
+
- - - - +
- - + + + + + + + + + + - \ No newline at end of file + From 963269e9fbbc51bca2534cdc17020f8810bcf1f2 Mon Sep 17 00:00:00 2001 From: Hamilton Sands Date: Fri, 15 Jun 2018 10:53:53 -0400 Subject: [PATCH 2/7] remove labels for inputs and a few == in app.js --- loginpage/public/js/app.js | 4 +++- loginpage/views/index.erb | 4 +--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/loginpage/public/js/app.js b/loginpage/public/js/app.js index 602d40f..b7e0499 100644 --- a/loginpage/public/js/app.js +++ b/loginpage/public/js/app.js @@ -9,13 +9,15 @@ $("#login-form").on("submit", (e)=> { $(`#${input.attr("id")}Glyph`).removeClass("hidden"); //make alert glyph visible input.attr("placeholder", "Field cannot be empty"); //use placeholder to message user noEmptyFields = false; - } else if (input.attr("id") == "emailInput" && !emailRegex(input.val())) { + } else if (input.attr("id") === "emailInput" && !emailRegex(input.val())) { input.parent().addClass("has-error has-feedback"); input.val(""); $(`#${input.attr("id")}Glyph`).removeClass("hidden"); input.attr("placeholder", "Must enter a valid email"); noEmptyFields = false; } else { + let placeholder = input.attr("id") === "emailInput" ? "Email" : "Password"; + input.attr("placeholder", placeholder); input.parent().removeClass("has-error has-feedback"); $(`#${input.attr("id")}Glyph`).addClass("hidden"); input.attr("placeholder", ""); //reset any previous error messages diff --git a/loginpage/views/index.erb b/loginpage/views/index.erb index 3642bda..c582bdd 100644 --- a/loginpage/views/index.erb +++ b/loginpage/views/index.erb @@ -43,13 +43,11 @@
- - +
-
From e77f98b0c66a44918830a0ca572750c3f66fdb42 Mon Sep 17 00:00:00 2001 From: Hamilton Sands Date: Fri, 15 Jun 2018 11:06:36 -0400 Subject: [PATCH 3/7] add back labels with sr-only class --- loginpage/views/index.erb | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/loginpage/views/index.erb b/loginpage/views/index.erb index c582bdd..1434888 100644 --- a/loginpage/views/index.erb +++ b/loginpage/views/index.erb @@ -43,11 +43,13 @@
- + +
+
From c41b4b2d97258229cb4d5d320d9b8f8ede779cd2 Mon Sep 17 00:00:00 2001 From: Hamilton Sands Date: Fri, 15 Jun 2018 11:57:07 -0400 Subject: [PATCH 4/7] inputs blink with error --- loginpage/login_page.rb | 8 ++++---- loginpage/public/css/app.css | 4 ++++ loginpage/public/js/app.js | 10 +++++++++- 3 files changed, 17 insertions(+), 5 deletions(-) diff --git a/loginpage/login_page.rb b/loginpage/login_page.rb index a07fc41..b764742 100644 --- a/loginpage/login_page.rb +++ b/loginpage/login_page.rb @@ -15,9 +15,9 @@ class LoginPage < Sinatra::Base end end -end + def user_params + permitted_fields = ["email", "password"] + params["user"].select {|k,v| permitted_fields.include?(k)} + end -def user_params - permitted_fields = ["email", "password"] - params["user"].select {|k,v| permitted_fields.include?(k)} end diff --git a/loginpage/public/css/app.css b/loginpage/public/css/app.css index 7ddefc1..18296e7 100644 --- a/loginpage/public/css/app.css +++ b/loginpage/public/css/app.css @@ -73,3 +73,7 @@ summary { .green { color: #00dd00; } + +.flash-error { + border-color: #ff0000 !important; +} diff --git a/loginpage/public/js/app.js b/loginpage/public/js/app.js index b7e0499..20f19d5 100644 --- a/loginpage/public/js/app.js +++ b/loginpage/public/js/app.js @@ -8,19 +8,20 @@ $("#login-form").on("submit", (e)=> { input.parent().addClass("has-error has-feedback"); //use bootsrap error css $(`#${input.attr("id")}Glyph`).removeClass("hidden"); //make alert glyph visible input.attr("placeholder", "Field cannot be empty"); //use placeholder to message user + inputErrorBlink(input); //briefly set border of input to bright red noEmptyFields = false; } else if (input.attr("id") === "emailInput" && !emailRegex(input.val())) { input.parent().addClass("has-error has-feedback"); input.val(""); $(`#${input.attr("id")}Glyph`).removeClass("hidden"); input.attr("placeholder", "Must enter a valid email"); + inputErrorBlink(input); noEmptyFields = false; } else { let placeholder = input.attr("id") === "emailInput" ? "Email" : "Password"; input.attr("placeholder", placeholder); input.parent().removeClass("has-error has-feedback"); $(`#${input.attr("id")}Glyph`).addClass("hidden"); - input.attr("placeholder", ""); //reset any previous error messages } }); @@ -39,6 +40,13 @@ const emailRegex = (str) => { return str.match(/^(([^<>()\[\]\\.,;:\s@"]+(\.[^<>()\[\]\\.,;:\s@"]+)*)|(".+"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/); }; +const inputErrorBlink = (input) => { + input.addClass("flash-error"); + setTimeout(() => { + input.removeClass("flash-error"); + },500); +}; + const signIn = (user) => { return $.ajax({ method: 'post', From cb59b9dd8156b1244276fcef6314d151deb5cfa4 Mon Sep 17 00:00:00 2001 From: Hamilton Sands Date: Fri, 15 Jun 2018 12:03:53 -0400 Subject: [PATCH 5/7] consolidate input error sequence into function --- loginpage/public/js/app.js | 19 ++++++++++--------- 1 file changed, 10 insertions(+), 9 deletions(-) diff --git a/loginpage/public/js/app.js b/loginpage/public/js/app.js index 20f19d5..c40069e 100644 --- a/loginpage/public/js/app.js +++ b/loginpage/public/js/app.js @@ -5,17 +5,10 @@ $("#login-form").on("submit", (e)=> { $("#emailInput, #passwordInput").each((index, input) => { input = $(input); if (input.val() === "") { - input.parent().addClass("has-error has-feedback"); //use bootsrap error css - $(`#${input.attr("id")}Glyph`).removeClass("hidden"); //make alert glyph visible - input.attr("placeholder", "Field cannot be empty"); //use placeholder to message user - inputErrorBlink(input); //briefly set border of input to bright red + inputError(input, "Field cannot be empty"); noEmptyFields = false; } else if (input.attr("id") === "emailInput" && !emailRegex(input.val())) { - input.parent().addClass("has-error has-feedback"); - input.val(""); - $(`#${input.attr("id")}Glyph`).removeClass("hidden"); - input.attr("placeholder", "Must enter a valid email"); - inputErrorBlink(input); + inputError(input, "Muset enter a valid email"); noEmptyFields = false; } else { let placeholder = input.attr("id") === "emailInput" ? "Email" : "Password"; @@ -40,6 +33,14 @@ const emailRegex = (str) => { return str.match(/^(([^<>()\[\]\\.,;:\s@"]+(\.[^<>()\[\]\\.,;:\s@"]+)*)|(".+"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/); }; +const inputError = (input, message) => { + input.parent().addClass("has-error has-feedback"); //use bootsrap error css + input.val(""); + $(`#${input.attr("id")}Glyph`).removeClass("hidden"); //make alert glyph visible + input.attr("placeholder", message); //use placeholder to message user + inputErrorBlink(input); //briefly set border of input to bright red +}; + const inputErrorBlink = (input) => { input.addClass("flash-error"); setTimeout(() => { From 9f636b16a208c9f2cc5e250a87a50b88076a8761 Mon Sep 17 00:00:00 2001 From: Hamilton Sands Date: Fri, 15 Jun 2018 13:57:26 -0400 Subject: [PATCH 6/7] created fade animation --- loginpage/public/css/app.css | 18 +++++++++++++++--- loginpage/public/js/app.js | 4 ++++ loginpage/views/index.erb | 2 +- 3 files changed, 20 insertions(+), 4 deletions(-) diff --git a/loginpage/public/css/app.css b/loginpage/public/css/app.css index 18296e7..1c0c2df 100644 --- a/loginpage/public/css/app.css +++ b/loginpage/public/css/app.css @@ -7,12 +7,19 @@ html, body { body { display: flex; flex-direction: column; - justify-content: space-between; - /*pushes footer to bottom */ + justify-content: space-between; /*pushes footer to bottom */ + opacity: 0; + transition: box-shadow 1s linear; + transition: opacity 1s linear; } +.opaque { + opacity: 1; +} + + .bg { - background: linear-gradient(rgba(0, 0, 0, 0.5), rgba(0, 0, 0, 0.5)), url("/img/Blue_sky_and_green_grass-wide.jpg"); + background: url("/img/Blue_sky_and_green_grass-wide.jpg"); height: 100%; background-position: center; background-attachment: fixed; @@ -20,6 +27,11 @@ body { background-size: cover; } +.darken { + box-shadow: inset 9999px 9999px rgba(0,0,0,0.50); + /* background: linear-gradient(rgba(0, 0, 0, 0.5), rgba(0, 0, 0, 0.5)), url("/img/Blue_sky_and_green_grass-wide.jpg"); */ +} + .upcase { text-transform: uppercase; } diff --git a/loginpage/public/js/app.js b/loginpage/public/js/app.js index c40069e..a3cc6dc 100644 --- a/loginpage/public/js/app.js +++ b/loginpage/public/js/app.js @@ -1,3 +1,7 @@ +setTimeout(()=> { + $("#body").addClass("opaque darken"); +},0); + $("#login-form").on("submit", (e)=> { e.preventDefault(); let noEmptyFields = true; diff --git a/loginpage/views/index.erb b/loginpage/views/index.erb index 1434888..45d099a 100644 --- a/loginpage/views/index.erb +++ b/loginpage/views/index.erb @@ -19,7 +19,7 @@ - +
From c9244aee7f918d570b944bf4532ea630799f8efc Mon Sep 17 00:00:00 2001 From: Hamilton Sands Date: Fri, 15 Jun 2018 23:17:57 -0400 Subject: [PATCH 7/7] typo --- loginpage/public/js/app.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/loginpage/public/js/app.js b/loginpage/public/js/app.js index a3cc6dc..99a12a9 100644 --- a/loginpage/public/js/app.js +++ b/loginpage/public/js/app.js @@ -12,7 +12,7 @@ $("#login-form").on("submit", (e)=> { inputError(input, "Field cannot be empty"); noEmptyFields = false; } else if (input.attr("id") === "emailInput" && !emailRegex(input.val())) { - inputError(input, "Muset enter a valid email"); + inputError(input, "Must enter a valid email"); noEmptyFields = false; } else { let placeholder = input.attr("id") === "emailInput" ? "Email" : "Password";