├── .github
├── FUNDING.yml
└── ISSUE_TEMPLATE
│ ├── bug_report.md
│ └── feature_request.md
├── .prettierignore
├── .prettierrc.json
├── .travis.yml
├── .vscode
└── Gindex.code-workspace
├── CODE_OF_CONDUCT.md
├── CONTRIBUTING.md
├── LICENSE
├── README.md
├── SECURITY.md
├── backend
├── .gitignore
├── Procfile
├── README.md
├── app.js
├── app.json
├── models
│ ├── categoryPost.js
│ ├── heroPost.js
│ ├── invitedUser.js
│ ├── pendingUser.js
│ ├── quickLink.js
│ ├── sessionSchema.js
│ ├── siteSettings.js
│ ├── spamUser.js
│ ├── trendingPost.js
│ └── user.js
├── package-lock.json
├── package.json
├── parsers
│ ├── torrent-name-parser-one
│ │ ├── index.js
│ │ └── src
│ │ │ ├── handlers.js
│ │ │ └── parser.js
│ └── torrent-name-parser-two
│ │ ├── core.js
│ │ ├── index.js
│ │ └── parts
│ │ ├── common.js
│ │ ├── excess.js
│ │ └── title.js
├── plugins
│ ├── checkOrigin.js
│ ├── deleteAll.js
│ ├── deleteInvitedUsers.js
│ ├── deletePendingUsers.js
│ ├── deleteUsers.js
│ ├── jwtVerify.js
│ ├── keepAlive.js
│ └── mailtransporter.js
├── public
│ └── css
│ │ └── styles.css
├── routes
│ ├── approve
│ │ └── index.js
│ ├── delete.js
│ ├── get.js
│ ├── getspam
│ │ └── index.js
│ ├── index.js
│ ├── invite.js
│ ├── login.js
│ ├── media.js
│ ├── pending
│ │ └── index.js
│ ├── ping.js
│ ├── poster.js
│ ├── posters
│ │ ├── categories
│ │ │ └── index.js
│ │ ├── hero
│ │ │ └── index.js
│ │ ├── quicklinks
│ │ │ └── index.js
│ │ └── trending
│ │ │ └── index.js
│ ├── register.js
│ ├── remove
│ │ ├── index.js
│ │ └── spam.js
│ ├── request.js
│ ├── settings.js
│ ├── spam.js
│ └── user.js
├── templates
│ ├── delete
│ │ ├── invitedUsers
│ │ │ └── toAll.js
│ │ ├── pending
│ │ │ └── toAll.js
│ │ └── users
│ │ │ ├── toNonVerified.js
│ │ │ ├── toSelf.js
│ │ │ └── toUsers.js
│ ├── invite
│ │ └── toUsers.js
│ ├── register
│ │ ├── toPromotedUsers.js
│ │ ├── toUsers.js
│ │ └── toVerifiedUser.js
│ ├── request
│ │ ├── existing
│ │ │ ├── forgotPass.js
│ │ │ ├── toAdmin.js
│ │ │ └── toUser.js
│ │ └── newUser
│ │ │ ├── toAdmin.js
│ │ │ └── toUser.js
│ └── spam
│ │ ├── removeUser.js
│ │ └── toAll.js
└── views
│ ├── dashboard.ejs
│ ├── footer.ejs
│ ├── generate.ejs
│ ├── header.ejs
│ └── signup.ejs
├── cli-tool
├── .gitignore
├── README.md
├── commands
│ ├── configure
│ │ ├── env
│ │ │ ├── checkHerokuLogin.js
│ │ │ ├── index.js
│ │ │ ├── inputPrompts.js
│ │ │ └── pushConfigKeys.js
│ │ └── index.js
│ ├── deploy
│ │ ├── backend
│ │ │ ├── checkHerokuLogin.js
│ │ │ ├── checkHerokuPresent.js
│ │ │ ├── createHerokuApp.js
│ │ │ ├── createTMP.js
│ │ │ ├── downloadUnzip.js
│ │ │ ├── getReleases.js
│ │ │ ├── gitCheckoutHApp.js
│ │ │ ├── gitPushHeroku.js
│ │ │ ├── index.js
│ │ │ ├── initBackendnCommit.js
│ │ │ ├── inputPrompts.js
│ │ │ └── pushConfigKeys.js
│ │ ├── frontend
│ │ │ ├── getAllPrompts.js
│ │ │ ├── getLatIndex.js
│ │ │ ├── index.js
│ │ │ ├── inputPrompts.js
│ │ │ └── replaceOpt.js
│ │ └── index.js
│ ├── index.js
│ ├── init
│ │ ├── checkGitExists.js
│ │ ├── checkNpmExists.js
│ │ ├── index.js
│ │ └── post-init.js
│ └── update
│ │ ├── checkHerokuLogin.js
│ │ ├── createTMP.js
│ │ ├── downloadUnzip.js
│ │ ├── getReleases.js
│ │ ├── gitCheckoutHApp.js
│ │ ├── index.js
│ │ ├── initBackendnCommit.js
│ │ ├── inputPrompts.js
│ │ └── pushBackend.js
├── displays
│ ├── initial-render.js
│ └── post-install.js
├── helpers
│ ├── configStore.js
│ └── spinner.js
├── index.js
├── package-lock.json
└── package.json
├── imgs
├── adminpage.jpg
├── home-nolog.png
├── home.png
├── home2.png
├── homelogged.jpeg
├── homelogout.jpg
├── login.jpg
├── newuserregister.jpg
├── pendinguser.jpeg
├── request.jpeg
├── settings.jpg
├── verify.jpeg
├── videoPlayer Modal.jpg
├── videoPlayer.jpg
└── videplayer2.jpg
├── scripts
├── before-build.sh
├── dev-after-deploy.sh
├── dev-build.sh
├── dev-deploy.sh
├── dev-release.sh
├── install.sh
├── prod-after-deploy.sh
├── prod-build.sh
├── prod-deploy.sh
└── prod-release.sh
├── version-manager
├── .gitignore
├── app.js
├── helpers
│ ├── get-commits.js
│ ├── get-diff.js
│ ├── get-releases.js
│ ├── push-release.js
│ └── spinner.js
├── package-lock.json
├── package.json
├── publish
│ ├── checks.js
│ ├── handle-publish.js
│ └── index.js
└── templates
│ └── publish-release.js
├── version.json
├── vetur.config.js
├── vuejs
├── .browserslistrc
├── .eslintrc.json
├── .gitignore
├── .yarn
│ ├── build-state.yml
│ ├── install-state.gz
│ ├── plugins
│ │ └── @yarnpkg
│ │ │ └── plugin-interactive-tools.cjs
│ └── releases
│ │ └── yarn-berry.js
├── .yarnrc.yml
├── LICENSE
├── README.md
├── babel.config.js
├── jsconfig.json
├── package.json
├── public
│ ├── images
│ │ ├── airplane.gif
│ │ ├── baidu-pan-logo.png
│ │ ├── eyes.png
│ │ ├── g-logo.png
│ │ ├── no-data.png
│ │ └── player
│ │ │ ├── aria2.png
│ │ │ ├── iina.png
│ │ │ ├── mxplayer.png
│ │ │ ├── nplayer.png
│ │ │ ├── potplayer.png
│ │ │ ├── thunder.png
│ │ │ └── vlc.png
│ └── index.html
├── rules.md
├── scripts
│ ├── others
│ │ ├── build-theme.sh
│ │ ├── buildAll.sh
│ │ └── serve-theme.sh
│ └── windows
│ │ ├── build-theme.bat
│ │ ├── buildAll.bat
│ │ └── serve-theme.bat
├── src
│ ├── App.vue
│ ├── components
│ │ ├── BreadCrumb.vue
│ │ ├── Footer.vue
│ │ ├── Markdown.vue
│ │ ├── Navbar.vue
│ │ ├── grid.vue
│ │ ├── list.vue
│ │ ├── notification.js
│ │ └── viewmode.vue
│ ├── libs
│ │ ├── util.cdn.js
│ │ ├── util.import.development.js
│ │ └── util.import.production.js
│ ├── main.js
│ ├── plugin
│ │ ├── aplayer
│ │ │ └── index.js
│ │ └── axios
│ │ │ └── index.js
│ ├── router
│ │ ├── index.js
│ │ └── routes.js
│ ├── styles
│ │ ├── base.scss
│ │ ├── carnation
│ │ │ └── register.scss
│ │ ├── curious-blue
│ │ │ └── register.scss
│ │ ├── emerald
│ │ │ └── register.scss
│ │ ├── ice-cold
│ │ │ └── register.scss
│ │ ├── konifer
│ │ │ └── register.scss
│ │ ├── kournikova
│ │ │ └── register.scss
│ │ ├── mona-lisa
│ │ │ └── register.scss
│ │ ├── netflix-red
│ │ │ └── register.scss
│ │ ├── persian-rose
│ │ │ └── register.scss
│ │ ├── purple-heart
│ │ │ └── register.scss
│ │ ├── purple-mountains-majesty
│ │ │ └── register.scss
│ │ ├── salmon
│ │ │ └── register.scss
│ │ ├── selective-yellow
│ │ │ └── register.scss
│ │ ├── shamrock
│ │ │ └── register.scss
│ │ └── witch-haze
│ │ │ └── register.scss
│ ├── themeConfigs.js
│ ├── themeManager.js
│ ├── utils
│ │ ├── AcrouUtil.js
│ │ ├── backendUtils.js
│ │ ├── encryptUtils.js
│ │ ├── localUtils.js
│ │ └── playUtils.js
│ └── views
│ │ ├── GoAudio.vue
│ │ ├── GoImg.vue
│ │ ├── GoList.vue
│ │ ├── GoOthers.vue
│ │ ├── GoPdf.vue
│ │ ├── GoText.vue
│ │ ├── GoVideo.vue
│ │ └── static
│ │ ├── Admin
│ │ ├── AdminArea.vue
│ │ ├── Invite.vue
│ │ ├── MainManagePostPage.vue
│ │ ├── ManagePosts
│ │ │ ├── ManageCategories.vue
│ │ │ ├── ManageHeros.vue
│ │ │ ├── ManageQuickLinks.vue
│ │ │ └── ManageTrendingPosts.vue
│ │ ├── ManageSpamUsers.vue
│ │ ├── ManageUsers.vue
│ │ ├── Register.vue
│ │ └── SiteSettings.vue
│ │ ├── Home.vue
│ │ ├── OtpRegister.vue
│ │ ├── Request.vue
│ │ ├── ResultPage.vue
│ │ └── Users
│ │ ├── ChangePassword.vue
│ │ ├── DeleteMe.vue
│ │ ├── Login.vue
│ │ ├── RequestPrivs.vue
│ │ └── Settings.vue
├── vue.config.js
├── webpack.config.js
├── webpack
│ ├── chain-webpack.js
│ ├── css-options.js
│ ├── custom-plugins
│ │ ├── buildAppJSPlugin.js
│ │ └── dependencies-cdn.js
│ ├── dev-server.js
│ ├── index.js
│ ├── loaders.js
│ ├── minimizers.js
│ ├── optimizations.js
│ ├── plugins.js
│ └── resolvers.js
└── yarn.lock
└── worker
└── index.js
/.github/FUNDING.yml:
--------------------------------------------------------------------------------
1 | patreon: tks18
2 | custom: ['paypal.me/shantk18', 'buymeacoffee.com/shantk18']
3 |
--------------------------------------------------------------------------------
/.github/ISSUE_TEMPLATE/bug_report.md:
--------------------------------------------------------------------------------
1 | ---
2 | name: Bug report
3 | about: Create a report to help us improve
4 | title: ''
5 | labels: ''
6 | assignees: ''
7 |
8 | ---
9 |
10 | **Describe the bug**
11 | A clear and concise description of what the bug is.
12 |
13 | **To Reproduce**
14 | Steps to reproduce the behavior:
15 | 1. Go to '...'
16 | 2. Click on '....'
17 | 3. Scroll down to '....'
18 | 4. See error
19 |
20 | **Expected behavior**
21 | A clear and concise description of what you expected to happen.
22 |
23 | **Screenshots**
24 | If applicable, add screenshots to help explain your problem.
25 |
26 | **Desktop (please complete the following information):**
27 | - OS: [e.g. iOS]
28 | - Browser [e.g. chrome, safari]
29 | - Version [e.g. 22]
30 |
31 | **Smartphone (please complete the following information):**
32 | - Device: [e.g. iPhone6]
33 | - OS: [e.g. iOS8.1]
34 | - Browser [e.g. stock browser, safari]
35 | - Version [e.g. 22]
36 |
37 | **Additional context**
38 | Add any other context about the problem here.
39 |
--------------------------------------------------------------------------------
/.github/ISSUE_TEMPLATE/feature_request.md:
--------------------------------------------------------------------------------
1 | ---
2 | name: Feature request
3 | about: Suggest an idea for this project
4 | title: ''
5 | labels: ''
6 | assignees: ''
7 |
8 | ---
9 |
10 | **Is your feature request related to a problem? Please describe.**
11 | A clear and concise description of what the problem is. Ex. I'm always frustrated when [...]
12 |
13 | **Describe the solution you'd like**
14 | A clear and concise description of what you want to happen.
15 |
16 | **Describe alternatives you've considered**
17 | A clear and concise description of any alternative solutions or features you've considered.
18 |
19 | **Additional context**
20 | Add any other context or screenshots about the feature request here.
21 |
--------------------------------------------------------------------------------
/.prettierignore:
--------------------------------------------------------------------------------
1 | webpack.config.js
--------------------------------------------------------------------------------
/.prettierrc.json:
--------------------------------------------------------------------------------
1 | {
2 | "trailingComma": "all",
3 | "tabWidth": 2,
4 | "semi": true,
5 | "singleQuote": true
6 | }
7 |
--------------------------------------------------------------------------------
/.travis.yml:
--------------------------------------------------------------------------------
1 | os: linux
2 | branches:
3 | only:
4 | - master
5 | - dev
6 | language: node_js
7 | node_js:
8 | - 14
9 |
10 | git:
11 | depth: 3
12 | quiet: true
13 | submodules: false
14 |
15 | cache:
16 | directories:
17 | - vuejs/.yarn/cache
18 | - vuejs/node_modules
19 |
20 | install: bash ./scripts/install.sh
21 |
22 | script: bash ./scripts/before-build.sh
23 |
24 | deploy:
25 | - provider: script
26 | skip_cleanup: true
27 | script: bash ./scripts/prod-deploy.sh
28 | on:
29 | branch: master
30 |
31 | - provider: script
32 | skip_cleanup: true
33 | script: bash ./scripts/dev-deploy.sh
34 | on:
35 | branch: dev
36 |
--------------------------------------------------------------------------------
/.vscode/Gindex.code-workspace:
--------------------------------------------------------------------------------
1 | {
2 | "folders": [
3 | {
4 | "name": "Root",
5 | "path": "../"
6 | },
7 | {
8 | "name": "Front-end",
9 | "path": "../vuejs"
10 | },
11 | {
12 | "name": "Back-end",
13 | "path": "../backend"
14 | },
15 | {
16 | "name": "CLI Tool",
17 | "path": "../cli-tool"
18 | },
19 | {
20 | "name": "Version Manager",
21 | "path": "../version-manager"
22 | },
23 | {
24 | "name": "Worker",
25 | "path": "../worker"
26 | }
27 | ],
28 | "settings": {
29 | "files.exclude": {
30 | "node_modules/": true,
31 | "packages/": true,
32 | "vuejs/": true,
33 | "backend/": true,
34 | "cli-tool/": true,
35 | "worker/": true,
36 | "version-manager/": true
37 | }
38 | }
39 | }
40 |
--------------------------------------------------------------------------------
/SECURITY.md:
--------------------------------------------------------------------------------
1 | # Security Policy
2 |
3 | ## Supported Versions
4 |
5 | Use this section to tell people about which versions of your project are
6 | currently being supported with security updates.
7 |
8 | | Version | Supported |
9 | | ------- | ------------------ |
10 | | 7.3.0 | :white_check_mark: |
11 |
12 | ## Reporting a Vulnerability
13 |
14 | Use this section to tell people how to report a vulnerability.
15 |
16 | Tell them where to go, how often they can expect to get an update on a
17 | reported vulnerability, what to expect if the vulnerability is accepted or
18 | declined, etc.
19 |
--------------------------------------------------------------------------------
/backend/.gitignore:
--------------------------------------------------------------------------------
1 | node_modules
2 | glorydb
3 | .env
4 |
--------------------------------------------------------------------------------
/backend/Procfile:
--------------------------------------------------------------------------------
1 | web: npm run start
2 |
--------------------------------------------------------------------------------
/backend/README.md:
--------------------------------------------------------------------------------
1 |
Google Drive Index by Sudharshan TK is licensed under a Creative Commons Attribution-NonCommercial 4.0 International License.
Based on a work at https://github.com/tks18/gindex-v4
2 |
3 | ##### What if Someone Violates my License ?
4 |
5 | A CC license terminates automatically when its conditions are violated. For example, if a reuser of CC-licensed material does not provide the attribution required when sharing the work, then the user no longer has the right to continue using the material and may be liable for copyright infringement. The license is terminated for the user who violated the license. However, all other users still have a valid license, so long as they are in compliance.
6 |
7 | Under the 4.0 licenses, a licensee automatically gets these rights back if she fixes the violation within 30 days of discovering it.
8 |
9 | If you apply a Creative Commons license and a user violates the license conditions, you may opt to contact the person directly to ask them to rectify the situation or consult a lawyer to act on your behalf. Creative Commons is not a law firm and cannot represent you or give you legal advice, but there are lawyers who have identified themselves as interested in representing people in CC-related matters.
10 |
11 | # gindex-backend
12 | Backend for gindex for Maintaining User Database
13 |
14 | **Support Group can be Found Here - [Here](https://t.me/joinchat/LVLR1U5Gs_9lmHGNGqpxIw)**
15 | Any Issues / Help Regarding Setup, Contact Through the telegram Group
16 |
17 | ##### without this the Main GIndex wont work, Both should run simultaneously.
18 |
19 | #### Deploy to Heroku Directly:
20 | [](https://dashboard.heroku.com/new?template=https%3A%2F%2Fgithub.com%2Ftks18%2Fgindex-backend%2Ftree%2Fmaster)
21 |
--------------------------------------------------------------------------------
/backend/app.js:
--------------------------------------------------------------------------------
1 | // Inititalisation
2 | require('dotenv').config();
3 | const express = require("express");
4 | var ping = require('ping');
5 | const cors = require('cors');
6 | const bodyParser = require("body-parser");
7 | const mongoose = require("mongoose");
8 | const keepAlive = require("./plugins/keepAlive");
9 | const deletePlugin = require('./plugins/deleteAll');
10 | const app = express();
11 |
12 | app.use(express.static("public"));
13 | app.set("view engine", "ejs");
14 | app.use(bodyParser.urlencoded({extended: false}));
15 | app.use(bodyParser.json());
16 | app.use(cors());
17 |
18 | mongoose.connect(process.env.DBURL, {useNewUrlParser: true, useUnifiedTopology: true, useCreateIndex: true})
19 |
20 | //Routes
21 | app.use('/', require('./routes/index'));
22 | app.use('/login', require('./routes/login'));
23 | app.use('/ping', require('./routes/ping'));
24 | app.use('/request', require('./routes/request'));
25 | app.use('/user', require('./routes/user'));
26 | app.use('/media', require('./routes/media'));
27 | app.use('/posters', require('./routes/poster'));
28 | app.use('/register', require('./routes/register'));
29 | app.use('/invite', require('./routes/invite'));
30 | app.use('/delete', require('./routes/delete'));
31 | app.use('/settings', require('./routes/settings'));
32 | app.use('/get', require('./routes/get'));
33 | app.use('/spam', require('./routes/spam'));
34 |
35 | deletePlugin();
36 | keepAlive();
37 | const PORT = process.env.PORT || 3000;
38 |
39 | app.listen(PORT, console.log('Server Started on ' + PORT ));
40 |
--------------------------------------------------------------------------------
/backend/app.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "G-Index Backend",
3 | "description": "This is the Live Backend Server for G-Index for Authenticating Users",
4 | "repository": "https://github.com/tks18/gindex-backend",
5 | "keywords": ["gindex-backend"],
6 | "env": {
7 | "DBURL": {
8 | "description": "MongoDB Atlas Connect URL for Your Database",
9 | "required": true
10 | },
11 | "SITE": {
12 | "description": "This is your Heroku's Backend Site Address. This is to Keep the Site Alive Every Half Hour.",
13 | "required": true
14 | },
15 | "EMAILID": {
16 | "description": "EmailID From Which OTP and Verification Emails will be Sent.",
17 | "required": true
18 | },
19 | "EMAILPASS": {
20 | "description": "Above Email ID's Password",
21 | "required": true
22 | },
23 | "EMAILSMTP": {
24 | "description": "SMTP Domain of your Email Service Provider",
25 | "required": true
26 | },
27 | "EMAILPORT": {
28 | "description": "Port of Your Email Service Provider",
29 | "required": true
30 | },
31 | "EMAILSERVICE": {
32 | "description": "Name of Your Email Service Provider. Example: Google, Yandex.., etc. Like that",
33 | "required": true
34 | },
35 | "ADMINEMAIL": {
36 | "description": "Whenever a User Registers or Verifies them. Their Details will be Sent to this Mail. Can be Same as Above Email ID",
37 | "required": true
38 | },
39 | "REPLYTOMAIL": {
40 | "description": "Whenver a User Replies to a Mail. That will be Sent to this Email ID",
41 | "required": true
42 | },
43 | "SITESECRET": {
44 | "description": "Can be Anything. This will be Asked When you are Setting up the Root User in Backend to Verify that its You.",
45 | "required": true
46 | },
47 | "FRONTENDSITENAME": {
48 | "description": "Your G-Index Name. Can be Anything",
49 | "required": true
50 | },
51 | "TMDBAPI": {
52 | "description": "Give Your TMDB V3 API Key for Automatic pulling of Video Data.",
53 | "required": false
54 | },
55 | "FRONTENDURL": {
56 | "description": "Your G-index Domain. This is Must, Otherwise Authentication will Fail.",
57 | "required": true
58 | },
59 | "TOKENSECRET": {
60 | "description": "Can be Anything. This will be Used to Issue JSON Web Tokens and Verify it. Recommended to Have Minimum 20 Characters. That will be Safe.",
61 | "required": true
62 | },
63 | "MAXSESSIONS": {
64 | "description": "Number of Sessions a User can Login",
65 | "required": true
66 | }
67 | },
68 | "buildpacks": [
69 | {
70 | "url": "heroku/nodejs"
71 | }
72 | ]
73 | }
74 |
--------------------------------------------------------------------------------
/backend/models/categoryPost.js:
--------------------------------------------------------------------------------
1 | const mongoose = require('mongoose');
2 |
3 | // Category Posters Schema
4 | const categoryPostSchema = {
5 | root: {
6 | type: Number,
7 | required: true,
8 | },
9 | title: {
10 | type: String,
11 | required: true,
12 | },
13 | poster: {
14 | type: String,
15 | required: true,
16 | },
17 | link: {
18 | type: String,
19 | required: true,
20 | },
21 | }
22 |
23 | const CategoryPost = mongoose.model("CategoryPost", categoryPostSchema);
24 |
25 | module.exports = CategoryPost;
26 |
--------------------------------------------------------------------------------
/backend/models/heroPost.js:
--------------------------------------------------------------------------------
1 | const mongoose = require('mongoose');
2 |
3 | // Hero Posters Schema
4 | const heroPostSchema = {
5 | root: {
6 | type: Number,
7 | required: true,
8 | },
9 | title: {
10 | type: String,
11 | required: true,
12 | },
13 | subtitle: {
14 | type: String,
15 | required: true,
16 | },
17 | poster: {
18 | type: String,
19 | required: true,
20 | },
21 | link: {
22 | type: String,
23 | required: true,
24 | },
25 | }
26 |
27 | const HeroPost = mongoose.model("HeroPost", heroPostSchema);
28 |
29 | module.exports = HeroPost;
30 |
--------------------------------------------------------------------------------
/backend/models/invitedUser.js:
--------------------------------------------------------------------------------
1 | const mongoose = require('mongoose');
2 |
3 | const invitedUserSchema = {
4 | name: {
5 | type: String,
6 | required: true
7 | },
8 | post: {
9 | type: String,
10 | required: true
11 | },
12 | email: {
13 | type: String,
14 | lowercase: true,
15 | required: true,
16 | unique: true
17 | },
18 | invitedDate: {
19 | type: Number,
20 | required: true,
21 | default: Date.now,
22 | },
23 | message: {
24 | type: String
25 | },
26 | invitedby: {
27 | type: String,
28 | lowercase: true,
29 | required: true
30 | }
31 | };
32 |
33 | const InvitedUser = mongoose.model("InvitedUser", invitedUserSchema);
34 |
35 | module.exports = InvitedUser;
36 |
--------------------------------------------------------------------------------
/backend/models/pendingUser.js:
--------------------------------------------------------------------------------
1 | const mongoose = require('mongoose');
2 |
3 | // Pending User Database Model
4 | const pendingUserSchema = {
5 | name: {
6 | type: String,
7 | required: true
8 | },
9 | post: {
10 | type: String,
11 | required: true
12 | },
13 | drive: {
14 | type: Number,
15 | required: true,
16 | },
17 | pendingFrom: {
18 | type: Number,
19 | required: true,
20 | default: Date.now,
21 | },
22 | email: {
23 | type: String,
24 | lowercase: true,
25 | required: true,
26 | unique: true },
27 | message: {
28 | type: String
29 | }
30 | };
31 |
32 | const PendingUser = mongoose.model("PendingUser", pendingUserSchema);
33 |
34 | module.exports = PendingUser;
35 |
--------------------------------------------------------------------------------
/backend/models/quickLink.js:
--------------------------------------------------------------------------------
1 | const mongoose = require('mongoose');
2 |
3 | // Category Posters Schema
4 | const quickLinkSchema = {
5 | root: {
6 | type: Number,
7 | required: true,
8 | },
9 | title: {
10 | type: String,
11 | required: true,
12 | },
13 | link: {
14 | type: String,
15 | required: true,
16 | },
17 | }
18 |
19 | const QuickLink = mongoose.model("QuickLink", quickLinkSchema);
20 |
21 | module.exports = QuickLink;
22 |
--------------------------------------------------------------------------------
/backend/models/sessionSchema.js:
--------------------------------------------------------------------------------
1 | const mongoose = require('mongoose');
2 |
3 | const sessionSchema = new mongoose.Schema({
4 | ip: {
5 | type: String,
6 | required: true
7 | },
8 | sessionid: {
9 | type: String,
10 | required: true
11 | },
12 | token: {
13 | type: String,
14 | required: true
15 | },
16 | time: {
17 | type: Number,
18 | required: true,
19 | }
20 | })
21 |
22 | module.exports = sessionSchema;
23 |
--------------------------------------------------------------------------------
/backend/models/siteSettings.js:
--------------------------------------------------------------------------------
1 | const mongoose = require('mongoose');
2 |
3 | const siteSettingsSchema = {
4 | cId: {
5 | type: String,
6 | required: true,
7 | default: process.env.FRONTENDSITENAME,
8 | },
9 | requests: {
10 | type: Boolean,
11 | required: true,
12 | default: true,
13 | },
14 | adminRequests: {
15 | type: Boolean,
16 | required: true,
17 | default: true,
18 | },
19 | tmdb: {
20 | type: Boolean,
21 | required: true,
22 | default: false,
23 | },
24 | otpVerify: {
25 | type: Boolean,
26 | required: true,
27 | default: true,
28 | },
29 | useMailing: {
30 | type: Boolean,
31 | required: true,
32 | default: true,
33 | },
34 | };
35 |
36 | const Settings = mongoose.model('Settings', siteSettingsSchema);
37 |
38 | module.exports = Settings;
39 |
--------------------------------------------------------------------------------
/backend/models/spamUser.js:
--------------------------------------------------------------------------------
1 | const mongoose = require('mongoose');
2 |
3 | const spamUserSchema = {
4 | name: {
5 | type: String,
6 | required: true
7 | },
8 | email: {
9 | type: String,
10 | required: true,
11 | unique: true,
12 | lowercase: true
13 | },
14 | post: {
15 | type: String,
16 | required: true
17 | },
18 | flaggedby: {
19 | type: String,
20 | required: true,
21 | lowercase: true
22 | },
23 | reason: {
24 | type: String,
25 | required: true
26 | }
27 | }
28 |
29 | const SpamUser = mongoose.model("SpamUser", spamUserSchema);
30 |
31 | module.exports = SpamUser;
32 |
--------------------------------------------------------------------------------
/backend/models/trendingPost.js:
--------------------------------------------------------------------------------
1 | const mongoose = require('mongoose');
2 |
3 | // Trending Posters Schema
4 | const trendingPostSchema = {
5 | root: {
6 | type: Number,
7 | required: true,
8 | },
9 | title: {
10 | type: String,
11 | required: true,
12 | },
13 | poster: {
14 | type: String,
15 | required: true,
16 | },
17 | link: {
18 | type: String,
19 | required: true,
20 | },
21 | }
22 |
23 | const TrendingPost = mongoose.model("TrendingPost", trendingPostSchema);
24 |
25 | module.exports = TrendingPost;
26 |
--------------------------------------------------------------------------------
/backend/models/user.js:
--------------------------------------------------------------------------------
1 | const mongoose = require('mongoose');
2 | const Sessions = require('./sessionSchema');
3 |
4 | // User Database Model
5 | const userSchema = {
6 | name: {
7 | type: String,
8 | required: true
9 | },
10 | email: {
11 | type: String,
12 | lowercase: true,
13 | required: true,
14 | unique: true
15 | },
16 | avatar: {
17 | type: String,
18 | lowercase: true,
19 | },
20 | registeredDate: {
21 | type: Number,
22 | required: true,
23 | default: Date.now,
24 | },
25 | password: {
26 | type: String,
27 | default: null
28 | },
29 | temppassword: {
30 | type: String
31 | },
32 | temprestricted: {
33 | type: Boolean,
34 | default: false
35 | },
36 | role: {
37 | type: String,
38 | required: true,
39 | default: 'user'
40 | },
41 | sessions: [Sessions],
42 | admin: {
43 | type: Boolean,
44 | required: true,
45 | default: false
46 | },
47 | superadmin: {
48 | type: Boolean,
49 | required: true,
50 | default: false
51 | },
52 | verified: {
53 | type: Boolean,
54 | required: true,
55 | default: false
56 | },
57 | };
58 |
59 | const User = mongoose.model("User", userSchema);
60 |
61 | module.exports = User;
62 |
--------------------------------------------------------------------------------
/backend/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "g-index-backend",
3 | "version": "2.2.5",
4 | "description": "",
5 | "main": "app.js",
6 | "scripts": {
7 | "start": "set NODE_ENV=production && node app",
8 | "develop": "set NODE_ENV=development && nodemon app.js",
9 | "test": "echo \"Error: no test specified\" && exit 1"
10 | },
11 | "author": "",
12 | "license": "ISC",
13 | "dependencies": {
14 | "axios": "^0.19.2",
15 | "bcrypt": "^5.0.0",
16 | "body-parser": "^1.19.0",
17 | "cors": "^2.8.5",
18 | "dotenv": "^8.2.0",
19 | "ejs": "^3.1.3",
20 | "express": "^4.17.1",
21 | "jsonwebtoken": "^8.5.1",
22 | "mongoose": "^5.9.25",
23 | "nodemailer": "^6.4.11",
24 | "nodemon": "^2.0.4",
25 | "ping": "^0.2.3",
26 | "randomstring": "^1.1.5",
27 | "sqlite3": "^4.2.0"
28 | }
29 | }
30 |
--------------------------------------------------------------------------------
/backend/parsers/torrent-name-parser-one/index.js:
--------------------------------------------------------------------------------
1 | const Parser = require("./src/parser").Parser;
2 | const handlers = require("./src/handlers");
3 |
4 | const defaultParser = new Parser();
5 |
6 | handlers.addDefaults(defaultParser);
7 |
8 | exports.addDefaults = handlers.addDefaults;
9 | exports.addHandler = (handlerName, handler, options) => defaultParser.addHandler(handlerName, handler, options);
10 | exports.parse = title => defaultParser.parse(title);
11 | exports.Parser = Parser;
12 |
--------------------------------------------------------------------------------
/backend/parsers/torrent-name-parser-one/src/parser.js:
--------------------------------------------------------------------------------
1 | function extendOptions(options) {
2 | options = options || {};
3 |
4 | const defaultOptions = {
5 | skipIfAlreadyFound: true,
6 | type: "string",
7 | };
8 |
9 | options.skipIfAlreadyFound = options.skipIfAlreadyFound || defaultOptions.skipIfAlreadyFound;
10 | options.type = options.type || defaultOptions.type;
11 |
12 | return options;
13 | }
14 |
15 | function createHandlerFromRegExp(name, regExp, options) {
16 | let transformer;
17 |
18 | if (!options.type) {
19 | transformer = input => input;
20 | } else if (options.type.toLowerCase() === "lowercase") {
21 | transformer = input => input.toLowerCase();
22 | } else if (options.type.toLowerCase().slice(0, 4) === "bool") {
23 | transformer = () => true;
24 | } else if (options.type.toLowerCase().slice(0, 3) === "int") {
25 | transformer = input => parseInt(input, 10);
26 | } else {
27 | transformer = input => input;
28 | }
29 |
30 | function handler({ title, result }) {
31 | if (result[name] && options.skipIfAlreadyFound) {
32 | return null;
33 | }
34 |
35 | const match = title.match(regExp);
36 | const [rawMatch, cleanMatch] = match || [];
37 |
38 | if (rawMatch) {
39 | result[name] = options.value || transformer(cleanMatch || rawMatch);
40 | return match.index;
41 | }
42 |
43 | return null;
44 | }
45 |
46 | handler.handlerName = name;
47 |
48 | return handler;
49 | }
50 |
51 | function cleanTitle(rawTitle) {
52 | let cleanedTitle = rawTitle;
53 |
54 | if (cleanedTitle.indexOf(" ") === -1 && cleanedTitle.indexOf(".") !== -1) {
55 | cleanedTitle = cleanedTitle.replace(/\./g, " ");
56 | }
57 |
58 | cleanedTitle = cleanedTitle.replace(/_/g, " ");
59 | cleanedTitle = cleanedTitle.replace(/([(_]|- )$/, "").trim();
60 |
61 | return cleanedTitle;
62 | }
63 |
64 | class Parser {
65 |
66 | constructor() {
67 | this.handlers = [];
68 | }
69 |
70 | addHandler(handlerName, handler, options) {
71 | if (typeof handler === "undefined" && typeof handlerName === "function") {
72 |
73 | // If no name is provided and a function handler is directly given
74 | handler = handlerName;
75 | handler.handlerName = "unknown";
76 |
77 | } else if (typeof handlerName === "string" && handler instanceof RegExp) {
78 |
79 | // If the handler provided is a regular expression
80 | options = extendOptions(options);
81 | handler = createHandlerFromRegExp(handlerName, handler, options);
82 |
83 | } else if (typeof handler === "function") {
84 |
85 | // If the handler is a function
86 | handler.handlerName = handlerName;
87 |
88 | } else {
89 |
90 | // If the handler is neither a function nor a regular expression, throw an error
91 | throw new Error(`Handler for ${handlerName} should be a RegExp or a function. Got: ${typeof handler}`);
92 |
93 | }
94 |
95 | this.handlers.push(handler);
96 | }
97 |
98 | parse(title) {
99 | const result = {};
100 | let endOfTitle = title.length;
101 |
102 | for (const handler of this.handlers) {
103 | const matchIndex = handler({ title, result });
104 |
105 | if (matchIndex && matchIndex < endOfTitle) {
106 | endOfTitle = matchIndex;
107 | }
108 | }
109 |
110 | result.title = cleanTitle(title.slice(0, endOfTitle));
111 |
112 | return result;
113 | }
114 | }
115 |
116 | exports.Parser = Parser;
117 |
--------------------------------------------------------------------------------
/backend/parsers/torrent-name-parser-two/core.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | var EventEmitter = require('events').EventEmitter;
4 |
5 | var Core = function() {
6 | EventEmitter.call(this);
7 |
8 | var parts;
9 |
10 | this.getParts = function() {
11 | return parts;
12 | };
13 |
14 | this.on('setup', function () {
15 | parts = {};
16 | });
17 |
18 | this.on('part', function (part) {
19 | parts[part.name] = part.clean;
20 | });
21 | };
22 |
23 | Core.prototype = Object.create(EventEmitter.prototype);
24 | Core.prototype.constructor = EventEmitter;
25 |
26 | Core.prototype.exec = function(name) {
27 | this.emit('setup', {
28 | name: name
29 | });
30 | this.emit('start');
31 | this.emit('end');
32 |
33 | return this.getParts();
34 | };
35 |
36 | module.exports = new Core();
37 |
--------------------------------------------------------------------------------
/backend/parsers/torrent-name-parser-two/index.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | require('./parts/common');
4 | require('./parts/title');
5 | require('./parts/excess');
6 |
7 | module.exports = function(name) {
8 | return require('./core').exec(name);
9 | };
10 |
--------------------------------------------------------------------------------
/backend/parsers/torrent-name-parser-two/parts/common.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | var core = require('../core');
4 |
5 | /**
6 | * Pattern should contain either none or two capturing groups.
7 | * In case of two groups - 1st is raw, 2nd is clean.
8 | */
9 | var patterns = {
10 | season: /([Ss]?([0-9]{1,2}))[Eex]/,
11 | episode: /([Eex]([0-9]{2})(?:[^0-9]|$))/,
12 | year: /([\[\(]?((?:19[0-9]|20[01])[0-9])[\]\)]?)/,
13 | resolution: /(([0-9]{3,4}p))[^M]/,
14 | quality: /(?:PPV\.)?[HP]DTV|(?:HD)?CAM|B[rR]Rip|TS|(?:PPV )?WEB-?DL(?: DVDRip)?|H[dD]Rip|DVDRip|DVDRiP|DVDRIP|CamRip|W[EB]B[rR]ip|[Bb]lu[Rr]ay|DvDScr|hdtv/,
15 | codec: /xvid|x264|h\.?264/i,
16 | audio: /MP3|DD5\.?1|Dual[\- ]Audio|LiNE|DTS|AAC(?:\.?2\.0)?|AC3(?:\.5\.1)?/,
17 | group: /(- ?([^-]+(?:-={[^-]+-?$)?))$/,
18 | region: /R[0-9]/,
19 | extended: /EXTENDED/,
20 | hardcoded: /HC/,
21 | proper: /PROPER/,
22 | repack: /REPACK/,
23 | container: /MKV|AVI/,
24 | widescreen: /WS/,
25 | website: /^(\[ ?([^\]]+?) ?\])/,
26 | language: /rus\.eng/,
27 | garbage: /1400Mb|3rd Nov| ((Rip))/
28 | };
29 | var types = {
30 | season: 'integer',
31 | episode: 'integer',
32 | year: 'integer',
33 | extended: 'boolean',
34 | hardcoded: 'boolean',
35 | proper: 'boolean',
36 | repack: 'boolean',
37 | widescreen: 'boolean'
38 | };
39 | var torrent;
40 |
41 | core.on('setup', function (data) {
42 | torrent = data;
43 | });
44 |
45 | core.on('start', function() {
46 | var key, match, index, clean, part;
47 |
48 | for(key in patterns) {
49 | if(patterns.hasOwnProperty(key)) {
50 | if(!(match = torrent.name.match(patterns[key]))) {
51 | continue;
52 | }
53 |
54 | index = {
55 | raw: match[1] ? 1 : 0,
56 | clean: match[1] ? 2 : 0
57 | };
58 |
59 | if(types[key] && types[key] === 'boolean') {
60 | clean = true;
61 | }
62 | else {
63 | clean = match[index.clean];
64 |
65 | if(types[key] && types[key] === 'integer') {
66 | clean = parseInt(clean, 10);
67 | }
68 | }
69 |
70 | if(key === 'group') {
71 | if(clean.match(patterns.codec) || clean.match(patterns.quality)) {
72 | continue;
73 | }
74 |
75 | if(clean.match(/[^ ]+ [^ ]+ .+/)) {
76 | key = 'episodeName';
77 | }
78 | }
79 |
80 | part = {
81 | name: key,
82 | match: match,
83 | raw: match[index.raw],
84 | clean: clean
85 | };
86 |
87 | if(key === 'episode') {
88 | core.emit('map', torrent.name.replace(part.raw, '{episode}'));
89 | }
90 |
91 | core.emit('part', part);
92 | }
93 | }
94 |
95 | core.emit('common');
96 | });
97 |
98 | core.on('late', function (part) {
99 | if(part.name === 'group') {
100 | core.emit('part', part);
101 | }
102 | else if(part.name === 'episodeName') {
103 | part.clean = part.clean.replace(/[\._]/g, ' ');
104 | part.clean = part.clean.replace(/_+$/, '').trim();
105 | core.emit('part', part);
106 | }
107 | });
108 |
--------------------------------------------------------------------------------
/backend/parsers/torrent-name-parser-two/parts/excess.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | var core = require('../core');
4 |
5 | var torrent, raw, groupRaw;
6 | var escapeRegex = function(string) {
7 | return string.replace(/[\-\[\]{}()*+?.,\\\^$|#\s]/g, '\\$&');
8 | };
9 |
10 | core.on('setup', function (data) {
11 | torrent = data;
12 | raw = torrent.name;
13 | groupRaw = '';
14 | });
15 |
16 | core.on('part', function (part) {
17 | if(part.name === 'excess') {
18 | return;
19 | }
20 | else if(part.name === 'group') {
21 | groupRaw = part.raw;
22 | }
23 |
24 | // remove known parts from the excess
25 | raw = raw.replace(part.raw, '');
26 | });
27 |
28 | core.on('map', function (map) {
29 | torrent.map = map;
30 | });
31 |
32 | core.on('end', function () {
33 | var clean, groupPattern, episodeNamePattern;
34 |
35 | // clean up excess
36 | clean = raw.replace(/(^[-\. ]+)|([-\. ]+$)/g, '');
37 | clean = clean.replace(/[\(\)\/]/g, ' ');
38 | clean = clean.split(/\.\.+| +/).filter(Boolean);
39 |
40 | if(clean.length !== 0) {
41 | groupPattern = escapeRegex(clean[clean.length - 1] + groupRaw) + '$';
42 |
43 | if(torrent.name.match(new RegExp(groupPattern))) {
44 | core.emit('late', {
45 | name: 'group',
46 | clean: clean.pop() + groupRaw
47 | });
48 | }
49 |
50 | if(torrent.map && clean[0]) {
51 | episodeNamePattern = '{episode}' + escapeRegex(clean[0].replace(/_+$/, ''));
52 |
53 | if(torrent.map.match(new RegExp(episodeNamePattern))) {
54 | core.emit('late', {
55 | name: 'episodeName',
56 | clean: clean.shift()
57 | });
58 | }
59 | }
60 | }
61 |
62 | if(clean.length !== 0) {
63 | core.emit('part', {
64 | name: 'excess',
65 | raw: raw,
66 | clean: clean.length === 1 ? clean[0] : clean
67 | });
68 | }
69 | });
70 |
--------------------------------------------------------------------------------
/backend/parsers/torrent-name-parser-two/parts/title.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | var core = require('../core');
4 |
5 | require('./common');
6 |
7 | var torrent, start, end, raw;
8 |
9 | core.on('setup', function (data) {
10 | torrent = data;
11 | start = 0;
12 | end = undefined;
13 | raw = undefined;
14 | });
15 |
16 | core.on('part', function (part) {
17 | if(!part.match) {
18 | return;
19 | }
20 |
21 | if(part.match.index === 0) {
22 | start = part.match[0].length;
23 |
24 | return;
25 | }
26 |
27 | if(!end || part.match.index < end) {
28 | end = part.match.index;
29 | }
30 | });
31 |
32 | core.on('common', function () {
33 | var raw = end ? torrent.name.substr(start, end - start).split('(')[0] : torrent.name;
34 | var clean = raw;
35 |
36 | // clean up title
37 | clean = raw.replace(/^ -/, '');
38 |
39 | if(clean.indexOf(' ') === -1 && clean.indexOf('.') !== -1) {
40 | clean = clean.replace(/\./g, ' ');
41 | }
42 |
43 | clean = clean.replace(/_/g, ' ');
44 | clean = clean.replace(/([\(_]|- )$/, '').trim();
45 |
46 | core.emit('part', {
47 | name: 'title',
48 | raw: raw,
49 | clean: clean
50 | });
51 | });
52 |
--------------------------------------------------------------------------------
/backend/plugins/checkOrigin.js:
--------------------------------------------------------------------------------
1 | module.exports = function (origin){
2 | var allowedOrigins = process.env.FRONTENDURL.split(",");
3 | if (origin && allowedOrigins.indexOf(origin) > -1){
4 | return true
5 | } else {
6 | return false
7 | }
8 | }
9 |
--------------------------------------------------------------------------------
/backend/plugins/deleteAll.js:
--------------------------------------------------------------------------------
1 | const deleteUsers = require('./deleteUsers');
2 | const deletePendingUsers = require('./deletePendingUsers');
3 | const deleteInvitedUsers = require('./deleteInvitedUsers');
4 |
5 | function deleteAll() {
6 | setInterval(async () => {
7 | await deleteUsers();
8 | await deletePendingUsers();
9 | await deleteInvitedUsers();
10 | }, (7200 * 1000))
11 | }
12 |
13 | module.exports = deleteAll;
14 |
--------------------------------------------------------------------------------
/backend/plugins/deleteInvitedUsers.js:
--------------------------------------------------------------------------------
1 | const transport = require('./mailtransporter');
2 | const InvitedUser = require("../models/invitedUser");
3 | const toInvitedUserEmail = require('../templates/delete/invitedUsers/toAll');
4 |
5 | function deleteInvitedUsers() {
6 | console.log("Triggered Verification Check")
7 | InvitedUser.find({}, function(error, result){
8 | if(result){
9 | result.forEach((user, i) => {
10 | const currentTime = Date.now();
11 | const allowedTill = user.pendingFrom + (86400*1000);
12 | if(currentTime > allowedTill){
13 | InvitedUser.deleteOne({ email: user.email }, function(error){
14 | if(!error){
15 | const deleteMessage = {
16 | from: `"${process.env.FRONTENDSITENAME} - Support"<${process.env.EMAILID}>`,
17 | to: user.invitedby,
18 | replyTo: process.env.REPLYTOMAIL,
19 | subject: `Regarding Your Invite to ${user.email}`,
20 | html: toInvitedUserEmail(user),
21 | };
22 | } else {
23 | console.log("Some Error While Trying to Deleting, Will be Deleted in Next Cycle.")
24 | }
25 | })
26 | } else {
27 | console.log("You Got Some Time Left")
28 | }
29 | });
30 |
31 | } else {
32 | console.log("No Invited Users")
33 | }
34 | })
35 | }
36 |
37 | module.exports = deleteInvitedUsers;
38 |
--------------------------------------------------------------------------------
/backend/plugins/deletePendingUsers.js:
--------------------------------------------------------------------------------
1 | const transport = require('./mailtransporter');
2 | const PendingUser = require("../models/pendingUser");
3 | const deletePendingUserTemplate = require('../templates/delete/pending/toAll');
4 |
5 | function deletePendingUsers() {
6 | console.log("Triggered Verification Check")
7 | PendingUser.find({}, function(error, result){
8 | if(result){
9 | result.forEach((user, i) => {
10 | const currentTime = Date.now();
11 | const allowedTill = user.pendingFrom + (86400*1000);
12 | if(currentTime > allowedTill){
13 | PendingUser.deleteOne({ email: user.email }, function(error){
14 | if(!error){
15 | const deleteMessage = {
16 | from: `"${process.env.FRONTENDSITENAME} - Support"<${process.env.EMAILID}>`,
17 | to: user.email,
18 | replyTo: process.env.REPLYTOMAIL,
19 | subject: 'Regarding Your Request',
20 | html: deletePendingUserTemplate(user),
21 | };
22 | transport.sendMail(deleteMessage, function(err, info){
23 | if(err){
24 | console.log(err);
25 | } else {
26 | console.log(info)
27 | }
28 | })
29 | } else {
30 | console.log("Some Error While Trying to Deleting, Will be Deleted in Next Cycle.")
31 | }
32 | })
33 | } else {
34 | console.log("You Got Some Time Left")
35 | }
36 | });
37 | } else {
38 | console.log("No Pending Users")
39 | }
40 | })
41 | }
42 |
43 | module.exports = deletePendingUsers
44 |
--------------------------------------------------------------------------------
/backend/plugins/deleteUsers.js:
--------------------------------------------------------------------------------
1 | const transport = require('./mailtransporter');
2 | const User = require("../models/user");
3 | const nonVerfiedEmailTemplate = require('../templates/delete/users/toNonVerified.js');
4 |
5 | function deleteTimeout() {
6 | console.log("Triggered Verification Check")
7 | User.find({ verified: false }, function(error, result){
8 | if(result){
9 | result.forEach((user, i) => {
10 | const currentDate = Date.now();
11 | const expiryDate = user.registeredDate + (10800 * 1000);
12 | console.log(currentDate, expiryDate);
13 | if(currentDate > expiryDate){
14 | User.deleteOne({ email: user.email }, function(error){
15 | if(error){
16 | console.log(error)
17 | } else {
18 | const deleteMessage = {
19 | from: `"${process.env.FRONTENDSITENAME} - Support"<${process.env.EMAILID}>`,
20 | to: user.email,
21 | replyTo: process.env.REPLYTOMAIL,
22 | subject: 'Deletion of Your Account.',
23 | html: nonVerfiedEmailTemplate(user), // Plain text body
24 | };
25 | transport.sendMail(deleteMessage, function(err, info){
26 | if(err){
27 | console.log(err);
28 | } else {
29 | console.log(info)
30 | }
31 | })
32 | }
33 | })
34 | } else {
35 | console.log("You Got Time to Get Verified.")
36 | }
37 | });
38 | } else {
39 | console.log("All Users are Verified.")
40 | }
41 | })
42 | }
43 |
44 | module.exports = deleteTimeout;
45 |
--------------------------------------------------------------------------------
/backend/plugins/jwtVerify.js:
--------------------------------------------------------------------------------
1 | const jwt = require("jsonwebtoken");
2 |
3 | function verify(token){
4 | if(token){
5 | return jwt.verify(token, process.env.TOKENSECRET, function(error, decoded){
6 | if(decoded){
7 | return true
8 | } else {
9 | return false
10 | }
11 | });
12 | } else {
13 | return false
14 | }
15 | }
16 |
17 | module.exports = verify
18 |
--------------------------------------------------------------------------------
/backend/plugins/keepAlive.js:
--------------------------------------------------------------------------------
1 | // Keep Site Online By Pinging every 25 Minutes.
2 | const site = process.env.SITE;
3 | const axios = require('axios');
4 |
5 | function keepalive() {
6 | if (site) {
7 | try {
8 | setInterval(async () => {
9 | const data = await axios.get(site);
10 | console.log(data.config.url, "status:"+''+ data.status , "Text:"+' '+data.statusText);
11 | }, 1560000);
12 | } catch(e) {
13 | console.log(e);
14 | }
15 | } else {
16 | console.warn("Set site env var");
17 | }
18 | }
19 |
20 | module.exports = keepalive;
21 |
--------------------------------------------------------------------------------
/backend/plugins/mailtransporter.js:
--------------------------------------------------------------------------------
1 | const nodemailer = require('nodemailer');
2 |
3 | // Define Mail Transporter
4 | let transport = nodemailer.createTransport({
5 | host: process.env.EMAILSMTP,
6 | port: process.env.EMAILPORT,
7 | service:process.env.EMAILSERVICE,
8 | auth: {
9 | user: process.env.EMAILID,
10 | pass: process.env.EMAILPASS
11 | }
12 | });
13 |
14 | module.exports = transport;
15 |
--------------------------------------------------------------------------------
/backend/public/css/styles.css:
--------------------------------------------------------------------------------
1 | .bd-placeholder-img {
2 | font-size: 1.125rem;
3 | text-anchor: middle;
4 | -webkit-user-select: none;
5 | -moz-user-select: none;
6 | -ms-user-select: none;
7 | user-select: none;
8 | }
9 |
10 | @media (min-width: 768px) {
11 | .bd-placeholder-img-lg {
12 | font-size: 3.5rem;
13 | }
14 | }
15 |
16 | .data {
17 | text-align: center;
18 | }
19 |
20 | .lead {
21 | font-weight: bold;
22 | }
23 |
--------------------------------------------------------------------------------
/backend/routes/index.js:
--------------------------------------------------------------------------------
1 | const express = require('express');
2 | const router = express.Router();
3 | const bcrypt = require('bcrypt');
4 |
5 | //Model Imports
6 | const User = require("../models/user");
7 | const PendingUser = require("../models/pendingUser");
8 | const SpamUser = require("../models/spamUser");
9 | const InvitedUser = require("../models/invitedUser");
10 | const checkOrigin = require("../plugins/checkOrigin");
11 |
12 | router.get('/', function(req, res){
13 | User.findOne({ superadmin: true }, function(error, result){
14 | if(result){
15 | res.render("dashboard.ejs", { user: false, showPass: false, data: "This is a Backend for G-Index. This has Been Already Setup. So Nothing Exists Here Afterwards. Use Your Frontend to Communicate.", fronturl: process.env.FRONTENDURL.split(",")[0] });
16 | } else {
17 | res.render("signup.ejs");
18 | }
19 | })
20 | });
21 |
22 | router.get('/generate', function(req, res){
23 | res.render("generate.ejs");
24 | });
25 |
26 | router.post('/generate', function(req, res){
27 | bcrypt.hash(req.body.password, 10, function(err, hashedPass){
28 | if(hashedPass){
29 | res.render("dashboard.ejs", {user: false, showPass: true, hybrid: hashedPass})
30 | }
31 | })
32 | });
33 |
34 | router.post('/checkmail', function(req, res){
35 | if(checkOrigin(req.headers.origin)){
36 | SpamUser.findOne({ email: req.body.email }, function(err, result){
37 | if(result){
38 | res.status(200).send({ auth: false, user: false, status: "Spammed User" })
39 | } else {
40 | PendingUser.findOne({ email: req.body.email }, function(err ,result){
41 | if(result){
42 | res.status(200).send({ auth: false, user: false, status: "Pending Confirmation from Admins." })
43 | } else {
44 | User.findOne({ email: req.body.email }, function(err, result){
45 | if(result){
46 | if(result.verified){
47 | res.status(200).send({ auth: true, user: true, status: "User Present & Verified" })
48 | } else {
49 | res.status(200).send({ auth: false, user:true, status: "User Present & Not Verified" })
50 | }
51 | } else {
52 | res.status(200).send({ auth: false, user: false, status: "User Not Present" })
53 | }
54 | })
55 | }
56 | })
57 | }
58 | })
59 | } else {
60 | res.status(200).send({ auth: false, message: "UNAUTHORIZED" })
61 | }
62 | })
63 |
64 | module.exports = router;
65 |
--------------------------------------------------------------------------------
/backend/routes/pending/index.js:
--------------------------------------------------------------------------------
1 | const express = require("express");
2 | const router = express.Router();
3 | const checkOrigin = require("../../plugins/checkOrigin");
4 | const jwtVerify = require('../../plugins/jwtVerify');
5 |
6 | //Model Imports
7 | const User = require("../../models/user");
8 | const PendingUser = require("../../models/pendingUser");
9 |
10 | router.post('/users', function(req, res){
11 | if(checkOrigin(req.headers.origin)){
12 | if(jwtVerify(req.headers.token)){
13 | User.findOne({ email: req.body.adminuseremail }, function(error, result){
14 | if(result){
15 | if(result.admin){
16 | PendingUser.find({ post: "User" }, function(error, result){
17 | if(result.length == 0){
18 | res.status(200).send({ auth: false, registered: true, message: "No Pending Users" })
19 | } else {
20 | res.status(200).send({ auth: true, registered: true, users: result })
21 | }
22 | })
23 | } else {
24 | res.status(200).send({ auth: false, registered: true, message: "You are Unauthorized" })
25 | }
26 | } else {
27 | res.status(200).send({ auth: false, registered: false, message: "BAD REQUEST" })
28 | }
29 | })
30 | } else {
31 | res.status(200).send({ auth: false, message: "Bearer Token Not Valid" })
32 | }
33 | } else {
34 | res.status(200).send({ auth: false, message: "UNAUTHORIZED" })
35 | }
36 | });
37 |
38 | router.post('/admins', function(req, res){
39 | if(checkOrigin(req.headers.origin)){
40 | if(jwtVerify(req.headers.token)){
41 | User.findOne({ email: req.body.adminuseremail }, function(error, result){
42 | if(result){
43 | if(result.admin){
44 | if(result.superadmin){
45 | PendingUser.find({ post: "Admin" }, function(error, result){
46 | if(result.length == 0){
47 | res.status(200).send({ auth: false, registered: true, message: "No Pending Users" })
48 | } else {
49 | res.status(200).send({ auth: true, registered: true, users: result })
50 | }
51 | })
52 | } else {
53 | res.status(200).send({ auth: false, registered: true, message: "You are Unauthorized" })
54 | }
55 | } else {
56 | res.status(200).send({ auth: false, registered: true, message: "You are Unauthorized" })
57 | }
58 | } else {
59 | res.status(200).send({ auth: false, registered: false, message: "BAD REQUEST" })
60 | }
61 | })
62 | } else {
63 | res.status(200).send({ auth: false, message: "Bearer Token Not Valid" })
64 | }
65 | } else {
66 | res.status(200).send({ auth: false, message: "UNAUTHORIZED" })
67 | }
68 | })
69 |
70 | router.post('/superadmins', function(req, res){
71 | if(checkOrigin(req.headers.origin)){
72 | if(jwtVerify(req.headers.token)){
73 | User.findOne({ email: req.body.adminuseremail }, function(error, result){
74 | if(result){
75 | if(result.admin){
76 | if(result.superadmin){
77 | PendingUser.find({ post: "SuperAdmin" }, function(error, result){
78 | if(result.length == 0){
79 | res.status(200).send({ auth: false, registered: true, message: "No Pending Users" })
80 | } else {
81 | res.status(200).send({ auth: true, registered: true, users: result })
82 | }
83 | })
84 | } else {
85 | res.status(200).send({ auth: false, registered: true, message: "You are Unauthorized" })
86 | }
87 | } else {
88 | res.status(200).send({ auth: false, registered: true, message: "You are Unauthorized" })
89 | }
90 | } else {
91 | res.status(200).send({ auth: false, registered: false, message: "BAD REQUEST" })
92 | }
93 | })
94 | } else {
95 | res.status(200).send({ auth: false, message: "Bearer Token Not Valid" })
96 | }
97 | } else {
98 | res.status(200).send({ auth: false, message: "UNAUTHORIZED" })
99 | }
100 | })
101 |
102 | module.exports = router;
103 |
--------------------------------------------------------------------------------
/backend/routes/ping.js:
--------------------------------------------------------------------------------
1 | const express = require("express");
2 | const router = express.Router();
3 | var ping = require('ping');
4 |
5 | router.post('/', async function(req, res){
6 | let pinged = await ping.promise.probe(req.body.pingsite, {
7 | timeout: 10,
8 | });
9 | res.send(pinged);
10 | })
11 |
12 | module.exports = router;
13 |
--------------------------------------------------------------------------------
/backend/routes/poster.js:
--------------------------------------------------------------------------------
1 | const express = require("express");
2 | const router = express.Router();
3 | const checkOrigin = require("../plugins/checkOrigin");
4 | const jwtVerify = require('../plugins/jwtVerify');
5 |
6 | //Model Imports
7 | const User = require("../models/user");
8 | const CategoryPost = require("../models/categoryPost");
9 | const HeroPost = require("../models/heroPost");
10 | const TrendingPost = require("../models/trendingPost");
11 | const QuickLink = require("../models/quickLink");
12 |
13 | router.post("/all", function(req, res){
14 | if(checkOrigin(req.headers.origin)){
15 | if(jwtVerify(req.headers.token)){
16 | User.findOne({ email: req.body.email }, function(error, result){
17 | if(result){
18 | TrendingPost.find({ root: req.body.root }, function(error, trendingPosts){
19 | HeroPost.find({ root: req.body.root }, function(error, heroPosts){
20 | CategoryPost.find({ root: req.body.root }, function(error, categoryPosts){
21 | QuickLink.find({ root: req.body.root }, function(error, quicklinks){
22 | if(quicklinks && trendingPosts.length < 1 && heroPosts.length < 1 && categoryPosts.length < 1){
23 | res.status(200).send({ auth: false, registered: true, message: "No Posts Found in Your DB" });
24 | } else {
25 | res.status(200).send({ auth: true, registered: true, root: req.body.root, quicklink: quicklinks, hero: heroPosts, category: categoryPosts, trending: trendingPosts });
26 | }
27 | })
28 | })
29 | })
30 | })
31 | } else {
32 | res.status(200).send({ auth: false, registered: false, message: "BAD REQUEST" });
33 | }
34 | })
35 | } else {
36 | res.status(200).send({ auth: false, message: "Bearer Token Not Valid" })
37 | }
38 | } else {
39 | res.status(200).send({ auth: false, message: "UNAUTHORIZED" })
40 | }
41 | })
42 |
43 | router.use("/categories", require("./posters/categories"));
44 | router.use("/hero", require("./posters/hero"));
45 | router.use("/trending", require("./posters/trending"));
46 | router.use("/quicklinks", require("./posters/quicklinks"));
47 |
48 | module.exports = router
49 |
--------------------------------------------------------------------------------
/backend/routes/settings.js:
--------------------------------------------------------------------------------
1 | const express = require("express");
2 | const router = express.Router();
3 | const checkOrigin = require("../plugins/checkOrigin");
4 | const jwtVerify = require('../plugins/jwtVerify');
5 |
6 | //Model Imports
7 | const User = require("../models/user");
8 | const Settings = require("../models/siteSettings");
9 |
10 | router.post('/set', function(req, res){
11 | if(checkOrigin(req.headers.origin)){
12 | if(jwtVerify(req.headers.token)){
13 | User.findOne({ email: req.body.email }, function(error, result){
14 | if(result){
15 | if(result.admin && result.superadmin){
16 | Settings.findOne({ cId: process.env.FRONTENDSITENAME }, function(error, settingsData){
17 | if(settingsData){
18 | Settings.updateOne({ cId: process.env.FRONTENDSITENAME }, { $set: req.body.settings }, function(error){
19 | if(!error){
20 | res.status(200).send({ auth: true, registered: true, changed: true, message: "Your Preferences have been Saved." });
21 | } else {
22 | res.status(200).send({ auth: true, registered: true, changed: false, message: "Error Occured while Saving Your Preferences" });
23 | }
24 | })
25 | } else {
26 | const newData = new Settings(req.body.settings);
27 | newData.save(function(error, doc){
28 | if(!error){
29 | res.status(200).send({ auth: true, registered: true, changed: true, data: doc, message: "Your Preferences have been Saved." });
30 | }
31 | })
32 | }
33 | })
34 | } else {
35 | res.status(200).send({ auth: false, registered: true, changed: false, message: "You don't Have Enough Permissions." })
36 | }
37 | } else {
38 | res.status(200).send({ auth: false, registered: false, changed: false, message: "Account Doesn't Exists" })
39 | }
40 | })
41 | } else {
42 | res.status(200).send({ auth: false, message: "Bearer Token Not Valid" })
43 | }
44 | } else {
45 | res.status(200).send({ auth: false, message: "UNAUTHORIZED" })
46 | }
47 | })
48 |
49 | router.post("/get", function(req, res){
50 | if(checkOrigin(req.headers.origin)){
51 | Settings.findOne({ cId: process.env.FRONTENDSITENAME }, function(error, result){
52 | if(result){
53 | res.status(200).send({ auth: true, registered: true, data: result });
54 | } else {
55 | res.status(200).send({ auth: false, registered: true, message: "There's an Error while Getting Site Details." });
56 | }
57 | })
58 | } else {
59 | res.status(200).send({ auth: false, message: "UNAUTHORIZED" })
60 | }
61 | })
62 |
63 | module.exports = router;
64 |
--------------------------------------------------------------------------------
/backend/views/dashboard.ejs:
--------------------------------------------------------------------------------
1 | <%- include("header") -%>
2 |
9 | Your Name is <%= details.name %> 10 |
11 |12 | Your Email is <%= details.email %> 13 |
14 |This Page is Only Visible Only for One Time
15 |Hereafter You Can Login to Frontend With this Email and Password.Login
16 |To setup the Frontend, Please Continue with this Wiki
17 |23 | <%= data %> 24 |
25 |26 | Generate a Hybrid Password 27 |
28 | 29 |