diff --git a/package-lock.json b/package-lock.json index 561a470..6f3dd3b 100644 --- a/package-lock.json +++ b/package-lock.json @@ -3598,6 +3598,11 @@ "promise": "^8.0.2" } }, + "express-rate-limit": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/express-rate-limit/-/express-rate-limit-5.0.0.tgz", + "integrity": "sha512-dhT57wqxfqmkOi4HM7NuT4Gd7gbUgSK2ocG27Y6lwm8lbOAw9XQfeANawGq8wLDtlGPO1ZgDj0HmKsykTxfFAg==" + }, "express-session": { "version": "1.17.0", "resolved": "https://registry.npmjs.org/express-session/-/express-session-1.17.0.tgz", @@ -5058,9 +5063,9 @@ } }, "handlebars": { - "version": "4.4.5", - "resolved": "https://registry.npmjs.org/handlebars/-/handlebars-4.4.5.tgz", - "integrity": "sha512-0Ce31oWVB7YidkaTq33ZxEbN+UDxMMgThvCe8ptgQViymL5DPis9uLdTA13MiRPhgvqyxIegugrP97iK3JeBHg==", + "version": "4.5.3", + "resolved": "https://registry.npmjs.org/handlebars/-/handlebars-4.5.3.tgz", + "integrity": "sha512-3yPecJoJHK/4c6aZhSvxOyG4vJKDshV36VHp0iVCDVh7o9w2vwi3NSnL2MMPj3YdduqaBcu7cGbggJQM0br9xA==", "requires": { "neo-async": "^2.6.0", "optimist": "^0.6.1", @@ -9223,9 +9228,9 @@ "integrity": "sha512-kMBmblijHJXyOpKzgDhKx9INYU4u4E1RPMB0HqmKSgWG8vEcf3exEfLh4FFfzd3xdQOw9EuIy/cP0akY6rHopQ==" }, "uglify-js": { - "version": "3.6.4", - "resolved": "https://registry.npmjs.org/uglify-js/-/uglify-js-3.6.4.tgz", - "integrity": "sha512-9Yc2i881pF4BPGhjteCXQNaXx1DCwm3dtOyBaG2hitHjLWOczw/ki8vD1bqyT3u6K0Ms/FpCShkmfg+FtlOfYA==", + "version": "3.7.2", + "resolved": "https://registry.npmjs.org/uglify-js/-/uglify-js-3.7.2.tgz", + "integrity": "sha512-uhRwZcANNWVLrxLfNFEdltoPNhECUR3lc+UdJoG9CBpMcSnKyWA94tc3eAujB1GcMY5Uwq8ZMp4qWpxWYDQmaA==", "optional": true, "requires": { "commander": "~2.20.3", diff --git a/package.json b/package.json index d6b0934..397f3e0 100644 --- a/package.json +++ b/package.json @@ -38,6 +38,7 @@ "cookie-parser": "^1.4.4", "express": "^4.17.1", "express-handlebars": "^3.1.0", + "express-rate-limit": "^5.0.0", "express-session": "^1.17.0", "glob": "^7.1.5", "helmet": "^3.21.2", diff --git a/public/javascripts/expressCart.js b/public/javascripts/expressCart.js index 5472145..98384f1 100644 --- a/public/javascripts/expressCart.js +++ b/public/javascripts/expressCart.js @@ -143,6 +143,29 @@ $(document).ready(function (){ }); }); + $('#customerForgotten').validator().on('submit', function(e){ + if(!e.isDefaultPrevented()){ + e.preventDefault(); + $.ajax({ + method: 'POST', + url: '/customer/forgotten_action', + data: { + email: $('#email').val() + } + }) + .done(function(msg){ + showNotification(msg.message, 'success'); + }) + .fail(function(msg){ + if(msg.message){ + showNotification(msg.responseJSON.message, 'danger'); + return; + } + showNotification(msg.responseText, 'danger'); + }); + } + }); + $('#createCustomerAccount').validator().on('click', function(e){ e.preventDefault(); if($('#shipping-form').validator('validate').has('.has-error').length === 0){ diff --git a/public/javascripts/expressCart.min.js b/public/javascripts/expressCart.min.js index 8ef3cb6..d361f59 100644 --- a/public/javascripts/expressCart.min.js +++ b/public/javascripts/expressCart.min.js @@ -1 +1 @@ -function deleteFromCart(t){$.ajax({method:"POST",url:"/product/removefromcart",data:{cartId:t.attr("data-id")}}).done(function(a){$("#cart-count").text(a.totalCartItems),0===a.totalCartItems?($(t).closest(".cart-row").hide("slow",function(){$(t).closest(".cart-row").remove()}),$(".cart-contents-shipping").hide("slow",function(){$(".cart-contents-shipping").remove()}),showNotification(a.message,"success"),setTimeout(function(){window.location="/"},3700)):($(t).closest(".cart-row").hide("slow",function(){$(t).closest(".cart-row").remove()}),showNotification(a.message,"success"))}).fail(function(t){showNotification(t.responseJSON.message,"danger")})}function cartUpdate(t){$(t).val()>0?""!==$(t).val()&&updateCart():$(t).val(1)}function updateCart(){var t=[];$(".cart-product-quantity").each(function(){var a={cartIndex:$(this).attr("id"),itemQuantity:$(this).val(),productId:$(this).attr("data-id")};t.push(a)}),$.ajax({method:"POST",url:"/product/updatecart",data:{items:JSON.stringify(t)}}).done(function(t){updateCartDiv(),$("#cart-count").text(t.totalCartItems)}).fail(function(t){showNotification(t.responseJSON.message,"danger",!0)})}function updateCartDiv(){var t=window.location.pathname.split("/").length>0?window.location.pathname.split("/")[1]:"";$.ajax({method:"GET",url:"/cartPartial",data:{path:t}}).done(function(t){$("#cart").html(t)}).fail(function(t){showNotification(t.responseJSON.message,"danger")})}function getSelectedOptions(){var t={};return $(".product-opt").each(function(){if("opt-"!==$(this).attr("name")){var a=$(this).val().trim();"radio"===$(this).attr("type")&&(a=$('input[name="'+$(this).attr("name")+'"]:checked').val()),t[$(this).attr("name").substring(4,$(this).attr("name").length)]=a}else t[$(this).val().trim()]=$(this).prop("checked")}),t}$(document).ready(function(){if("Material"===$("#cartTheme").val()&&$(".materialboxed").materialbox(),$(window).width()<768&&($(".menu-side").on("click",function(t){t.preventDefault(),$('.menu-side li:not(".active")').slideToggle()}),$('.menu-side li:not(".active")').hide(),$(".menu-side>.active").html(''),$(".menu-side>.active").addClass("menu-side-mobile"),0===$("#navbar ul li").length&&$("#navbar").hide(),$("#offcanvasClose").hide()),$("#userSetupForm").validator().on("submit",function(t){t.isDefaultPrevented()||(t.preventDefault(),$.ajax({method:"POST",url:"/admin/setup_action",data:{usersName:$("#usersName").val(),userEmail:$("#userEmail").val(),userPassword:$("#userPassword").val()}}).done(function(t){showNotification(t.message,"success",!1,"/admin/login")}).fail(function(t){showNotification(t.responseJSON.message,"danger")}))}),$(".shipping-form input").each(function(t){$(this).wrap("
");var a=$(this).attr("placeholder");$(this).after('")}),$(".shipping-form input").on("focus",function(){$(this).next().addClass("floatLabel"),$(this).next().removeClass("hidden")}),$(".shipping-form input").on("blur",function(){""===$(this).val()&&($(this).next().addClass("hidden"),$(this).next().removeClass("floatLabel"))}),$(".menu-btn").on("click",function(t){t.preventDefault()}),$("table").each(function(){$(this).addClass("table table-hover")}),$("#productTags").tokenfield(),$(document).on("click",".dashboard_list",function(t){window.document.location=$(this).attr("href")}).hover(function(){$(this).toggleClass("hover")}),$(".product-title").dotdotdot({ellipsis:"..."}),$(document).on("click",".btn-qty-minus",function(t){var a=$(t.target).parent().parent().find(".cart-product-quantity");$(a).val(parseInt(a.val())-1),cartUpdate(a)}),$(document).on("click",".btn-qty-add",function(t){var a=$(t.target).parent().parent().find(".cart-product-quantity");$(a).val(parseInt(a.val())+1),cartUpdate(a)}),$(document).on("change",".cart-product-quantity",function(t){cartUpdate(t.target)}),$(document).on("click",".btn-delete-from-cart",function(t){deleteFromCart($(t.target))}),$("#pager").length){var t=$("#pageNum").val(),a=$("#productsPerPage").val(),e=$("#totalProductCount").val(),n=$("#paginateUrl").val(),o=$("#searchTerm").val();""!==o&&(o+="/");var i="/"+n+"/"+o+"{{number}}",r=Math.ceil(e/a);parseInt(e)>parseInt(a)&&$("#pager").bootpag({total:r,page:t,maxVisible:5,href:i,wrapClass:"pagination",prevClass:"waves-effect",nextClass:"waves-effect",activeClass:"pag-active waves-effect"})}if($("#customerLogout").on("click",function(t){$.ajax({method:"POST",url:"/customer/logout",data:{}}).done(function(t){location.reload()})}),$("#createCustomerAccount").validator().on("click",function(t){t.preventDefault(),0===$("#shipping-form").validator("validate").has(".has-error").length&&$.ajax({method:"POST",url:"/customer/create",data:{email:$("#shipEmail").val(),firstName:$("#shipFirstname").val(),lastName:$("#shipLastname").val(),address1:$("#shipAddr1").val(),address2:$("#shipAddr2").val(),country:$("#shipCountry").val(),state:$("#shipState").val(),postcode:$("#shipPostcode").val(),phone:$("#shipPhoneNumber").val(),password:$("#newCustomerPassword").val()}}).done(function(t){location.reload()}).fail(function(t){showNotification(t.responseJSON.message,"danger")})}),$("#loginForm").on("click",function(t){t.isDefaultPrevented()||(t.preventDefault(),$.ajax({method:"POST",url:"/admin/login_action",data:{email:$("#email").val(),password:$("#password").val()}}).done(function(t){window.location="/admin"}).fail(function(t){showNotification(t.responseJSON.message,"danger")})),t.preventDefault()}),$("#customerLogin").on("click",function(t){t.isDefaultPrevented()||(t.preventDefault(),$.ajax({method:"POST",url:"/customer/login_action",data:{loginEmail:$("#customerLoginEmail").val(),loginPassword:$("#customerLoginPassword").val()}}).done(function(t){var a=t.customer;$("#shipEmail").val(a.email),$("#shipFirstname").val(a.firstName),$("#shipLastname").val(a.lastName),$("#shipAddr1").val(a.address1),$("#shipAddr2").val(a.address2),$("#shipCountry").val(a.country),$("#shipState").val(a.state),$("#shipPostcode").val(a.postcode),$("#shipPhoneNumber").val(a.phone),location.reload()}).fail(function(t){showNotification(t.responseJSON.message,"danger")})),t.preventDefault()}),$(document).on("click",".image-next",function(t){var a=$(".thumbnail-image"),e=0,n=0;$(".thumbnail-image").each(function(){$("#product-title-image").attr("src")===$(this).attr("src")&&(n=e+1===a.length||e+1<0?0:e+1),e++}),$("#product-title-image").attr("src",$(a).eq(n).attr("src"))}),$(document).on("click",".image-prev",function(t){var a=$(".thumbnail-image"),e=0,n=0;$(".thumbnail-image").each(function(){$("#product-title-image").attr("src")===$(this).attr("src")&&(n=e-1===a.length||e-1<0?a.length-1:e-1),e++}),$("#product-title-image").attr("src",$(a).eq(n).attr("src"))}),$(document).on("click",".product-add-to-cart",function(t){var a=getSelectedOptions();parseInt($("#product_quantity").val())<0&&$("#product_quantity").val(0),$.ajax({method:"POST",url:"/product/addtocart",data:{productId:$("#productId").val(),productQuantity:$("#product_quantity").val(),productOptions:JSON.stringify(a),productComment:$("#product_comment").val()}}).done(function(t){$("#cart-count").text(t.totalCartItems),updateCartDiv(),showNotification(t.message,"success")}).fail(function(t){showNotification(t.responseJSON.message,"danger")})}),$(".cart-product-quantity").on("input",function(){cartUpdate()}),$(document).on("click",".pushy-link",function(t){$("body").removeClass("pushy-open-right")}),$(document).on("click",".add-to-cart",function(t){var a="/product/"+$(this).attr("data-id");$(this).attr("data-link")&&(a="/product/"+$(this).attr("data-link")),"true"===$(this).attr("data-has-options")?window.location=a:$.ajax({method:"POST",url:"/product/addtocart",data:{productId:$(this).attr("data-id")}}).done(function(t){$("#cart-count").text(t.totalCartItems),updateCartDiv(),showNotification(t.message,"success")}).fail(function(t){showNotification(t.responseJSON.message,"danger")})}),$(document).on("click","#empty-cart",function(t){$.ajax({method:"POST",url:"/product/emptycart"}).done(function(t){$("#cart-count").text(t.totalCartItems),updateCartDiv(),showNotification(t.message,"success",!0)})}),$(".qty-btn-minus").on("click",function(){var t=parseInt($("#product_quantity").val())-1;$("#product_quantity").val(t>0?t:1)}),$(".qty-btn-plus").on("click",function(){$("#product_quantity").val(parseInt($("#product_quantity").val())+1)}),$(".thumbnail-image").on("click",function(){$("#product-title-image").attr("src",$(this).attr("src"))}),$(document).on("click","#btn_search_reset",function(t){window.location.replace("/")}),$(document).on("click","#btn_search",function(t){t.preventDefault(),""===$("#frm_search").val().trim()?showNotification("Please enter a search value","danger"):window.location.href="/search/"+$("#frm_search").val()}),""!==$("#input_notify_message").val()){var s=$("#input_notify_message").val(),c=$("#input_notify_messageType").val();$("#input_notify_message").val(""),$("#input_notify_messageType").val(""),showNotification(s,c,!1)}}); \ No newline at end of file +function deleteFromCart(t){$.ajax({method:"POST",url:"/product/removefromcart",data:{cartId:t.attr("data-id")}}).done(function(a){$("#cart-count").text(a.totalCartItems),0===a.totalCartItems?($(t).closest(".cart-row").hide("slow",function(){$(t).closest(".cart-row").remove()}),$(".cart-contents-shipping").hide("slow",function(){$(".cart-contents-shipping").remove()}),showNotification(a.message,"success"),setTimeout(function(){window.location="/"},3700)):($(t).closest(".cart-row").hide("slow",function(){$(t).closest(".cart-row").remove()}),showNotification(a.message,"success"))}).fail(function(t){showNotification(t.responseJSON.message,"danger")})}function cartUpdate(t){$(t).val()>0?""!==$(t).val()&&updateCart():$(t).val(1)}function updateCart(){var t=[];$(".cart-product-quantity").each(function(){var a={cartIndex:$(this).attr("id"),itemQuantity:$(this).val(),productId:$(this).attr("data-id")};t.push(a)}),$.ajax({method:"POST",url:"/product/updatecart",data:{items:JSON.stringify(t)}}).done(function(t){updateCartDiv(),$("#cart-count").text(t.totalCartItems)}).fail(function(t){showNotification(t.responseJSON.message,"danger",!0)})}function updateCartDiv(){var t=window.location.pathname.split("/").length>0?window.location.pathname.split("/")[1]:"";$.ajax({method:"GET",url:"/cartPartial",data:{path:t}}).done(function(t){$("#cart").html(t)}).fail(function(t){showNotification(t.responseJSON.message,"danger")})}function getSelectedOptions(){var t={};return $(".product-opt").each(function(){if("opt-"!==$(this).attr("name")){var a=$(this).val().trim();"radio"===$(this).attr("type")&&(a=$('input[name="'+$(this).attr("name")+'"]:checked').val()),t[$(this).attr("name").substring(4,$(this).attr("name").length)]=a}else t[$(this).val().trim()]=$(this).prop("checked")}),t}$(document).ready(function(){if("Material"===$("#cartTheme").val()&&$(".materialboxed").materialbox(),$(window).width()<768&&($(".menu-side").on("click",function(t){t.preventDefault(),$('.menu-side li:not(".active")').slideToggle()}),$('.menu-side li:not(".active")').hide(),$(".menu-side>.active").html(''),$(".menu-side>.active").addClass("menu-side-mobile"),0===$("#navbar ul li").length&&$("#navbar").hide(),$("#offcanvasClose").hide()),$("#userSetupForm").validator().on("submit",function(t){t.isDefaultPrevented()||(t.preventDefault(),$.ajax({method:"POST",url:"/admin/setup_action",data:{usersName:$("#usersName").val(),userEmail:$("#userEmail").val(),userPassword:$("#userPassword").val()}}).done(function(t){showNotification(t.message,"success",!1,"/admin/login")}).fail(function(t){showNotification(t.responseJSON.message,"danger")}))}),$(".shipping-form input").each(function(t){$(this).wrap("");var a=$(this).attr("placeholder");$(this).after('")}),$(".shipping-form input").on("focus",function(){$(this).next().addClass("floatLabel"),$(this).next().removeClass("hidden")}),$(".shipping-form input").on("blur",function(){""===$(this).val()&&($(this).next().addClass("hidden"),$(this).next().removeClass("floatLabel"))}),$(".menu-btn").on("click",function(t){t.preventDefault()}),$("table").each(function(){$(this).addClass("table table-hover")}),$("#productTags").tokenfield(),$(document).on("click",".dashboard_list",function(t){window.document.location=$(this).attr("href")}).hover(function(){$(this).toggleClass("hover")}),$(".product-title").dotdotdot({ellipsis:"..."}),$(document).on("click",".btn-qty-minus",function(t){var a=$(t.target).parent().parent().find(".cart-product-quantity");$(a).val(parseInt(a.val())-1),cartUpdate(a)}),$(document).on("click",".btn-qty-add",function(t){var a=$(t.target).parent().parent().find(".cart-product-quantity");$(a).val(parseInt(a.val())+1),cartUpdate(a)}),$(document).on("change",".cart-product-quantity",function(t){cartUpdate(t.target)}),$(document).on("click",".btn-delete-from-cart",function(t){deleteFromCart($(t.target))}),$("#pager").length){var t=$("#pageNum").val(),a=$("#productsPerPage").val(),e=$("#totalProductCount").val(),o=$("#paginateUrl").val(),n=$("#searchTerm").val();""!==n&&(n+="/");var i="/"+o+"/"+n+"{{number}}",s=Math.ceil(e/a);parseInt(e)>parseInt(a)&&$("#pager").bootpag({total:s,page:t,maxVisible:5,href:i,wrapClass:"pagination",prevClass:"waves-effect",nextClass:"waves-effect",activeClass:"pag-active waves-effect"})}if($("#customerLogout").on("click",function(t){$.ajax({method:"POST",url:"/customer/logout",data:{}}).done(function(t){location.reload()})}),$("#customerForgotten").validator().on("submit",function(t){t.isDefaultPrevented()||(t.preventDefault(),$.ajax({method:"POST",url:"/customer/forgotten_action",data:{email:$("#email").val()}}).done(function(t){showNotification(t.message,"success")}).fail(function(t){t.message?showNotification(t.responseJSON.message,"danger"):showNotification(t.responseText,"danger")}))}),$("#createCustomerAccount").validator().on("click",function(t){t.preventDefault(),0===$("#shipping-form").validator("validate").has(".has-error").length&&$.ajax({method:"POST",url:"/customer/create",data:{email:$("#shipEmail").val(),firstName:$("#shipFirstname").val(),lastName:$("#shipLastname").val(),address1:$("#shipAddr1").val(),address2:$("#shipAddr2").val(),country:$("#shipCountry").val(),state:$("#shipState").val(),postcode:$("#shipPostcode").val(),phone:$("#shipPhoneNumber").val(),password:$("#newCustomerPassword").val()}}).done(function(t){location.reload()}).fail(function(t){showNotification(t.responseJSON.message,"danger")})}),$("#loginForm").on("click",function(t){t.isDefaultPrevented()||(t.preventDefault(),$.ajax({method:"POST",url:"/admin/login_action",data:{email:$("#email").val(),password:$("#password").val()}}).done(function(t){window.location="/admin"}).fail(function(t){showNotification(t.responseJSON.message,"danger")})),t.preventDefault()}),$("#customerLogin").on("click",function(t){t.isDefaultPrevented()||(t.preventDefault(),$.ajax({method:"POST",url:"/customer/login_action",data:{loginEmail:$("#customerLoginEmail").val(),loginPassword:$("#customerLoginPassword").val()}}).done(function(t){var a=t.customer;$("#shipEmail").val(a.email),$("#shipFirstname").val(a.firstName),$("#shipLastname").val(a.lastName),$("#shipAddr1").val(a.address1),$("#shipAddr2").val(a.address2),$("#shipCountry").val(a.country),$("#shipState").val(a.state),$("#shipPostcode").val(a.postcode),$("#shipPhoneNumber").val(a.phone),location.reload()}).fail(function(t){showNotification(t.responseJSON.message,"danger")})),t.preventDefault()}),$(document).on("click",".image-next",function(t){var a=$(".thumbnail-image"),e=0,o=0;$(".thumbnail-image").each(function(){$("#product-title-image").attr("src")===$(this).attr("src")&&(o=e+1===a.length||e+1<0?0:e+1),e++}),$("#product-title-image").attr("src",$(a).eq(o).attr("src"))}),$(document).on("click",".image-prev",function(t){var a=$(".thumbnail-image"),e=0,o=0;$(".thumbnail-image").each(function(){$("#product-title-image").attr("src")===$(this).attr("src")&&(o=e-1===a.length||e-1<0?a.length-1:e-1),e++}),$("#product-title-image").attr("src",$(a).eq(o).attr("src"))}),$(document).on("click",".product-add-to-cart",function(t){var a=getSelectedOptions();parseInt($("#product_quantity").val())<0&&$("#product_quantity").val(0),$.ajax({method:"POST",url:"/product/addtocart",data:{productId:$("#productId").val(),productQuantity:$("#product_quantity").val(),productOptions:JSON.stringify(a),productComment:$("#product_comment").val()}}).done(function(t){$("#cart-count").text(t.totalCartItems),updateCartDiv(),showNotification(t.message,"success")}).fail(function(t){showNotification(t.responseJSON.message,"danger")})}),$(".cart-product-quantity").on("input",function(){cartUpdate()}),$(document).on("click",".pushy-link",function(t){$("body").removeClass("pushy-open-right")}),$(document).on("click",".add-to-cart",function(t){var a="/product/"+$(this).attr("data-id");$(this).attr("data-link")&&(a="/product/"+$(this).attr("data-link")),"true"===$(this).attr("data-has-options")?window.location=a:$.ajax({method:"POST",url:"/product/addtocart",data:{productId:$(this).attr("data-id")}}).done(function(t){$("#cart-count").text(t.totalCartItems),updateCartDiv(),showNotification(t.message,"success")}).fail(function(t){showNotification(t.responseJSON.message,"danger")})}),$(document).on("click","#empty-cart",function(t){$.ajax({method:"POST",url:"/product/emptycart"}).done(function(t){$("#cart-count").text(t.totalCartItems),updateCartDiv(),showNotification(t.message,"success",!0)})}),$(".qty-btn-minus").on("click",function(){var t=parseInt($("#product_quantity").val())-1;$("#product_quantity").val(t>0?t:1)}),$(".qty-btn-plus").on("click",function(){$("#product_quantity").val(parseInt($("#product_quantity").val())+1)}),$(".thumbnail-image").on("click",function(){$("#product-title-image").attr("src",$(this).attr("src"))}),$(document).on("click","#btn_search_reset",function(t){window.location.replace("/")}),$(document).on("click","#btn_search",function(t){t.preventDefault(),""===$("#frm_search").val().trim()?showNotification("Please enter a search value","danger"):window.location.href="/search/"+$("#frm_search").val()}),""!==$("#input_notify_message").val()){var r=$("#input_notify_message").val(),c=$("#input_notify_messageType").val();$("#input_notify_message").val(""),$("#input_notify_messageType").val(""),showNotification(r,c,!1)}}); \ No newline at end of file diff --git a/routes/customer.js b/routes/customer.js index 76846fa..b58bcfc 100644 --- a/routes/customer.js +++ b/routes/customer.js @@ -4,10 +4,16 @@ const colors = require('colors'); const randtoken = require('rand-token'); const bcrypt = require('bcryptjs'); const common = require('../lib/common'); +const rateLimit = require('express-rate-limit'); const { indexCustomers } = require('../lib/indexing'); const { validateJson } = require('../lib/schema'); const { restrict } = require('../lib/auth'); +const apiLimiter = rateLimit({ + windowMs: 300000, // 5 minutes + max: 5 +}); + // insert a customer router.post('/customer/create', async (req, res) => { const db = req.app.db; @@ -281,21 +287,21 @@ router.get('/customer/forgotten', (req, res) => { }); // forgotten password -router.post('/customer/forgotten_action', async (req, res) => { +router.post('/customer/forgotten_action', apiLimiter, async (req, res) => { const db = req.app.db; const config = req.app.config; const passwordToken = randtoken.generate(30); // find the user const customer = await db.customers.findOne({ email: req.body.email }); - // if we have a customer, set a token, expiry and email it - if(!customer){ - req.session.message = 'Account does not exist'; - req.session.message_type = 'danger'; - res.redirect('/customer/forgotten'); - return; - } try{ + if(!customer){ + // if don't have an email on file, silently fail + res.status(200).json({ + message: 'If your account exists, a password reset has been sent to your email' + }); + return; + } const tokenExpiry = Date.now() + 3600000; await db.customers.updateOne({ email: req.body.email }, { $set: { resetToken: passwordToken, resetTokenExpiry: tokenExpiry } }, { multi: false }); // send forgotten password email @@ -311,13 +317,13 @@ router.post('/customer/forgotten_action', async (req, res) => { // send the email with token to the user // TODO: Should fix this to properly handle result common.sendEmail(mailOpts.to, mailOpts.subject, mailOpts.body); - req.session.message = 'An email has been sent to ' + req.body.email + ' with further instructions'; - req.session.message_type = 'success'; - res.redirect('/customer/forgotten'); + res.status(200).json({ + message: 'If your account exists, a password reset has been sent to your email' + }); }catch(ex){ - req.session.message = 'Account does not exist'; - req.session.message_type = 'danger'; - res.redirect('/customer/forgotten'); + res.status(400).json({ + message: 'Password reset failed.' + }); } }); diff --git a/views/forgotten.hbs b/views/forgotten.hbs index 73fe2d7..4421416 100644 --- a/views/forgotten.hbs +++ b/views/forgotten.hbs @@ -1,9 +1,9 @@