{"id":20650803,"url":"https://github.com/or-abdillh/evote-rest-api","last_synced_at":"2026-05-08T02:11:55.100Z","repository":{"id":64444936,"uuid":"460021795","full_name":"or-abdillh/evote-rest-api","owner":"or-abdillh","description":"REST API application for delivery request from client to server for HIMA TI Electronic Voting System - Express JS","archived":false,"fork":false,"pushed_at":"2022-12-27T01:37:22.000Z","size":1414,"stargazers_count":2,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"stable-v.2.0","last_synced_at":"2025-01-17T10:24:26.968Z","etag":null,"topics":["express","jwt","postgres","sequelize"],"latest_commit_sha":null,"homepage":"","language":"JavaScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/or-abdillh.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2022-02-16T13:44:23.000Z","updated_at":"2023-11-16T00:46:22.000Z","dependencies_parsed_at":"2023-01-13T14:47:36.167Z","dependency_job_id":null,"html_url":"https://github.com/or-abdillh/evote-rest-api","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/or-abdillh%2Fevote-rest-api","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/or-abdillh%2Fevote-rest-api/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/or-abdillh%2Fevote-rest-api/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/or-abdillh%2Fevote-rest-api/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/or-abdillh","download_url":"https://codeload.github.com/or-abdillh/evote-rest-api/tar.gz/refs/heads/stable-v.2.0","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":242750790,"owners_count":20179256,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["express","jwt","postgres","sequelize"],"created_at":"2024-11-16T17:23:15.625Z","updated_at":"2026-05-08T02:11:50.031Z","avatar_url":"https://github.com/or-abdillh.png","language":"JavaScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Evote REST API v.2\n\nThis is an application server for Electronic Vote System build using Node JS and Express JS.\n\nThe main file of this application is located on `server.js`.\n\n`.env` is a file to store environment variables.\n\n`logs.txt` is a file to store log history of every request that enters the server.\n\n\n## Install\n\n    git clone https://github.com/or-abdillh/evote-api-v2 \u0026\u0026 cd evote-api-v2 \u0026\u0026 npm install\n\n## Run the app\n\n    npm run dev\n\n## .env configuration\n\n\t\tDB_HOST=YOUR_HOSTNAME_DB\n\t\tDB_PORT=YOUR_PORT_DB\n\t\tDB_USER=YOUR_USERNAME\n\t\tDB_PASSWORD=YOUR_PASSWORD\n\t\tDB_NAME=evote_db\n\t\tJWT_SECRET_KEY=YOUR_SECRET_KEY\n\t\tLOGGER_PATH=logs.txt\n\n## logs.txt structure\n\n\t\t[20/2/2022 12.16.40] [403 - Forbidden] /quick-count GET 3,981ms\n\t\t[20/2/2022 12.16.35] [200 - OK] /admin/login POST 167,745ms\n\t\t[20/2/2022 11.18.05] [404 - Not Found] /admin/accounts PUT 148,866ms\n    \n# Database Structure\n\n### Accounts table\n\n\t\t| Field         | Type         | Null | Key | Default   | Extra |\n\t\t|---------------|--------------|------|-----|-----------|-------|\n\t\t| username      | varchar(15)  | NO   | PRI | NULL      |       |\n\t\t| password      | varchar(15)  | NO   |     | NULL      |       |\n\t\t| fullname      | varchar(50)  | NO   |     | NULL      |       |\n\t\t| token         | varchar(250) | YES  |     | undefined |       |\n\t\t| status_vote   | tinyint(1)   | YES  |     | 0         |       |\n\t\t| candidate_id  | int(11)      | YES  | MUL | NULL      |       |\n\t\t| job_id        | int(11)      | NO   | MUL | NULL      |       |\n\t\t| gender        | varchar(6)   | NO   |     | NULL      |       |\n\t\t| last_modified | bigint(20)   | NO   |     | NULL      |       |\n\t\t| time_stamp    | bigint(20)   | YES  |     | 0         |       |\n\t\t| role          | varchar(10)  | NO   |     | general   |       |\n\n### Candidates table\n\n\t\t| Field               | Type         | Null | Key | Default | Extra          |\n\t\t|---------------------|--------------|------|-----|---------|----------------|\n\t\t| candidate_id        | int(11)      | NO   | PRI | NULL    | auto_increment |\n\t\t| chairman_name       | varchar(30)  | NO   |     | NULL    |                |\n\t\t| chairman_image      | varchar(150) | NO   |     | NULL    |                |\n\t\t| vice_chairman_name  | varchar(30)  | NO   |     | NULL    |                |\n\t\t| vice_chairman_image | varchar(150) | NO   |     | NULL    |                |\n\t\t| candidate_number    | int(11)      | NO   |     | NULL    |                |\n\n### Event table\n\t\t\n\t\t| Field           | Type         | Null | Key | Default | Extra |\n\t\t|-----------------|--------------|------|-----|---------|-------|\n\t\t| event_start_at  | bigint(20)   | NO   |     | NULL    |       |\n\t\t| event_finish_at | bigint(20)   | NO   |     | NULL    |       |\n\t\t| event_title     | varchar(250) | NO   |     | NULL    |       |\n\t\t| passcode        | varchar(10)  | YES  |     | HIMATI  |       |\n\n### Jobs table\n\n\t\t| Field    | Type        | Null | Key | Default | Extra          |\n\t\t|----------|-------------|------|-----|---------|----------------|\n\t\t| job_id   | int(11)     | NO   | PRI | NULL    | auto_increment |\n\t\t| job_name | varchar(30) | NO   |     | NULL    |                |\n\t\t\n### Role guide account\n\n`master`, using for the administrator.\n`general` as ordinary or voter account.\n\n# REST API\n\nThe REST API to the example app is described below.\n\nIn the explanation below I use the `axios library` in exemplifying requests to the server\n\n## Get JWT token / Login\n\n### JWT structure payload\n\nJWT tokens will expire 30 minutes after tokens are generated\n\n\t\tjwt.decoded.payload = {\n\t\t\tusername: 'YOUR USERNAME HERE',\n\t\t\tisAdmin: true or false\n\t\t}\n\n### Request\n\n`POST /login` or `POST /admin/login` for admin\n\n\t\taxios.post(\n\t\t\t'http://localhost:8080/login',\n\t\t\t{ username, password }\n\t\t)\n\n### Response\n\n\t\t{\n\t\t\t\"status\": true,\n\t\t\t\"code\": 200,\n\t\t\t\"message\": 'success',\n\t\t\t\"response\": {\n\t\t\t\t\"token\": \"YOUR JWT TOKEN\"\n\t\t\t},\n\t\t\t\"createAt\": \"20/2022 16:45:32\"\n\t\t}\n\n## Get list of Candidates\n\n### Request\n\n`GET /candidates`\n\n\t\taxios.get(\n\t\t\t'http://localhost:8080/candidates',\n\t\t\t{ headers: { authorization: 'YOUR JWT TOKEN' } }\n\t\t)\n\n### Response\n\n\t\t{\n\t\t\t\"status\": true,\n\t\t\t\"code\": 200,\n\t\t\t\"message\": 'success',\n\t\t\t\"response\": {\n\t\t\t\t\"candidates\": [\n\t\t\t\t\t{\n\t\t\t\t\t\t\"candidate_id\": \"1\",\n\t\t\t\t\t\t\"candidate_number\": \"1\",\n\t\t\t\t\t\t\"chairman_name\": \"fulan\",\n\t\t\t\t\t\t\"vice_chairman_name\": \"fulanah\",\n\t\t\t\t\t\t\"chairman_image\": \"/male.jpg\",\n\t\t\t\t\t\t\"vice_chairman_name\": \"/female.jpg\"\n\t\t\t\t\t}\n\t\t\t\t]\n\t\t\t},\n\t\t\t\"createAt\": \"20/2022 16:45:32\"\n\t\t}\n\n## Create new candidate\n\n`POST /admin/candidates`\n\n### Request\n\n\t\t//Create body request\n\n\t\tconst body = {\n\t\t\tchairman_name: 'fulan',\n\t\t\tvice_chairman_name: 'fulanah',\n\t\t\tchairman_image: '/male.jpg',\n\t\t\tvice_chairman_image: '/female.jpg',\n\t\t\tcandidate_number: '2'\n\t\t}\n\t\t\n\t\taxios.post(\n\t\t\t'http://localhost:8080/admin/candidates',\n\t\t\tbody,\n\t\t\t{ headers: { authorization: 'YOUR TOKEN JWT' } }\n\t\t)\n\n### Response\n\n\t\t{\n\t\t\t\"status\": true,\n\t\t\t\"code\": 200,\n\t\t\t\"message\": 'success',\n\t\t\t\"response\": \"success to create new candidate for fulan - fulanah\",\n\t\t\t\"createAt\": \"20/2022 16:45:32\"\n\t\t}\n\n## Update candidate\n\n`PUT /admin/candidates`\n\n### Request\n\n\t\t//Create body request\n\n\t\tconst body = {\n\t\t\tchairman_name: 'fulan',\n\t\t\tvice_chairman_name: 'fulanah',\n\t\t\tchairman_image: '/male.jpg',\n\t\t\tvice_chairman_image: '/female.jpg',\n\t\t\tcandidate_number: '2',\n\t\t\tcandidate_id: '1' //PRIMARY KEY\n\t\t}\n\t\t\n\t\taxios.put(\n\t\t\t'http://localhost:8080/admin/candidates',\n\t\t\tbody,\n\t\t\t{ headers: { authorization: 'YOUR TOKEN JWT' } }\n\t\t)\n\n### Response\n\n\t\t{\n\t\t\t\"status\": true,\n\t\t\t\"code\": 200,\n\t\t\t\"message\": 'success',\n\t\t\t\"response\": \"success to update candidate for fulan - fulanah\",\n\t\t\t\"createAt\": \"20/2022 16:45:32\"\n\t\t}\n\n\n## Remove a candidate\n\n### Request\n\n`DELETE /admin/candidates`\n\n\t\t//Create body\n\t\tconst body = { candidate_id: '1' }\n\n\t\taxios.delete(\n\t\t\t'http://loaclhost:8080/admin/candidates',\n\t\t\t{ body, headers: { authorization: 'YOUR TOKEN JWT' } }\n\t\t)\n\n### Response\n\n\t\t{\n\t\t\t\"status\": true,\n\t\t\t\"code\": 200,\n\t\t\t\"message\": 'success',\n\t\t\t\"response\": \"success to remove candidate from list by ID 1\",\n\t\t\t\"createAt\": \"20/2022 16:45:32\"\n\t\t}\n\n## Get list of accounts\n\n### Request\n\n`GET /admin/accounts`\n\n\t\taxios.get(\n\t\t\t'http://localhost:8080/admin/accounts',\n\t\t\t{ headers: { authorization: 'YOUR JWT TOKEN' } }\n\t\t)\n\n### Response\n\n\t\t{\n\t\t\t\"status\": true,\n\t\t\t\"code\": 200,\n\t\t\t\"message\": 'success',\n\t\t\t\"response\": {\n\t\t\t\t\"accounts\": [\n\t\t\t\t\t{\n\t\t\t\t\t\t\"fullname\": \"fulan bin fulan\",\n\t\t\t\t\t\t\"username\": \"fulan123\",\n\t\t\t\t\t\t\"password\": \"fulan123\",\n\t\t\t\t\t\t\"status_vote\": 0,\n\t\t\t\t\t\t\"jobs_name\": \"Dosen\",\n\t\t\t\t\t\t\"gender\": \"male\",\n\t\t\t\t\t\t\"timestamp\": 0\n\t\t\t\t\t}\n\t\t\t\t]\n\t\t\t},\n\t\t\t\"createAt\": \"20/2022 16:45:32\"\n\t\t}\n\n## Craete new account\n\n### Request \n\n`POST /admin/accounts`\n\n\t\t//Create body request\n\t\tconst body = {\n\t\t\tfullname: 'fulanah binti fulan',\n\t\t\tusername: 'fulanah123',\n\t\t\tpassword: 'fulanah123',\n\t\t\tgender: 'female',\n\t\t\tjob_id: '1'\n\t\t}\n\n\t\taxios.post(\n\t\t\t'http://localhost:8080/admin/accounts',\n\t\t\tbody,\n\t\t\t{ headers: { authorization: 'YOUR JWT TOKEN' } }\n\t\t)\n\n### Response\n\n\t\t{\n\t\t\t\"status\": true,\n\t\t\t\"code\": 200,\n\t\t\t\"message\": 'success',\n\t\t\t\"response\": \"success to create new account for fulanah binti fulan\",\n\t\t\t\"createAt\": \"20/2022 16:45:32\"\n\t\t}\n\t\t\n## Update an account\n\n### Request \n\n`PUT /admin/accounts`\n\n\t\t//Create body request\n\t\tconst body = {\n\t\t\tfullname: 'fulanah binti fulan',\n\t\t\tusername: 'fulanah123',\n\t\t\tpassword: 'fulanah123',\n\t\t\tgender: 'female',\n\t\t\tjob_id: '1',\n\t\t\tkey: '1' //PRIMARY KEY username\n\t\t}\n\n\t\taxios.put(\n\t\t\t'http://localhost:8080/admin/accounts',\n\t\t\tbody,\n\t\t\t{ headers: { authorization: 'YOUR JWT TOKEN' } }\n\t\t)\n\n### Response\n\n\t\t{\n\t\t\t\"status\": true,\n\t\t\t\"code\": 200,\n\t\t\t\"message\": 'success',\n\t\t\t\"response\": \"success to update account for fulanah binti fulan\",\n\t\t\t\"createAt\": \"20/2022 16:45:32\"\n\t\t}\n\n## Remove account\n\n### Request\n\n`DELETE /admin/accounts`\n\n\t\t//Create body request\n\t\tconst body = {\n\t\t\tusername: 'fulanah123'\n\t\t}\n\n\t\taxios.delete(\n\t\t\t'http://localhost:8080/admin/accounts',\n\t\t\t{ body, headers: { authorization: 'YOUR JWT TOKEN' } }\n\t\t)\n\n### Response \n\n\t\t{\n\t\t\t\"status\": true,\n\t\t\t\"code\": 200,\n\t\t\t\"message\": 'success',\n\t\t\t\"response\": \"success to remove fulanah123 from list accounts\",\n\t\t\t\"createAt\": \"20/2022 16:45:32\"\n\t\t}\n\n## Get profile for spesific account\n\n### Request\n\n`GET /accounts/profile`\n\n\t\taxios.get(\n\t\t\t'http://localhost/8080/accounts/profile',\n\t\t\t{ headers: { authorization: 'YOUR JWT TOKEN' } }\n\t\t)\n\n### Response\n\n\t\t{\n\t\t\t\"status\": true,\n\t\t\t\"code\": 200,\n\t\t\t\"message\": 'success',\n\t\t\t\"response\": {\n\t\t\t\tprofile: {\n\t\t\t\t\t\"fullname\": \"fulan bin fulan\",\n\t\t\t\t\t\"username\": \"fulan123\",\n\t\t\t\t\t\"password\": \"fulan123\",\n\t\t\t\t\t\"status_vote\": 0,\n\t\t\t\t\t\"jobs_name\": \"Dosen\",\n\t\t\t\t\t\"gender\": \"male\",\n\t\t\t\t\t\"timestamp\": 0\n\t\t\t\t}\n\t\t\t},\n\t\t\t\"createAt\": \"20/2022 16:45:32\"\n\t\t}\n\n## Submit vote\n\n### Request\n\n`POST /accounts/vote/:candidate`\n\n\t\t//Get candidate_id\n\t\tconst candiateID = 1\n\t\t\n\t\taxios.post(\n\t\t\t'http://localhost:8080/accounts/vote/' + candidateID,\n\t\t\t{ headers: { authorization: 'YOUR JWT TOKEN'} }\n\t\t)\n\n### Response\n\n\t\t{\n\t\t\t\"status\": true,\n\t\t\t\"code\": 200,\n\t\t\t\"message\": 'success',\n\t\t\t\"response\": \"Your vote success to submit\",\n\t\t\t\"createAt\": \"20/2022 16:45:32\"\n\t\t}\n\n## Check if the account is logged in\n\n### Request\n\n`GET /auth`\n\n\t\taxios.get(\n\t\t\t'http://localhost:8080/auth',\n\t\t\t{ headers: { authorization: 'YOUR JWT TOKEN' } }\n\t\t)\n\n### Response\n\n\t\t{\n\t\t\t\"status\": true,\n\t\t\t\"code\": 200,\n\t\t\t\"message\": 'success',\n\t\t\t\"response\": \"Your account verified\",\n\t\t\t\"createAt\": \"20/2022 16:45:32\"\n\t\t}\n\n## Get event information\n\n### Request\n\n`GET /event`\n\n\t\taxios.get(\n\t\t\t'http://localhost:8080/event',\n\t\t\t{ headers: { authorization: 'YOUR JWT TOKEN' } }\n\t\t)\n\n### Response\n\n\t\t{\n\t\t\t\"status\": true,\n\t\t\t\"code\": 200,\n\t\t\t\"message\": 'success',\n\t\t\t\"response\": {\n\t\t\t\tevent: {\n\t\t\t\t\t\"event_title\": \"Pemilihan Ketum dan Waketum\",\n\t\t\t\t\t\"event_start_at\": 162532730000, //UNIX Time\n\t\t\t\t\t\"event_finish_at\": 10820130000,\n\t\t\t\t\t\"passcode\": \"VOTE2022\",\n\t\t\t\t\t\"count\": 4 //accounts has voted\n\t\t\t\t}\n\t\t\t},\n\t\t\t\"createAt\": \"20/2022 16:45:32\"\n\t\t}\n\n## Update Event\n\n### Request\n\n`PUT /admin/event`\n\n\t\t//Create body\n\t\tconst body = {\n\t\t\tevent_title: 'Pemilihan Ketum dan Waketum',\n\t\t\tevent_start_at: 16846820000,\n\t\t\tevent_finish_at: 2310349000,\n\t\t\tevent_passcode: 'VOTINGYUUK'\n\t\t}\n\n\t\taxios.put(\n\t\t\t'http://localhost:8080/admin/event',\n\t\t\t{ body, headers: { authorization: 'YOUR JWT TOKEN' } }\n\t\t)\n\n### Response\n\n\t\t{\n\t\t\t\"status\": true,\n\t\t\t\"code\": 200,\n\t\t\t\"message\": 'success',\n\t\t\t\"response\": \"Success to update Event detail\",\n\t\t\t\"createAt\": \"20/2022 16:45:32\"\n\t\t}\n\n## Get dashboard admin \n\n### Request\n\n`GET /admin/event`\n\n\t\taxios.get(\n\t\t\t'http://localhost:8080/admin/event',\n\t\t\t{ headers: { authorization: 'YOUR JWT TOKEN' } }\n\t\t)\n\n### Response\n\n\t\t{\n\t\t\t\"status\": true,\n\t\t\t\"code\": 200,\n\t\t\t\"message\": 'success',\n\t\t\t\"response\": {\n\t\t\t\t\"dashboard\": {\n\t\t\t\t\t\"candidates\": 4,\n\t\t\t\t\t\"participants\": 6,\n\t\t\t\t\t\"incomingVote\": 2,\n\t\t\t\t\t\"participations\": \"32.56%\"\n\t\t\t\t}\n\t\t\t},\n\t\t\t\"createAt\": \"20/2022 16:45:32\"\n\t\t}\n\n## Get quick count result\n\n### Request\n\n`GET /admin/event/quick-count`\n\n\t\taxios.get(\n\t\t\t'http://localhost:8080/admin/event/quick-count',\n\t\t\t{ headers: { authorization: 'YOUR JWT TOKEN' } }\n\t\t)\n\n### Response\n\n\t\t{\n\t\t\t\"status\": true,\n\t\t\t\"code\": 200,\n\t\t\t\"message\": 'success',\n\t\t\t\"response\": {\n\t\t\t\t\"quickCount\": [\n\t\t\t\t\t{\n\t\t\t\t\t\t\"candidate\": \"Fulan - Fulanah\",\n\t\t\t\t\t\t\"candidateNumber\": 1,\n\t\t\t\t\t\t\"vote\": 9,\n\t\t\t\t\t\t\"decimal\": 42.77777778,\n\t\t\t\t\t\t\"percent\": \"42.88%\"\"\n\t\t\t\t\t}\n\t\t\t\t]\n\t\t\t},\n\t\t\t\"createAt\": \"20/2022 16:45:32\"\n\t\t}\n\n## Error handling\n\n### This is example response error from server\n\n\t\t{\n\t\t\t\"status\": true,\n\t\t\t\"code\": 403,\n\t\t\t\"message\": 'Ilegal access',\n\t\t\t\"response\": \"Just admin can access this resource\",\n\t\t\t\"createAt\": \"20/2022 16:45:32\"\n\t\t}\n\n### You can get the errror message using axios error handling\n\n\t\taxios.get(\n\t\t\t'http://localhost:8080/admin/accounts',\n\t\t\t{ headers: { athorization: 'TOKEN NOT FROM ADMIN' } },\n\t\t)\n\t\t.then( res =\u003e console.log(res.data) )\n\t\t.catch( err =\u003e {\n\t\t\tif ( err.response ) console.error(err.response.data) //response error from server \t\n\t\t})\n\n## Thanks \n- Support me with a cup of coffee and other snacks [here ..](https://saweria.co/orabdillh)\n- Don't forget to give me star in this repository 🙏🏻🙏🏻\n- See my other projects on instagram [@or.abdillh](http://www.instagram.com/or.abdillh)\n\n[Oka R Abdillah ](http://github.com/or-abdillh)\n\u003cbr\u003e\nLast edited on : 20/02/2022\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2For-abdillh%2Fevote-rest-api","html_url":"https://awesome.ecosyste.ms/projects/github.com%2For-abdillh%2Fevote-rest-api","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2For-abdillh%2Fevote-rest-api/lists"}