increments
v1.2.5
Published
Create polls and manage votes with a MongoDB or MySQL database.
Downloads
55
Maintainers
Readme
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.
Fig 1. A screen-shot of the voting options listed in an example Canadian elections poll.
Instant Gratification
$ 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...
$ 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.
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) / (MongoDB)
- 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 v4+ to run Increments on your system. Next, download or clone the latest release from GitHub. Use NPM to install the required dependences. Warning: Dependences may not be secure and safe to use in a production environment.
npm install increments --save
or install it from GitHub repository
$ git clone https://github.com/bentbot/increments
$ cd ./increment
$ npm install
$ node index.js
Database
MongoDB
Create a user with the name
increment
which hasreadWrite
access to a database.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>
let increments = require('increments');
increments.setup('mongodb://increments:<password>@localhost/polls');
or
MySQL
Create a user with the name
increment
and add it to a database calledpolls
Grant the following privileges to the user: Alter, Create, Insert, Select
Setup Increments using your MySQL username and password in a JDBC URL.
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.
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.
increments.vote('election', 'Red Team');
A vote may be passed as an object with the poll and name defined within it.
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
Fig 2. Canadian elections poll example: view this project's source code.
Generating basic statistics can be accomplished by specifying the poll to count.
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.
- Forwarding Ports: 8080, 3000 ( ex. 443, 3030 )
Enable/disable browser cookies to prevent double-voting:
increments.setup({ cookies: true });
- Enable/disable browser instance keys to prevent double-voting:
increments.setup({ instance: true });
Testing
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
$ 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:
Fig 5. Statistics View (with 1 spoiled ballot):
Fig 6. This error message is seen when trying to re-vote:
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