{"id":18396257,"url":"https://github.com/jahn08/web-timer","last_synced_at":"2026-04-09T19:51:22.178Z","repository":{"id":31027430,"uuid":"126672164","full_name":"Jahn08/WEB-TIMER","owner":"Jahn08","description":"A web application to set a timer or stopwatch along with some customisation provided","archived":false,"fork":false,"pushed_at":"2023-03-04T02:41:53.000Z","size":3177,"stargazers_count":1,"open_issues_count":10,"forks_count":0,"subscribers_count":2,"default_branch":"master","last_synced_at":"2025-02-16T02:28:12.004Z","etag":null,"topics":["bootstrap4","docker","docker-compose","docker-container","docker-image","docker-secrets","dockerfile","eslint","javascript","mocha","mongo","mongoose","nodejs","nodemailer","passport","timer","vuejs2"],"latest_commit_sha":null,"homepage":null,"language":"JavaScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"bsd-3-clause","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/Jahn08.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2018-03-25T06:51:46.000Z","updated_at":"2022-01-14T17:16:50.000Z","dependencies_parsed_at":"2024-12-24T10:26:54.678Z","dependency_job_id":"27a10567-4730-4720-a03f-e62e8f524e2b","html_url":"https://github.com/Jahn08/WEB-TIMER","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/Jahn08%2FWEB-TIMER","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Jahn08%2FWEB-TIMER/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Jahn08%2FWEB-TIMER/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Jahn08%2FWEB-TIMER/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/Jahn08","download_url":"https://codeload.github.com/Jahn08/WEB-TIMER/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":248581797,"owners_count":21128241,"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":["bootstrap4","docker","docker-compose","docker-container","docker-image","docker-secrets","dockerfile","eslint","javascript","mocha","mongo","mongoose","nodejs","nodemailer","passport","timer","vuejs2"],"created_at":"2024-11-06T02:13:14.481Z","updated_at":"2025-12-30T19:08:31.503Z","avatar_url":"https://github.com/Jahn08.png","language":"JavaScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"\n![alt text](https://github.com/Jahn08/WEB-TIMER/blob/master/WebTimer/resources/images/favicon.svg)\n\n# WEB-TIMER\n\nA web application to set a timer or stopwatch along with some customisation provided. The main features are:\n\n* Timer and stopwatch available without registration\n* Customised timers for registered users\n* OAuth authentication and registration by Facebook\n* Administration module to gather the users' statistics\n* MongoDB as a default DB model provider ([more about database](#headDatabase))\n* Prerendering for better SEO ([a detailed description of my approach](https://medium.com/swlh/a-quick-approach-to-mend-seo-in-vue-8a94753eebfc)) \n\n## Installing / Getting started\n\nThe application is dependent on Node.js (and its npm utility) ([more about its version](#headPrerequisites)) along with MongoDB ([more about its version](#headSettingUpDev)).\n\nBefore starting the application all its dependencies must be installed by running a command from inside the WebTimer directory (where there is a file package.json): *npm install*. Building and starting the project is possible by using configurations inside VS Code: Debug Build or Prod Build. The configurations already have some environment variables set up in a file .vscode/launch.json, however, some parameters require revision in accordance to a local environment (more about configuring in the [configuration section below](#headConfiguration)).\n\nTo turn on debugging while testing there is a script available in package.json: *npm run debug-test*. After running the command it's possible to join the process in Google Chrome through the url: *chrome://inspect*. A directive *debugger* should be used for break points in tests.\n\nThe first user registered in the application will be granted the role of an administrator.\n\n## Developing\n\n### Built with\n\n* [express 4.16.3](https://www.npmjs.com/package/express/v/4.16.3)\n* [Vue 2.5.16](https://www.npmjs.com/package/vue/v/2.5.16)\n* [vue-router 3.0.1](https://www.npmjs.com/package/vue-router/v/3.0.1)\n* [Bootstrap 4.3.1](https://www.npmjs.com/package/bootstrap/v/4.3.1)\n* [jQuery 3.4.1](https://www.npmjs.com/package/jquery/v/3.4.1)\n* [Mongoose 5.7.5](https://www.npmjs.com/package/mongoose/v/5.7.5)\n* [mocha 7.1.1](https://www.npmjs.com/package/mocha/v/7.1.1)\n* [Passport 0.4.0](https://www.npmjs.com/package/passport/v/0.4.0)\n* [passport-facebook-token 3.3.0](https://www.npmjs.com/package/passport-facebook-token/v/3.3.0)\n* [body-parser 1.18.2](https://www.npmjs.com/package/body-parser/v/1.18.2)\n* [Multiple Select 1.2.1](https://www.npmjs.com/package/multiple-select/v/1.2.1)\n* [Nodemailer 4.6.7](https://www.npmjs.com/package/nodemailer/v/4.6.7)\n* [escape-html 1.0.3](https://www.npmjs.com/package/escape-html/v/1.0.3)\n* [helmet 3.21.3](https://www.npmjs.com/package/helmet/v/3.21.3)\n\nIcons made by [Smashicons](https://www.flaticon.com/authors/smashicons) from [www.flaticon.com](https://www.flaticon.com/) are licensed by [CC 3.0 BY](http://creativecommons.org/licenses/by/3.0/)\n\n### \u003ca name=\"headPrerequisites\"\u003e\u003c/a\u003ePrerequisites\n\n* [Node.js 16.14.0](https://nodejs.org/download/release/latest-v16.x/)\n* [MongoDB 3.6.2](https://www.mongodb.org/dl/win32/x86_64-2008plus-ssl?_ga=2.113660480.637015255.1538331504-1402874581.1537118071)\n* The project was developed in MS Visual Studio 2017 Community ([the product page](https://visualstudio.microsoft.com/vs/community/)) and Visual Studio Code\n\n### \u003ca name=\"headSettingUpDev\"\u003e\u003c/a\u003eSetting up Dev\n\nDeveloping the application in VS 2017 Community requires turning on the Node.js development component while installing. Additionally, [Node JS Tools](https://github.com/Microsoft/nodejstools/) is a requirement.\n\nThe developer computer has to have an access to a MongoDB server installed to deploy the database ([more about database](#headDatabase)).\n\n### Deploying / Publishing\n\nThe stages to deploy the application in a docker container by command prompt:\n1. Build the solution by choosing an option *Run Build Task -\u003e build-prod* when clicking *F1* in VS Code or by running a command from the WebTimer folder: *npm run build*\n2. Run a command in the root folder of the project where the Dockerfile file is available (including the dot at the end): *docker build -t webtimer .*\n3. Before the usage of the docker stack deploy command a swarm has to be initialised: *docker swarm init*\n4. Since the application relies on secret values they have to be entered the next way: *echo SECRET_VALUE|docker secret create SECRET_NAME -*\nThe list of all the possible secrets can be found in the docker-compose.yml file (more about them in the [configuration section below](#headConfiguration)).\n5. In the same directory where the docker-compose.yml file lies run a command: *docker stack deploy -c docker-compose.yml webtimer*\n\n[Here](https://github.com/Jahn08/GKE-WITH-INGRESS) is an example of how the application can be deployed on Google Kubernetes Engine.\n\n## \u003ca name=\"headConfiguration\"\u003e\u003c/a\u003eConfiguration\n\nAll preferences are set in config.js inside the WebTimer directory. Each option supplemented with a secret parameter can also be determined through an environment variable with the same name for purposes of developing. The structure of the settings is next:\n* URLs for databases: *db.uri* and *db.testUri* are distinct in names for the main and test databases respectively, whereas the host for MongoDB is determined through an environment variable *MONGO_HOST* or *mongodb://localhost:27017/* by default\n* Parameters for the Facebook authentication: *auth.facebook.clientId* and *auth.facebook.secretId* (both are set by secrets  *AUTH_FACEBOOK_CLIENT_ID* and *AUTH_FACEBOOK_CLIENT_SECRET* accordingly)\n* To set a path to a certificate in a pfx-format along with its password when running the application on HTTPS: *server.pfx.path* (an environment variable *SERVER_PFX_PATH* or *1.pfx* by default) and *server.pfx.password* (a secret *SERVER_PFX_PASSWORD*). An environment variable *SERVER_USE_HTTP* set to *true* makes it possible to run the application without the certificate\n* *server.url* is the main web address for the application that comprises a host name and port (environment variables *SERVER_HOST* or *0.0.0.0* by default and *SERVER_PORT* or *3443* by default)\n* *server.externalUrl* works as a public url for cases when it is different from the previous one (e.g., the application was deployed in a docker container) and it is required to give a link to the applciation (e.g., in emails); the external address also accepts a host name and port (environment variables *SERVER_EXTERNAL_HOST* and *SERVER_EXTERNAL_PORT* or *443* by default)\n* For sending automatic email messages: *mail.host* (an environment variable *MAIL_HOST*), *mail.port* (an environment variable *MAIL_SECURE_PORT* or *465*), *mail.auth.user* (an environment variable *MAIL_AUTH_USER*) and *mail.auth.pass* (a secret *MAIL_AUTH_PASSWORD*). The mechanism works out as long as the host and authentication options are set up \n* Parameters to store additional information: *about.website* (an environment variable *ABOUT_WEBSITE*) determines a URL for a home site on the about page\n* *logger* to define a console logger with the next logging levels: *error* (by defult), *warn*, *info* (an environmental variable *LOGGER_LEVEL*)\n\n## API Reference\n\nPublic API methods working for anonymous visitors:\n* **GET programs/default** returns programs available by default without registration: *[{ name, userId, stages: [order, duration, descr], active, audioBetweenStages }]*\n* **GET modules** sends static script files\n* **GET modules/about** to read basic contact information from the configuration: *{ email, website }* ([more about configuring](#headConfiguration))\n\nSome API methods are for authenticated users and that's why they require a Facebook token as a header Authorization: *Bearer [token]*. The methods:\n* **POST auth/logIn** updates the user's login time and returns whether the user is an administrator *{ hasAdminRole }*; provided it's a new user it sends an email to them if the respective preferences are set ([more about configuring](#headConfiguration))\n* **GET programs** to get a user's customised programs through an object *{ programs: { _id, name, userId, stages: [order, duration, descr], active, audioBetweenStages }, schemaRestrictions }*, where *schemaRestrictions* describes restrictions imposed by the program schema\n* **POST programs** updates the user's program list: *{ deletedIds: [], updated: [{ _id, name, userId, stages: [order, duration, descr], active, audioBetweenStages }], created: [{ _id, name, userId, stages: [order, duration, descr], active, audioBetweenStages }] }*, then it redirects to **GET programs**\n* **GET programs/active** returns the list of the user's active programs: *[{ _id, name, userId, stages: [order, duration, descr], active }]*\n* **GET users/profile** to get the user's preferences: *{ hideDefaultPrograms }* - the sole option determines whether only active customised timers should be shown (if there are such available) or all timer programs including default ones\n* **POST users/profile** accepts the user's only option to update: *{ hideDefaultPrograms }*\n* **DELETE users/profile** after removal sends an email to the user if the respective preferences are set ([more about configuring](#headConfiguration))\n\nThe user must be an administrator to have access to the methods:\n* **GET users** accepts an object for sorting and filtering its outcome: *{ query: { page || 1, searchFor, sortField || 'name', sortDirection || -1 } }*; returns *{ queryFilter: { page, searchFor, sortField, sortDirection }, curUserId, users: [_id, name, administrator, location, gender, lastLogin, createdAt, activeProgramCount], pageCount }*\n* **POST users/adminSwitch** switch the user's administrative right; thereafter it sends an email to the user if the respective preferences are set ([more about configuring](#headConfiguration))\n\n## \u003ca name=\"headDatabase\"\u003e\u003c/a\u003eDatabase\n\nThe project database is built upon MongoDB ([more about its version](#headPrerequisites)). A default database server address used in the application is *mongodb://localhost:27017/*.\n\nThere are 2 tables altogether:\n* **User** stores users' data such as: name, gender, location, email, preferences, etc.\n* **Program** keeps all information about users' customised timers (with a name and 2 boolean properties: *active* and *audioBetweenStages* (should play a sound during a stage shift)) and their stages in an included schema (a duration, description and order)\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fjahn08%2Fweb-timer","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fjahn08%2Fweb-timer","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fjahn08%2Fweb-timer/lists"}