-
Notifications
You must be signed in to change notification settings - Fork 529
/
idGenerator.ts
116 lines (105 loc) · 4.19 KB
/
idGenerator.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
const modulename = 'IDGen';
import fsp from 'node:fs/promises';
import humanizeDuration, { HumanizerOptions } from 'humanize-duration';
import * as nanoidSecure from 'nanoid';
import * as nanoidNonSecure from 'nanoid/non-secure';
import consts from '@core/extras/consts';
import getOsDistro from '@core/extras/getOsDistro.js';
import { convars, txEnv } from '@core/globalData';
import { DatabaseObjectType } from './database';
import consoleFactory from '@extras/console';
const console = consoleFactory(modulename);
//Consts
type IdStorageTypes = DatabaseObjectType | Set<string>;
const maxAttempts = 10;
const noIdErrorMessage = 'Unnable to generate new Random ID possibly due to the decreased available entropy. Please send a screenshot of the detailed information in the terminal for the txAdmin devs.';
/**
* Prints a diagnostics message to the console that should help us identify what is the problem and the potential solution
*/
const printDiagnostics = async () => {
const humanizeOptions: HumanizerOptions = {
round: true,
units: ['d', 'h', 'm'],
};
let uptime;
let entropy;
try {
uptime = humanizeDuration(process.uptime() * 1000, humanizeOptions);
entropy = (await fsp.readFile('/proc/sys/kernel/random/entropy_avail', 'utf8')).trim();
} catch (error) {
entropy = (error as Error).message;
}
const secureStorage = new Set();
for (let i = 0; i < 100; i++) {
const randID = nanoidSecure.customAlphabet(consts.noLookAlikesAlphabet, 4)();
if (!secureStorage.has(randID)) secureStorage.add(randID);
}
const nonsecureStorage = new Set();
for (let i = 0; i < 100; i++) {
const randID = nanoidNonSecure.customAlphabet(consts.noLookAlikesAlphabet, 4)();
if (!nonsecureStorage.has(randID)) nonsecureStorage.add(randID);
}
const osDistro = await getOsDistro();
console.error(noIdErrorMessage);
console.error(`Uptime: ${uptime}`);
console.error(`Entropy: ${entropy}`);
console.error(`Distro: ${osDistro}`);
console.error(`txAdmin: ${txEnv.txAdminVersion}`);
console.error(`FXServer: ${txEnv.fxServerVersion}`);
console.error(`ZAP: ${convars.isZapHosting}`);
console.error(`Pterodactyl: ${convars.isPterodactyl}`);
console.error(`Unique Test: secure ${secureStorage.size}/100, non-secure ${nonsecureStorage.size}/100`);
};
/**
* Check in a storage weather the ID is unique or not.
* @param {Set|Object} storage the Set or lowdb instance
* @param {String} id
* @param {String} lowdbTable
* @returns {Boolean} if is unique
*/
const checkUniqueness = (storage: IdStorageTypes, id: string, lowdbTable: string) => {
if (storage instanceof Set) {
return !storage.has(id);
} else {
return !storage.chain.get(lowdbTable).find({ id }).value();
}
};
/**
* Generates an unique whitelist ID, or throws an error
* @param {Set|Object} storage set or lowdb instance
* @returns {String} id
*/
export const genWhitelistRequestID = (storage: IdStorageTypes) => {
let attempts = 0;
while (attempts < maxAttempts) {
attempts++;
if (attempts > 5) globals.databus.txStatsData.randIDFailures++;
const randFunc = (attempts <= 5) ? nanoidSecure : nanoidNonSecure;
const id = 'R' + randFunc.customAlphabet(consts.noLookAlikesAlphabet, 4)();
if (checkUniqueness(storage, id, 'whitelistRequests')) {
return id;
}
}
printDiagnostics().catch();
throw new Error(noIdErrorMessage);
};
/**
* Generates an unique action ID, or throws an error
*/
export const genActionID = (storage: IdStorageTypes, actionType: string) => {
let attempts = 0;
while (attempts < maxAttempts) {
attempts++;
if (attempts > 5) globals.databus.txStatsData.randIDFailures++;
const randFunc = (attempts <= 5) ? nanoidSecure : nanoidNonSecure;
const id = actionType[0].toUpperCase()
+ randFunc.customAlphabet(consts.noLookAlikesAlphabet, 3)()
+ '-'
+ randFunc.customAlphabet(consts.noLookAlikesAlphabet, 4)();
if (checkUniqueness(storage, id, 'actions')) {
return id;
}
}
printDiagnostics().catch();
throw new Error(noIdErrorMessage);
};