From f8e8885a0c66de2aef7ba275f1151c06ac439e51 Mon Sep 17 00:00:00 2001 From: Reid Phillips Date: Wed, 8 Jan 2020 08:44:36 -0600 Subject: [PATCH 01/53] Initial changes for sprint 2 employee edit functionality, incomplete. --- public/scripts/employeeDetail.js | 32 +++++ .../employees/helpers/employeeHelper.ts | 9 ++ .../commands/models/constants/entityTypes.ts | 6 + .../employeeDetailRouteController.ts | 109 ++++++++++++++++++ src/controllers/typeDefinitions.ts | 11 ++ views/employeeDetail.ejs | 74 ++++++++++++ 6 files changed, 241 insertions(+) create mode 100644 public/scripts/employeeDetail.js create mode 100644 src/controllers/commands/employees/helpers/employeeHelper.ts create mode 100644 src/controllers/commands/models/constants/entityTypes.ts create mode 100644 src/controllers/employeeDetailRouteController.ts create mode 100644 views/employeeDetail.ejs diff --git a/public/scripts/employeeDetail.js b/public/scripts/employeeDetail.js new file mode 100644 index 0000000..3a17add --- /dev/null +++ b/public/scripts/employeeDetail.js @@ -0,0 +1,32 @@ +let hideEmployeeSavedAlertTimer = undefined; + +document.addEventListener("DOMContentLoaded", () => { + // TODO: Things that need doing when the view is loaded +}); + +// Save +function saveActionClick(event) { + // TODO: Actually save the employee via an AJAX call + displayEmployeeSavedAlertModal(); +} + +function displayEmployeeSavedAlertModal() { + if (hideEmployeeSavedAlertTimer) { + clearTimeout(hideEmployeeSavedAlertTimer); + } + + const savedAlertModalElement = getSavedAlertModalElement(); + savedAlertModalElement.style.display = "none"; + savedAlertModalElement.style.display = "block"; + + hideEmployeeSavedAlertTimer = setTimeout(hideEmployeeSavedAlertModal, 1200); +} + +function hideEmployeeSavedAlertModal() { + if (hideEmployeeSavedAlertTimer) { + clearTimeout(hideEmployeeSavedAlertTimer); + } + + getSavedAlertModalElement().style.display = "none"; +} +// End save diff --git a/src/controllers/commands/employees/helpers/employeeHelper.ts b/src/controllers/commands/employees/helpers/employeeHelper.ts new file mode 100644 index 0000000..acb8102 --- /dev/null +++ b/src/controllers/commands/employees/helpers/employeeHelper.ts @@ -0,0 +1,9 @@ +import { EmployeeClassification } from "../../models/constants/entityTypes"; + +export const hashString = (toHash: string): string => { + return ""; // TODO: Look at https://nodejs.org/docs/latest-v12.x/api/crypto.html#crypto_crypto_createhash_algorithm_options as one option +}; + +export const isElevatedUser = (employeeClassification: EmployeeClassification): boolean => { + return false; // TODO: Determine if an employee is an elevated user by their classification +}; diff --git a/src/controllers/commands/models/constants/entityTypes.ts b/src/controllers/commands/models/constants/entityTypes.ts new file mode 100644 index 0000000..f017e20 --- /dev/null +++ b/src/controllers/commands/models/constants/entityTypes.ts @@ -0,0 +1,6 @@ +export enum EmployeeClassification { + NotDefined = -1, + Cashier = 101, + ShiftManager = 501, + GeneralManager = 701 +} diff --git a/src/controllers/employeeDetailRouteController.ts b/src/controllers/employeeDetailRouteController.ts new file mode 100644 index 0000000..2e35c80 --- /dev/null +++ b/src/controllers/employeeDetailRouteController.ts @@ -0,0 +1,109 @@ +import { Request, Response } from "express"; +import * as Helper from "./helpers/routeControllerHelper"; +import { Resources, ResourceKey } from "../resourceLookup"; +import * as EmployeeHelper from "./commands/employees/helpers/employeeHelper"; +import * as ValidateActiveUser from "./commands/activeUsers/validateActiveUserCommand"; +import { CommandResponse, Employee, EmployeeSaveRequest, ActiveUser } from "./typeDefinitions"; + +interface CanCreateEmployee { + employeeExists: boolean; + isElevatedUser: boolean; +} + +const determineCanCreateEmployee = async (req: Request): Promise => { + // TODO: Logic to determine if the user associated with the current session + // is able to create an employee + return { employeeExists: false, isElevatedUser: false }; +}; + +export const start = async (req: Request, res: Response): Promise => { + if (Helper.handleInvalidSession(req, res)) { + return; + } + + return determineCanCreateEmployee(req) + .then((canCreateEmployee: CanCreateEmployee): void => { + if (canCreateEmployee.employeeExists + && !canCreateEmployee.isElevatedUser) { + + return res.redirect(Helper.buildNoPermissionsRedirectUrl()); + } + + // TODO: Serve up the page + }).catch((error: any): void => { + // TODO: Handle any errors that occurred + }); +}; + +export const startWithEmployee = async (req: Request, res: Response): Promise => { + if (Helper.handleInvalidSession(req, res)) { + return; + } + + return ValidateActiveUser.execute((req.session).id) + .then((activeUserCommandResponse: CommandResponse): Promise => { + if (!EmployeeHelper.isElevatedUser((activeUserCommandResponse.data).classification)) { + return Promise.reject(>{ + status: 403, + message: Resources.getString(ResourceKey.USER_NO_PERMISSIONS) + }); + } + + // TODO: Query the employee details using the request route parameter + return Promise.resolve(); + }).then((/* TODO: Some employee details */): void => { + // TODO: Serve up the page + }).catch((error: any): void => { + // TODO: Handle any errors that occurred + }); +}; + +const saveEmployee = async ( + req: Request, + res: Response, + performSave: ( + employeeSaveRequest: EmployeeSaveRequest, + isInitialEmployee?: boolean + ) => Promise> +): Promise => { + + if (Helper.handleInvalidApiSession(req, res)) { + return; + } + + let employeeExists: boolean; + + return determineCanCreateEmployee(req) + .then((canCreateEmployee: CanCreateEmployee): Promise> => { + if (canCreateEmployee.employeeExists + && !canCreateEmployee.isElevatedUser) { + + return Promise.reject(>{ + status: 403, + message: Resources.getString(ResourceKey.USER_NO_PERMISSIONS) + }); + } + + employeeExists = canCreateEmployee.employeeExists; + + return performSave(req.body, !employeeExists); + }).then((saveEmployeeCommandResponse: CommandResponse): void => { + // TODO: Handle the save response and send a response to the HTTP request + }).catch((error: any): void => { + return Helper.processApiError( + error, + res, + { + defaultErrorMessage: Resources.getString( + ResourceKey.EMPLOYEE_UNABLE_TO_SAVE) + }); + }); +}; + +export const updateEmployee = async (req: Request, res: Response): Promise => { + return; // TODO: invoke saveEmployee() with the appropriate save functionality +}; + +export const createEmployee = async (req: Request, res: Response): Promise => { + return; // TODO: invoke saveEmployee() with the appropriate save functionality +}; diff --git a/src/controllers/typeDefinitions.ts b/src/controllers/typeDefinitions.ts index 52d81d3..22ee42b 100644 --- a/src/controllers/typeDefinitions.ts +++ b/src/controllers/typeDefinitions.ts @@ -4,6 +4,17 @@ export interface ProductSaveRequest { count: number; lookupCode: string; } + +export interface EmployeeSaveRequest { + id?: string; + active: boolean; + lastName: string; + password: string; + firstName: string; + managerId?: string; + classification: number; + isInitialEmployee?: boolean; +} // End request object definitions // Response object definitions diff --git a/views/employeeDetail.ejs b/views/employeeDetail.ejs new file mode 100644 index 0000000..79376fa --- /dev/null +++ b/views/employeeDetail.ejs @@ -0,0 +1,74 @@ + + + + Register - Employee + + + + + + + + + + +
+

Employee Detail

+
+ +
+
class="hidden" <% } %>> +

+ <% if (locals.errorMessage && (locals.errorMessage !== "")) { %> + <%= locals.errorMessage %> + <% } %> +

+
+ +
+ + + + + + + + + + + class="hidden"<% } %>> + + + + + +
Employee ID: + +
+
+ + + + +
+ + + + + + \ No newline at end of file From 5c1141479136639ada1ba9b8785970d06d8e684a Mon Sep 17 00:00:00 2001 From: Reid Phillips Date: Wed, 8 Jan 2020 08:51:48 -0600 Subject: [PATCH 02/53] Updates to the product details route controller for sprint 2 functionality, incomplete. --- .../productDetailRouteController.ts | 50 ++++++++++++++----- 1 file changed, 38 insertions(+), 12 deletions(-) diff --git a/src/controllers/productDetailRouteController.ts b/src/controllers/productDetailRouteController.ts index 460aa78..53da925 100644 --- a/src/controllers/productDetailRouteController.ts +++ b/src/controllers/productDetailRouteController.ts @@ -1,11 +1,13 @@ import { Request, Response } from "express"; +import * as Helper from "./helpers/routeControllerHelper"; import { Resources, ResourceKey } from "../resourceLookup"; import * as ProductQuery from "./commands/products/productQuery"; -import { ViewNameLookup, ParameterLookup, RouteLookup } from "./lookups/routingLookup"; import * as ProductCreateCommand from "./commands/products/productCreateCommand"; import * as ProductDeleteCommand from "./commands/products/productDeleteCommand"; import * as ProductUpdateCommand from "./commands/products/productUpdateCommand"; -import { CommandResponse, Product, ProductDetailPageResponse, ApiResponse, ProductSaveResponse, ProductSaveRequest } from "./typeDefinitions"; +import * as ValidateActiveUser from "./commands/activeUsers/validateActiveUserCommand"; +import { ViewNameLookup, ParameterLookup, RouteLookup } from "./lookups/routingLookup"; +import { CommandResponse, Product, ProductDetailPageResponse, ApiResponse, ProductSaveResponse, ProductSaveRequest, ActiveUser } from "./typeDefinitions"; const processStartProductDetailError = (res: Response, error: any): void => { let errorMessage: (string | undefined) = ""; @@ -45,17 +47,33 @@ const saveProduct = async ( performSave: (productSaveRequest: ProductSaveRequest) => Promise> ): Promise => { - return performSave(req.body) - .then((createProductCommandResponse: CommandResponse): void => { + if (Helper.handleInvalidApiSession(req, res)) { + return; + } + + return ValidateActiveUser.execute((req.session).id) + .then((activeUserCommandResponse: CommandResponse): Promise> => { + if (false/* TODO: Verify that the user associated with the current session is elevated or not */) { + return Promise.reject(>{ + status: 403, + message: Resources.getString(ResourceKey.USER_NO_PERMISSIONS) + }); + } + + return performSave(req.body); + }).then((createProductCommandResponse: CommandResponse): void => { res.status(createProductCommandResponse.status) .send({ product: createProductCommandResponse.data }); }).catch((error: any): void => { - res.status(error.status || 500) - .send({ - errorMessage: (error.message - || Resources.getString(ResourceKey.PRODUCT_UNABLE_TO_SAVE)) + return Helper.processApiError( + error, + res, + { + redirectBaseLocation: RouteLookup.ProductListing, + defaultErrorMessage: Resources.getString( + ResourceKey.PRODUCT_UNABLE_TO_SAVE) }); }); }; @@ -69,6 +87,11 @@ export const createProduct = async (req: Request, res: Response): Promise }; export const deleteProduct = async (req: Request, res: Response): Promise => { + if (Helper.handleInvalidApiSession(req, res)) { + return; + } + + // TODO: Verify that the user associated with the current session is elevated or not return ProductDeleteCommand.execute(req.params[ParameterLookup.ProductId]) .then((deleteProductCommandResponse: CommandResponse): void => { res.status(deleteProductCommandResponse.status) @@ -76,10 +99,13 @@ export const deleteProduct = async (req: Request, res: Response): Promise redirectUrl: RouteLookup.ProductListing }); }).catch((error: any): void => { - res.status(error.status || 500) - .send({ - errorMessage: (error.message - || Resources.getString(ResourceKey.PRODUCT_UNABLE_TO_DELETE)) + return Helper.processApiError( + error, + res, + { + redirectBaseLocation: RouteLookup.ProductListing, + defaultErrorMessage: Resources.getString( + ResourceKey.PRODUCT_UNABLE_TO_DELETE) }); }); }; From 4a2830dfea6971bc8b58969bd95a5ef17af4dbab Mon Sep 17 00:00:00 2001 From: Reid Phillips Date: Fri, 24 Jan 2020 09:12:48 -0600 Subject: [PATCH 03/53] Load string resources at app startup. --- src/app.ts | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/app.ts b/src/app.ts index cf7f595..a5704c8 100644 --- a/src/app.ts +++ b/src/app.ts @@ -7,6 +7,7 @@ import * as fileSystem from "fs"; import bodyParser from "body-parser"; import compression from "compression"; import session from "express-session"; +import { Resources } from "./resourceLookup"; // Load environment variables from .env file, where API keys and passwords are configured dotenv.config({ path: ".env" }); @@ -46,4 +47,6 @@ fileSystem.readdirSync(__dirname + "/routes").forEach(function (routeConfig: str } }); +Resources.loadStrings(); + export default app; \ No newline at end of file From d44adeb88280b6bf36b7a8bc9f6cd51fc5add6bb Mon Sep 17 00:00:00 2001 From: robertjohnsonark <60170193+robertjohnsonark@users.noreply.github.com> Date: Thu, 20 Feb 2020 12:53:19 -0600 Subject: [PATCH 04/53] updated signIn.ejs for sprint 2 task 2 added input elements to for the sign in form --- views/signIn.ejs | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/views/signIn.ejs b/views/signIn.ejs index 556f05c..62dcd4d 100644 --- a/views/signIn.ejs +++ b/views/signIn.ejs @@ -26,10 +26,14 @@
- +
+
+
+

+
- \ No newline at end of file + From 5adb8146147d9e90901018d60138b9ba321bc074 Mon Sep 17 00:00:00 2001 From: bouchara0303 Date: Thu, 20 Feb 2020 13:50:31 -0600 Subject: [PATCH 05/53] Routing for sign in page --- src/controllers/signInRouteController.ts | 39 ++++++++++++++++++++++++ src/routes/signInRoutes.ts | 1 + 2 files changed, 40 insertions(+) diff --git a/src/controllers/signInRouteController.ts b/src/controllers/signInRouteController.ts index 6363b08..bd0212f 100644 --- a/src/controllers/signInRouteController.ts +++ b/src/controllers/signInRouteController.ts @@ -1,9 +1,48 @@ import { Request, Response } from "express"; +import { Resources } from "../resourceLookup"; +import * as Helper from "./helpers/routeControllerHelper"; +import { ViewNameLookup, QueryParameterLookup } from "./lookups/routingLookup"; +import * as ValidateActiveUser from "./commands/activeUsers/validateActiveUserCommand"; +import { PageResponse, CommandResponse, MainMenuPageResponse, ActiveUser } from "./typeDefinitions"; + +export const start = async (req: Request, res: Response): Promise => { + if (Helper.handleInvalidSession(req, res)) { + return; + } + + return res.render( + ViewNameLookup.SignIn, + { + errorMessage: + Resources.getString(req.query[QueryParameterLookup.ErrorCode]) + }); +}; export const signIn = async (req: Request, res: Response): Promise => { // TODO: Use the credentials provided in the request body (req.body) // and the "id" property of the (Express.Session)req.session variable // to sign in the user + if (Helper.handleInvalidSession(req, res)) { + return; + } + + return ValidateActiveUser.execute((req.session).id).then((activeUserCommandResponse: CommandResponse): void => { + const isElevatedUser: boolean = true; + + return res.render( + ViewNameLookup.MainMenu, + { + isElevatedUser: isElevatedUser, + errorMessage: + Resources.getString(req.query[QueryParameterLookup.ErrorCode]) + }); + }).catch((error: any): void => { + if (Helper.processStartError(error, res)) { + return res.render( + ViewNameLookup.SignIn, + { errorMessage: error.message}); + } + }); }; export const clearActiveUser = async (req: Request, res: Response): Promise => { diff --git a/src/routes/signInRoutes.ts b/src/routes/signInRoutes.ts index 2ba6248..b2c0589 100644 --- a/src/routes/signInRoutes.ts +++ b/src/routes/signInRoutes.ts @@ -4,6 +4,7 @@ import * as SignInRouteController from "../controllers/signInRouteController"; function signInRoutes(server: express.Express) { // TODO: Route for initial page load + server.get(RouteLookup.SignIn, SignInRouteController.start); server.post(RouteLookup.SignIn, SignInRouteController.signIn); From f2dc9eee7bd12e5d19bb54b6fb6e2f953dc39c04 Mon Sep 17 00:00:00 2001 From: EmrLan <57022651+EmrLan@users.noreply.github.com> Date: Thu, 20 Feb 2020 15:53:25 -0600 Subject: [PATCH 06/53] Task 3: Sign In - Client-side functionality --- public/scripts/signIn.js | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/public/scripts/signIn.js b/public/scripts/signIn.js index 9d69ba7..92752d9 100644 --- a/public/scripts/signIn.js +++ b/public/scripts/signIn.js @@ -4,5 +4,20 @@ document.addEventListener("DOMContentLoaded", () => { function validateForm() { // TODO: Validate the user input + var employeeID = document.getElementById("employeeID").value; + var password = document.getElementById("password").value; + + if(isNaN(employeeID)) + { + alert("Enter a valid ID number") + return false; + } + + if(password == "") + { + alert("Enter a password") + return false; + } + return true; } From 2d30ee00bbe838146abd5a5578985c8e8ab5ab87 Mon Sep 17 00:00:00 2001 From: benguthrie44 <60238133+benguthrie44@users.noreply.github.com> Date: Thu, 20 Feb 2020 18:03:58 -0600 Subject: [PATCH 07/53] Add files via upload Added other employee inputs. Also added basic save button w/o functionality. --- views/employeeDetail.ejs | 37 +++++++++++++++++++++++++++++++++++++ 1 file changed, 37 insertions(+) diff --git a/views/employeeDetail.ejs b/views/employeeDetail.ejs index 79376fa..8c3e975 100644 --- a/views/employeeDetail.ejs +++ b/views/employeeDetail.ejs @@ -47,11 +47,48 @@ + + First Name: + + + + + + Last Name: + + + + + + Password: + + + + + + Confirm Password: + + + + + + Employee Type: + +
+
+

+ + + + + + + From 15b3941ebe82a3887ec4c66214c45627bf640c98 Mon Sep 17 00:00:00 2001 From: bouchara0303 Date: Tue, 3 Mar 2020 13:31:19 -0600 Subject: [PATCH 23/53] Added ViewNameLookup.SignIn --- src/controllers/lookups/routingLookup.ts | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/controllers/lookups/routingLookup.ts b/src/controllers/lookups/routingLookup.ts index 458042d..a889f60 100644 --- a/src/controllers/lookups/routingLookup.ts +++ b/src/controllers/lookups/routingLookup.ts @@ -10,7 +10,8 @@ export enum QueryParameterLookup { export enum ViewNameLookup { ProductDetail = "productDetail", ProductListing = "productListing", - EmployeeDetail = "employeeDetail" + EmployeeDetail = "employeeDetail", + SignIn = "signIn" } export enum RouteLookup { From 1c8ed69d71a3e8626267dc92ce669bfce85649f9 Mon Sep 17 00:00:00 2001 From: Lily Date: Tue, 3 Mar 2020 14:52:34 -0600 Subject: [PATCH 24/53] Added view functionality to product details for elevated users. Way to check elevated users not implemented yet --- src/controllers/productDetailRouteController.ts | 13 +++++++++++++ views/productDetail.ejs | 7 +++++++ 2 files changed, 20 insertions(+) diff --git a/src/controllers/productDetailRouteController.ts b/src/controllers/productDetailRouteController.ts index 460aa78..055c18b 100644 --- a/src/controllers/productDetailRouteController.ts +++ b/src/controllers/productDetailRouteController.ts @@ -7,6 +7,9 @@ import * as ProductDeleteCommand from "./commands/products/productDeleteCommand" import * as ProductUpdateCommand from "./commands/products/productUpdateCommand"; import { CommandResponse, Product, ProductDetailPageResponse, ApiResponse, ProductSaveResponse, ProductSaveRequest } from "./typeDefinitions"; +//Other Imports +import * as ValidateActiveUser from "./commands/activeUsers/validateActiveUserCommand"; + const processStartProductDetailError = (res: Response, error: any): void => { let errorMessage: (string | undefined) = ""; if ((error.status != null) && (error.status >= 500)) { @@ -29,9 +32,19 @@ const processStartProductDetailError = (res: Response, error: any): void => { export const start = async (req: Request, res: Response): Promise => { return ProductQuery.queryById(req.params[ParameterLookup.ProductId]) .then((productsCommandResponse: CommandResponse): void => { + //Copy paste from mainMenuRouteController + const isElevatedUser: boolean = true; + + //Check for isElevatedUser + + //const isElevatedUser: boolean = false; + // EmployeeHelper.isElevatedUser( + // (activeUserCommandResponse.data).classification); + return res.render( ViewNameLookup.ProductDetail, { + isElevatedUser: isElevatedUser, product: productsCommandResponse.data }); }).catch((error: any): void => { diff --git a/views/productDetail.ejs b/views/productDetail.ejs index 16dc167..6839a29 100644 --- a/views/productDetail.ejs +++ b/views/productDetail.ejs @@ -50,6 +50,13 @@ + + <% if (!locals.isElevatedUser) { %> + <% document.getElementById("saveButton").style.display = "none"; %> + <% document.getElementById("deleteButton").style.display = "none"; %> + <% document.getElementById("productLookupCode").disabled = true; %> + <% document.getElementById("productCount").disabled = true; %> + <% } %>

From 1f4afb3c80101a05e5c18a8652372e1abf160432 Mon Sep 17 00:00:00 2001 From: robertjohnsonark <60170193+robertjohnsonark@users.noreply.github.com> Date: Tue, 3 Mar 2020 22:53:47 -0600 Subject: [PATCH 25/53] Update employeeDetail.js --- public/scripts/employeeDetail.js | 65 ++++++++++++++++++++++++++++++++ 1 file changed, 65 insertions(+) diff --git a/public/scripts/employeeDetail.js b/public/scripts/employeeDetail.js index fa001a2..b4de401 100644 --- a/public/scripts/employeeDetail.js +++ b/public/scripts/employeeDetail.js @@ -8,6 +8,12 @@ document.addEventListener("DOMContentLoaded", () => { // Save function saveActionClick(event) { // TODO: Actually save the employee via an AJAX call + if (!validateSave()) { + return; + } + + const saveActionElement = event.target; + saveActionElement.disabled = true; displayEmployeeSavedAlertModal(); } @@ -16,22 +22,34 @@ function validateSave() { const employeeFirstName = getEmployeeFirstName(); if ((employeeFirstName == null) || (employeeFirstName.trim() === "")) { displayError("Please provide your first name."); + employeeFirstName.focus(); + employeeFirstName.select(); return false; } const employeeLastName = getEmployeeLastName(); if ((employeeLastName == null) || (employeeLastName.trim() === "")) { displayError("Please provide your last name."); + employeeLastName.focus(); + employeeLastName.select(); return false; } const employeePassword = getEmployeePassword(); if ((employeePassword == null) || (employeePassword.trim() === "") || (employeePassword != getEmployeeConfirmPassword())) { displayError("The password you entered is not correct."); + employeePassword.focus(); + employeePassword.select(); return false; } const employeeType = getEmployeeType(); + if ((employeeType == null) || (employeeType.trim() === "")) { + displayError("Please provide a valid employee type."); + employeeType.focus(); + employeeType.select(); + return false; + } return true; } @@ -55,9 +73,46 @@ function hideEmployeeSavedAlertModal() { getSavedAlertModalElement().style.display = "none"; } + +function ajaxPost(resourceRelativeUri, data, ajaxPatch) { + return ajax(resourceRelativeUri, "POST", data, callback); +} + +function ajaxPatch(resourceRelativeUri, data, callback) { + return ajax(resourceRelativeUri, "PATCH", data, callback); +} + +function ajax(resourceRelativeUri, verb, data, callback) { + const httpRequest = new XMLHttpRequest(); + + if (httpRequest == null) { + return httpRequest; + } + + httpRequest.onreadystatechange = () => { + if (httpRequest.readyState === XMLHttpRequest.DONE) { + if ((httpRequest.status >= 200) && (httpRequest.status < 300)) { + handleSuccessResponse(httpRequest, callback); + } else { + handleFailureResponse(httpRequest, callback); + } + } + }; + + httpRequest.open(verb, resourceRelativeUri, true); + if (data != null) { + httpRequest.setRequestHeader('Content-Type', 'application/json'); + httpRequest.send(JSON.stringify(data)); + } else { + httpRequest.send(); + } + + return httpRequest; +} // End save // Getters and setters + function getSaveActionElement() { return document.getElementById("saveButton"); } @@ -97,3 +152,13 @@ function getEmployeeConfirmPassword() { function getEmployeeConfirmPasswordElement() { return document.getElementById("employeeConfirmPassword"); } + +function getEmployeeType() { + return getEmployeeTypeElement().value; +} + +function getEmployeeTypeElement() { + return document.getElementById("employeeType"); +} + +// End getters and setters \ No newline at end of file From 466d6f660768a36928bf9b61cadc661484615332 Mon Sep 17 00:00:00 2001 From: bouchara0303 Date: Wed, 4 Mar 2020 08:10:25 -0600 Subject: [PATCH 26/53] GET request controllers --- .../employeeDetailRouteController.ts | 113 ++++++++++-------- 1 file changed, 64 insertions(+), 49 deletions(-) diff --git a/src/controllers/employeeDetailRouteController.ts b/src/controllers/employeeDetailRouteController.ts index 7d41c97..de212ec 100644 --- a/src/controllers/employeeDetailRouteController.ts +++ b/src/controllers/employeeDetailRouteController.ts @@ -2,9 +2,11 @@ import { Request, Response } from "express"; import * as Helper from "./helpers/routeControllerHelper"; import { Resources, ResourceKey } from "../resourceLookup"; import * as EmployeeHelper from "./commands/employees/helpers/employeeHelper"; +import * as EmployeeQuery from "./commands/employees/employeeQuery"; import { ViewNameLookup, ParameterLookup, RouteLookup } from "./lookups/routingLookup"; import * as ValidateActiveUser from "./commands/activeUsers/validateActiveUserCommand"; -import { CommandResponse, Employee, EmployeeSaveRequest, ActiveUser } from "./typeDefinitions"; +import * as ActiveEmployeeExistsQuery from "./commands/employees/activeEmployeeExistsQuery" +import { CommandResponse, Employee, EmployeeSaveRequest, ActiveUser, PageResponse } from "./typeDefinitions"; interface CanCreateEmployee { employeeExists: boolean; @@ -12,60 +14,72 @@ interface CanCreateEmployee { } const determineCanCreateEmployee = async (req: Request): Promise => { - // TODO: Logic to determine if the user associated with the current session - // is able to create an employee - return { employeeExists: false, isElevatedUser: false }; + return ActiveEmployeeExists() + .then((activeUserCommandResponse: >): Promise => { + return ValidateActiveUser(req.session.id) + .then((activeUser: CommandResponse): Promise => { + if (EmployeeHelper.isElevatedUser(activeUser.data)) { + return { employeeExists: true, isElevatedUser: false }; + } + + return { employeeExists: true, isElevatedUser: false } + }).catch(()=>{ + return { employeeExists: true, isElevatedUser: false}; + }); + return { employeeExists: true, isElevatedUser: false }; + }).catch((error: any): Promise => { + return { employeeExists: false, isElevatedUser: false }; + }); }; export const start = async (req: Request, res: Response): Promise => { - if (Helper.handleInvalidSession(req, res)) { - return; - } - - return determineCanCreateEmployee(req) - .then((canCreateEmployee: CanCreateEmployee): void => { - if (canCreateEmployee.employeeExists - && !canCreateEmployee.isElevatedUser) { - - return res.redirect(Helper.buildNoPermissionsRedirectUrl()); - } - - return res.render(ViewNameLookup.EmployeeDetail); - }).catch((error: any): void => { - let errorMessage: (string | undefined) = ""; - if ((error.status != null) && (error.status >= 500)) { - errorMessage = error.message; + if (Helper.handleInvalidSession(req, res)) { + return; + } + + return determineCanCreateEmployee(req) + .then((canCreateEmployee: CanCreateEmployee): void => { + if (canCreateEmployee.employeeExists + && !canCreateEmployee.isElevatedUser) { + return res.redirect(Helper.buildNoPermissionsRedirectUrl()); + } + else if (!canCreateEmployee.employeeExists || canCreateEmployee.isElevatedUser) { + return res.render(ViewNameLookup.EmployeeDetail); } - return res.render(ViewNameLookup.EmployeeDetail, { - errorMessage: errorMessage + return res.render(ViewNameLookup.SignIn, { + errorMessage: ResouResources.getString(ResourceKey.USER_SESSION_NOT_ACTIVE) }); - }); - }; - -export const startWithEmployee = async (req: Request, res: Response): Promise => { - if (Helper.handleInvalidSession(req, res)) { - return; - } - - return ValidateActiveUser.execute((req.session).id) - .then((activeUserCommandResponse: CommandResponse): Promise => { - if (!EmployeeHelper.isElevatedUser((activeUserCommandResponse.data).classification)) { - return Promise.reject(>{ - status: 403, - message: Resources.getString(ResourceKey.USER_NO_PERMISSIONS) + }).catch((error: any): void => { + return res.render(ViewNameLookup.SignIn, { + errorMessage: Resources.getString(ResourceKey.USER_SESSION_NOT_FOUND) + }); + }); + }; + + export const startWithEmployee = async (req: Request, res: Response): Promise => { + if (Helper.handleInvalidSession(req, res)) { + return; + } + + return ValidateActiveUser.execute((req.session).id) + .then((activeUserCommandResponse: CommandResponse): Promise => { + if (!EmployeeHelper.isElevatedUser((activeUserCommandResponse.data).classification)) { + return Promise.reject(>{ + status: 403, + message: Resources.getString(ResourceKey.USER_NO_PERMISSIONS) + }); + } + + return EmployeeQuery.execute(activeUserCommandResponse.data.id); + }).then((employee: Employee): void => { + return res.render(ViewNameLookup.EmployeeDetail, employee); + }).catch((error: any): void => { + return res.redirect(RouteLookup.SignIn, { + errorMessage: error.message }); - } - - // TODO: Query the employee details using the request route parameter - const req.params[ParameterLookup.EmployeeId] - return Promise.resolve(); - }).then((/* TODO: Some employee details */): void => { - // TODO: Serve up the page - }).catch((error: any): void => { - // TODO: Handle any errors that occurred - }); -}; + }); + }; const saveEmployee = async ( req: Request, @@ -110,9 +124,10 @@ const saveEmployee = async ( }; export const updateEmployee = async (req: Request, res: Response): Promise => { - return; // TODO: invoke saveEmployee() with the appropriate save functionality + return saveEmployee(req, res, ); // TODO: invoke saveEmployee() with the appropriate save functionality }; export const createEmployee = async (req: Request, res: Response): Promise => { + return; // TODO: invoke saveEmployee() with the appropriate save functionality }; From 57762ea91324d9daab1fe3bb757f210d0aaf227e Mon Sep 17 00:00:00 2001 From: bouchara0303 Date: Wed, 4 Mar 2020 10:19:24 -0600 Subject: [PATCH 27/53] Finished route controller --- .../employeeDetailRouteController.ts | 99 ++++++++++--------- 1 file changed, 52 insertions(+), 47 deletions(-) diff --git a/src/controllers/employeeDetailRouteController.ts b/src/controllers/employeeDetailRouteController.ts index de212ec..e44592e 100644 --- a/src/controllers/employeeDetailRouteController.ts +++ b/src/controllers/employeeDetailRouteController.ts @@ -3,6 +3,8 @@ import * as Helper from "./helpers/routeControllerHelper"; import { Resources, ResourceKey } from "../resourceLookup"; import * as EmployeeHelper from "./commands/employees/helpers/employeeHelper"; import * as EmployeeQuery from "./commands/employees/employeeQuery"; +import * as EmployeeCreateCommand from "./commands/employees/employeeCreateCommand"; +import * as EmployeeUpdateCommand from "./commands/employees/employeeUpdateCommand"; import { ViewNameLookup, ParameterLookup, RouteLookup } from "./lookups/routingLookup"; import * as ValidateActiveUser from "./commands/activeUsers/validateActiveUserCommand"; import * as ActiveEmployeeExistsQuery from "./commands/employees/activeEmployeeExistsQuery" @@ -15,7 +17,7 @@ interface CanCreateEmployee { const determineCanCreateEmployee = async (req: Request): Promise => { return ActiveEmployeeExists() - .then((activeUserCommandResponse: >): Promise => { + .then((activeUserCommandResponse: CommandResponse): Promise => { return ValidateActiveUser(req.session.id) .then((activeUser: CommandResponse): Promise => { if (EmployeeHelper.isElevatedUser(activeUser.data)) { @@ -33,53 +35,53 @@ const determineCanCreateEmployee = async (req: Request): Promise => { - if (Helper.handleInvalidSession(req, res)) { - return; - } - - return determineCanCreateEmployee(req) - .then((canCreateEmployee: CanCreateEmployee): void => { - if (canCreateEmployee.employeeExists - && !canCreateEmployee.isElevatedUser) { - return res.redirect(Helper.buildNoPermissionsRedirectUrl()); - } + if (Helper.handleInvalidSession(req, res)) { + return; + } + + return determineCanCreateEmployee(req) + .then((canCreateEmployee: CanCreateEmployee): void => { + if (canCreateEmployee.employeeExists + && !canCreateEmployee.isElevatedUser) { + return res.redirect(Helper.buildNoPermissionsRedirectUrl()); + } else if (!canCreateEmployee.employeeExists || canCreateEmployee.isElevatedUser) { return res.render(ViewNameLookup.EmployeeDetail); } - return res.render(ViewNameLookup.SignIn, { + return res.render(ViewNameLookup.SignIn, { errorMessage: ResouResources.getString(ResourceKey.USER_SESSION_NOT_ACTIVE) }); - }).catch((error: any): void => { + }).catch((error: any): void => { return res.render(ViewNameLookup.SignIn, { errorMessage: Resources.getString(ResourceKey.USER_SESSION_NOT_FOUND) }); - }); - }; - - export const startWithEmployee = async (req: Request, res: Response): Promise => { - if (Helper.handleInvalidSession(req, res)) { - return; - } - - return ValidateActiveUser.execute((req.session).id) - .then((activeUserCommandResponse: CommandResponse): Promise => { - if (!EmployeeHelper.isElevatedUser((activeUserCommandResponse.data).classification)) { - return Promise.reject(>{ - status: 403, - message: Resources.getString(ResourceKey.USER_NO_PERMISSIONS) - }); - } - - return EmployeeQuery.execute(activeUserCommandResponse.data.id); - }).then((employee: Employee): void => { - return res.render(ViewNameLookup.EmployeeDetail, employee); - }).catch((error: any): void => { - return res.redirect(RouteLookup.SignIn, { - errorMessage: error.message - }); - }); - }; + }); + }; + +export const startWithEmployee = async (req: Request, res: Response): Promise => { + if (Helper.handleInvalidSession(req, res)) { + return; + } + + return ValidateActiveUser.execute((req.session).id) + .then((activeUserCommandResponse: CommandResponse): Promise => { + if (!EmployeeHelper.isElevatedUser((activeUserCommandResponse.data).classification)) { + return Promise.reject(>{ + status: 403, + message: Resources.getString(ResourceKey.USER_NO_PERMISSIONS) + }); + } + + return EmployeeQuery.execute(activeUserCommandResponse.data.id); + }).then((employee: Employee): void => { + return res.render(ViewNameLookup.EmployeeDetail, employee); + }).catch((error: any): void => { + return res.redirect(RouteLookup.SignIn, { + errorMessage: error.message + }); + }); +}; const saveEmployee = async ( req: Request, @@ -97,9 +99,9 @@ const saveEmployee = async ( let employeeExists: boolean; return determineCanCreateEmployee(req) - .then((canCreateEmployee: CanCreateEmployee): Promise> => { - if (canCreateEmployee.employeeExists - && !canCreateEmployee.isElevatedUser) { + .then((canCreateEmployee: CanCreateEmployee): Promise> => { + if (canCreateEmployee.employeeExists + && !canCreateEmployee.isElevatedUser) { return Promise.reject(>{ status: 403, @@ -111,7 +113,10 @@ const saveEmployee = async ( return performSave(req.body, !employeeExists); }).then((saveEmployeeCommandResponse: CommandResponse): void => { - // TODO: Handle the save response and send a response to the HTTP request + res.status(saveEmployeeCommandResponse.status) + .send({ + redirectUrl: RouteLookup.SignIn + "?id=" + saveEmployeeCommandResponse.data.id + }); }).catch((error: any): void => { return Helper.processApiError( error, @@ -119,15 +124,15 @@ const saveEmployee = async ( { defaultErrorMessage: Resources.getString( ResourceKey.EMPLOYEE_UNABLE_TO_SAVE) + }); }); - }); -}; + }; export const updateEmployee = async (req: Request, res: Response): Promise => { - return saveEmployee(req, res, ); // TODO: invoke saveEmployee() with the appropriate save functionality + return saveEmployee(req, res, EmployeeUpdateCommand.execute); }; export const createEmployee = async (req: Request, res: Response): Promise => { - return; // TODO: invoke saveEmployee() with the appropriate save functionality + return saveEmployee(req, res, EmployeeSaveCommand.execute); }; From 0bb5f79c14b4ca12ff716fbf3f8229eafb4721b9 Mon Sep 17 00:00:00 2001 From: bouchara0303 Date: Wed, 4 Mar 2020 11:46:09 -0600 Subject: [PATCH 28/53] Bugs --- .../employeeDetailRouteController.ts | 43 +++++++++---------- src/controllers/lookups/routingLookup.ts | 3 +- 2 files changed, 22 insertions(+), 24 deletions(-) diff --git a/src/controllers/employeeDetailRouteController.ts b/src/controllers/employeeDetailRouteController.ts index e44592e..75fd431 100644 --- a/src/controllers/employeeDetailRouteController.ts +++ b/src/controllers/employeeDetailRouteController.ts @@ -8,7 +8,7 @@ import * as EmployeeUpdateCommand from "./commands/employees/employeeUpdateComma import { ViewNameLookup, ParameterLookup, RouteLookup } from "./lookups/routingLookup"; import * as ValidateActiveUser from "./commands/activeUsers/validateActiveUserCommand"; import * as ActiveEmployeeExistsQuery from "./commands/employees/activeEmployeeExistsQuery" -import { CommandResponse, Employee, EmployeeSaveRequest, ActiveUser, PageResponse } from "./typeDefinitions"; +import { ApiResponse, CommandResponse, Employee, EmployeeSaveRequest, ActiveUser, PageResponse } from "./typeDefinitions"; interface CanCreateEmployee { employeeExists: boolean; @@ -16,21 +16,20 @@ interface CanCreateEmployee { } const determineCanCreateEmployee = async (req: Request): Promise => { - return ActiveEmployeeExists() - .then((activeUserCommandResponse: CommandResponse): Promise => { - return ValidateActiveUser(req.session.id) + return ActiveEmployeeExistsQuery.execute() + .then((activeUserCommandResponse: CommandResponse): Promise => { + return ValidateActiveUser.execute(req.session!.id) .then((activeUser: CommandResponse): Promise => { - if (EmployeeHelper.isElevatedUser(activeUser.data)) { - return { employeeExists: true, isElevatedUser: false }; + if (EmployeeHelper.isElevatedUser(activeUser.data!.classification)) { + return Promise.resolve( { employeeExists: true, isElevatedUser: false }); } - return { employeeExists: true, isElevatedUser: false } + return Promise.reject( { employeeExists: true, isElevatedUser: false }); }).catch(()=>{ - return { employeeExists: true, isElevatedUser: false}; + return Promise.reject( { employeeExists: true, isElevatedUser: false}); + }).catch((error: any): Promise => { + return Promise.resolve({ employeeExists: false, isElevatedUser: false }); }); - return { employeeExists: true, isElevatedUser: false }; - }).catch((error: any): Promise => { - return { employeeExists: false, isElevatedUser: false }; }); }; @@ -50,7 +49,7 @@ export const start = async (req: Request, res: Response): Promise => { } return res.render(ViewNameLookup.SignIn, { - errorMessage: ResouResources.getString(ResourceKey.USER_SESSION_NOT_ACTIVE) + errorMessage: Resources.getString(ResourceKey.USER_SESSION_NOT_ACTIVE) }); }).catch((error: any): void => { return res.render(ViewNameLookup.SignIn, { @@ -65,7 +64,7 @@ export const startWithEmployee = async (req: Request, res: Response): Promisereq.session).id) - .then((activeUserCommandResponse: CommandResponse): Promise => { + .then((activeUserCommandResponse: CommandResponse): Promise> => { if (!EmployeeHelper.isElevatedUser((activeUserCommandResponse.data).classification)) { return Promise.reject(>{ status: 403, @@ -73,13 +72,14 @@ export const startWithEmployee = async (req: Request, res: Response): Promise { - return res.render(ViewNameLookup.EmployeeDetail, employee); + return EmployeeQuery.execute(activeUserCommandResponse.data!.id); + }).then((employeeCommandResponse: CommandResponse): void => { + return res.render(ViewNameLookup.EmployeeDetail, employeeCommandResponse.data); }).catch((error: any): void => { - return res.redirect(RouteLookup.SignIn, { - errorMessage: error.message - }); + res.send({ + errorMessage: error.message, + redirectUrl: RouteLookup.SignIn + }) }); }; @@ -113,9 +113,9 @@ const saveEmployee = async ( return performSave(req.body, !employeeExists); }).then((saveEmployeeCommandResponse: CommandResponse): void => { - res.status(saveEmployeeCommandResponse.status) + res.status(saveEmployeeCommandResponse!.status) .send({ - redirectUrl: RouteLookup.SignIn + "?id=" + saveEmployeeCommandResponse.data.id + redirectUrl: RouteLookup.SignIn + "?id=" + saveEmployeeCommandResponse.data!.id }); }).catch((error: any): void => { return Helper.processApiError( @@ -133,6 +133,5 @@ export const updateEmployee = async (req: Request, res: Response): Promise }; export const createEmployee = async (req: Request, res: Response): Promise => { - return saveEmployee(req, res, EmployeeSaveCommand.execute); }; diff --git a/src/controllers/lookups/routingLookup.ts b/src/controllers/lookups/routingLookup.ts index 0822970..a0811d2 100644 --- a/src/controllers/lookups/routingLookup.ts +++ b/src/controllers/lookups/routingLookup.ts @@ -12,8 +12,7 @@ export enum ViewNameLookup { MainMenu = "mainMenu", ProductDetail = "productDetail", ProductListing = "productListing", - EmployeeDetail = "employeeDetail", - SignIn = "signIn" + EmployeeDetail = "employeeDetail" } export enum RouteLookup { From 53ac83c5a29b6c11f7e0e1a184cdd8b29b9d89aa Mon Sep 17 00:00:00 2001 From: bouchara0303 Date: Wed, 4 Mar 2020 12:17:52 -0600 Subject: [PATCH 29/53] isElevatedUser helper function --- src/controllers/commands/employees/helpers/employeeHelper.ts | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/controllers/commands/employees/helpers/employeeHelper.ts b/src/controllers/commands/employees/helpers/employeeHelper.ts index acb8102..2e92dec 100644 --- a/src/controllers/commands/employees/helpers/employeeHelper.ts +++ b/src/controllers/commands/employees/helpers/employeeHelper.ts @@ -5,5 +5,8 @@ export const hashString = (toHash: string): string => { }; export const isElevatedUser = (employeeClassification: EmployeeClassification): boolean => { - return false; // TODO: Determine if an employee is an elevated user by their classification + if ([EmployeeClassification.GeneralManager, EmployeeClassification.ShiftManager].indexOf(employeeClassification) <= -1) { + return false; + } + return true; }; From 583d6e89b2645878ac99c43ad219ee69401f215e Mon Sep 17 00:00:00 2001 From: Willard Date: Wed, 4 Mar 2020 12:25:59 -0600 Subject: [PATCH 30/53] Implement employeeCreateCommand and employeeUpdateCommand --- .../employees/employeeCreateCommand.ts | 88 +++++++++++++++++++ .../commands/employees/employeeQuery.ts | 33 +------ .../employees/employeeUpdateCommand.ts | 88 +++++++++++++++++++ .../employees/helpers/employeeHelper.ts | 16 ++++ 4 files changed, 195 insertions(+), 30 deletions(-) create mode 100644 src/controllers/commands/employees/employeeCreateCommand.ts create mode 100644 src/controllers/commands/employees/employeeUpdateCommand.ts diff --git a/src/controllers/commands/employees/employeeCreateCommand.ts b/src/controllers/commands/employees/employeeCreateCommand.ts new file mode 100644 index 0000000..3284819 --- /dev/null +++ b/src/controllers/commands/employees/employeeCreateCommand.ts @@ -0,0 +1,88 @@ +import Sequelize from "sequelize"; +import { EmployeeModel } from "../models/employeeModel"; +import * as EmployeeRepository from "../models/employeeModel"; +import { Resources, ResourceKey } from "../../../resourceLookup"; +import * as DatabaseConnection from "../models/databaseConnection"; +import { CommandResponse, Employee, EmployeeSaveRequest } from "../../typeDefinitions"; + +const validateSaveRequest = ( + saveEmployeeRequest: EmployeeSaveRequest +): CommandResponse => { + + let errorMessage: string = ""; + + if (!saveEmployeeRequest.firstName) { + errorMessage = Resources.getString(ResourceKey.EMPLOYEE_FIRST_NAME_INVALID); + } else if (!saveEmployeeRequest.lastName) { + errorMessage = Resources.getString(ResourceKey.EMPLOYEE_LAST_NAME_INVALID); + } else if (!saveEmployeeRequest.password) { + errorMessage = Resources.getString(ResourceKey.EMPLOYEE_PASSWORD_INVALID); + } + + return ((errorMessage === "") + ? >{ status: 200 } + : >{ + status: 422, + message: errorMessage + }); +}; + +export const execute = async ( + saveEmployeeRequest: EmployeeSaveRequest +): Promise> => { + + const validationResponse: CommandResponse = + validateSaveRequest(saveEmployeeRequest); + if (validationResponse.status !== 200) { + return Promise.reject(validationResponse); + } + + const employeeToCreate: EmployeeModel = { + id: saveEmployeeRequest.id, + active: saveEmployeeRequest.active, + lastName: saveEmployeeRequest.lastName, + firstName: saveEmployeeRequest.firstName, + managerId: saveEmployeeRequest.managerId, + classification: saveEmployeeRequest.classification + }; + + let createTransaction: Sequelize.Transaction; + + return DatabaseConnection.createTransaction() + .then((createdTransaction: Sequelize.Transaction): Promise => { + createTransaction = createdTransaction; + + return EmployeeModel.create( + employeeToCreate, + { + transaction: createTransaction + } + ); + }).then((createdEmployee: EmployeeModel): CommandResponse => { + createTransaction.commit(); + + return >{ + status: 201, + data: { + id: createdEmployee.id, + active: createdEmployee.active, + lastName: createdEmployee.lastName, + createdOn: createdEmployee.createdOn, + firstName: createdEmployee.firstName, + managerId: createdEmployee.managerId, + employeeId: createdEmployee.employeeId.toString(), + classification: createdEmployee.classification + } + }; + }).catch((error: any): Promise> => { + if (createTransaction != null) { + createTransaction.rollback(); + } + + return Promise.reject(>{ + status: (error.status || 500), + message: (error.message + || Resources.getString(ResourceKey.EMPLOYEE_UNABLE_TO_SAVE)) + }); + }); +}; diff --git a/src/controllers/commands/employees/employeeQuery.ts b/src/controllers/commands/employees/employeeQuery.ts index 06281c9..4b3cb34 100644 --- a/src/controllers/commands/employees/employeeQuery.ts +++ b/src/controllers/commands/employees/employeeQuery.ts @@ -9,7 +9,7 @@ export const queryById = async (employeeId?: string): Promise>{ status: 422, - message: Resources.getString(ResourceKey.PRODUCT_RECORD_ID_INVALID) + message: Resources.getString(ResourceKey.EMPLOYEE_RECORD_ID_INVALID) }); } @@ -18,7 +18,7 @@ export const queryById = async (employeeId?: string): Promise>{ status: 404, - message: Resources.getString(ResourceKey.PRODUCT_NOT_FOUND) + message: Resources.getString(ResourceKey.EMPLOYEE_NOT_FOUND) }); } @@ -27,31 +27,4 @@ export const queryById = async (employeeId?: string): Promise> => { - - if (Helper.isBlankString(employeeLookupCode)) { - return Promise.reject(>{ - status: 422, - message: Resources.getString(ResourceKey.PRODUCT_LOOKUP_CODE_INVALID) - }); - } - - return EmployeeRepository.queryByLookupCode(employeeLookupCode) - .then((queriedEmployee: (EmployeeModel | null)): Promise> => { - if (queriedEmployee == null) { - return Promise.reject(>{ - status: 404, - message: Resources.getString(ResourceKey.PRODUCT_NOT_FOUND) - }); - } - - return Promise.resolve(>{ - status: 200, - data: EmployeeHelper.mapEmployeeData(queriedEmployee) - }); - }); -}; +}; \ No newline at end of file diff --git a/src/controllers/commands/employees/employeeUpdateCommand.ts b/src/controllers/commands/employees/employeeUpdateCommand.ts new file mode 100644 index 0000000..0d70197 --- /dev/null +++ b/src/controllers/commands/employees/employeeUpdateCommand.ts @@ -0,0 +1,88 @@ +import Sequelize from "sequelize"; +import { EmployeeModel } from "../models/employeeModel"; +import * as EmployeeHelper from "./helpers/employeeHelper"; +import * as EmployeeRepository from "../models/employeeModel"; +import { Resources, ResourceKey } from "../../../resourceLookup"; +import * as DatabaseConnection from "../models/databaseConnection"; +import { CommandResponse, Employee, EmployeeSaveRequest } from "../../typeDefinitions"; + +const validateSaveRequest = ( + saveEmployeeRequest: EmployeeSaveRequest +): CommandResponse => { + + let errorMessage: string = ""; + + if (!saveEmployeeRequest.firstName) { + errorMessage = Resources.getString(ResourceKey.EMPLOYEE_FIRST_NAME_INVALID); + } else if (!saveEmployeeRequest.lastName) { + errorMessage = Resources.getString(ResourceKey.EMPLOYEE_LAST_NAME_INVALID); + } else if (!saveEmployeeRequest.password) { + errorMessage = Resources.getString(ResourceKey.EMPLOYEE_PASSWORD_INVALID); + } + + return ((errorMessage === "") + ? >{ status: 200 } + : >{ + status: 422, + message: errorMessage + }); +}; + +export const execute = async ( + saveEmployeeRequest: EmployeeSaveRequest +): Promise> => { + + const validationResponse: CommandResponse = + validateSaveRequest(saveEmployeeRequest); + if (validationResponse.status !== 200) { + return Promise.reject(validationResponse); + } + + let updateTransaction: Sequelize.Transaction; + + return DatabaseConnection.createTransaction() + .then((createdTransaction: Sequelize.Transaction): Promise => { + updateTransaction = createdTransaction; + + return EmployeeRepository.queryById( + saveEmployeeRequest.id, + updateTransaction); + }).then((queriedEmployee: (EmployeeModel | null)): Promise => { + if (queriedEmployee == null) { + return Promise.reject(>{ + status: 404, + message: Resources.getString(ResourceKey.EMPLOYEE_NOT_FOUND) + }); + } + + return queriedEmployee.update( + { + id: saveEmployeeRequest.id, + active: saveEmployeeRequest.active, + lastName: saveEmployeeRequest.lastName, + firstName: saveEmployeeRequest.firstName, + managerId: saveEmployeeRequest.managerId, + classification: saveEmployeeRequest.classification + }, + { + transaction: updateTransaction + }); + }).then((updatedEmployee: EmployeeModel): CommandResponse => { + updateTransaction.commit(); + + return >{ + status: 200, + data: EmployeeHelper.mapEmployeeData(updatedEmployee) + }; + }).catch((error: any): Promise> => { + if (updateTransaction != null) { + updateTransaction.rollback(); + } + + return Promise.reject(>{ + status: (error.status || 500), + message: (error.messsage + || Resources.getString(ResourceKey.EMPLOYEE_UNABLE_TO_SAVE)) + }); + }); +}; diff --git a/src/controllers/commands/employees/helpers/employeeHelper.ts b/src/controllers/commands/employees/helpers/employeeHelper.ts index bd4c33c..2728024 100644 --- a/src/controllers/commands/employees/helpers/employeeHelper.ts +++ b/src/controllers/commands/employees/helpers/employeeHelper.ts @@ -1,4 +1,7 @@ import { EmployeeClassification } from '../../models/constants/entityTypes'; +import { Employee } from "../../../typeDefinitions"; +import { EmployeeModel } from "../../models/employeeModel"; +import * as Helper from "../../helpers/helper"; import crypto from 'crypto'; export const hashString = (toHash: string): string => { @@ -8,3 +11,16 @@ export const hashString = (toHash: string): string => { export const isElevatedUser = (employeeClassification: EmployeeClassification): boolean => { return false; // TODO: Determine if an employee is an elevated user by their classification }; + +export const mapEmployeeData = (queriedEmployee: EmployeeModel): Employee => { + return { + id: queriedEmployee.id, + active: queriedEmployee.active, + lastName: queriedEmployee.lastName, + createdOn: queriedEmployee.createdOn, + firstName: queriedEmployee.firstName, + managerId: queriedEmployee.managerId, + employeeId: queriedEmployee.employeeId.toString(), + classification: queriedEmployee.classification + }; +}; \ No newline at end of file From c59162fa17a25c37b59c9b85adc78a57d19f38da Mon Sep 17 00:00:00 2001 From: bouchara0303 Date: Wed, 4 Mar 2020 12:27:19 -0600 Subject: [PATCH 31/53] bug --- .../employees/activeEmployeeExistsQuery.ts | 21 +++++++++++++------ 1 file changed, 15 insertions(+), 6 deletions(-) diff --git a/src/controllers/commands/employees/activeEmployeeExistsQuery.ts b/src/controllers/commands/employees/activeEmployeeExistsQuery.ts index e46e1f7..9c54610 100644 --- a/src/controllers/commands/employees/activeEmployeeExistsQuery.ts +++ b/src/controllers/commands/employees/activeEmployeeExistsQuery.ts @@ -1,18 +1,27 @@ import { EmployeeModel } from "../models/employeeModel"; import { Resources, ResourceKey } from "../../../resourceLookup"; import * as EmployeeRepository from "../models/employeeModel"; -import { CommandResponse } from "../../typeDefinitions"; +import { CommandResponse, Employee } from "../../typeDefinitions"; -export const execute = async (): Promise> => { +export const execute = async (): Promise> => { return EmployeeRepository.queryActiveExists() - .then((queriedActiveUser: (EmployeeModel | null)): Promise> => { + .then((queriedActiveUser: (EmployeeModel | null)): Promise> => { if (queriedActiveUser) { - return Promise.resolve(>{ + return Promise.resolve(>{ status: 200, - data: queriedActiveUser}); + data: { + id: queriedActiveUser.id, + active: queriedActiveUser.active, + lastName: queriedActiveUser.lastName, + createdOn: queriedActiveUser.createdOn, + firstName: queriedActiveUser.firstName, + managerId: queriedActiveUser.managerId, + employeeId: queriedActiveUser.employeeId, + classification: queriedActiveUser.classification, + }}); } - return Promise.reject(>{ + return Promise.reject(>{ status: 404, message: Resources.getString(ResourceKey.EMPLOYEES_UNABLE_TO_QUERY) }); From 20ac2905340492dc8c3fa1a65e147d67db450af4 Mon Sep 17 00:00:00 2001 From: bouchara0303 Date: Wed, 4 Mar 2020 12:28:36 -0600 Subject: [PATCH 32/53] bug --- src/controllers/employeeDetailRouteController.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/controllers/employeeDetailRouteController.ts b/src/controllers/employeeDetailRouteController.ts index 75fd431..45344be 100644 --- a/src/controllers/employeeDetailRouteController.ts +++ b/src/controllers/employeeDetailRouteController.ts @@ -17,7 +17,7 @@ interface CanCreateEmployee { const determineCanCreateEmployee = async (req: Request): Promise => { return ActiveEmployeeExistsQuery.execute() - .then((activeUserCommandResponse: CommandResponse): Promise => { + .then((activeUserCommandResponse: CommandResponse): Promise => { return ValidateActiveUser.execute(req.session!.id) .then((activeUser: CommandResponse): Promise => { if (EmployeeHelper.isElevatedUser(activeUser.data!.classification)) { From b017d75cb56305c1be81d559350248c8c541c6df Mon Sep 17 00:00:00 2001 From: Willard Date: Wed, 4 Mar 2020 12:28:59 -0600 Subject: [PATCH 33/53] Remove unused imports --- src/controllers/commands/employees/helpers/employeeHelper.ts | 1 - 1 file changed, 1 deletion(-) diff --git a/src/controllers/commands/employees/helpers/employeeHelper.ts b/src/controllers/commands/employees/helpers/employeeHelper.ts index 1db77ee..6ba2cf2 100644 --- a/src/controllers/commands/employees/helpers/employeeHelper.ts +++ b/src/controllers/commands/employees/helpers/employeeHelper.ts @@ -1,7 +1,6 @@ import { EmployeeClassification } from '../../models/constants/entityTypes'; import { Employee } from "../../../typeDefinitions"; import { EmployeeModel } from "../../models/employeeModel"; -import * as Helper from "../../helpers/helper"; import crypto from 'crypto'; export const hashString = (toHash: string): string => { From ffd1eb4b2d7f1267f24efb3873a83cd50ef753b0 Mon Sep 17 00:00:00 2001 From: bouchara0303 Date: Wed, 4 Mar 2020 12:33:18 -0600 Subject: [PATCH 34/53] bugs --- src/controllers/commands/employees/activeEmployeeExistsQuery.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/controllers/commands/employees/activeEmployeeExistsQuery.ts b/src/controllers/commands/employees/activeEmployeeExistsQuery.ts index 9c54610..64ccc55 100644 --- a/src/controllers/commands/employees/activeEmployeeExistsQuery.ts +++ b/src/controllers/commands/employees/activeEmployeeExistsQuery.ts @@ -16,7 +16,7 @@ export const execute = async (): Promise> => { createdOn: queriedActiveUser.createdOn, firstName: queriedActiveUser.firstName, managerId: queriedActiveUser.managerId, - employeeId: queriedActiveUser.employeeId, + employeeId: queriedActiveUser.employeeId.toString(), classification: queriedActiveUser.classification, }}); } From cccb50ef399bf91cd6d01bdc1465bbb35abe98d6 Mon Sep 17 00:00:00 2001 From: bouchara0303 Date: Wed, 4 Mar 2020 12:52:52 -0600 Subject: [PATCH 35/53] bug --- .../commands/employees/helpers/employeeHelper.ts | 8 ++++---- src/controllers/employeeDetailRouteController.ts | 10 +++++----- 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/src/controllers/commands/employees/helpers/employeeHelper.ts b/src/controllers/commands/employees/helpers/employeeHelper.ts index 6ba2cf2..f150db8 100644 --- a/src/controllers/commands/employees/helpers/employeeHelper.ts +++ b/src/controllers/commands/employees/helpers/employeeHelper.ts @@ -1,10 +1,10 @@ -import { EmployeeClassification } from '../../models/constants/entityTypes'; +import { EmployeeClassification } from "../../models/constants/entityTypes"; import { Employee } from "../../../typeDefinitions"; import { EmployeeModel } from "../../models/employeeModel"; -import crypto from 'crypto'; +import crypto from "crypto"; export const hashString = (toHash: string): string => { - return crypto.createHash('md5').update(toHash).digest('hex'); + return crypto.createHash("md5").update(toHash).digest("hex"); }; export const isElevatedUser = (employeeClassification: EmployeeClassification): boolean => { @@ -25,4 +25,4 @@ export const mapEmployeeData = (queriedEmployee: EmployeeModel): Employee => { employeeId: queriedEmployee.employeeId.toString(), classification: queriedEmployee.classification }; -}; \ No newline at end of file +}; diff --git a/src/controllers/employeeDetailRouteController.ts b/src/controllers/employeeDetailRouteController.ts index 45344be..5bcb43b 100644 --- a/src/controllers/employeeDetailRouteController.ts +++ b/src/controllers/employeeDetailRouteController.ts @@ -7,7 +7,7 @@ import * as EmployeeCreateCommand from "./commands/employees/employeeCreateComma import * as EmployeeUpdateCommand from "./commands/employees/employeeUpdateCommand"; import { ViewNameLookup, ParameterLookup, RouteLookup } from "./lookups/routingLookup"; import * as ValidateActiveUser from "./commands/activeUsers/validateActiveUserCommand"; -import * as ActiveEmployeeExistsQuery from "./commands/employees/activeEmployeeExistsQuery" +import * as ActiveEmployeeExistsQuery from "./commands/employees/activeEmployeeExistsQuery"; import { ApiResponse, CommandResponse, Employee, EmployeeSaveRequest, ActiveUser, PageResponse } from "./typeDefinitions"; interface CanCreateEmployee { @@ -25,7 +25,7 @@ const determineCanCreateEmployee = async (req: Request): Promise { employeeExists: true, isElevatedUser: false }); - }).catch(()=>{ + }).catch((error: any): Promise => { return Promise.reject( { employeeExists: true, isElevatedUser: false}); }).catch((error: any): Promise => { return Promise.resolve({ employeeExists: false, isElevatedUser: false }); @@ -72,14 +72,14 @@ export const startWithEmployee = async (req: Request, res: Response): Promise): void => { return res.render(ViewNameLookup.EmployeeDetail, employeeCommandResponse.data); }).catch((error: any): void => { res.send({ errorMessage: error.message, redirectUrl: RouteLookup.SignIn - }) + }); }); }; @@ -133,5 +133,5 @@ export const updateEmployee = async (req: Request, res: Response): Promise }; export const createEmployee = async (req: Request, res: Response): Promise => { - return saveEmployee(req, res, EmployeeSaveCommand.execute); + return saveEmployee(req, res, EmployeeCreateCommand.execute); }; From ece406ec4f2b540192862a8b28f1ac6f9f8e0758 Mon Sep 17 00:00:00 2001 From: bouchara0303 Date: Wed, 4 Mar 2020 13:27:17 -0600 Subject: [PATCH 36/53] bugs --- src/controllers/productDetailRouteController.ts | 4 ++-- src/controllers/signInRouteController.ts | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/controllers/productDetailRouteController.ts b/src/controllers/productDetailRouteController.ts index 460aa78..4689f60 100644 --- a/src/controllers/productDetailRouteController.ts +++ b/src/controllers/productDetailRouteController.ts @@ -61,11 +61,11 @@ const saveProduct = async ( }; export const updateProduct = async (req: Request, res: Response): Promise => { - saveProduct(req, res, ProductUpdateCommand.execute); + return saveProduct(req, res, ProductUpdateCommand.execute); }; export const createProduct = async (req: Request, res: Response): Promise => { - saveProduct(req, res, ProductCreateCommand.execute); + return saveProduct(req, res, ProductCreateCommand.execute); }; export const deleteProduct = async (req: Request, res: Response): Promise => { diff --git a/src/controllers/signInRouteController.ts b/src/controllers/signInRouteController.ts index e1a5b36..9410178 100644 --- a/src/controllers/signInRouteController.ts +++ b/src/controllers/signInRouteController.ts @@ -27,7 +27,7 @@ export const start = async (req: Request, res: Response): Promise => { .then((): void => { return res.render(ViewNameLookup.SignIn); }).catch((): void => { - return res.render(ViewNameLookup.MainMenu); + return res.render(ViewNameLookup.EmployeeDetail); }); }; From 38e7458a53c154d627943d37e0be76001dcca7cd Mon Sep 17 00:00:00 2001 From: Lily Date: Wed, 4 Mar 2020 17:46:53 -0600 Subject: [PATCH 37/53] Added isElevatedUser functionality to product listing and product detail pages --- .../productDetailRouteController.ts | 23 +++++++++++-------- .../productListingRouteController.ts | 13 ++++++++++- views/productListing.ejs | 6 ++++- 3 files changed, 31 insertions(+), 11 deletions(-) diff --git a/src/controllers/productDetailRouteController.ts b/src/controllers/productDetailRouteController.ts index 055c18b..c50a44f 100644 --- a/src/controllers/productDetailRouteController.ts +++ b/src/controllers/productDetailRouteController.ts @@ -30,16 +30,21 @@ const processStartProductDetailError = (res: Response, error: any): void => { }; export const start = async (req: Request, res: Response): Promise => { + if (Helper.handleInvalidSession(req, res)) { + return; + } + + let isElevatedUser: boolean; + + return ValidateActiveUser.execute((req.session).id) + .then((activeUserCommandResponse: CommandResponse): Promise> => { + isElevatedUser = + EmployeeHelper.isElevatedUser( + (activeUserCommandResponse.data).classification); + + return ProductQuery.queryById(req.params[ParameterLookup.ProductId]) - .then((productsCommandResponse: CommandResponse): void => { - //Copy paste from mainMenuRouteController - const isElevatedUser: boolean = true; - - //Check for isElevatedUser - - //const isElevatedUser: boolean = false; - // EmployeeHelper.isElevatedUser( - // (activeUserCommandResponse.data).classification); + }).then((productsCommandResponse: CommandResponse): void => { return res.render( ViewNameLookup.ProductDetail, diff --git a/src/controllers/productListingRouteController.ts b/src/controllers/productListingRouteController.ts index 9a32b3d..eb3802b 100644 --- a/src/controllers/productListingRouteController.ts +++ b/src/controllers/productListingRouteController.ts @@ -21,8 +21,19 @@ const processStartProductListingError = (error: any, res: Response): void => { }; export const start = async (req: Request, res: Response): Promise => { + if (Helper.handleInvalidSession(req, res)) { + return; + } + let isElevatedUser: boolean; + + return ValidateActiveUser.execute((req.session).id) + .then((activeUserCommandResponse: CommandResponse): Promise> => { + isElevatedUser = + EmployeeHelper.isElevatedUser( + (activeUserCommandResponse.data).classification); + return ProductsQuery.query() - .then((productsCommandResponse: CommandResponse): void => { + }).then((productsCommandResponse: CommandResponse): void => { res.setHeader( "Cache-Control", "no-cache, max-age=0, must-revalidate, no-store"); diff --git a/views/productListing.ejs b/views/productListing.ejs index 35c45ca..2df2899 100644 --- a/views/productListing.ejs +++ b/views/productListing.ejs @@ -24,10 +24,14 @@ <% } %> + + <% if (!locals.isElevatedUser) { %> + <% document.getElementById("createNewButton").style.display = "none"; %> + <% } %>


From cfc8c4937037a016f5b95f175954d9b804cd2186 Mon Sep 17 00:00:00 2001 From: robertjohnsonark <60170193+robertjohnsonark@users.noreply.github.com> Date: Wed, 4 Mar 2020 18:46:14 -0600 Subject: [PATCH 38/53] Finished task 10 I think? --- public/scripts/employeeDetail.js | 55 ++++++++++++++++++++++++++++++-- 1 file changed, 52 insertions(+), 3 deletions(-) diff --git a/public/scripts/employeeDetail.js b/public/scripts/employeeDetail.js index b4de401..363a6a4 100644 --- a/public/scripts/employeeDetail.js +++ b/public/scripts/employeeDetail.js @@ -14,8 +14,47 @@ function saveActionClick(event) { const saveActionElement = event.target; saveActionElement.disabled = true; - displayEmployeeSavedAlertModal(); -} + + const employeeId = getEmployeeId(); + const employeeIdIsDefined = ((employeeId != null) && (employeeId.trim() !== "")); + const saveActionUrl = ("/api/employeeDetail/" + + (employeeIdIsDefined ? employeeId : "")); + const saveEmployeeRequest = { + id: employeeId, + firstName: getEmployeeFirstName(), + lastName: getEmployeeLastName(), + password: getEmployeePassword(), + type: getEmployeeType() + }; + + if (employeeIdIsDefined) { + ajaxPatch(saveActionUrl, saveEmployeeRequest, (callbackResponse) => { + saveActionElement.disabled = false; + + if (isSuccessResponse(callbackResponse)) { + displayEmployeeSavedAlertModal(); + } + }); + } else { + ajaxPost(saveActionUrl, saveEmployeeRequest, (callbackResponse) => { + saveActionElement.disabled = false; + + if (isSuccessResponse(callbackResponse)) { + displayEmployeeSavedAlertModal(); + + if ((callbackResponse.data != null) + && (callbackResponse.data.employee != null) + && (callbackResponse.data.employee.id.trim() !== "")) { + + document.getElementById("deleteActionContainer").classList.remove("hidden"); + + setEmployeeId(callbackResponse.data.employee.id.trim()); + } + } + }); + } +}; + function validateSave() { @@ -74,7 +113,7 @@ function hideEmployeeSavedAlertModal() { getSavedAlertModalElement().style.display = "none"; } -function ajaxPost(resourceRelativeUri, data, ajaxPatch) { +function ajaxPost(resourceRelativeUri, data, callback) { return ajax(resourceRelativeUri, "POST", data, callback); } @@ -161,4 +200,14 @@ function getEmployeeTypeElement() { return document.getElementById("employeeType"); } +function getEmployeeId() { + return getEmployeeIdElement().value; +} +function setEmployeeId(employeeId) { + getEmployeeIdElement().value = employeeId; +} +function getEmployeeIdElement() { + return document.getElementById("employeeId"); +} + // End getters and setters \ No newline at end of file From ebe9be2df13cd569f0a1b6c68f5e85cab1af7ee9 Mon Sep 17 00:00:00 2001 From: robertjohnsonark <60170193+robertjohnsonark@users.noreply.github.com> Date: Wed, 4 Mar 2020 18:51:35 -0600 Subject: [PATCH 39/53] fixed one mistake - sorry --- public/scripts/employeeDetail.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/public/scripts/employeeDetail.js b/public/scripts/employeeDetail.js index 363a6a4..748c459 100644 --- a/public/scripts/employeeDetail.js +++ b/public/scripts/employeeDetail.js @@ -46,7 +46,7 @@ function saveActionClick(event) { && (callbackResponse.data.employee != null) && (callbackResponse.data.employee.id.trim() !== "")) { - document.getElementById("deleteActionContainer").classList.remove("hidden"); + document.getElementById("employeeID").classList.remove("hidden"); setEmployeeId(callbackResponse.data.employee.id.trim()); } @@ -210,4 +210,4 @@ function getEmployeeIdElement() { return document.getElementById("employeeId"); } -// End getters and setters \ No newline at end of file +// End getters and setters From 1d75e1caecf24c7d5a83f4ee0576cbf75845e189 Mon Sep 17 00:00:00 2001 From: bouchara0303 Date: Wed, 4 Mar 2020 20:46:02 -0600 Subject: [PATCH 40/53] bugs --- src/controllers/signInRouteController.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/controllers/signInRouteController.ts b/src/controllers/signInRouteController.ts index 9410178..3d5cd78 100644 --- a/src/controllers/signInRouteController.ts +++ b/src/controllers/signInRouteController.ts @@ -1,6 +1,6 @@ import { Request, Response } from "express"; import { Resources, ResourceKey } from "../resourceLookup"; -import { ViewNameLookup, QueryParameterLookup } from "./lookups/routingLookup"; +import { ViewNameLookup, QueryParameterLookup, RouteLookup } from "./lookups/routingLookup"; import { ApiResponse, PageResponse } from "./typeDefinitions"; import * as ActiveEmployeeExists from "./commands/employees/activeEmployeeExistsQuery"; import * as EmployeeSignIn from "./commands/employees/employeeSignInCommand"; @@ -27,7 +27,7 @@ export const start = async (req: Request, res: Response): Promise => { .then((): void => { return res.render(ViewNameLookup.SignIn); }).catch((): void => { - return res.render(ViewNameLookup.EmployeeDetail); + return res.redirect(RouteLookup.EmployeeDetail); }); }; From d6a93a2b5711f1dcf1eeac5597d73668fa6018d5 Mon Sep 17 00:00:00 2001 From: bouchara0303 Date: Wed, 4 Mar 2020 23:01:20 -0600 Subject: [PATCH 41/53] Fixed SignIn and Employee Detail routing + functionality --- .../employees/activeEmployeeExistsQuery.ts | 20 ++++------- .../commands/employees/employeeQuery.ts | 6 ++-- .../employees/employeeSignInCommand.ts | 8 +++-- .../employeeDetailRouteController.ts | 33 ++++++++----------- 4 files changed, 28 insertions(+), 39 deletions(-) diff --git a/src/controllers/commands/employees/activeEmployeeExistsQuery.ts b/src/controllers/commands/employees/activeEmployeeExistsQuery.ts index 64ccc55..e32f371 100644 --- a/src/controllers/commands/employees/activeEmployeeExistsQuery.ts +++ b/src/controllers/commands/employees/activeEmployeeExistsQuery.ts @@ -2,28 +2,20 @@ import { EmployeeModel } from "../models/employeeModel"; import { Resources, ResourceKey } from "../../../resourceLookup"; import * as EmployeeRepository from "../models/employeeModel"; import { CommandResponse, Employee } from "../../typeDefinitions"; +import * as EmployeeHelper from "./helpers/employeeHelper"; export const execute = async (): Promise> => { return EmployeeRepository.queryActiveExists() - .then((queriedActiveUser: (EmployeeModel | null)): Promise> => { + .then((queriedActiveUser: (EmployeeModel | null)): CommandResponse => { if (queriedActiveUser) { - return Promise.resolve(>{ + return >{ status: 200, - data: { - id: queriedActiveUser.id, - active: queriedActiveUser.active, - lastName: queriedActiveUser.lastName, - createdOn: queriedActiveUser.createdOn, - firstName: queriedActiveUser.firstName, - managerId: queriedActiveUser.managerId, - employeeId: queriedActiveUser.employeeId.toString(), - classification: queriedActiveUser.classification, - }}); + data: EmployeeHelper.mapEmployeeData(queriedActiveUser)}; } - return Promise.reject(>{ + return >{ status: 404, message: Resources.getString(ResourceKey.EMPLOYEES_UNABLE_TO_QUERY) - }); + }; }); }; diff --git a/src/controllers/commands/employees/employeeQuery.ts b/src/controllers/commands/employees/employeeQuery.ts index 4b3cb34..ac06175 100644 --- a/src/controllers/commands/employees/employeeQuery.ts +++ b/src/controllers/commands/employees/employeeQuery.ts @@ -7,10 +7,10 @@ import { CommandResponse, Employee } from "../../typeDefinitions"; export const queryById = async (employeeId?: string): Promise> => { if (Helper.isBlankString(employeeId)) { - return Promise.reject(>{ + return >{ status: 422, message: Resources.getString(ResourceKey.EMPLOYEE_RECORD_ID_INVALID) - }); + }; } return EmployeeRepository.queryById(employeeId) @@ -27,4 +27,4 @@ export const queryById = async (employeeId?: string): Promise> => { if (Helper.isBlankString(userSignInRequest.employeeId) || !Helper.isValidUUID(userSignInRequest.employeeId)) { - return Promise.reject(> { + return Promise.reject(>{ status: 404, message: Resources.getString(ResourceKey.EMPLOYEE_RECORD_ID_INVALID) }); @@ -23,9 +24,10 @@ export const execute = async (userSignInRequest: UserSignInRequest, session: Exp return EmployeeRepository.queryByEmployeeId(parseInt(userSignInRequest.employeeId)) .then(async (employeeModel: (EmployeeModel | null)): Promise> => { - if (employeeModel && (parseInt(userSignInRequest.employeeId) == employeeModel.employeeId) && (userSignInRequest.password == employeeModel.password.toString("utf8"))) { + + if (employeeModel && (parseInt(userSignInRequest.employeeId) == employeeModel.employeeId) && (EmployeeHelper.hashString(userSignInRequest.password) == employeeModel.password.toString("utf8"))) { ActiveUserRepository.queryByEmployeeId(userSignInRequest.employeeId, await DatabaseConnection.createTransaction()) - .then(async (activeUserModel: (ActiveUserModel | null)): Promise> => { + .then((activeUserModel: (ActiveUserModel | null)): Promise> => { if (activeUserModel) { activeUserModel.sessionKey = session.id; activeUserModel.update(activeUserModel); diff --git a/src/controllers/employeeDetailRouteController.ts b/src/controllers/employeeDetailRouteController.ts index 5bcb43b..393b9db 100644 --- a/src/controllers/employeeDetailRouteController.ts +++ b/src/controllers/employeeDetailRouteController.ts @@ -18,20 +18,22 @@ interface CanCreateEmployee { const determineCanCreateEmployee = async (req: Request): Promise => { return ActiveEmployeeExistsQuery.execute() .then((activeUserCommandResponse: CommandResponse): Promise => { - return ValidateActiveUser.execute(req.session!.id) - .then((activeUser: CommandResponse): Promise => { + + return ValidateActiveUser.execute((req.session!).id) + .then((activeUser: CommandResponse): CanCreateEmployee => { if (EmployeeHelper.isElevatedUser(activeUser.data!.classification)) { - return Promise.resolve( { employeeExists: true, isElevatedUser: false }); + return { employeeExists: true, isElevatedUser: true }; } - return Promise.reject( { employeeExists: true, isElevatedUser: false }); - }).catch((error: any): Promise => { - return Promise.reject( { employeeExists: true, isElevatedUser: false}); - }).catch((error: any): Promise => { - return Promise.resolve({ employeeExists: false, isElevatedUser: false }); + return { employeeExists: true, isElevatedUser: false }; + }).catch((error: any): CanCreateEmployee => { + return { employeeExists: true, isElevatedUser: false}; + }); + }).catch((error: any): CanCreateEmployee => { + return { employeeExists: false, isElevatedUser: false }; }); - }); -}; + + }; export const start = async (req: Request, res: Response): Promise => { if (Helper.handleInvalidSession(req, res)) { @@ -44,17 +46,10 @@ export const start = async (req: Request, res: Response): Promise => { && !canCreateEmployee.isElevatedUser) { return res.redirect(Helper.buildNoPermissionsRedirectUrl()); } - else if (!canCreateEmployee.employeeExists || canCreateEmployee.isElevatedUser) { - return res.render(ViewNameLookup.EmployeeDetail); - } - return res.render(ViewNameLookup.SignIn, { - errorMessage: Resources.getString(ResourceKey.USER_SESSION_NOT_ACTIVE) - }); + return res.render(ViewNameLookup.EmployeeDetail); }).catch((error: any): void => { - return res.render(ViewNameLookup.SignIn, { - errorMessage: Resources.getString(ResourceKey.USER_SESSION_NOT_FOUND) - }); + return res.redirect(Helper.invalidSessionRedirectUrl); }); }; From 3ff41a03b0d75495b6905b84f5ed9fddbacc2a77 Mon Sep 17 00:00:00 2001 From: bouchara0303 Date: Thu, 5 Mar 2020 12:55:54 -0600 Subject: [PATCH 42/53] bugs --- public/scripts/signIn.js | 12 ++- .../employees/activeEmployeeExistsQuery.ts | 10 +-- .../employees/employeeCreateCommand.ts | 6 +- .../employees/employeeSignInCommand.ts | 73 +++++++++++++++---- .../commands/models/employeeModel.ts | 4 + .../employeeDetailRouteController.ts | 37 +++++----- src/controllers/mainMenuRouteController.ts | 3 +- src/controllers/signInRouteController.ts | 20 ++--- src/routes/mainMenuRoutes.ts | 2 +- views/mainMenu.ejs | 34 ++++----- views/signIn.ejs | 8 +- 11 files changed, 128 insertions(+), 81 deletions(-) diff --git a/public/scripts/signIn.js b/public/scripts/signIn.js index 92752d9..f22d439 100644 --- a/public/scripts/signIn.js +++ b/public/scripts/signIn.js @@ -1,23 +1,21 @@ document.addEventListener("DOMContentLoaded", () => { - // TODO: Anything you want to do when the page is loaded? }); function validateForm() { - // TODO: Validate the user input var employeeID = document.getElementById("employeeID").value; - var password = document.getElementById("password").value; - - if(isNaN(employeeID)) + var pass = document.getElementById("password").value; + + if((isNaN(employeeID)) || (employeeID == "")) { alert("Enter a valid ID number") return false; } - if(password == "") + if(pass == "") { alert("Enter a password") return false; } return true; -} +}; diff --git a/src/controllers/commands/employees/activeEmployeeExistsQuery.ts b/src/controllers/commands/employees/activeEmployeeExistsQuery.ts index e32f371..8bca9e8 100644 --- a/src/controllers/commands/employees/activeEmployeeExistsQuery.ts +++ b/src/controllers/commands/employees/activeEmployeeExistsQuery.ts @@ -6,16 +6,16 @@ import * as EmployeeHelper from "./helpers/employeeHelper"; export const execute = async (): Promise> => { return EmployeeRepository.queryActiveExists() - .then((queriedActiveUser: (EmployeeModel | null)): CommandResponse => { + .then((queriedActiveUser: (EmployeeModel | null)): Promise> => { if (queriedActiveUser) { - return >{ + return Promise.resolve(>{ status: 200, - data: EmployeeHelper.mapEmployeeData(queriedActiveUser)}; + data: EmployeeHelper.mapEmployeeData(queriedActiveUser)}); } - return >{ + return Promise.reject(>{ status: 404, message: Resources.getString(ResourceKey.EMPLOYEES_UNABLE_TO_QUERY) - }; + }); }); }; diff --git a/src/controllers/commands/employees/employeeCreateCommand.ts b/src/controllers/commands/employees/employeeCreateCommand.ts index 3284819..b970c7b 100644 --- a/src/controllers/commands/employees/employeeCreateCommand.ts +++ b/src/controllers/commands/employees/employeeCreateCommand.ts @@ -4,6 +4,7 @@ import * as EmployeeRepository from "../models/employeeModel"; import { Resources, ResourceKey } from "../../../resourceLookup"; import * as DatabaseConnection from "../models/databaseConnection"; import { CommandResponse, Employee, EmployeeSaveRequest } from "../../typeDefinitions"; +import * as EmployeeHelper from "./helpers/employeeHelper"; const validateSaveRequest = ( saveEmployeeRequest: EmployeeSaveRequest @@ -43,8 +44,9 @@ export const execute = async ( lastName: saveEmployeeRequest.lastName, firstName: saveEmployeeRequest.firstName, managerId: saveEmployeeRequest.managerId, - classification: saveEmployeeRequest.classification - }; + classification: saveEmployeeRequest.classification, + password: Buffer.from(EmployeeHelper.hashString(saveEmployeeRequest.password), "utf8") + }; let createTransaction: Sequelize.Transaction; diff --git a/src/controllers/commands/employees/employeeSignInCommand.ts b/src/controllers/commands/employees/employeeSignInCommand.ts index e95fdf7..4a84711 100644 --- a/src/controllers/commands/employees/employeeSignInCommand.ts +++ b/src/controllers/commands/employees/employeeSignInCommand.ts @@ -7,9 +7,10 @@ import * as ActiveUserRepository from "../models/activeUserModel"; import * as DatabaseConnection from "../models/databaseConnection"; import * as Helper from "../helpers/helper"; import * as EmployeeHelper from "./helpers/employeeHelper"; +import Sequelize from "sequelize"; export const execute = async (userSignInRequest: UserSignInRequest, session: Express.Session): Promise> => { - if (Helper.isBlankString(userSignInRequest.employeeId) || !Helper.isValidUUID(userSignInRequest.employeeId)) { + if (Helper.isBlankString(userSignInRequest.employeeId)) { return Promise.reject(>{ status: 404, message: Resources.getString(ResourceKey.EMPLOYEE_RECORD_ID_INVALID) @@ -26,21 +27,63 @@ export const execute = async (userSignInRequest: UserSignInRequest, session: Exp .then(async (employeeModel: (EmployeeModel | null)): Promise> => { if (employeeModel && (parseInt(userSignInRequest.employeeId) == employeeModel.employeeId) && (EmployeeHelper.hashString(userSignInRequest.password) == employeeModel.password.toString("utf8"))) { - ActiveUserRepository.queryByEmployeeId(userSignInRequest.employeeId, await DatabaseConnection.createTransaction()) + ActiveUserRepository.queryByEmployeeId(userSignInRequest.employeeId) .then((activeUserModel: (ActiveUserModel | null)): Promise> => { - if (activeUserModel) { - activeUserModel.sessionKey = session.id; - activeUserModel.update(activeUserModel); - } - else { - activeUserModel = new ActiveUserModel(employeeModel); - activeUserModel.sessionKey = session.id; - ActiveUserModel.create(activeUserModel); - } + let createTransaction: Sequelize.Transaction; - return Promise.resolve(>{ - status: 200, - data: activeUserModel + return DatabaseConnection.createTransaction() + .then((createdTransaction: Sequelize.Transaction): Promise =>{ + createTransaction = createdTransaction; + let activeUserToCreate: any; + if (activeUserModel) { + activeUserModel.sessionKey = session.id; + activeUserToCreate = activeUserModel; + return ActiveUserModel.update( + activeUserModel, + { + transaction: createdTransaction + } + ); + } + else { + activeUserToCreate = { + name: employeeModel.firstName, + employeeId: employeeModel.employeeId, + sessionKey: session.id, + classification: employeeModel.classification, + id: employeeModel.id, + createdOn: employeeModel.createdOn + }; + + return ActiveUserModel.create( + activeUserModel, + { + transaction: createdTransaction + } + ); + } + }).then((activeUserModel: ActiveUserModel): CommandResponse =>{ + createTransaction.commit(); + + return >{ + status: 201, + data: { + id: activeUserModel.id, + name: activeUserModel.name, + employeeId: activeUserModel.employeeId, + classification: activeUserModel.classification + } + }; + }).catch((error: any): Promise> =>{ + if (createTransaction != null) { + createTransaction.rollback(); + } + + return Promise.reject(>{ + status: (error.status || 500), + message: (error.message + || Resources.getString(ResourceKey.USER_UNABLE_TO_SIGN_IN)) + }); }); }) .catch((error: any): Promise> => { @@ -55,7 +98,7 @@ export const execute = async (userSignInRequest: UserSignInRequest, session: Exp return Promise.reject(>{ status: 400, - message: Resources.getString(ResourceKey.USER_SIGN_IN_CREDENTIALS_INVALID) + message: Resources.getString(ResourceKey.EMPLOYEE_UNABLE_TO_SAVE) }); }).catch((error: any): Promise> => { return Promise.reject(>{ diff --git a/src/controllers/commands/models/employeeModel.ts b/src/controllers/commands/models/employeeModel.ts index b2c704b..013bad1 100644 --- a/src/controllers/commands/models/employeeModel.ts +++ b/src/controllers/commands/models/employeeModel.ts @@ -107,3 +107,7 @@ export const queryActiveExists = async (): Promise => { where: { active: true } }); }; + +export const queryExists = async (): Promise => { + return EmployeeModel.findOne(); +}; diff --git a/src/controllers/employeeDetailRouteController.ts b/src/controllers/employeeDetailRouteController.ts index 393b9db..d530a27 100644 --- a/src/controllers/employeeDetailRouteController.ts +++ b/src/controllers/employeeDetailRouteController.ts @@ -5,9 +5,10 @@ import * as EmployeeHelper from "./commands/employees/helpers/employeeHelper"; import * as EmployeeQuery from "./commands/employees/employeeQuery"; import * as EmployeeCreateCommand from "./commands/employees/employeeCreateCommand"; import * as EmployeeUpdateCommand from "./commands/employees/employeeUpdateCommand"; -import { ViewNameLookup, ParameterLookup, RouteLookup } from "./lookups/routingLookup"; +import { ViewNameLookup, ParameterLookup, RouteLookup, QueryParameterLookup } from "./lookups/routingLookup"; import * as ValidateActiveUser from "./commands/activeUsers/validateActiveUserCommand"; import * as ActiveEmployeeExistsQuery from "./commands/employees/activeEmployeeExistsQuery"; +import * as EmployeeExistsQuery from "./commands/employees/employeeExistsQuery"; import { ApiResponse, CommandResponse, Employee, EmployeeSaveRequest, ActiveUser, PageResponse } from "./typeDefinitions"; interface CanCreateEmployee { @@ -16,24 +17,22 @@ interface CanCreateEmployee { } const determineCanCreateEmployee = async (req: Request): Promise => { - return ActiveEmployeeExistsQuery.execute() + return EmployeeExistsQuery.execute() .then((activeUserCommandResponse: CommandResponse): Promise => { - return ValidateActiveUser.execute((req.session!).id) - .then((activeUser: CommandResponse): CanCreateEmployee => { + .then((activeUser: CommandResponse): Promise => { if (EmployeeHelper.isElevatedUser(activeUser.data!.classification)) { - return { employeeExists: true, isElevatedUser: true }; + return Promise.resolve( { employeeExists: true, isElevatedUser: true }); } - return { employeeExists: true, isElevatedUser: false }; - }).catch((error: any): CanCreateEmployee => { - return { employeeExists: true, isElevatedUser: false}; - }); - }).catch((error: any): CanCreateEmployee => { - return { employeeExists: false, isElevatedUser: false }; + return Promise.resolve( { employeeExists: true, isElevatedUser: false }); + }).catch((error: any): Promise => { + return Promise.reject({ employeeExists: true, isElevatedUser: false }); }); - - }; + }).catch((error: any): Promise => { + return Promise.resolve({ employeeExists: false, isElevatedUser: false}); + }); +}; export const start = async (req: Request, res: Response): Promise => { if (Helper.handleInvalidSession(req, res)) { @@ -42,14 +41,14 @@ export const start = async (req: Request, res: Response): Promise => { return determineCanCreateEmployee(req) .then((canCreateEmployee: CanCreateEmployee): void => { - if (canCreateEmployee.employeeExists - && !canCreateEmployee.isElevatedUser) { - return res.redirect(Helper.buildNoPermissionsRedirectUrl()); - } + if (canCreateEmployee.employeeExists + && !canCreateEmployee.isElevatedUser) { + return res.redirect(Helper.buildNoPermissionsRedirectUrl()); + } return res.render(ViewNameLookup.EmployeeDetail); - }).catch((error: any): void => { - return res.redirect(Helper.invalidSessionRedirectUrl); + }).catch((canCreateEmployee: CanCreateEmployee): void => { + return res.redirect(RouteLookup.SignIn + "?" + QueryParameterLookup.ErrorCode + "=" + ResourceKey.USER_SESSION_NOT_ACTIVE); }); }; diff --git a/src/controllers/mainMenuRouteController.ts b/src/controllers/mainMenuRouteController.ts index cff2214..368f121 100644 --- a/src/controllers/mainMenuRouteController.ts +++ b/src/controllers/mainMenuRouteController.ts @@ -4,6 +4,7 @@ import * as Helper from "./helpers/routeControllerHelper"; import { ViewNameLookup, QueryParameterLookup } from "./lookups/routingLookup"; import * as ValidateActiveUser from "./commands/activeUsers/validateActiveUserCommand"; import { PageResponse, CommandResponse, ActiveUser, MainMenuPageResponse } from "./typeDefinitions"; +import * as EmployeeHelper from "./commands/employees/helpers/employeeHelper"; export const start = async (req: Request, res: Response): Promise => { if (Helper.handleInvalidSession(req, res)) { @@ -13,7 +14,7 @@ export const start = async (req: Request, res: Response): Promise => { return ValidateActiveUser.execute((req.session).id) .then((activeUserCommandResponse: CommandResponse): void => { // TODO: Examine the ActiveUser classification if you want this information - const isElevatedUser: boolean = + const isElevatedUser: boolean = EmployeeHelper.isElevatedUser( (activeUserCommandResponse.data).classification); diff --git a/src/controllers/signInRouteController.ts b/src/controllers/signInRouteController.ts index 3d5cd78..7b62546 100644 --- a/src/controllers/signInRouteController.ts +++ b/src/controllers/signInRouteController.ts @@ -1,8 +1,8 @@ import { Request, Response } from "express"; import { Resources, ResourceKey } from "../resourceLookup"; import { ViewNameLookup, QueryParameterLookup, RouteLookup } from "./lookups/routingLookup"; -import { ApiResponse, PageResponse } from "./typeDefinitions"; -import * as ActiveEmployeeExists from "./commands/employees/activeEmployeeExistsQuery"; +import { ApiResponse, PageResponse, UserSignInRequest, Employee, CommandResponse } from "./typeDefinitions"; +import * as EmployeeExists from "./commands/employees/employeeExistsQuery"; import * as EmployeeSignIn from "./commands/employees/employeeSignInCommand"; import * as ClearActiveUser from "./commands/employees/clearActiveUserCommand"; @@ -23,18 +23,19 @@ const processSignInError = (res: Response, error: any): void => { }; export const start = async (req: Request, res: Response): Promise => { - return ActiveEmployeeExists.execute() - .then((): void => { + return EmployeeExists.execute() + .then((employeeQueryCommandResponse: CommandResponse): void => { return res.render(ViewNameLookup.SignIn); - }).catch((): void => { +}).catch((error: any): void => { return res.redirect(RouteLookup.EmployeeDetail); -}); + }); }; export const signIn = async (req: Request, res: Response): Promise => { - return EmployeeSignIn.execute(req.body, req.session!) + const signInRequest: UserSignInRequest = { employeeId: req.body["employeeId"], password: req.body["password"] }; + return EmployeeSignIn.execute(signInRequest, req.session!) .then((): void => { - return res.render(ViewNameLookup.MainMenu); + return res.redirect(ViewNameLookup.MainMenu); }).catch((error: any): void => { return processSignInError(res, error); }); @@ -43,8 +44,7 @@ export const signIn = async (req: Request, res: Response): Promise => { export const clearActiveUser = async (req: Request, res: Response): Promise => { return ClearActiveUser.execute((req.session).id) .then((): void => { - return res.render(ViewNameLookup.SignIn, { - redirectUrl: ViewNameLookup.SignIn, + return res.render(ViewNameLookup.SignIn, { errorMessage: Resources.getString(req.query[QueryParameterLookup.ErrorCode]) }); }).catch((error: any): void => { diff --git a/src/routes/mainMenuRoutes.ts b/src/routes/mainMenuRoutes.ts index d46a58e..8fc4251 100644 --- a/src/routes/mainMenuRoutes.ts +++ b/src/routes/mainMenuRoutes.ts @@ -4,7 +4,7 @@ import * as mainMenuRouteController from "../controllers/mainMenuRouteController function mainMenuRoutes(server: express.Express) { // TODO: Route for initial page load - server.get(RouteLookup.mainMenu, mainMenuRouteController.start); + server.get(RouteLookup.MainMenu, mainMenuRouteController.start); } module.exports.routes = mainMenuRoutes; diff --git a/views/mainMenu.ejs b/views/mainMenu.ejs index 70abed9..2e4c973 100644 --- a/views/mainMenu.ejs +++ b/views/mainMenu.ejs @@ -2,7 +2,7 @@ Register - Main Menu - + @@ -16,7 +16,7 @@

Main Menu

- +
class="hidden" <% } %>>

@@ -25,36 +25,28 @@ <% } %>

- +
- +
- - - - <% if (!locals.isElevatedUser) { %> - <% document.getElementById("createEmployeeButton").style.display = "none"; %> - <% document.getElementById("salesReportButton").style.display = "none"; %> - <% document.getElementById("cashierReportButton").style.display = "none"; %> - <% } %> - +
- +
- + @@ -80,7 +72,15 @@ - + + <% if (!locals.isElevatedUser) { %> + + <% } %> + - \ No newline at end of file + diff --git a/views/signIn.ejs b/views/signIn.ejs index 62dcd4d..e040901 100644 --- a/views/signIn.ejs +++ b/views/signIn.ejs @@ -2,7 +2,7 @@ Register - Sign In - + @@ -15,7 +15,7 @@

Sign In

- +
class="hidden" <% } %>>

@@ -27,13 +27,13 @@

-
+



- + From 8e885caa7d3f343e5abe8c8a3a72b05963118780 Mon Sep 17 00:00:00 2001 From: bouchara0303 Date: Thu, 5 Mar 2020 12:57:03 -0600 Subject: [PATCH 43/53] Check if employee exists --- .../commands/employees/employeeExistsQuery.ts | 21 +++++++++++++++++++ 1 file changed, 21 insertions(+) create mode 100644 src/controllers/commands/employees/employeeExistsQuery.ts diff --git a/src/controllers/commands/employees/employeeExistsQuery.ts b/src/controllers/commands/employees/employeeExistsQuery.ts new file mode 100644 index 0000000..3641921 --- /dev/null +++ b/src/controllers/commands/employees/employeeExistsQuery.ts @@ -0,0 +1,21 @@ +import { EmployeeModel } from "../models/employeeModel"; +import { Resources, ResourceKey } from "../../../resourceLookup"; +import * as EmployeeRepository from "../models/employeeModel"; +import { CommandResponse, Employee } from "../../typeDefinitions"; +import * as EmployeeHelper from "./helpers/employeeHelper"; + +export const execute = async (): Promise> => { + return EmployeeRepository.queryExists() + .then((queriedActiveUser: (EmployeeModel | null)): Promise> => { + if (queriedActiveUser) { + return Promise.resolve(>{ + status: 200, + data: EmployeeHelper.mapEmployeeData(queriedActiveUser)}); + } + + return Promise.reject(>{ + status: 404, + message: Resources.getString(ResourceKey.EMPLOYEES_UNABLE_TO_QUERY) + }); + }); + }; From 6722984b0ce820e3e575d4085f32d9b77f385421 Mon Sep 17 00:00:00 2001 From: Willard Date: Thu, 5 Mar 2020 13:51:06 -0600 Subject: [PATCH 44/53] Fix employeeSignInCommand --- .../employees/employeeSignInCommand.ts | 134 +++++++----------- 1 file changed, 53 insertions(+), 81 deletions(-) diff --git a/src/controllers/commands/employees/employeeSignInCommand.ts b/src/controllers/commands/employees/employeeSignInCommand.ts index 4a84711..df51f37 100644 --- a/src/controllers/commands/employees/employeeSignInCommand.ts +++ b/src/controllers/commands/employees/employeeSignInCommand.ts @@ -23,90 +23,62 @@ export const execute = async (userSignInRequest: UserSignInRequest, session: Exp }); } - return EmployeeRepository.queryByEmployeeId(parseInt(userSignInRequest.employeeId)) - .then(async (employeeModel: (EmployeeModel | null)): Promise> => { + const employeeModel: (EmployeeModel | null) = await EmployeeRepository.queryByEmployeeId(parseInt(userSignInRequest.employeeId)); - if (employeeModel && (parseInt(userSignInRequest.employeeId) == employeeModel.employeeId) && (EmployeeHelper.hashString(userSignInRequest.password) == employeeModel.password.toString("utf8"))) { - ActiveUserRepository.queryByEmployeeId(userSignInRequest.employeeId) - .then((activeUserModel: (ActiveUserModel | null)): Promise> => { - let createTransaction: Sequelize.Transaction; - - return DatabaseConnection.createTransaction() - .then((createdTransaction: Sequelize.Transaction): Promise =>{ - createTransaction = createdTransaction; - let activeUserToCreate: any; - if (activeUserModel) { - activeUserModel.sessionKey = session.id; - activeUserToCreate = activeUserModel; - return ActiveUserModel.update( - activeUserModel, - { - transaction: createdTransaction - } - ); - } - else { - activeUserToCreate = { - name: employeeModel.firstName, - employeeId: employeeModel.employeeId, - sessionKey: session.id, - classification: employeeModel.classification, - id: employeeModel.id, - createdOn: employeeModel.createdOn - }; + if (employeeModel && (parseInt(userSignInRequest.employeeId) == employeeModel.employeeId) && (EmployeeHelper.hashString(userSignInRequest.password) == employeeModel.password.toString("utf8"))) { + const activeUserModel: (ActiveUserModel | null) = await ActiveUserRepository.queryByEmployeeId(userSignInRequest.employeeId).catch(error => Promise.reject({ + status: 404, + message: (error.message + || + Resources.getString(ResourceKey.EMPLOYEE_UNABLE_TO_QUERY)) + }) + ); - return ActiveUserModel.create( - activeUserModel, - { - transaction: createdTransaction - } - ); - } - }).then((activeUserModel: ActiveUserModel): CommandResponse =>{ - createTransaction.commit(); + const createdTransaction: Sequelize.Transaction = await DatabaseConnection.createTransaction(); + let activeUserToCreate: any = activeUserModel; + if (activeUserModel) { + activeUserModel.sessionKey = session.id; + activeUserToCreate = activeUserModel; + await ActiveUserModel.update( + activeUserModel, + { + transaction: createdTransaction + } + ); + } + else { + activeUserToCreate = { + name: employeeModel.firstName, + employeeId: employeeModel.employeeId, + sessionKey: session.id, + classification: employeeModel.classification, + id: employeeModel.id, + createdOn: employeeModel.createdOn + }; - return >{ - status: 201, - data: { - id: activeUserModel.id, - name: activeUserModel.name, - employeeId: activeUserModel.employeeId, - classification: activeUserModel.classification - } - }; - }).catch((error: any): Promise> =>{ - if (createTransaction != null) { - createTransaction.rollback(); - } + await ActiveUserModel.create( + activeUserToCreate, + { + transaction: createdTransaction + } + ); + } + createdTransaction.commit(); - return Promise.reject(>{ - status: (error.status || 500), - message: (error.message - || Resources.getString(ResourceKey.USER_UNABLE_TO_SIGN_IN)) - }); - }); - }) - .catch((error: any): Promise> => { - return Promise.reject(>{ - status: 404, - message: (error.message - || - Resources.getString(ResourceKey.EMPLOYEE_UNABLE_TO_QUERY)) - }); - }); + return >{ + status: 201, + data: { + id: activeUserToCreate.id, + name: activeUserToCreate.name, + employeeId: activeUserToCreate.employeeId, + classification: activeUserToCreate.classification } - - return Promise.reject(>{ - status: 400, - message: Resources.getString(ResourceKey.EMPLOYEE_UNABLE_TO_SAVE) - }); - }).catch((error: any): Promise> => { - return Promise.reject(>{ - status: 404, - message: ( - error.message - || - Resources.getString(ResourceKey.USER_SIGN_IN_CREDENTIALS_INVALID)) - }); - }); }; + } + return Promise.reject(>{ + status: 404, + message: ( + Resources.getString(ResourceKey.USER_SIGN_IN_CREDENTIALS_INVALID) + ) + }); +}; \ No newline at end of file From a95b33226da7dc8f9e9cfe97947d097438412ad0 Mon Sep 17 00:00:00 2001 From: bouchara0303 Date: Thu, 5 Mar 2020 13:58:04 -0600 Subject: [PATCH 45/53] Fix clearActiveUser controller --- src/controllers/signInRouteController.ts | 13 +++++-------- 1 file changed, 5 insertions(+), 8 deletions(-) diff --git a/src/controllers/signInRouteController.ts b/src/controllers/signInRouteController.ts index 7b62546..d634eb0 100644 --- a/src/controllers/signInRouteController.ts +++ b/src/controllers/signInRouteController.ts @@ -44,15 +44,12 @@ export const signIn = async (req: Request, res: Response): Promise => { export const clearActiveUser = async (req: Request, res: Response): Promise => { return ClearActiveUser.execute((req.session).id) .then((): void => { - return res.render(ViewNameLookup.SignIn, { - errorMessage: Resources.getString(req.query[QueryParameterLookup.ErrorCode]) + res.send({ + redirectUrl: RouteLookup.SignIn }); }).catch((error: any): void => { - return res.status((error.status || 500)) - .render( - ViewNameLookup.MainMenu, - { - errorMessage: error.message - }); + res.send({ + errorMessage: error.message + }); }); }; From 74d4eaa06e83b1fde000303870100b16198d50a2 Mon Sep 17 00:00:00 2001 From: Lily Date: Thu, 5 Mar 2020 15:23:53 -0600 Subject: [PATCH 46/53] Added whitespace to view, fixed bugs to make it compile, made sure that types were correct, imports also were corrected --- src/controllers/mainMenuRouteController.ts | 5 ++-- .../productDetailRouteController.ts | 23 +++++++------------ .../productListingRouteController.ts | 13 ++++++----- src/routes/mainMenuRoutes.ts | 2 +- views/mainMenu.ejs | 11 +++++++++ 5 files changed, 29 insertions(+), 25 deletions(-) diff --git a/src/controllers/mainMenuRouteController.ts b/src/controllers/mainMenuRouteController.ts index cff2214..e6c4a90 100644 --- a/src/controllers/mainMenuRouteController.ts +++ b/src/controllers/mainMenuRouteController.ts @@ -3,6 +3,7 @@ import { Resources } from "../resourceLookup"; import * as Helper from "./helpers/routeControllerHelper"; import { ViewNameLookup, QueryParameterLookup } from "./lookups/routingLookup"; import * as ValidateActiveUser from "./commands/activeUsers/validateActiveUserCommand"; +import * as EmployeeHelper from "./commands/employees/helpers/employeeHelper"; import { PageResponse, CommandResponse, ActiveUser, MainMenuPageResponse } from "./typeDefinitions"; export const start = async (req: Request, res: Response): Promise => { @@ -13,9 +14,7 @@ export const start = async (req: Request, res: Response): Promise => { return ValidateActiveUser.execute((req.session).id) .then((activeUserCommandResponse: CommandResponse): void => { // TODO: Examine the ActiveUser classification if you want this information - const isElevatedUser: boolean = - EmployeeHelper.isElevatedUser( - (activeUserCommandResponse.data).classification); + const isElevatedUser: boolean = EmployeeHelper.isElevatedUser((activeUserCommandResponse.data).classification); // This recommends to Firefox that it refresh the page every time // it is accessed diff --git a/src/controllers/productDetailRouteController.ts b/src/controllers/productDetailRouteController.ts index 3312c62..423e628 100644 --- a/src/controllers/productDetailRouteController.ts +++ b/src/controllers/productDetailRouteController.ts @@ -5,10 +5,10 @@ import { ViewNameLookup, ParameterLookup, RouteLookup } from "./lookups/routingL import * as ProductCreateCommand from "./commands/products/productCreateCommand"; import * as ProductDeleteCommand from "./commands/products/productDeleteCommand"; import * as ProductUpdateCommand from "./commands/products/productUpdateCommand"; -import { CommandResponse, Product, ProductDetailPageResponse, ApiResponse, ProductSaveResponse, ProductSaveRequest } from "./typeDefinitions"; - -//Other Imports +import * as EmployeeHelper from "./commands/employees/helpers/employeeHelper"; import * as ValidateActiveUser from "./commands/activeUsers/validateActiveUserCommand"; +import * as Helper from "./helpers/routeControllerHelper"; +import { CommandResponse, Product, ProductDetailPageResponse, ApiResponse, ProductSaveResponse, ProductSaveRequest, ActiveUser } from "./typeDefinitions"; const processStartProductDetailError = (res: Response, error: any): void => { let errorMessage: (string | undefined) = ""; @@ -33,24 +33,17 @@ export const start = async (req: Request, res: Response): Promise => { if (Helper.handleInvalidSession(req, res)) { return; } - let isElevatedUser: boolean; - return ValidateActiveUser.execute((req.session).id) - .then((activeUserCommandResponse: CommandResponse): Promise> => { - isElevatedUser = - EmployeeHelper.isElevatedUser( - (activeUserCommandResponse.data).classification); - - - return ProductQuery.queryById(req.params[ParameterLookup.ProductId]) + .then((activeUserCommandResponse: CommandResponse): Promise> => { + isElevatedUser = EmployeeHelper.isElevatedUser((activeUserCommandResponse.data).classification); + return ProductQuery.queryById(req.params[ParameterLookup.ProductId]); }).then((productsCommandResponse: CommandResponse): void => { - return res.render( ViewNameLookup.ProductDetail, { - isElevatedUser: isElevatedUser, - product: productsCommandResponse.data + product: productsCommandResponse.data, + isElevatedUser: isElevatedUser }); }).catch((error: any): void => { return processStartProductDetailError(res, error); diff --git a/src/controllers/productListingRouteController.ts b/src/controllers/productListingRouteController.ts index eb3802b..ead01f8 100644 --- a/src/controllers/productListingRouteController.ts +++ b/src/controllers/productListingRouteController.ts @@ -2,7 +2,10 @@ import { Request, Response } from "express"; import { ViewNameLookup } from "./lookups/routingLookup"; import { Resources, ResourceKey } from "../resourceLookup"; import * as ProductsQuery from "./commands/products/productsQuery"; -import { CommandResponse, Product, ProductListingPageResponse } from "./typeDefinitions"; +import * as EmployeeHelper from "./commands/employees/helpers/employeeHelper"; +import * as ValidateActiveUser from "./commands/activeUsers/validateActiveUserCommand"; +import * as Helper from "./helpers/routeControllerHelper"; +import { CommandResponse, Product, ProductListingPageResponse, ActiveUser } from "./typeDefinitions"; const processStartProductListingError = (error: any, res: Response): void => { res.setHeader( @@ -25,14 +28,11 @@ export const start = async (req: Request, res: Response): Promise => { return; } let isElevatedUser: boolean; - return ValidateActiveUser.execute((req.session).id) .then((activeUserCommandResponse: CommandResponse): Promise> => { - isElevatedUser = - EmployeeHelper.isElevatedUser( - (activeUserCommandResponse.data).classification); + isElevatedUser = EmployeeHelper.isElevatedUser((activeUserCommandResponse.data).classification); - return ProductsQuery.query() + return ProductsQuery.query(); }).then((productsCommandResponse: CommandResponse): void => { res.setHeader( "Cache-Control", @@ -41,6 +41,7 @@ export const start = async (req: Request, res: Response): Promise => { return res.render( ViewNameLookup.ProductListing, { + isElevatedUser: isElevatedUser, products: productsCommandResponse.data }); }).catch((error: any): void => { diff --git a/src/routes/mainMenuRoutes.ts b/src/routes/mainMenuRoutes.ts index d46a58e..8fc4251 100644 --- a/src/routes/mainMenuRoutes.ts +++ b/src/routes/mainMenuRoutes.ts @@ -4,7 +4,7 @@ import * as mainMenuRouteController from "../controllers/mainMenuRouteController function mainMenuRoutes(server: express.Express) { // TODO: Route for initial page load - server.get(RouteLookup.mainMenu, mainMenuRouteController.start); + server.get(RouteLookup.MainMenu, mainMenuRouteController.start); } module.exports.routes = mainMenuRoutes; diff --git a/views/mainMenu.ejs b/views/mainMenu.ejs index 70abed9..82c98c7 100644 --- a/views/mainMenu.ejs +++ b/views/mainMenu.ejs @@ -31,11 +31,16 @@ Start Transaction

+
+
+
+
+
@@ -49,16 +54,22 @@ Create Employee

+
+

+
+

+
+