JS Module Security - javascript

Recently finished a module of which is supposed to track the inventory of a store. Upon completion, the project was returned to me because the security of the internal information is lacking, e.g. test cases allow modification of the inventory and such.
Module:
'use strict';
let obj = {};
let list = [];
let sortedList = [];
obj.addItem = function(name, price) {
let item = {name:name, price:price};
list.push(item);
};
obj.items = function(){
let sortList = list;
let completeSort = sortList.sort(function(a, b) {
return a.price - b.price;
});
completeSort.forEach(function (itemObject) {
sortedList.push(itemObject);
});
return completeSort;
};
obj.getMostExpensive = function() {
let sortList = list;
let completeSort = sortList.sort(function(a, b) {
return a.price - b.price;
});
completeSort.forEach(function (itemObject) {
sortedList.push(itemObject);
});
let hCostIndex = (sortedList.length) - 1;
let mostExpensive = sortedList[hCostIndex];
return mostExpensive;
};
obj.getLeastExpensive = function() {
let sortList = list;
let completeSort = sortList.sort(function(a, b) {
return a.price - b.price;
});
completeSort.forEach(function (itemObject) {
sortedList.push(itemObject);
});
let lCostIndex = sortedList[0];
let leastExpensive = lCostIndex;
return leastExpensive;
};
obj.removeItem = function(name) {
let index = 0;
list.forEach(function(item) {
if(item.name == name){
index = list.indexOf(item);
if (index >= 0){
list.splice(index, 1);
}
}
});
};
obj.getItemByName = function(name) {
for (let i = 0; i < list.length; i++) {
if(list[i].name == name){
return list[i];
}
}
};
obj.getItemByPrice = function(price) {
for (let i = 0; i < list.length; i++) {
if(list[i].price == price){
return list[i];
}
}
};
module.exports = obj;
The problem mainly is that the items function and my other functions that return an inventory item can be used to modify the inventory information, and I don't know how to prevent that from happening. Any help would be greatly appreciated.
EDIT--
I believe I've fixed it, given the answers I've been provided. Should this change to the item function fix the issue?
obj.items = function(){
let sortedList = [];
let completeSort = list.sort(function(a, b) {
return a.price - b.price;
});
completeSort.forEach(function (itemObject) {
sortedList.push(itemObject);
});
return sortedList;
};

Related

Get a value of a HashTable

I was making a HashTable to have as an example and have it saved for any problem, but I ran into a problem trying to implement a method that returns true or false in case the value belongs to the HashTable, since it is inside a arrays of objects as comment in the code.
I have tried for loops, .map and for of, but it always fails, if someone could help me.
function HashTable () {
this.buckets = [];
this.numbuckets = 35;
}
HashTable.prototype.hash = function (key) {
let suma = 0;
for (let i = 0; i < key.length; i++) {
suma = suma + key.charCodeAt(i);
}
return suma % this.numbuckets;
}
HashTable.prototype.set = function (key, value) {
if (typeof key !== "string") {
throw new TypeError ("Keys must be strings")
} else {
var index = this.hash(key);
if(this.buckets[index] === undefined) {
this.buckets[index] = {};
}
this.buckets[index][key] = value;
}
}
HashTable.prototype.get = function (key) {
var index = this.hash(key);
return this.buckets[index][key];
}
HashTable.prototype.hasKey = function (key) {
var index = this.hash(key);
return this.buckets[index].hasOwnProperty(key)
}
HashTable.prototype.remove = function (key) {
var index = this.hash(key);
if (this.buckets[index].hasOwnProperty(key)) {
delete this.buckets[index]
return true;
}
return false;
}
HashTable.prototype.hasValue = function (value) {
let result = this.buckets;
result = result.flat(Infinity);
return result // [{Name: Toni}, {Mame: Tino}, {Answer: Jhon}]
}
You can use Object.values() to get the values of all the propertyies in the bucket.
function HashTable() {
this.buckets = [];
this.numbuckets = 35;
}
HashTable.prototype.hash = function(key) {
let suma = 0;
for (let i = 0; i < key.length; i++) {
suma = suma + key.charCodeAt(i);
}
return suma % this.numbuckets;
}
HashTable.prototype.set = function(key, value) {
if (typeof key !== "string") {
throw new TypeError("Keys must be strings")
} else {
var index = this.hash(key);
if (this.buckets[index] === undefined) {
this.buckets[index] = {};
}
this.buckets[index][key] = value;
}
}
HashTable.prototype.get = function(key) {
var index = this.hash(key);
return this.buckets[index][key];
}
HashTable.prototype.hasKey = function(key) {
var index = this.hash(key);
return this.buckets[index].hasOwnProperty(key)
}
HashTable.prototype.remove = function(key) {
var index = this.hash(key);
if (this.buckets[index].hasOwnProperty(key)) {
delete this.buckets[index]
return true;
}
return false;
}
HashTable.prototype.hasValue = function(value) {
return this.buckets.some(bucket => Object.values(bucket).includes(value));
}
let h = new HashTable;
h.set("Abc", 1);
h.set("Def", 2);
console.log(h.hasValue(1));
console.log(h.hasValue(3));

Promises in Node js: how to improve?

I'm working on a coding assignment for node.js and I finished it. However, I am wondering if there is any way to improve upon it. The assignment is to take in 3 promises with JSON objects and merge the data as such.
My code does take in the three promises, resolves them, and merges them according to the specifications. I am worried that the code may be too convoluted.
Are there any recommendations to improve it?
Thanks!
{
travelers: [
id,
name,
flights: [
{
legs: [
{
airlineCode,
airlineName,
flightNumber,
frequentFlyerNumber
}
]
}
]
]
}
As I said, my code works but I'm wondering if it can be improved. Here is my code.
'use strict';
// TODO Import what you need
var tripService = require('./api/trip.service.js');
var profile = require('./api/profiles.service.js');
var airlines = require('./api/airlines.service.js');
function getTravelersFlightInfo() {
var tripServiceGet= () => tripService.get();
var profileGet = () =>profile.get();
var airlinesGet = () => airlines.get();
var trips = tripServiceGet().then(function(trip){
return trip;
});
var profiles = profileGet().then(function(profile){
return profile;
});
var airline = airlinesGet().then(function(airlines){
return airlines;
});
function assignLegsToTraveler(passengerFlight, legs , airline , ff){
passengerFlight = {};
passengerFlight.legs = [];
for(let i = 0; i < legs.length; i++){
var airCode = legs[i].airlineCode;
passengerFlight.legs[i] = {};
passengerFlight.legs[i].airlineCode = airCode;
passengerFlight.legs[i].airlineName = airline.airlines.find( x => x.code === airCode).name;
passengerFlight.legs[i].flightNumber = legs[i].flightNumber;
if (ff.hasOwnProperty(airCode) === true){
passengerFlight.legs[i].frequentFlyerNumber = ff[airCode];
}
}
return passengerFlight;
}
function assignFlights(passenger, trips, airline, ff){
for(let i = 0; i < trips.flights.length; i++){
if(trips.flights[i].travelerIds.includes(passenger.id)){
passenger.flights[passenger.flights.length] = assignLegsToTraveler(passenger.flights[passenger.flights.length], trips.flights[i].legs, airline, ff);
}
}
return passenger;
}
return Promise.all([trips, profiles, airline]).then(function([trips, profiles, airline]) {
var result = {};
result.travelers = [];
for(let i = 0; i < profiles.profiles.length; i++){
result.travelers[i] = {};
result.travelers[i].id = profiles.profiles[i].personId;
result.travelers[i].name = profiles.profiles[i].name;
result.travelers[i].flights = [];
assignFlights(result.travelers[i], trips.trip, airline, profiles.profiles[i].rewardPrograms.air);
}
console.log(JSON.stringify(result, null,2));
return result;
});
}
getTravelersFlightInfo();
module.exports = getTravelersFlightInfo;

Implementing Dijkstra in Javascript

I am trying to get an implementation of Dijkstra's algorithm in JavaScript to run properly.
I found a walkthrough Here and do not understand the return line
return `Path is ${path} and time is ${times[endNode]}
I have collected the code from the link below to make it easier.
class Graph {
constructor() {
this.nodes = [];
this.adjacencyList = [];
}
addNode(node) {
this.nodes.push(node);
this.adjacencyList[node] = [];
}
addEdge(node1, node2, weight) {
this.adjacencyList[node1].push({node:node2, weight: weight});
this.adjacencyList[node2].push({node:node1, weight: weight});
}
findPathWithDijkstra(startNode, endNode) {
let times = [];
let backtrace = [];
let pq = new PriorityQueue();
times[startNode] = 0;
this.nodes.forEach(node => {
if (node !== startNode) {
times[node] = Infinity
}
});
pq.enqueue([startNode, 0]);
while (!pq.isEmpty()) {
let shortestStep = pq.dequeue();
let currentNode = shortestStep[0];
this.adjacencyList[currentNode].forEach(neighbor => {
let time = times[currentNode] + neighbor.weight;
if (time < times[neighbor.node]) {
times[neighbor.node] = time;
backtrace[neighbor.node] = currentNode;
pq.enqueue([neighbor.node, time]);
}
});
}
let path = [endNode];
let lastStep = endNode;
while(lastStep !== startNode) {
path.unshift(backtrace[lastStep])
lastStep = backtrace[lastStep]
}
return `Path is ${path} and time is ${times[endNode] }`
}
}
class PriorityQueue {
constructor() {
this.collection = [];
}
enqueue(element){
if (this.isEmpty()){
this.collection.push(element);
} else {
let added = false;
for (let i = 1; i <= this.collection.length; i++){
if (element[1] < this.collection[i-1][1]){
this.collection.splice(i-1, 0, element);
added = true;
break;
}
}
if (!added){
this.collection.push(element);
}
}
};
dequeue() {
let value = this.collection.shift();
return value;
};
isEmpty() {
return (this.collection.length === 0)
};
}
let testGraph01 = new Graph();
let testGraph02 = new Graph();
let testGraph03 = new Graph();
//creating graphs
testGraph01.addNode("A");
testGraph01.addNode("B");
testGraph01.addNode("C");
testGraph01.addNode("D");
testGraph01.addEdge("A","B",10);
testGraph01.addEdge("C","D",5);
testGraph01.addEdge("D","B",5);
console.log(testGraph01.findPathWithDijkstra("A","D"));
I am looking for an explanation of the templated return. How does it work in javascript i guess?

Depth first search using node gives, RangeError: Maximum call stack size exceeded

I’m trying to rewrite my code to get over a stack size error “RangeError: Maximum call stack size exceeded” I run into. I’m trying to run a DFS using a stack in JavaScript using node.
I’ve heard a lot about settimeout but I’m not sure how to implement it in my case. Any advice would be great.
Heres the code that fails:
var Stack = function() {
this.items = [];
};
Stack.prototype.push = function(obj) {
this.items.push(obj);
};
Stack.prototype.pop = function() {
return this.items.pop();
};
Stack.prototype.isEmpty = function() {
return this.items.length === 0;
};
Stack.prototype.isExplored = function(n){
return this.items.indexOf(n) !== -1;
}
Stack.prototype.emptyOut = function() {
this.items = [];
return this.items.length === 0;
};
var stack = new Stack();
var adjList=[];
for(var i= 1; i<15557;i++){
adjList.push([i])
}
adjList.push([0])
function DFS(graph, s){
stack.push(s);
for(var i = 0 ; i < graph[s].length; i++){
var v = graph[s][i];
if(!stack.isExplored(v)){
DFS(graph, v);
}
}
}
DFS(adjList, 0)
console.log("done", stack);
Have you considered switching to an iterative approach?
var Stack = function() {
this.items = [];
};
Stack.prototype.push = function(obj) {
this.items.push(obj);
};
Stack.prototype.pop = function() {
return this.items.pop();
};
Stack.prototype.isEmpty = function() {
return this.items.length === 0;
};
Stack.prototype.isExplored = function(n) {
return this.items.indexOf(n) !== -1;
}
Stack.prototype.emptyOut = function() {
this.items = [];
return this.items.length === 0;
};
var stack = new Stack();
var adjList = [];
for (var i = 1; i < 15557; i++) {
adjList.push([i]);
}
adjList.push([0])
function DFS(graph, v) {
var queue = [v];
while (queue.length) {
v = queue.pop();
if (stack.isExplored(v))
continue;
stack.push(v);
for (var i = graph[v].length - 1; i >= 0; i--) {
queue.push(graph[v][i]);
}
}
}
DFS(adjList, 0);
console.log("done", stack);
The limit is now the amount of memory node has at disposal.

Improvising Code Into A More DRY Approach?

I am formatting an array in the function inputCategories, and am unable to correctly add a third argument of "category" - forcing me replicate the function multiple times.
Here is the current state:
Calling the function with arguments.
$scope.categories = inputCategories($scope.item.categories, $scope.settings.categories);
function inputCategories (input, settings) {
var updatedSettings = [];
angular.forEach(input, function(obj) {
updatedSettings.push({"category": obj, "ticked": true});
});
var list = updatedSettings.concat(settings);
list.sort(function(a, b) {
return (a.category > b.category) - (a.category < b.category);
});
for ( var i = 1; i < list.length; i++ ){
if(list[i-1].category == list[i].category) {
list.splice(i,1);
}
}
return list;
};
Here are the places which would require a third argument of "category".
function inputCategories (input, settings) {
var updatedSettings = [];
angular.forEach(input, function(obj) {
updatedSettings.push({****"category"****: obj, "ticked": true});
});
var list = updatedSettings.concat(settings);
list.sort(function(a, b) {
return (a.****category**** > b.****category****) - (a.****category**** < b.****category****);
});
for ( var i = 1; i < list.length; i++ ){
if(list[i-1].****category**** == list[i].****category****) {
list.splice(i,1);
}
}
return list;
};
I think that the issue I am having is because I am mixing up strings and a variable that is a string, inside of the object on the fourth line...?
Perhaps you could do something like this:
function inputCategories (input, settings, category) {
var updatedSettings = [];
angular.forEach(input, function(obj) {
var setting = { "ticked": true };
setting[category] = obj;
updatedSettings.push(setting);
});
var list = updatedSettings.concat(settings);
list.sort(function(a, b) {
return (a[category] > b[category]) - (a[category] < b[category]);
});
for ( var i = 1; i < list.length; i++ ){
if(list[i-1][category] == list[i][category]) {
list.splice(i,1);
}
}
return list;
};

Categories

Resources