Skip to content
This repository was archived by the owner on Dec 30, 2022. It is now read-only.
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 3 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
.DS_Store
node_modules
config/flagged-repos.json
config/flagged-repos.json
config/config.js
main.db
9 changes: 9 additions & 0 deletions .prettierrc
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
{
"tabWidth": 4,
"singleQuote": false,
"useTabs": false,
"arrowParens": "always",
"bracketSpacing": true,
"semi": true,
"trailingComma": "none"
}
5 changes: 3 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -21,8 +21,9 @@ Additionally, if you wish to report a dangerous repo, please contact [@SileoSupp

1. `yarn install`
2. Move `config/flagged-repos.example.json` to `config/flagged-repos.json` and add some sample repos for testing
3. `node index.js`
4. :tada:
3. move `config/config.example.js` to `config/config.js` and fill out the values accordingly.
4. `node index.js`
5. :tada:

## Developers

Expand Down
20 changes: 20 additions & 0 deletions config/config.example.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
class Configuration {
static get Misc() {
return {
version: 1,
updated: ""
};
}
static get Database() {
return {
type: "postgres",
host: "localhost",
port: 5432,
database: "FlaggedRepoAPI",
synchronize: true,
username: "postgres",
password: "123"
};
}
}
module.exports = Configuration;
2 changes: 0 additions & 2 deletions config/flagged-repos.example.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,4 @@
{
"version": 1,
"updated": "",
"flaggedRepoURLs": [
"pirates.com"
]
Expand Down
60 changes: 60 additions & 0 deletions controllers/flagged.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
const { parse } = require("url");
const { ApiRequest } = require("../database/entities/ApiRequest");
const repolist = require("../config/flagged-repos.json");
const flaggedRepos = repolist.flaggedRepoURLs;

let repoRegexes = [];

const createRegex = (url) => {
// basically https://stackoverflow.com/a/39095107/9784092 but better
const split = /([^\/]+)(\/.*)?/;

const matches = url.match(split);
if (!matches) return null;

var preparedURL = "";
preparedURL = `${matches[1]}`
.replace(/[?()[\]\\.+^$|]/g, "\\$&")
.replace(/\*\\./g, "(?:[^/]*\\.)*")
.replace(/\*$/, "[^/]*");

if (matches[2]) {
preparedURL += matches[2]
.replace(/[?()[\]\\.+^$|]/g, "\\$&")
.replace(/\/\*(?=$|\/)/g, "(?:/[^]*)?");
}
return new RegExp(`^${preparedURL}$`, "i");
};

const regenerateRegex = () => {
console.log("Generating regex array.");
for (const repo of flaggedRepos) {
const regex = createRegex(repo);
if (!regex)
return console.error(`Failed to generate regex for ${repo}.`);

repoRegexes.push(regex);
}
console.log("Generated regex array.");
};

const flaggedController = (req, res) => {
if (!req.body.url) return res.status(400).end();
const parsed = parse(req.body.url);
// prettier-ignore
const normalised = `${parsed.hostname}${parsed.pathname == "/" ? "" : parsed.pathname}`
.replace(/^www\./, "")
.trim();

const isPiracy = repoRegexes.some((regex) => {
return normalised.match(regex) !== null;
});
ApiRequest.sync().then(() => {
ApiRequest.create({
isPiracy
});
});
return res.send(isPiracy);
};

module.exports = { regenerateRegex, flaggedController };
3 changes: 3 additions & 0 deletions controllers/homepageController.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
exports.homepageController = (_, res) => {
return res.redirect("https://github.com/SileoApp/FlaggedRepoAPI");
};
18 changes: 18 additions & 0 deletions controllers/info.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
const { Misc } = require("../config/config");
const { ApiRequest } = require("../database/entities/ApiRequest");
const repolist = require("../config/flagged-repos.json");
exports.infoController = async (req, res) => {
const piracyReq = await ApiRequest.findAll({
where: {
isPiracy: true
}
});
const totalReq = await ApiRequest.findAll();
return res.json({
piracy_req_count: piracyReq.length,
total_req_count: totalReq.length,
version: Misc.version,
updated: Misc.updated,
flagged_count: repolist.flaggedRepoURLs.length
});
};
8 changes: 8 additions & 0 deletions database/entities/ApiRequest.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
const Sequelize = require("sequelize");
const { getSequelize } = require("../index");

exports.ApiRequest = getSequelize().define("ApiRequest", {
isPiracy: {
type: Sequelize.BOOLEAN
}
});
22 changes: 22 additions & 0 deletions database/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
const Sequelize = require("sequelize");
const { Database } = require("../config/config");
const sequelize = new Sequelize(Database.database, null, null, {
dialect: "sqlite",
operatorsAliases: false,
logging: false,
storage: Database.storage,
pool: {
max: 5,
min: 0,
acquire: 30000,
idle: 10000
}
});
exports.initDatabase = () => {
return sequelize.authenticate();
};

// A getter to access the object from other files.
exports.getSequelize = () => {
return sequelize;
};
68 changes: 11 additions & 57 deletions index.js
Original file line number Diff line number Diff line change
@@ -1,66 +1,20 @@
const { parse } = require("url");
const express = require("express");
const { initDatabase } = require("./database/index");
const { infoController } = require("./controllers/info");
const { flaggedController, regenerateRegex } = require("./controllers/flagged");
const { homepageController } = require("./controllers/homepageController");
const app = express();

const repolist = require("./config/flagged-repos.json");
const flaggedRepos = repolist.flaggedRepoURLs;

var repoRegexes = [];

const createRegex = (url) => {
// basically https://stackoverflow.com/a/39095107/9784092 but better
const split = /([^\/]+)(\/.*)?/;

const matches = url.match(split);
if (!matches) return null;

var preparedURL = "";
preparedURL = `${matches[1]}`.replace(/[?()[\]\\.+^$|]/g, "\\$&").replace(/\*\\./g,'(?:[^/]*\\.)*').replace(/\*$/,'[^/]*');

if (matches[2]) {
preparedURL += matches[2].replace(/[?()[\]\\.+^$|]/g, "\\$&").replace(/\/\*(?=$|\/)/g, '(?:/[^]*)?');
}
return new RegExp(`^${preparedURL}$`, "i");
}

const regenerateRegex = () => {
console.log("Generating regex array.");
for (const repo of flaggedRepos) {
const regex = createRegex(repo);
if (!regex) return console.error(`Failed to generate regex for ${repo}.`);

repoRegexes.push(regex);
}
console.log("Generated regex array.");
}

app.use(express.json());

app.get("/", (_, res) => {
return res.redirect("https://github.com/SileoApp/FlaggedRepoAPI");
});

app.get("/info", (_, res) => {
return res.json({
version: repolist.version,
updated: repolist.updated,
flagged_count: repolist.flaggedRepoURLs.length
});
});

app.post("/flagged", (req, res) => {
if (!req.body.url) return res.sendStatus(400);

const parsed = parse(req.body.url);
const normalised = `${parsed.hostname}${parsed.pathname == "/" ? "" : parsed.pathname}`.replace(/^www\./,'').trim();

const hasFlagged = repoRegexes.some(regex => {
return normalised.match(regex) !== null;
});
app.get("/", homepageController);
app.get("/info", infoController);
app.post("/flagged", flaggedController);

return res.send(hasFlagged);
});
initDatabase().then(() => console.log("Database connected."));

regenerateRegex();
const port = process.env.PORT || 3000;
app.listen(port, () => console.log(`Flagged Repo API listening on http://localhost:${port}.`));
app.listen(port, () =>
console.log(`Flagged Repo API listening on http://localhost:${port}.`)
);
4 changes: 3 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@
"author": "nullpixel & Sileo Team",
"license": "MIT",
"dependencies": {
"express": "^4.16.4"
"express": "^4.16.4",
"sequelize": "^4.42.0",
"sqlite3": "^4.0.4"
}
}
Loading