mirror of
https://github.com/Litlyx/litlyx
synced 2025-12-09 23:48:36 +01:00
add broker
This commit is contained in:
5
broker/.gitignore
vendored
Normal file
5
broker/.gitignore
vendored
Normal file
@@ -0,0 +1,5 @@
|
||||
node_modules
|
||||
static
|
||||
ecosystem.config.cjs
|
||||
dist
|
||||
scripts/start_dev.js
|
||||
19
broker/ecosystem.config.example.cjs
Normal file
19
broker/ecosystem.config.example.cjs
Normal file
@@ -0,0 +1,19 @@
|
||||
module.exports = {
|
||||
apps: [
|
||||
{
|
||||
name: 'QueueBroker',
|
||||
port: '3000',
|
||||
exec_mode: 'cluster',
|
||||
instances: '2',
|
||||
script: './dist/index.js',
|
||||
env: {
|
||||
EMAIL_SERVICE: "",
|
||||
EMAIL_HOST: "",
|
||||
EMAIL_USER: "",
|
||||
EMAIL_PASS: "",
|
||||
PORT: "",
|
||||
MONGO_CONNECTION_STRING: ""
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
1264
broker/package-lock.json
generated
Normal file
1264
broker/package-lock.json
generated
Normal file
File diff suppressed because it is too large
Load Diff
32
broker/package.json
Normal file
32
broker/package.json
Normal file
@@ -0,0 +1,32 @@
|
||||
{
|
||||
"dependencies": {
|
||||
"cors": "^2.8.5",
|
||||
"express": "^4.19.2",
|
||||
"mongoose": "^8.3.2",
|
||||
"nodemailer": "^6.9.13",
|
||||
"ua-parser-js": "^1.0.37"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@types/cors": "^2.8.17",
|
||||
"@types/express": "^4.17.21",
|
||||
"@types/node": "^20.12.13",
|
||||
"@types/nodemailer": "^6.4.15",
|
||||
"@types/ua-parser-js": "^0.7.39",
|
||||
"glob": "^10.4.1",
|
||||
"node-ssh": "^13.2.0",
|
||||
"typescript": "^5.4.5"
|
||||
},
|
||||
"name": "litlyx-queue-broker",
|
||||
"version": "1.0.0",
|
||||
"main": "dist/index.js",
|
||||
"scripts": {
|
||||
"dev": "node scripts/start_dev.js",
|
||||
"compile": "tsc",
|
||||
"build": "ts-node scripts/build.ts",
|
||||
"create_db": "cd scripts && ts-node create_database.ts"
|
||||
},
|
||||
"keywords": [],
|
||||
"author": "Emily",
|
||||
"license": "MIT",
|
||||
"description": "Queue broker for Litlyx - Saves events to database."
|
||||
}
|
||||
1253
broker/pnpm-lock.yaml
generated
Normal file
1253
broker/pnpm-lock.yaml
generated
Normal file
File diff suppressed because it is too large
Load Diff
486255
broker/scripts/GeoLite2-Country-Blocks-IPv4.csv
Normal file
486255
broker/scripts/GeoLite2-Country-Blocks-IPv4.csv
Normal file
File diff suppressed because it is too large
Load Diff
253
broker/scripts/GeoLite2-Country-Locations-en.csv
Normal file
253
broker/scripts/GeoLite2-Country-Locations-en.csv
Normal file
@@ -0,0 +1,253 @@
|
||||
geoname_id,locale_code,continent_code,continent_name,country_iso_code,country_name,is_in_european_union
|
||||
49518,en,AF,Africa,RW,Rwanda,0
|
||||
51537,en,AF,Africa,SO,Somalia,0
|
||||
69543,en,AS,Asia,YE,Yemen,0
|
||||
99237,en,AS,Asia,IQ,Iraq,0
|
||||
102358,en,AS,Asia,SA,"Saudi Arabia",0
|
||||
130758,en,AS,Asia,IR,Iran,0
|
||||
146669,en,EU,Europe,CY,Cyprus,1
|
||||
149590,en,AF,Africa,TZ,Tanzania,0
|
||||
163843,en,AS,Asia,SY,Syria,0
|
||||
174982,en,AS,Asia,AM,Armenia,0
|
||||
192950,en,AF,Africa,KE,Kenya,0
|
||||
203312,en,AF,Africa,CD,"DR Congo",0
|
||||
223816,en,AF,Africa,DJ,Djibouti,0
|
||||
226074,en,AF,Africa,UG,Uganda,0
|
||||
239880,en,AF,Africa,CF,"Central African Republic",0
|
||||
241170,en,AF,Africa,SC,Seychelles,0
|
||||
248816,en,AS,Asia,JO,Jordan,0
|
||||
272103,en,AS,Asia,LB,Lebanon,0
|
||||
285570,en,AS,Asia,KW,Kuwait,0
|
||||
286963,en,AS,Asia,OM,Oman,0
|
||||
289688,en,AS,Asia,QA,Qatar,0
|
||||
290291,en,AS,Asia,BH,Bahrain,0
|
||||
290557,en,AS,Asia,AE,"United Arab Emirates",0
|
||||
294640,en,AS,Asia,IL,Israel,0
|
||||
298795,en,AS,Asia,TR,Türkiye,0
|
||||
337996,en,AF,Africa,ET,Ethiopia,0
|
||||
338010,en,AF,Africa,ER,Eritrea,0
|
||||
357994,en,AF,Africa,EG,Egypt,0
|
||||
366755,en,AF,Africa,SD,Sudan,0
|
||||
390903,en,EU,Europe,GR,Greece,1
|
||||
433561,en,AF,Africa,BI,Burundi,0
|
||||
453733,en,EU,Europe,EE,Estonia,1
|
||||
458258,en,EU,Europe,LV,Latvia,1
|
||||
587116,en,AS,Asia,AZ,Azerbaijan,0
|
||||
597427,en,EU,Europe,LT,Lithuania,1
|
||||
607072,en,EU,Europe,SJ,"Svalbard and Jan Mayen",0
|
||||
614540,en,AS,Asia,GE,Georgia,0
|
||||
617790,en,EU,Europe,MD,Moldova,0
|
||||
630336,en,EU,Europe,BY,Belarus,0
|
||||
660013,en,EU,Europe,FI,Finland,1
|
||||
661882,en,EU,Europe,AX,"Åland Islands",1
|
||||
690791,en,EU,Europe,UA,Ukraine,0
|
||||
718075,en,EU,Europe,MK,"North Macedonia",0
|
||||
719819,en,EU,Europe,HU,Hungary,1
|
||||
732800,en,EU,Europe,BG,Bulgaria,1
|
||||
783754,en,EU,Europe,AL,Albania,0
|
||||
798544,en,EU,Europe,PL,Poland,1
|
||||
798549,en,EU,Europe,RO,Romania,1
|
||||
831053,en,EU,Europe,XK,Kosovo,0
|
||||
878675,en,AF,Africa,ZW,Zimbabwe,0
|
||||
895949,en,AF,Africa,ZM,Zambia,0
|
||||
921929,en,AF,Africa,KM,Comoros,0
|
||||
927384,en,AF,Africa,MW,Malawi,0
|
||||
932692,en,AF,Africa,LS,Lesotho,0
|
||||
933860,en,AF,Africa,BW,Botswana,0
|
||||
934292,en,AF,Africa,MU,Mauritius,0
|
||||
934841,en,AF,Africa,SZ,Eswatini,0
|
||||
935317,en,AF,Africa,RE,Réunion,1
|
||||
953987,en,AF,Africa,ZA,"South Africa",0
|
||||
1024031,en,AF,Africa,YT,Mayotte,1
|
||||
1036973,en,AF,Africa,MZ,Mozambique,0
|
||||
1062947,en,AF,Africa,MG,Madagascar,0
|
||||
1149361,en,AS,Asia,AF,Afghanistan,0
|
||||
1168579,en,AS,Asia,PK,Pakistan,0
|
||||
1210997,en,AS,Asia,BD,Bangladesh,0
|
||||
1218197,en,AS,Asia,TM,Turkmenistan,0
|
||||
1220409,en,AS,Asia,TJ,Tajikistan,0
|
||||
1227603,en,AS,Asia,LK,"Sri Lanka",0
|
||||
1252634,en,AS,Asia,BT,Bhutan,0
|
||||
1269750,en,AS,Asia,IN,India,0
|
||||
1282028,en,AS,Asia,MV,Maldives,0
|
||||
1282588,en,AS,Asia,IO,"British Indian Ocean Territory",0
|
||||
1282988,en,AS,Asia,NP,Nepal,0
|
||||
1327865,en,AS,Asia,MM,Myanmar,0
|
||||
1512440,en,AS,Asia,UZ,Uzbekistan,0
|
||||
1522867,en,AS,Asia,KZ,Kazakhstan,0
|
||||
1527747,en,AS,Asia,KG,Kyrgyzstan,0
|
||||
1546748,en,AN,Antarctica,TF,"French Southern Territories",0
|
||||
1547314,en,AN,Antarctica,HM,"Heard and McDonald Islands",0
|
||||
1547376,en,AS,Asia,CC,"Cocos (Keeling) Islands",0
|
||||
1559582,en,OC,Oceania,PW,Palau,0
|
||||
1562822,en,AS,Asia,VN,Vietnam,0
|
||||
1605651,en,AS,Asia,TH,Thailand,0
|
||||
1643084,en,AS,Asia,ID,Indonesia,0
|
||||
1655842,en,AS,Asia,LA,Laos,0
|
||||
1668284,en,AS,Asia,TW,Taiwan,0
|
||||
1694008,en,AS,Asia,PH,Philippines,0
|
||||
1733045,en,AS,Asia,MY,Malaysia,0
|
||||
1814991,en,AS,Asia,CN,China,0
|
||||
1819730,en,AS,Asia,HK,"Hong Kong",0
|
||||
1820814,en,AS,Asia,BN,Brunei,0
|
||||
1821275,en,AS,Asia,MO,Macao,0
|
||||
1831722,en,AS,Asia,KH,Cambodia,0
|
||||
1835841,en,AS,Asia,KR,"South Korea",0
|
||||
1861060,en,AS,Asia,JP,Japan,0
|
||||
1873107,en,AS,Asia,KP,"North Korea",0
|
||||
1880251,en,AS,Asia,SG,Singapore,0
|
||||
1899402,en,OC,Oceania,CK,"Cook Islands",0
|
||||
1966436,en,OC,Oceania,TL,Timor-Leste,0
|
||||
2017370,en,EU,Europe,RU,Russia,0
|
||||
2029969,en,AS,Asia,MN,Mongolia,0
|
||||
2077456,en,OC,Oceania,AU,Australia,0
|
||||
2078138,en,OC,Oceania,CX,"Christmas Island",0
|
||||
2080185,en,OC,Oceania,MH,"Marshall Islands",0
|
||||
2081918,en,OC,Oceania,FM,"Federated States of Micronesia",0
|
||||
2088628,en,OC,Oceania,PG,"Papua New Guinea",0
|
||||
2103350,en,OC,Oceania,SB,"Solomon Islands",0
|
||||
2110297,en,OC,Oceania,TV,Tuvalu,0
|
||||
2110425,en,OC,Oceania,NR,Nauru,0
|
||||
2134431,en,OC,Oceania,VU,Vanuatu,0
|
||||
2139685,en,OC,Oceania,NC,"New Caledonia",0
|
||||
2155115,en,OC,Oceania,NF,"Norfolk Island",0
|
||||
2186224,en,OC,Oceania,NZ,"New Zealand",0
|
||||
2205218,en,OC,Oceania,FJ,Fiji,0
|
||||
2215636,en,AF,Africa,LY,Libya,0
|
||||
2233387,en,AF,Africa,CM,Cameroon,0
|
||||
2245662,en,AF,Africa,SN,Senegal,0
|
||||
2260494,en,AF,Africa,CG,"Congo Republic",0
|
||||
2264397,en,EU,Europe,PT,Portugal,1
|
||||
2275384,en,AF,Africa,LR,Liberia,0
|
||||
2287781,en,AF,Africa,CI,"Ivory Coast",0
|
||||
2300660,en,AF,Africa,GH,Ghana,0
|
||||
2309096,en,AF,Africa,GQ,"Equatorial Guinea",0
|
||||
2328926,en,AF,Africa,NG,Nigeria,0
|
||||
2361809,en,AF,Africa,BF,"Burkina Faso",0
|
||||
2363686,en,AF,Africa,TG,Togo,0
|
||||
2372248,en,AF,Africa,GW,Guinea-Bissau,0
|
||||
2378080,en,AF,Africa,MR,Mauritania,0
|
||||
2395170,en,AF,Africa,BJ,Benin,0
|
||||
2400553,en,AF,Africa,GA,Gabon,0
|
||||
2403846,en,AF,Africa,SL,"Sierra Leone",0
|
||||
2410758,en,AF,Africa,ST,"São Tomé and Príncipe",0
|
||||
2411586,en,EU,Europe,GI,Gibraltar,0
|
||||
2413451,en,AF,Africa,GM,Gambia,0
|
||||
2420477,en,AF,Africa,GN,Guinea,0
|
||||
2434508,en,AF,Africa,TD,Chad,0
|
||||
2440476,en,AF,Africa,NE,Niger,0
|
||||
2453866,en,AF,Africa,ML,Mali,0
|
||||
2461445,en,AF,Africa,EH,"Western Sahara",0
|
||||
2464461,en,AF,Africa,TN,Tunisia,0
|
||||
2510769,en,EU,Europe,ES,Spain,1
|
||||
2542007,en,AF,Africa,MA,Morocco,0
|
||||
2562770,en,EU,Europe,MT,Malta,1
|
||||
2589581,en,AF,Africa,DZ,Algeria,0
|
||||
2622320,en,EU,Europe,FO,"Faroe Islands",0
|
||||
2623032,en,EU,Europe,DK,Denmark,1
|
||||
2629691,en,EU,Europe,IS,Iceland,0
|
||||
2635167,en,EU,Europe,GB,"United Kingdom",0
|
||||
2658434,en,EU,Europe,CH,Switzerland,0
|
||||
2661886,en,EU,Europe,SE,Sweden,1
|
||||
2750405,en,EU,Europe,NL,"The Netherlands",1
|
||||
2782113,en,EU,Europe,AT,Austria,1
|
||||
2802361,en,EU,Europe,BE,Belgium,1
|
||||
2921044,en,EU,Europe,DE,Germany,1
|
||||
2960313,en,EU,Europe,LU,Luxembourg,1
|
||||
2963597,en,EU,Europe,IE,Ireland,1
|
||||
2993457,en,EU,Europe,MC,Monaco,0
|
||||
3017382,en,EU,Europe,FR,France,1
|
||||
3041565,en,EU,Europe,AD,Andorra,0
|
||||
3042058,en,EU,Europe,LI,Liechtenstein,0
|
||||
3042142,en,EU,Europe,JE,Jersey,0
|
||||
3042225,en,EU,Europe,IM,"Isle of Man",0
|
||||
3042362,en,EU,Europe,GG,Guernsey,0
|
||||
3057568,en,EU,Europe,SK,Slovakia,1
|
||||
3077311,en,EU,Europe,CZ,Czechia,1
|
||||
3144096,en,EU,Europe,NO,Norway,0
|
||||
3164670,en,EU,Europe,VA,"Vatican City",0
|
||||
3168068,en,EU,Europe,SM,"San Marino",0
|
||||
3175395,en,EU,Europe,IT,Italy,1
|
||||
3190538,en,EU,Europe,SI,Slovenia,1
|
||||
3194884,en,EU,Europe,ME,Montenegro,0
|
||||
3202326,en,EU,Europe,HR,Croatia,1
|
||||
3277605,en,EU,Europe,BA,"Bosnia and Herzegovina",0
|
||||
3351879,en,AF,Africa,AO,Angola,0
|
||||
3355338,en,AF,Africa,NA,Namibia,0
|
||||
3370751,en,AF,Africa,SH,"Saint Helena",0
|
||||
3371123,en,AN,Antarctica,BV,"Bouvet Island",0
|
||||
3374084,en,NA,"North America",BB,Barbados,0
|
||||
3374766,en,AF,Africa,CV,"Cabo Verde",0
|
||||
3378535,en,SA,"South America",GY,Guyana,0
|
||||
3381670,en,SA,"South America",GF,"French Guiana",1
|
||||
3382998,en,SA,"South America",SR,Suriname,0
|
||||
3424932,en,NA,"North America",PM,"Saint Pierre and Miquelon",0
|
||||
3425505,en,NA,"North America",GL,Greenland,0
|
||||
3437598,en,SA,"South America",PY,Paraguay,0
|
||||
3439705,en,SA,"South America",UY,Uruguay,0
|
||||
3469034,en,SA,"South America",BR,Brazil,0
|
||||
3474414,en,SA,"South America",FK,"Falkland Islands",0
|
||||
3474415,en,AN,Antarctica,GS,"South Georgia and the South Sandwich Islands",0
|
||||
3489940,en,NA,"North America",JM,Jamaica,0
|
||||
3508796,en,NA,"North America",DO,"Dominican Republic",0
|
||||
3562981,en,NA,"North America",CU,Cuba,0
|
||||
3570311,en,NA,"North America",MQ,Martinique,1
|
||||
3572887,en,NA,"North America",BS,Bahamas,0
|
||||
3573345,en,NA,"North America",BM,Bermuda,0
|
||||
3573511,en,NA,"North America",AI,Anguilla,0
|
||||
3573591,en,NA,"North America",TT,"Trinidad and Tobago",0
|
||||
3575174,en,NA,"North America",KN,"St Kitts and Nevis",0
|
||||
3575830,en,NA,"North America",DM,Dominica,0
|
||||
3576396,en,NA,"North America",AG,"Antigua and Barbuda",0
|
||||
3576468,en,NA,"North America",LC,"Saint Lucia",0
|
||||
3576916,en,NA,"North America",TC,"Turks and Caicos Islands",0
|
||||
3577279,en,NA,"North America",AW,Aruba,0
|
||||
3577718,en,NA,"North America",VG,"British Virgin Islands",0
|
||||
3577815,en,NA,"North America",VC,"St Vincent and Grenadines",0
|
||||
3578097,en,NA,"North America",MS,Montserrat,0
|
||||
3578421,en,NA,"North America",MF,"Saint Martin",1
|
||||
3578476,en,NA,"North America",BL,"Saint Barthélemy",0
|
||||
3579143,en,NA,"North America",GP,Guadeloupe,1
|
||||
3580239,en,NA,"North America",GD,Grenada,0
|
||||
3580718,en,NA,"North America",KY,"Cayman Islands",0
|
||||
3582678,en,NA,"North America",BZ,Belize,0
|
||||
3585968,en,NA,"North America",SV,"El Salvador",0
|
||||
3595528,en,NA,"North America",GT,Guatemala,0
|
||||
3608932,en,NA,"North America",HN,Honduras,0
|
||||
3617476,en,NA,"North America",NI,Nicaragua,0
|
||||
3624060,en,NA,"North America",CR,"Costa Rica",0
|
||||
3625428,en,SA,"South America",VE,Venezuela,0
|
||||
3658394,en,SA,"South America",EC,Ecuador,0
|
||||
3686110,en,SA,"South America",CO,Colombia,0
|
||||
3703430,en,NA,"North America",PA,Panama,0
|
||||
3723988,en,NA,"North America",HT,Haiti,0
|
||||
3865483,en,SA,"South America",AR,Argentina,0
|
||||
3895114,en,SA,"South America",CL,Chile,0
|
||||
3923057,en,SA,"South America",BO,Bolivia,0
|
||||
3932488,en,SA,"South America",PE,Peru,0
|
||||
3996063,en,NA,"North America",MX,Mexico,0
|
||||
4030656,en,OC,Oceania,PF,"French Polynesia",0
|
||||
4030699,en,OC,Oceania,PN,"Pitcairn Islands",0
|
||||
4030945,en,OC,Oceania,KI,Kiribati,0
|
||||
4031074,en,OC,Oceania,TK,Tokelau,0
|
||||
4032283,en,OC,Oceania,TO,Tonga,0
|
||||
4034749,en,OC,Oceania,WF,"Wallis and Futuna",0
|
||||
4034894,en,OC,Oceania,WS,Samoa,0
|
||||
4036232,en,OC,Oceania,NU,Niue,0
|
||||
4041468,en,OC,Oceania,MP,"Northern Mariana Islands",0
|
||||
4043988,en,OC,Oceania,GU,Guam,0
|
||||
4566966,en,NA,"North America",PR,"Puerto Rico",0
|
||||
4796775,en,NA,"North America",VI,"U.S. Virgin Islands",0
|
||||
5854968,en,OC,Oceania,UM,"U.S. Outlying Islands",0
|
||||
5880801,en,OC,Oceania,AS,"American Samoa",0
|
||||
6251999,en,NA,"North America",CA,Canada,0
|
||||
6252001,en,NA,"North America",US,"United States",0
|
||||
6254930,en,AS,Asia,PS,Palestine,0
|
||||
6255147,en,AS,Asia,,,0
|
||||
6255148,en,EU,Europe,,,0
|
||||
6290252,en,EU,Europe,RS,Serbia,0
|
||||
6697173,en,AN,Antarctica,AQ,Antarctica,0
|
||||
7609695,en,NA,"North America",SX,"Sint Maarten",0
|
||||
7626836,en,NA,"North America",CW,Curaçao,0
|
||||
7626844,en,NA,"North America",BQ,"Bonaire, Sint Eustatius, and Saba",0
|
||||
7909807,en,AF,Africa,SS,"South Sudan",0
|
||||
|
17
broker/scripts/build.ts
Normal file
17
broker/scripts/build.ts
Normal file
@@ -0,0 +1,17 @@
|
||||
|
||||
import fs from 'fs';
|
||||
import { globSync } from 'glob';
|
||||
const tsconfigContent = fs.readFileSync('tsconfig.json', 'utf8');
|
||||
const tsconfigObject = JSON.parse(tsconfigContent);
|
||||
const paths = tsconfigObject.compilerOptions.paths;
|
||||
const filesList = globSync('dist/**/*.js');
|
||||
filesList.forEach(file => {
|
||||
let raw = fs.readFileSync(file, 'utf8');
|
||||
for (const path in paths) {
|
||||
const deep = (file.match(/\\/g) || []).length;
|
||||
const pathText = path.replace('*', '');
|
||||
const toReplaceText = new RegExp(`"${pathText}(.*?)"`, 'g');
|
||||
raw = raw.replace(toReplaceText, `"${new Array(deep - 2).fill('../').join('')}${paths[path][0].replace('*', '')}${'$1'}"`);
|
||||
}
|
||||
fs.writeFileSync(file, raw);
|
||||
});
|
||||
36
broker/scripts/create_database.ts
Normal file
36
broker/scripts/create_database.ts
Normal file
@@ -0,0 +1,36 @@
|
||||
import fs from 'fs';
|
||||
|
||||
function createIpDatabase() {
|
||||
const data = fs.readFileSync('GeoLite2-Country-Blocks-IPv4.csv', 'utf8');
|
||||
const rows = data.split('\n');
|
||||
rows.splice(0, 1);
|
||||
rows.splice(-1);
|
||||
const parsed: [number, string, number][] = [];
|
||||
for (const row of rows) {
|
||||
const lineData = row.trim().split(',');
|
||||
parsed.push([
|
||||
parseInt(lineData[0].split('.')[0]),
|
||||
lineData[0],
|
||||
parseInt(lineData[1] || '0')
|
||||
]);
|
||||
}
|
||||
fs.writeFileSync('../dist/ipv4-db.json', JSON.stringify(parsed));
|
||||
|
||||
}
|
||||
|
||||
function createCountryDatabase() {
|
||||
const data = fs.readFileSync('GeoLite2-Country-Locations-en.csv', 'utf8');
|
||||
const rows = data.split('\n');
|
||||
rows.splice(0, 1);
|
||||
rows.splice(-1);
|
||||
const parsed: [number, string, string][] = [];
|
||||
for (const row of rows) {
|
||||
const lineData = row.trim().split(',');
|
||||
parsed.push([parseInt(lineData[0]), lineData[2], lineData[4]]);
|
||||
}
|
||||
fs.writeFileSync('../dist/countries-db.json', JSON.stringify(parsed));
|
||||
|
||||
}
|
||||
|
||||
createIpDatabase();
|
||||
createCountryDatabase();
|
||||
20
broker/src/Controller.ts
Normal file
20
broker/src/Controller.ts
Normal file
@@ -0,0 +1,20 @@
|
||||
import { TProjectCount } from "@schema/ProjectsCounts";
|
||||
import { ProjectModel } from "@schema/ProjectSchema";
|
||||
import { UserModel } from "@schema/UserSchema";
|
||||
import { LimitNotifyModel } from "@schema/broker/LimitNotifySchema";
|
||||
import { sendLimitEmail50 } from '@services/EmailService';
|
||||
|
||||
export async function checkLimitsForEmail(projectCounts: TProjectCount) {
|
||||
|
||||
if ((projectCounts.visits + projectCounts.events) >= (projectCounts.limit / 2)) {
|
||||
const notify = await LimitNotifyModel.findOne({ project_id: projectCounts._id });
|
||||
if (notify && notify.limit1 === true) return;
|
||||
const project = await ProjectModel.findById(projectCounts.project_id);
|
||||
if (!project) return;
|
||||
const owner = await UserModel.findById(project.owner);
|
||||
if (!owner) return;
|
||||
await sendLimitEmail50(owner.email);
|
||||
await LimitNotifyModel.updateOne({ project_id: projectCounts._id }, { limit1: true, limit2: false, limit3: false }, { upsert: true });
|
||||
}
|
||||
|
||||
}
|
||||
16
broker/src/ScreenSize.ts
Normal file
16
broker/src/ScreenSize.ts
Normal file
@@ -0,0 +1,16 @@
|
||||
|
||||
|
||||
export function getDeviceFromScreenSize(width: number, height: number) {
|
||||
const totalArea = width * height;
|
||||
|
||||
const mobileArea = 375 * 667;
|
||||
const tabletMinArea = 768 * 1366
|
||||
const tabletMaxArea = 1024 * 1366
|
||||
|
||||
const isMobile = totalArea <= mobileArea;
|
||||
const isTablet = totalArea >= tabletMinArea && totalArea <= tabletMaxArea;
|
||||
|
||||
if (isMobile) return 'mobile';
|
||||
if (isTablet) return 'tablet'
|
||||
return 'desktop';
|
||||
}
|
||||
17
broker/src/index.ts
Normal file
17
broker/src/index.ts
Normal file
@@ -0,0 +1,17 @@
|
||||
import express from 'express';
|
||||
import cors from 'cors';
|
||||
|
||||
import { requireEnv } from '../../shared/utilts/requireEnv';
|
||||
import { connectDatabase } from '@services/DatabaseService';
|
||||
|
||||
const app = express();
|
||||
app.use(cors());
|
||||
|
||||
connectDatabase(requireEnv('MONGO_CONNECTION_STRING'));
|
||||
|
||||
import HealthRouter from './routes/HealthRouter';
|
||||
app.use('/health', HealthRouter);
|
||||
import V1Router from './routes/v1/Router';
|
||||
app.use('/v1', V1Router);
|
||||
|
||||
app.listen(requireEnv('PORT'), () => console.log(`Listening on port ${requireEnv('PORT')}`));
|
||||
42
broker/src/lookup.ts
Normal file
42
broker/src/lookup.ts
Normal file
@@ -0,0 +1,42 @@
|
||||
import fs from 'fs';
|
||||
|
||||
const ipsData = JSON.parse(fs.readFileSync('./dist/ipv4-db.json', 'utf8'));
|
||||
const countriesData = JSON.parse(fs.readFileSync('./dist/countries-db.json', 'utf8'));
|
||||
|
||||
function inRange(ip: string, cidr: string) {
|
||||
const [subnet, mask] = cidr.split('/');
|
||||
const ipBytes = ip.split('.').map(Number);
|
||||
const subnetBytes = subnet.split('.').map(Number);
|
||||
|
||||
const ipInt = (ipBytes[0] << 24) | (ipBytes[1] << 16) | (ipBytes[2] << 8) | ipBytes[3];
|
||||
const subnetInt = (subnetBytes[0] << 24) | (subnetBytes[1] << 16) | (subnetBytes[2] << 8) | subnetBytes[3];
|
||||
|
||||
const maskInt = 0xffffffff << (32 - parseInt(mask));
|
||||
|
||||
return (ipInt & maskInt) === (subnetInt & maskInt);
|
||||
}
|
||||
|
||||
function getCountryFromId(id: number) {
|
||||
for (const country of countriesData) {
|
||||
if (country[0] == id) {
|
||||
return country;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
export function lookup(ip: string) {
|
||||
try {
|
||||
const startPiece = parseInt(ip.split('.')[0]);
|
||||
for (const target of ipsData) {
|
||||
const matchingStartPiece = target[0] == startPiece;
|
||||
if (!matchingStartPiece) continue;
|
||||
if (!inRange(ip, target[1])) continue;
|
||||
const country = getCountryFromId(target[2]);
|
||||
return [country[1], country[2]];
|
||||
}
|
||||
return ['??', '??'];
|
||||
} catch (ex) {
|
||||
console.error('ERROR DURING LOOKUP', ex);
|
||||
return ['??', '??'];
|
||||
}
|
||||
}
|
||||
15
broker/src/routes/HealthRouter.ts
Normal file
15
broker/src/routes/HealthRouter.ts
Normal file
@@ -0,0 +1,15 @@
|
||||
|
||||
import { Router } from "express";
|
||||
|
||||
const router = Router();
|
||||
|
||||
router.get('/', async (req, res) => {
|
||||
try {
|
||||
return res.json({ alive: true });
|
||||
} catch (ex) {
|
||||
console.error(ex);
|
||||
return res.status(500).json({ error: 'ERROR' });
|
||||
}
|
||||
});
|
||||
|
||||
export default router;
|
||||
127
broker/src/routes/v1/Router.ts
Normal file
127
broker/src/routes/v1/Router.ts
Normal file
@@ -0,0 +1,127 @@
|
||||
|
||||
import { Router, json } from "express";
|
||||
import { createSessionHash, getIPFromRequest } from "../../utils/Utils";
|
||||
import { checkProjectCount } from "@functions/UtilsProjectCounts";
|
||||
|
||||
import { SessionModel } from "@schema/metrics/SessionSchema";
|
||||
import { EVENT_LOG_LIMIT_PERCENT } from '@data/broker/Limits';
|
||||
import { EventType } from '@data/broker/EventType';
|
||||
import { lookup } from "../../lookup";
|
||||
import { UAParser } from "ua-parser-js";
|
||||
import { getDeviceFromScreenSize } from "../../ScreenSize";
|
||||
import { VisitModel } from "@schema/metrics/VisitSchema";
|
||||
import { EventModel } from "@schema/metrics/EventSchema";
|
||||
import { ProjectCountModel } from "@schema/ProjectsCounts";
|
||||
import { checkLimitsForEmail } from "../../Controller";
|
||||
|
||||
const router = Router();
|
||||
|
||||
const allowAnyType = () => true;
|
||||
const jsonOptions = { limit: '10mb', type: allowAnyType }
|
||||
|
||||
router.post('/keep_alive', json(jsonOptions), async (req, res) => {
|
||||
try {
|
||||
|
||||
const ip = getIPFromRequest(req);
|
||||
|
||||
const { pid, website, userAgent, instant } = req.body;
|
||||
|
||||
const sessionHash = createSessionHash(website, ip, userAgent);
|
||||
|
||||
if (instant == true) {
|
||||
await SessionModel.updateOne({ project_id: pid, session: sessionHash, }, {
|
||||
$inc: { duration: 0 },
|
||||
updated_at: Date.now()
|
||||
}, { upsert: true });
|
||||
} else {
|
||||
await SessionModel.updateOne({ project_id: pid, session: sessionHash, }, {
|
||||
$inc: { duration: 1 },
|
||||
updated_at: Date.now()
|
||||
}, { upsert: true });
|
||||
}
|
||||
|
||||
return res.sendStatus(200);
|
||||
|
||||
} catch (ex) {
|
||||
console.error(ex);
|
||||
return res.status(500).json({ error: 'ERROR' });
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
router.post('/metrics/push', json(jsonOptions), async (req, res) => {
|
||||
|
||||
try {
|
||||
|
||||
const { pid } = req.body;
|
||||
|
||||
const projectCounts = await checkProjectCount(pid);
|
||||
|
||||
const TOTAL_COUNT = projectCounts.events + projectCounts.visits;
|
||||
const LIMIT = projectCounts.limit;
|
||||
if ((TOTAL_COUNT * EVENT_LOG_LIMIT_PERCENT) > LIMIT) return;
|
||||
|
||||
await checkLimitsForEmail(projectCounts);
|
||||
|
||||
const ip = getIPFromRequest(req);
|
||||
|
||||
const { type } = req.body;
|
||||
|
||||
if (type === null || type === undefined) return res.status(400).json({ error: 'type is required' });
|
||||
if (typeof type !== 'number') return res.status(400).json({ error: 'type must be a number' });
|
||||
if (type < 0) return res.status(400).json({ error: 'type must be positive' });
|
||||
|
||||
if (type === EventType.VISIT) {
|
||||
const { website, page, referrer, screenWidth, screenHeight, userAgent } = req.body;
|
||||
let referrerParsed;
|
||||
try {
|
||||
referrerParsed = new URL(referrer);
|
||||
} catch (ex) {
|
||||
referrerParsed = { hostname: referrer };
|
||||
}
|
||||
|
||||
const geoLocation = lookup(ip);
|
||||
|
||||
const userAgentParsed = UAParser(userAgent);
|
||||
|
||||
const device = getDeviceFromScreenSize(screenWidth, screenHeight);
|
||||
|
||||
const visit = new VisitModel({
|
||||
project_id: pid, website, page, referrer: referrerParsed.hostname,
|
||||
browser: userAgentParsed.browser.name || 'NO_BROWSER',
|
||||
os: userAgentParsed.os.name || 'NO_OS',
|
||||
device,
|
||||
continent: geoLocation[0],
|
||||
country: geoLocation[1],
|
||||
});
|
||||
|
||||
await visit.save();
|
||||
|
||||
} else {
|
||||
const { name, metadata } = req.body;
|
||||
let metadataObject;
|
||||
try {
|
||||
if (metadata) metadataObject = JSON.parse(metadata);
|
||||
} catch (ex) {
|
||||
metadataObject = { error: 'Error parsing metadata' }
|
||||
}
|
||||
|
||||
const event = new EventModel({ project_id: pid, name, metadata: metadataObject });
|
||||
await event.save();
|
||||
}
|
||||
|
||||
|
||||
const fieldToInc = type === EventType.VISIT ? 'visits' : 'events';
|
||||
|
||||
await ProjectCountModel.updateOne({ _id: projectCounts._id }, { $inc: { [fieldToInc]: 1 } });
|
||||
|
||||
return res.sendStatus(200);
|
||||
|
||||
} catch (ex) {
|
||||
console.error(ex);
|
||||
return res.status(500).json({ error: 'ERROR' });
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
export default router;
|
||||
15
broker/src/utils/Utils.ts
Normal file
15
broker/src/utils/Utils.ts
Normal file
@@ -0,0 +1,15 @@
|
||||
import { Request } from "express";
|
||||
import crypto from 'crypto';
|
||||
|
||||
export function getIPFromRequest(req: Request) {
|
||||
const ip = req.header('X-Real-IP') || req.header('X-Forwarded-For') || '0.0.0.0';
|
||||
return ip;
|
||||
}
|
||||
|
||||
|
||||
export function createSessionHash(website: string, ip: string, userAgent: string) {
|
||||
const dailySalt = new Date().toLocaleDateString('it-IT');
|
||||
const sessionClean = dailySalt + website + ip + userAgent;
|
||||
const sessionHash = crypto.createHash('md5').update(sessionClean).digest("hex");
|
||||
return sessionHash;
|
||||
}
|
||||
29
broker/tsconfig.json
Normal file
29
broker/tsconfig.json
Normal file
@@ -0,0 +1,29 @@
|
||||
{
|
||||
"compilerOptions": {
|
||||
"module": "NodeNext",
|
||||
"target": "ESNext",
|
||||
"esModuleInterop": true,
|
||||
"outDir": "dist",
|
||||
"paths": {
|
||||
"@schema/*": [
|
||||
"../shared/schema/*"
|
||||
],
|
||||
"@services/*": [
|
||||
"../shared/services/*"
|
||||
],
|
||||
"@data/*": [
|
||||
"../shared/data/*"
|
||||
],
|
||||
"@functions/*": [
|
||||
"../shared/functions/*"
|
||||
]
|
||||
}
|
||||
},
|
||||
"include": [
|
||||
"src/**/*.ts",
|
||||
"scripts/**/*.ts"
|
||||
],
|
||||
"exclude": [
|
||||
"node_modules"
|
||||
]
|
||||
}
|
||||
Reference in New Issue
Block a user