UNPKG

increments

Version:

Create polls and manage votes with a MongoDB or MySQL database.

242 lines (193 loc) 8.98 kB
# Increments Increments is a **database-driven** for creating **polls** and taking **votes** for various options, candidates, or parties. Using MongoJS collections as a storage framework, Increments offers in-depth statistical data on generated polls. ![N|Solid](https://raw.githubusercontent.com/bentbot/increments/master/screenshots/canadian_poll.png) ***Fig 1.** A screen-shot of the voting options listed in an example [Canadian elections](https://github.com/bentbot/Canada-Votes-2019) poll.* ## Instant Gratification ```js $ npm install $ node index.js ``` Modify the _index_ file for a quick & easy web-based poll that's nearly ready to deploy. ## Usage Install the **increments** module with NPM... ```js $ npm install increments ``` Add Increments to your code and specify a database. Increments can create polls with options, vote on polls, require unique keys & cookies, generate statistics, and calculate a winner. ```js let increments = require('increments'); increments.setup({ db: 'mongodb://increment:inc@localhost/increment' }); increments.setup('mysql://increments:increment@localhost:3306/polls'); increments.poll('fruits', ['Apples','Bananas','Oranges','Pears']); increments.vote('fruits', 'Oranges'); increments.statistics('fruits', function(e, f) { console.log( f.projectedWinner ); }); ``` ### Features - Poll & voting mechanics - Database driven statistics with ([MySQL](https://www.mysql.com/)) / ([MongoDB](https://www.mongodb.com/)) - Unique browser session keys and cookie protection ### You can also: - Create and interact with different polls - Add as many political parties as need - Test voting with an automated script - Log votes to a file - Turn cookies and session keys on or off - Submit or discard spoiled ballots ## Installation Node.JS is required. Please install [Node.js](https://nodejs.org/) v4+ to run _Increments_ on your system. Next, download or clone [the latest release](https://github.com/bentbot/increments) from GitHub. Use NPM to install the required dependences. **Warning: Dependences may not be secure and safe to use in a production environment.** ```js npm install increments --save ``` or install it from GitHub repository ```js $ git clone https://github.com/bentbot/increments $ cd ./increment $ npm install $ node index.js ``` ### Database #### MongoDB 1. Create a user with the name `increment` which has `readWrite` access to a database. 2. Modify the databse line in `./increment.js` to **reflect your local or remote MongoDB** server. - The first segment is your database username and password: `mongodb://<username>:<password>` - The second part is your database IP address and port: `@<address>:<port>` - Finally, add the title of the collecton to the MongoDB URL: `/<collection name>` ```js let increments = require('increments'); increments.setup('mongodb://increments:<password>@localhost/polls'); ``` or #### MySQL 1. Create a user with the name `increment` and add it to a database called `polls` 2. Grant the following privileges to the user: Alter, Create, Insert, Select 3. Setup Increments using your MySQL username and password in a JDBC URL. ```js let increments = require('increments'); increments.setup('mysql://increments:<password>@localhost:3306/polls'); ``` ### Modifying Candidates The first few lines of `index.js` define the **candidates** and basic security settings. Candidates are encoded using the __JSON__ data standard. Make sure the structure remains intact and programmicly correct. Remember to omit the ending comma from the last candidate. ```js let candidates = [ { name: 'Red Team', color: 'red' }, { name: 'Blue Team', color: 'blue' } ]; increments.poll('election', candidates); ``` ### Voting A vote can be formed in multiple ways. The most simple is to reference a poll and provide a name. ```js increments.vote('election', 'Red Team'); ``` A vote may be passed as an object with the poll and name defined within it. ```js var ballot = { poll: 'election', name: 'Red Team', data: '123' }; increments.vote(ballot, function(err, res) { if (err) throw(err); console.log(res); }); /* Output: { __v: 0, unique: '90699e2...', name: 'Red Team', poll: 'election', data: '123', _id: 58bb40f79477c58065acc950, time: 2017-03-04T22:34:31.929Z } */ ``` ### Statistics [ ![N|Solid](https://raw.githubusercontent.com/bentbot/increments/master/screenshots/canadian_poll_results.png) ](https://github.com/bentbot/Canada-Votes-2019) ***Fig 2.** Canadian elections poll example: [view this project's source code.](https://github.com/bentbot/Canada-Votes-2019)* Generating basic statistics can be accomplished by specifying the poll to count. ```js increments.statistics('election', function (err, statistics) { console.log(statistics); }); /* Statistics Output: { poll: 'election', candidates: [ { name: 'Red Team', color: 'red', count: 1, id: 'red_team', percentage: '100.0' }, { name: 'Blue Team', color: 'blue', count: 0, id: 'blue_team', percentage: 0 } ], total: 1, projectedWinner: { name: 'Red Team', color: 'red', count: 1, id: 'red_team', percentage: '100.0' } } */ ``` ### Security Expremental security features are available. It is suggusted to log a user's **IP addresses** in the __data__ mutiable when submitting a vote. - Also Consider - Comparing ISP information by resolving the IP Address of each vote. - Uniqueness of geolocation provided by a third-party or the client itself. - Automatically checking voting machine software for files that were modified. - Client specific info ( Gecko Versions, System OS, time, window size / position ) - The time between each vote submitted. Votes in fast succession may suggest fraud. - Reverse-hashing each vote data to help detect database modifications. - Creating HTTPS layers for **POST** and **Socket.IO** routes with a [webserver proxy](http://nginx.com/blog/nginx-nodejs-websockets-socketio/). - Forwarding Ports: _8080_, _3000_ ( ex. _443, 3030_ ) - Enable/disable **browser cookies** to prevent double-voting: ```js increments.setup({ cookies: true }); ``` - Enable/disable **browser instance keys** to prevent double-voting: ```js increments.setup({ instance: true }); ``` ## Testing ![N|Solid](https://raw.githubusercontent.com/bentbot/increments/master/screenshots/votes.gif) ***Fig 3.** The Increments testing program adds votes to a local environment using Seleium Webdriver.* The _Increments_ package includes application to automatically test the voting procedure. Increment uses **Selenium Webdriver** to preform rapid-fire testing by replicating how a user would cast a vote. ### Setup WebDriver The **webdriver-service** should only take only a moment to install. It can be installed to your system with **NPM** or downloaded directly: http://www.seleniumhq.org/projects/webdriver/ `npm install webdriver-service -g` ### Incremental Testing - Start the vote server so it is accessable from your web browser at http://localhost:8000/. - In a new terminal window or _screen_, start the **webdriver-manager** by running: `$ webdriver-manager start` In the terminal, if run the test.js file with the help argument you will see a list of options. - -c --candidate 1 Select the candidate number by number - -n --numerations 100 Set the number of votes - -k --thousands Set the number of votes (multiplied my a thousand) - -m --millions Set the number of votes (multiplied my a million) - -r --random Choose a random candidate for each vote `$ node test.js --help` ```ssh $ node test.js -c 1 -n 65 Running 65 votes for candidate 1 ``` If the test runs correctly, you should see a web browser pop-up and repeatedly cast a vote for the selected candidate. The results will are tabulated on the statistics page: http://localhost:8000/statistics ## Example Screenshots #### **Fig 4.** The voting screen: ![N|Solid](https://raw.githubusercontent.com/bentbot/increments/master/screenshots/vote.png) #### **Fig 5.** Statistics View (with 1 spoiled ballot): ![N|Solid](https://raw.githubusercontent.com/bentbot/increments/master/screenshots/statistics.png) #### **Fig 6.** This error message is seen when trying to re-vote: ![N|Solid](https://raw.githubusercontent.com/bentbot/increments/master/screenshots/verification.png) ### Frameworks Increment uses a number of open source projects to work properly: * [MySQL] - MySQL database driver * [Crypto] - Unique key generation * [node.js] - A self-contained server * [ExpressJS] - HTTP service for web pages * [Mongoose] - Mongo database driver * [MongoDB] - Local or remote database server * [Webdriver] - Automated browser testing * [jQuery] - Frontend scripting