The website for the Manga and Anime Society Kharagpur (currently running in kgpmask.club)
- VPS provider: OVH
- Backend reverse proxy for port-forwarding: NGINX
- Containerized deployments: Docker (we aren't using dockerized containers right now)
- Application language: Node.js
- App routing: Express.js
- Page templates: Nunjucks
- Page styling: SASS
- Database: MongoDB
- Database ORM: mongoose
- Linting: ESLint
- Testing suite: Mocha
This server requires Node.js v16.0+ to run, and all tests are performed on v16. Please upgrade to Node v16 or higher if you haven't already done so.
There are multiple ways to run the server. The vast majority of the time, you will be running it in dev mode - the command for this is npm run dev
. If you wish to run in regular mode, the command is npm start
. Note that the server run in both cases will be identical - the only difference is that dev mode will automatically refresh changes made to the server code and/or pages, while regular mode will not. In addition, you can add flags to customize the operation of the server. These are:
dev
(d): An internal flag that does the same asnpm run dev
, except you lose access to nodemon. Just usenpm run dev
instead.This is in progress.jsonuser
(t): Runs the server with the user details being defined in/src/user.json
.local
(l): Uses a local database (mongodb://127.0.0.1/mask) instead of the designated test database. Overwrites all other DB flags.mongoless
(m): Runs the server without a database connection. All database-based pages cannot be loaded. This is a superset of theuserless
flag (ie; amongoless
server will also always beuserless
).prod
(p): Connects directly to the production database. Do NOT use this flag lightly; it can break many, many things if you mess up and the testing database should serve your purposes. Cannot be used in conjuction with dev mode, for security reasons.quiz
(q): Allows for infinite quiz attempts. Should be used withdev
.test
(t): Used to isolate the testing port and prevent interference with the running server.userless
(u): Runs the server without a user connection/query. All user-based pages cannot be loaded. A planned feature is to have a dummy user with a modifiable JSON file, but as of now no user exists.
In order to start the server, you will require an src/credentials.json
file - contact your WebDev Team Head for this file, and do NOT share it. The only exception to this is the mongoless flag - it is recommended to use npm run dev mongoless
(or npm run dm
) for any page that does not involve database-related stuff.
You may also override the database connection string for testing purposes, like so:
MONGO_TEST_URL="mongodb://4.20.69.420/mask" npm dev
Furthermore, for those with access to multiple sets of credentials (the three existing types are admin
, member
, and github
), you can switch between sets of credentials by doing the following:
- Save each file in the
src
folder asadmin-credentials.json
,member-credentials.json
, and/orgithub-credentials.json
(whichever of these you have). - These files will not be committed to the repository and are .gitignored, so you don't need to worry about accidentally uploading them.
- When booting up the server normally, it will attempt to refer to the default
credentials.json
file (should one exist), so copy whichever credentials file you use most often (usually admin). - When you wish to test the server with a different set of credentials, use an environment variable titled
CREDS
and set it to the prefix of the credentials file you wish to access (eg; set it togithub
to use thesrc/github-credentials.json
file). - If you have terminal access (standard Linux terminal, VS Code terminal, Windows PowerShell), you can set environment variables by:
- Linux/VS Code:
CREDS=github npm run dev
- Windows PowerShell:
$env:CREDS="github"; npm run dev
- Linux/VS Code:
Note (edited): You can now connect to the database even while on WiFi/LAN without a VPN. The domain name has been whitelisted. The IP address has NOT been whitelisted for direct http/https connections.
Pages are located as .njk files in /templates. The following variables may be set:
pagetitle
: Title of the page (default MASK)pagedesc
: Description of the page (default 'MASK website')thispage
: URL of intended position of current page, used to select active page in NAVBAR (default none)scripts
: Array of script links to be loaded (default none)
Additionally, the following blocks may be set:
pagecontent
: HTML contents of the page (default 'This is an empty page')customcss
: Custom CSS (remember to enclose in <style>) (default none)customjs
: Custom JS (remember to enclose in <script>) (default none)navbar
: Sets the navbar (default NAVBAR)
The default page template is:
{% extends "_base.njk" %}
{% set thispage = 'navref' %}
{% set pagetitle = 'TITLEHERE' %}
{% block pagecontent %}
Page content
{% endblock %}
The default newsletter template is:
{% extends "_newsletter.njk" %}
{% set pagetitle = 'Month - Issue num' %}
{% set pagecount = number_of_pages %}
{% block article %}
Article goes here
{% endblock %}
{% block letterjs %}<script></script>{% endblock %}
{% block lettercss %}<style></style>{% endblock %}
Take a look at existing articles for the various classes and where they're used.
Among templates, there are a separate group of templates which use the _form.njk
template as a base. These templates have a slightly different pattern and some more features.
{% extends '_base.njk' %}
{% import '_form.njk' as forms %}
{% set scripts = ['https://cdn.jsdelivr.net/npm/axios/dist/axios.min.js'] %}
{% block pagecontent %}
{% call forms.form() %}
{# Form Content #}
{% endcall %}
{% endblock %}
{% block customcss %}
{{ forms.formCss() }}
<style>
{# Extra Styles #}
</style>
{% endblock %}
{% block customjs %}
{{ forms.formFunction() }}
<script>
axios.defaults.withCredentials = true;
axios.defaults.headers.common['X-CSRF-TOKEN'] = '{{ csrfToken }}';
{# Other Functions #}
</script>
{% endblock %}
For in-depth info about the same, check out the forms markdown file.
The Express app's router is set up by /src/route.js
. The file route.js imports routers from the /routes
folder. Each router file has the following format:
const router = require('express').Router();
// This router is used to configure the app for a specific route
// GET requests
app.get('/path', (req, res, next) => {
// some code
return res.renderFile(template, ctx);
});
// POST requests
app.post('/path', (req, res, next) => {
// some code
return res.status(statusCode).send;
});
/*
Notes:
The next argument is optional in most cases.
The functions in the requests can be asynchronous too.
You can use other routers as well if needed.
*/
module.exports = {
route: '/path'
router;
}
All routers are imported and used in route.js
in the src
folder.
const routerModules = (await fs.readdir(path.join(__dirname, '../routes'))).filter(file => file.endsWith('.js'));
routerModules.forEach(module => {
const { route, router } = require(`../routes/${module}`);
app.use(route, router);
});
All non-trivial changes are done through PULL REQUESTS ONLY. The WebDev Team Head (currently @ItsAnkan) is responsible for testing and merging all PRs. Feel free to pester them to look at the changes you've prepared.
To create a pull request, navigate to the dev
branch (clicking on the GitHub client, or git checkout dev
on the CLI) and create a new branch based on it (New Branch
button (based on the dev
branch, again!) on the GitHub client's branches page, or git checkout -b [branch-name]
on the CLI). Pull requests will never be merged directly to main
; they will be first merged to dev
and batches of changes and/or patches will be merged from dev
to main
alongside version increments.
To work on templates which require access to credentials using dev userless
(du
) mode, check out this page for some info.
Changes to the dev
server are automatically deployed to test.kgpmask.club. This does not extend to environment configuration changes (eg: docker changes).
Ensure that pull requests pass tests (npm test
for both lint and mocha tests).
- For any new route, make sure to use a new router file instead of adding to
route.js
- Make sure to extend your template from either
_base.njk
or another template (in case of similar pages, like events or newsletters). - Make sure the code passes the lint and mocha tests. You can check that by running
npm run test
. The ESLint configuration can be seen in.eslintrc.json
and tests can be seen in thetest
folder. - If you have any questions, post 'em in the WebDev channel.
- If you aren't a member of the society but have queries/reports/suggestions, feel free to use the Issues/Discussions pages.
- Vidunram A R (Lead)
- Nishkal Prakash
- Jai Sachdev
- Ankan Saha
- Sahil Patel
- Soumil Maiti
- Dishant Bothra
- Sharanya Chakraborty