now typescript

This commit is contained in:
2024-02-03 00:35:29 +01:00
parent 3298f85120
commit a8cce75725
24 changed files with 4801 additions and 269 deletions
+16
View File
@@ -0,0 +1,16 @@
"use strict";
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.PasswordGenerator = exports.RateLimit = exports.PassPolicy = exports.JwtAuth = exports.PassCheck = void 0;
const passwordcheck_1 = __importDefault(require("./passwordcheck"));
exports.PassCheck = passwordcheck_1.default;
const jsonwebtoken_1 = __importDefault(require("jsonwebtoken"));
exports.JwtAuth = jsonwebtoken_1.default;
const passpolicy_1 = __importDefault(require("./passpolicy"));
exports.PassPolicy = passpolicy_1.default;
const ratelimit_1 = __importDefault(require("./ratelimit"));
exports.RateLimit = ratelimit_1.default;
const passgen_1 = __importDefault(require("./passgen"));
exports.PasswordGenerator = passgen_1.default;
Vendored
+121
View File
@@ -0,0 +1,121 @@
"use strict";
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
var desc = Object.getOwnPropertyDescriptor(m, k);
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
desc = { enumerable: true, get: function() { return m[k]; } };
}
Object.defineProperty(o, k2, desc);
}) : (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
o[k2] = m[k];
}));
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
Object.defineProperty(o, "default", { enumerable: true, value: v });
}) : function(o, v) {
o["default"] = v;
});
var __importStar = (this && this.__importStar) || function (mod) {
if (mod && mod.__esModule) return mod;
var result = {};
if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
__setModuleDefault(result, mod);
return result;
};
Object.defineProperty(exports, "__esModule", { value: true });
const jwt = __importStar(require("jsonwebtoken"));
class JwtAuth {
constructor(JWTSecretKey) {
this.JWTSecretKey = JWTSecretKey;
this.blacklist = [];
}
generateJWT(payload, settings = {}, secretKey = this.JWTSecretKey) {
return jwt.sign(payload, secretKey, settings);
}
verifyJWT(token, secretKey = this.JWTSecretKey) {
try {
if (this.blacklist.includes(token))
return { valid: false, message: "Token is blacklisted." };
const vertoken = jwt.verify(token, secretKey);
if (vertoken instanceof Object) {
return vertoken;
}
else {
return undefined;
}
}
catch (error) {
return { valid: false, message: "Token is invalid." };
}
}
decodeJWT(token) {
if (this.blacklist.includes(token))
return { valid: false, message: "Token is blacklisted." };
return jwt.decode(token);
}
getJWTExpirationDate(token) {
if (this.blacklist.includes(token))
return { valid: false, message: "Token is blacklisted." };
const decoded = this.decodeJWT(token);
return decoded.exp;
}
isJWTExpired(token) {
if (this.blacklist.includes(token))
return { valid: false, message: "Token is blacklisted." };
const expirationDate = this.getJWTExpirationDate(token);
return expirationDate < Date.now();
}
refreshJWT(token, settings = {}, secretKey = this.JWTSecretKey) {
if (this.blacklist.includes(token))
return { valid: false, message: "Token is blacklisted." };
const decoded = this.verifyJWT(token, secretKey);
if (decoded instanceof Object) {
if (decoded.valid == false)
return { valid: false, message: "Token is invalid." };
let payLoadArray = {};
if (decoded instanceof Object) {
payLoadArray = decoded;
}
else {
return { valid: false, message: "Token is invalid." };
}
const newToken = this.generateJWT(payLoadArray, settings, secretKey);
return newToken;
}
return { valid: false, message: "Token is invalid." };
}
BlackListJWT(token) {
//check if token is already blacklisted
if (this.blacklist.includes(token)) {
return { valid: false, message: "Token is already blacklisted." };
}
//add token to blacklist
this.blacklist.push(token);
return { valid: true, message: "Token successfully blacklisted." };
}
ClearBlackList() {
//clear blacklist
this.blacklist = [];
return { valid: true, message: "Blacklist successfully cleared." };
}
GetBlackList() {
//return blacklist
return this.blacklist;
}
RemoveFromBlackList(token) {
//remove token from blacklist
if (this.blacklist.includes(token)) {
this.blacklist = this.blacklist.filter((item) => item !== token);
return { valid: true, message: "Token successfully removed from blacklist." };
}
return { valid: false, message: "Token is not blacklisted." };
}
IsBlackListed(token) {
//check if token is blacklisted
if (this.blacklist.includes(token)) {
return { valid: true, message: "Token is blacklisted." };
}
return { valid: false, message: "Token is not blacklisted." };
}
}
exports.default = JwtAuth;
+51
View File
@@ -0,0 +1,51 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
class PasswordGenerator {
constructor(options) {
const defaultOptions = {
minLength: 6,
maxLength: 32,
minLower: 2,
minUpper: 2,
minNum: 2,
minSpecial: 3,
specialChars: "!@#$%^&*()_+~`|}{[]:;?><,./-=",
};
this.options = Object.assign(Object.assign({}, defaultOptions), options);
}
Generate(length = 0) {
// Generate random password that complies with the options
const { minLength, maxLength, minLower, minUpper, minNum, minSpecial, specialChars } = this.options;
let pass = "";
let lowerRegex = 'abcdefghijklmnopqrstuvwxyz';
let upperRegex = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ';
let numRegex = '0123456789';
// Generate password
//generate random length
if (length === undefined || length < minLength || length > maxLength || length === 0) {
length = Math.floor(Math.random() * (maxLength - minLength + 1) + minLength);
}
//generate random length for each character type
let lowerLength = Math.floor(Math.random() * (length - minLower - minUpper - minNum - minSpecial + 1) + minLower);
let upperLength = Math.floor(Math.random() * (length - lowerLength - minUpper - minNum - minSpecial + 1) + minUpper);
let numLength = Math.floor(Math.random() * (length - lowerLength - upperLength - minNum - minSpecial + 1) + minNum);
let specialLength = Math.floor(Math.random() * (length - lowerLength - upperLength - numLength - minSpecial + 1) + minSpecial);
//generate random characters
for (let i = 0; i < lowerLength; i++) {
pass += lowerRegex[Math.floor(Math.random() * lowerRegex.length)];
}
for (let i = 0; i < upperLength; i++) {
pass += upperRegex[Math.floor(Math.random() * upperRegex.length)];
}
for (let i = 0; i < numLength; i++) {
pass += numRegex[Math.floor(Math.random() * numRegex.length)];
}
for (let i = 0; i < specialLength; i++) {
pass += specialChars[Math.floor(Math.random() * specialChars.length)];
}
//shuffle password
pass = pass.split('').sort(function () { return 0.5 - Math.random(); }).join('');
return pass;
}
}
exports.default = PasswordGenerator;
+74
View File
@@ -0,0 +1,74 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
class PassPolicy {
constructor(options) {
const defaultOptions = {
minLength: 6,
maxLength: 32,
minLower: 2,
minUpper: 2,
minNum: 2,
minSpecial: 3,
specialChars: "!@#$%^&*()_+~`|}{[]:;?><,./-=",
};
this.options = Object.assign(Object.assign({}, defaultOptions), options);
}
validate(password) {
const { minLength, maxLength, minLower, minUpper, minNum, minSpecial, specialChars } = this.options;
if (password.length < minLength || password.length > maxLength) {
return { valid: false, message: "Password length does not meet requirements." };
}
const lowerRegex = /[a-z]/g;
const upperRegex = /[A-Z]/g;
const numRegex = /[0-9]/g;
const specialRegex = new RegExp(`[${specialChars.replace(/[-/\\^$*+?.()|[\]{}]/g, "\\$&")}]`, "g");
const lowerCount = (password.match(lowerRegex) || []).length;
const upperCount = (password.match(upperRegex) || []).length;
const numCount = (password.match(numRegex) || []).length;
const specialCount = (password.match(specialRegex) || []).length;
if (lowerCount < minLower) {
return { valid: false, message: "Password must contain at least " + minLower + " lowercase letter(s)." };
}
if (upperCount < minUpper) {
return { valid: false, message: "Password must contain at least " + minUpper + " uppercase letter(s)." };
}
if (numCount < minNum) {
return { valid: false, message: "Password must contain at least " + minNum + " digit(s)." };
}
if (specialCount < minSpecial) {
return { valid: false, message: "Password must contain at least " + minSpecial + " special character(s)." };
}
return { valid: true };
}
CheckDifference(newPassword, oldPassword, neededDifference = 3) {
//check if new password is different from old password
if (newPassword === oldPassword) {
return { valid: false, message: "New password must be different from old password." };
}
//check how many characters are different
let diffCount = 0;
//check if new password is longer than old password
if (newPassword.length > oldPassword.length) {
for (let i = 0; i < oldPassword.length; i++) {
if (newPassword[i] != oldPassword[i]) {
diffCount++;
}
}
diffCount += newPassword.length - oldPassword.length;
}
else {
for (let i = 0; i < newPassword.length; i++) {
if (newPassword[i] != oldPassword[i]) {
diffCount++;
}
}
diffCount += oldPassword.length - newPassword.length;
}
//check if difference is enough
if (diffCount < neededDifference) {
return { valid: false, message: "New password must be different from old password by at least " + neededDifference + " characters." };
}
return { valid: true };
}
}
exports.default = PassPolicy;
+35
View File
@@ -0,0 +1,35 @@
"use strict";
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
return new (P || (P = Promise))(function (resolve, reject) {
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
step((generator = generator.apply(thisArg, _arguments || [])).next());
});
};
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
const bcrypt_1 = __importDefault(require("bcrypt"));
const passpolicy_1 = __importDefault(require("./passpolicy"));
class PassCheck {
constructor(BcryptSaltRounds, PassPolicyOptions) {
this.BcryptSaltRounds = BcryptSaltRounds;
this.PassPolicy = new passpolicy_1.default(PassPolicyOptions);
}
verifyPassword(password, hash) {
return __awaiter(this, void 0, void 0, function* () {
return yield bcrypt_1.default.compare(password, hash);
});
}
hashPassword(password) {
return __awaiter(this, void 0, void 0, function* () {
const salt = yield bcrypt_1.default.genSalt(this.BcryptSaltRounds);
const hash = yield bcrypt_1.default.hash(password, salt);
return hash;
});
}
}
exports.default = PassCheck;
+166
View File
@@ -0,0 +1,166 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
class RateLimit {
constructor(users = {}, events = {}) {
this.users = users;
this.events = events;
this.users = users;
this.events = events;
}
addEvent(event) {
try {
this.events[event.name] = event;
//add event to all users
for (const token in this.users) {
this.users[token].events[event.name] = event;
}
return true;
}
catch (error) {
return false;
}
}
removeEvent(name) {
try {
delete this.events[name];
//remove event from all users
for (const token in this.users) {
delete this.users[token].events[name];
}
return true;
}
catch (error) {
return false;
}
}
addUser(token) {
try {
this.users[token] = { token, events: this.events };
return true;
}
catch (error) {
return false;
}
}
removeUser(token) {
try {
delete this.users[token];
return true;
}
catch (error) {
return false;
}
}
attempt(token, name) {
try {
if (!this.users[token] || !this.users[token].events[name]) {
return false;
}
const event = this.users[token].events[name];
if (event.attempts === undefined) {
event.attempts = [];
}
const now = Date.now();
if (event.lastAttempt && now - event.lastAttempt < event.cooldown) {
return false;
}
event.lastAttempt = now;
event.attempts.push(now);
if (event.attempts.length > event.maxAttempts) {
return false;
}
return true;
}
catch (error) {
return false;
}
}
getEvents() {
return this.events;
}
getUsers() {
return this.users;
}
getEvent(name) {
return this.events[name];
}
getUser(token) {
return this.users[token];
}
remainingAttempts(token, name) {
try {
if (!this.users[token] || !this.users[token].events[name]) {
return -1;
}
const event = this.users[token].events[name];
if (event.attempts === undefined) {
event.attempts = [];
}
return event.maxAttempts - event.attempts.length;
}
catch (error) {
return -1;
}
}
resetAttempts(token, name) {
try {
if (!this.users[token] || !this.users[token].events[name]) {
return false;
}
const event = this.users[token].events[name];
event.attempts = [];
return true;
}
catch (error) {
return false;
}
}
resetAllAttempts(token) {
try {
if (!this.users[token]) {
return false;
}
for (const name in this.users[token].events) {
this.resetAttempts(token, name);
}
return true;
}
catch (error) {
return false;
}
}
resetAllUsers() {
try {
for (const token in this.users) {
this.resetAllAttempts(token);
}
return true;
}
catch (error) {
return false;
}
}
resetEvent(name) {
try {
for (const token in this.users) {
this.resetAttempts(token, name);
}
return true;
}
catch (error) {
return false;
}
}
resetUser(token) {
try {
for (const name in this.users[token].events) {
this.resetAttempts(token, name);
}
return true;
}
catch (error) {
return false;
}
}
}
exports.default = RateLimit;