diff --git a/dist/index.d.ts b/dist/cjs/index.d.ts similarity index 100% rename from dist/index.d.ts rename to dist/cjs/index.d.ts diff --git a/dist/index.js b/dist/cjs/index.js similarity index 100% rename from dist/index.js rename to dist/cjs/index.js diff --git a/dist/jwt.d.ts b/dist/cjs/jwt.d.ts similarity index 82% rename from dist/jwt.d.ts rename to dist/cjs/jwt.d.ts index a808ebf..c3a5a99 100644 --- a/dist/jwt.d.ts +++ b/dist/cjs/jwt.d.ts @@ -7,12 +7,15 @@ export default class JwtAuth { [key: string]: any; }, settings?: jwt.SignOptions, secretKey?: string): string; verifyJWT(token: string, secretKey?: string): jwt.JwtPayload | undefined; - decodeJWT(token: string): string | jwt.JwtPayload | null; - getJWTExpirationDate(token: string): any; - isJWTExpired(token: string): boolean | { + decodeJWT(token: string): jwt.JwtPayload; + getJWTExpirationDate(token: string): number | { valid: boolean; message: string; }; + isJWTExpired(token: string): { + valid: boolean; + message: string; + } | boolean; refreshJWT(token: string, settings?: jwt.SignOptions, secretKey?: string): string | { valid: boolean; message: string; diff --git a/dist/jwt.js b/dist/cjs/jwt.js similarity index 92% rename from dist/jwt.js rename to dist/cjs/jwt.js index 13852d5..a6e2350 100644 --- a/dist/jwt.js +++ b/dist/cjs/jwt.js @@ -38,7 +38,7 @@ class JwtAuth { return { valid: false, message: "Token is blacklisted." }; const vertoken = jwt.verify(token, secretKey); if (vertoken instanceof Object) { - return vertoken; + return (vertoken); } else { return undefined; @@ -51,7 +51,13 @@ class JwtAuth { decodeJWT(token) { if (this.blacklist.includes(token)) return { valid: false, message: "Token is blacklisted." }; - return jwt.decode(token); + const decoded = jwt.decode(token); + if (decoded instanceof Object) { + return decoded; + } + else { + return { valid: false, message: "Token is invalid." }; + } } getJWTExpirationDate(token) { if (this.blacklist.includes(token)) @@ -63,7 +69,9 @@ class JwtAuth { if (this.blacklist.includes(token)) return { valid: false, message: "Token is blacklisted." }; const expirationDate = this.getJWTExpirationDate(token); - return expirationDate < Date.now(); + if (expirationDate instanceof Object) + return expirationDate; + return expirationDate < (Date.now() / 1000); } refreshJWT(token, settings = {}, secretKey = this.JWTSecretKey) { if (this.blacklist.includes(token)) diff --git a/dist/passgen.d.ts b/dist/cjs/passgen.d.ts similarity index 100% rename from dist/passgen.d.ts rename to dist/cjs/passgen.d.ts diff --git a/dist/passgen.js b/dist/cjs/passgen.js similarity index 100% rename from dist/passgen.js rename to dist/cjs/passgen.js diff --git a/dist/passpolicy.d.ts b/dist/cjs/passpolicy.d.ts similarity index 72% rename from dist/passpolicy.d.ts rename to dist/cjs/passpolicy.d.ts index bbce5bd..d0665ea 100644 --- a/dist/passpolicy.d.ts +++ b/dist/cjs/passpolicy.d.ts @@ -11,16 +11,10 @@ export default class PassPolicy { }); validate(password: string): { valid: boolean; - message: string; - } | { - valid: boolean; - message?: undefined; + message?: string; }; CheckDifference(newPassword: string, oldPassword: string, neededDifference?: number): { valid: boolean; - message: string; - } | { - valid: boolean; - message?: undefined; + message?: string; }; } diff --git a/dist/passpolicy.js b/dist/cjs/passpolicy.js similarity index 100% rename from dist/passpolicy.js rename to dist/cjs/passpolicy.js diff --git a/dist/passwordcheck.d.ts b/dist/cjs/passwordcheck.d.ts similarity index 100% rename from dist/passwordcheck.d.ts rename to dist/cjs/passwordcheck.d.ts diff --git a/dist/passwordcheck.js b/dist/cjs/passwordcheck.js similarity index 92% rename from dist/passwordcheck.js rename to dist/cjs/passwordcheck.js index 1b67f4a..38df8e5 100644 --- a/dist/passwordcheck.js +++ b/dist/cjs/passwordcheck.js @@ -21,14 +21,14 @@ class PassCheck { } verifyPassword(password, hash) { return __awaiter(this, void 0, void 0, function* () { - return yield bcrypt_1.default.compare(password, hash); + return Promise.resolve(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; + return Promise.resolve(hash); }); } } diff --git a/dist/ratelimit.d.ts b/dist/cjs/ratelimit.d.ts similarity index 100% rename from dist/ratelimit.d.ts rename to dist/cjs/ratelimit.d.ts diff --git a/dist/ratelimit.js b/dist/cjs/ratelimit.js similarity index 100% rename from dist/ratelimit.js rename to dist/cjs/ratelimit.js diff --git a/dist/esm/index.d.ts b/dist/esm/index.d.ts new file mode 100644 index 0000000..b4336d0 --- /dev/null +++ b/dist/esm/index.d.ts @@ -0,0 +1,6 @@ +import PassCheck from "./passwordcheck"; +import JwtAuth from "./jwt"; +import PassPolicy from "./passpolicy"; +import RateLimit from "./ratelimit"; +import PasswordGenerator from "./passgen"; +export { PassCheck, JwtAuth, PassPolicy, RateLimit, PasswordGenerator }; diff --git a/dist/esm/index.js b/dist/esm/index.js new file mode 100644 index 0000000..b4336d0 --- /dev/null +++ b/dist/esm/index.js @@ -0,0 +1,6 @@ +import PassCheck from "./passwordcheck"; +import JwtAuth from "./jwt"; +import PassPolicy from "./passpolicy"; +import RateLimit from "./ratelimit"; +import PasswordGenerator from "./passgen"; +export { PassCheck, JwtAuth, PassPolicy, RateLimit, PasswordGenerator }; diff --git a/dist/esm/jwt.d.ts b/dist/esm/jwt.d.ts new file mode 100644 index 0000000..c3a5a99 --- /dev/null +++ b/dist/esm/jwt.d.ts @@ -0,0 +1,40 @@ +import * as jwt from 'jsonwebtoken'; +export default class JwtAuth { + private JWTSecretKey; + private blacklist; + constructor(JWTSecretKey: string); + generateJWT(payload: { + [key: string]: any; + }, settings?: jwt.SignOptions, secretKey?: string): string; + verifyJWT(token: string, secretKey?: string): jwt.JwtPayload | undefined; + decodeJWT(token: string): jwt.JwtPayload; + getJWTExpirationDate(token: string): number | { + valid: boolean; + message: string; + }; + isJWTExpired(token: string): { + valid: boolean; + message: string; + } | boolean; + refreshJWT(token: string, settings?: jwt.SignOptions, secretKey?: string): string | { + valid: boolean; + message: string; + }; + BlackListJWT(token: string): { + valid: boolean; + message: string; + }; + ClearBlackList(): { + valid: boolean; + message: string; + }; + GetBlackList(): string[]; + RemoveFromBlackList(token: string): { + valid: boolean; + message: string; + }; + IsBlackListed(token: string): { + valid: boolean; + message: string; + }; +} diff --git a/dist/esm/jwt.js b/dist/esm/jwt.js new file mode 100644 index 0000000..84fed93 --- /dev/null +++ b/dist/esm/jwt.js @@ -0,0 +1,103 @@ +import * as jwt from 'jsonwebtoken'; +export default 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." }; + const decoded = jwt.decode(token); + if (decoded instanceof Object) { + return decoded; + } + else { + return { valid: false, message: "Token is invalid." }; + } + } + 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); + if (expirationDate instanceof Object) + return expirationDate; + return expirationDate < (Date.now() / 1000); + } + 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." }; + } +} diff --git a/dist/esm/package.json b/dist/esm/package.json new file mode 100644 index 0000000..1632c2c --- /dev/null +++ b/dist/esm/package.json @@ -0,0 +1 @@ +{"type": "module"} \ No newline at end of file diff --git a/dist/esm/passgen.d.ts b/dist/esm/passgen.d.ts new file mode 100644 index 0000000..2ad447b --- /dev/null +++ b/dist/esm/passgen.d.ts @@ -0,0 +1,13 @@ +export default class PasswordGenerator { + private options; + constructor(options: { + minLength: number; + maxLength: number; + minLower: number; + minUpper: number; + minNum: number; + minSpecial: number; + specialChars: string; + }); + Generate(length?: number): string; +} diff --git a/dist/esm/passgen.js b/dist/esm/passgen.js new file mode 100644 index 0000000..4e039dc --- /dev/null +++ b/dist/esm/passgen.js @@ -0,0 +1,48 @@ +export default 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; + } +} diff --git a/dist/esm/passpolicy.d.ts b/dist/esm/passpolicy.d.ts new file mode 100644 index 0000000..d0665ea --- /dev/null +++ b/dist/esm/passpolicy.d.ts @@ -0,0 +1,20 @@ +export default class PassPolicy { + private options; + constructor(options: { + minLength: number; + maxLength: number; + minLower: number; + minUpper: number; + minNum: number; + minSpecial: number; + specialChars: string; + }); + validate(password: string): { + valid: boolean; + message?: string; + }; + CheckDifference(newPassword: string, oldPassword: string, neededDifference?: number): { + valid: boolean; + message?: string; + }; +} diff --git a/dist/esm/passpolicy.js b/dist/esm/passpolicy.js new file mode 100644 index 0000000..8daeed7 --- /dev/null +++ b/dist/esm/passpolicy.js @@ -0,0 +1,71 @@ +export default 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 }; + } +} diff --git a/dist/esm/passwordcheck.d.ts b/dist/esm/passwordcheck.d.ts new file mode 100644 index 0000000..502a913 --- /dev/null +++ b/dist/esm/passwordcheck.d.ts @@ -0,0 +1,15 @@ +export default class PassCheck { + private BcryptSaltRounds; + private PassPolicy; + constructor(BcryptSaltRounds: number, PassPolicyOptions: { + minLength: number; + maxLength: number; + minLower: number; + minUpper: number; + minNum: number; + minSpecial: number; + specialChars: string; + }); + verifyPassword(password: string, hash: string): Promise; + hashPassword(password: string): Promise; +} diff --git a/dist/esm/passwordcheck.js b/dist/esm/passwordcheck.js new file mode 100644 index 0000000..9057f32 --- /dev/null +++ b/dist/esm/passwordcheck.js @@ -0,0 +1,29 @@ +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()); + }); +}; +import bcrypt from 'bcrypt'; +import PassPolicy from './passpolicy'; +export default class PassCheck { + constructor(BcryptSaltRounds, PassPolicyOptions) { + this.BcryptSaltRounds = BcryptSaltRounds; + this.PassPolicy = new PassPolicy(PassPolicyOptions); + } + verifyPassword(password, hash) { + return __awaiter(this, void 0, void 0, function* () { + return Promise.resolve(yield bcrypt.compare(password, hash)); + }); + } + hashPassword(password) { + return __awaiter(this, void 0, void 0, function* () { + const salt = yield bcrypt.genSalt(this.BcryptSaltRounds); + const hash = yield bcrypt.hash(password, salt); + return Promise.resolve(hash); + }); + } +} diff --git a/dist/esm/ratelimit.d.ts b/dist/esm/ratelimit.d.ts new file mode 100644 index 0000000..10ad027 --- /dev/null +++ b/dist/esm/ratelimit.d.ts @@ -0,0 +1,46 @@ +type Event = { + name: string; + cooldown: number; + maxAttempts: number; + lastAttempt?: number; + attempts?: number[]; +}; +type user = { + token: string; + events: { + [name: string]: Event; + }; +}; +export default class RateLimit { + users: { + [token: string]: user; + }; + events: { + [name: string]: Event; + }; + constructor(users?: { + [token: string]: user; + }, events?: { + [name: string]: Event; + }); + addEvent(event: Event): boolean; + removeEvent(name: string): boolean; + addUser(token: string): boolean; + removeUser(token: string): boolean; + attempt(token: string, name: string): boolean; + getEvents(): { + [name: string]: Event; + }; + getUsers(): { + [token: string]: user; + }; + getEvent(name: string): Event; + getUser(token: string): user; + remainingAttempts(token: string, name: string): number; + resetAttempts(token: string, name: string): boolean; + resetAllAttempts(token: string): boolean; + resetAllUsers(): boolean; + resetEvent(name: string): boolean; + resetUser(token: string): boolean; +} +export {}; diff --git a/dist/esm/ratelimit.js b/dist/esm/ratelimit.js new file mode 100644 index 0000000..31b49f6 --- /dev/null +++ b/dist/esm/ratelimit.js @@ -0,0 +1,163 @@ +export default 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; + } + } +} diff --git a/dist/types/index.d.ts b/dist/types/index.d.ts new file mode 100644 index 0000000..b4336d0 --- /dev/null +++ b/dist/types/index.d.ts @@ -0,0 +1,6 @@ +import PassCheck from "./passwordcheck"; +import JwtAuth from "./jwt"; +import PassPolicy from "./passpolicy"; +import RateLimit from "./ratelimit"; +import PasswordGenerator from "./passgen"; +export { PassCheck, JwtAuth, PassPolicy, RateLimit, PasswordGenerator }; diff --git a/dist/types/jwt.d.ts b/dist/types/jwt.d.ts new file mode 100644 index 0000000..c3a5a99 --- /dev/null +++ b/dist/types/jwt.d.ts @@ -0,0 +1,40 @@ +import * as jwt from 'jsonwebtoken'; +export default class JwtAuth { + private JWTSecretKey; + private blacklist; + constructor(JWTSecretKey: string); + generateJWT(payload: { + [key: string]: any; + }, settings?: jwt.SignOptions, secretKey?: string): string; + verifyJWT(token: string, secretKey?: string): jwt.JwtPayload | undefined; + decodeJWT(token: string): jwt.JwtPayload; + getJWTExpirationDate(token: string): number | { + valid: boolean; + message: string; + }; + isJWTExpired(token: string): { + valid: boolean; + message: string; + } | boolean; + refreshJWT(token: string, settings?: jwt.SignOptions, secretKey?: string): string | { + valid: boolean; + message: string; + }; + BlackListJWT(token: string): { + valid: boolean; + message: string; + }; + ClearBlackList(): { + valid: boolean; + message: string; + }; + GetBlackList(): string[]; + RemoveFromBlackList(token: string): { + valid: boolean; + message: string; + }; + IsBlackListed(token: string): { + valid: boolean; + message: string; + }; +} diff --git a/dist/types/passgen.d.ts b/dist/types/passgen.d.ts new file mode 100644 index 0000000..2ad447b --- /dev/null +++ b/dist/types/passgen.d.ts @@ -0,0 +1,13 @@ +export default class PasswordGenerator { + private options; + constructor(options: { + minLength: number; + maxLength: number; + minLower: number; + minUpper: number; + minNum: number; + minSpecial: number; + specialChars: string; + }); + Generate(length?: number): string; +} diff --git a/dist/types/passpolicy.d.ts b/dist/types/passpolicy.d.ts new file mode 100644 index 0000000..d0665ea --- /dev/null +++ b/dist/types/passpolicy.d.ts @@ -0,0 +1,20 @@ +export default class PassPolicy { + private options; + constructor(options: { + minLength: number; + maxLength: number; + minLower: number; + minUpper: number; + minNum: number; + minSpecial: number; + specialChars: string; + }); + validate(password: string): { + valid: boolean; + message?: string; + }; + CheckDifference(newPassword: string, oldPassword: string, neededDifference?: number): { + valid: boolean; + message?: string; + }; +} diff --git a/dist/types/passwordcheck.d.ts b/dist/types/passwordcheck.d.ts new file mode 100644 index 0000000..502a913 --- /dev/null +++ b/dist/types/passwordcheck.d.ts @@ -0,0 +1,15 @@ +export default class PassCheck { + private BcryptSaltRounds; + private PassPolicy; + constructor(BcryptSaltRounds: number, PassPolicyOptions: { + minLength: number; + maxLength: number; + minLower: number; + minUpper: number; + minNum: number; + minSpecial: number; + specialChars: string; + }); + verifyPassword(password: string, hash: string): Promise; + hashPassword(password: string): Promise; +} diff --git a/dist/types/ratelimit.d.ts b/dist/types/ratelimit.d.ts new file mode 100644 index 0000000..10ad027 --- /dev/null +++ b/dist/types/ratelimit.d.ts @@ -0,0 +1,46 @@ +type Event = { + name: string; + cooldown: number; + maxAttempts: number; + lastAttempt?: number; + attempts?: number[]; +}; +type user = { + token: string; + events: { + [name: string]: Event; + }; +}; +export default class RateLimit { + users: { + [token: string]: user; + }; + events: { + [name: string]: Event; + }; + constructor(users?: { + [token: string]: user; + }, events?: { + [name: string]: Event; + }); + addEvent(event: Event): boolean; + removeEvent(name: string): boolean; + addUser(token: string): boolean; + removeUser(token: string): boolean; + attempt(token: string, name: string): boolean; + getEvents(): { + [name: string]: Event; + }; + getUsers(): { + [token: string]: user; + }; + getEvent(name: string): Event; + getUser(token: string): user; + remainingAttempts(token: string, name: string): number; + resetAttempts(token: string, name: string): boolean; + resetAllAttempts(token: string): boolean; + resetAllUsers(): boolean; + resetEvent(name: string): boolean; + resetUser(token: string): boolean; +} +export {}; diff --git a/package.json b/package.json index 404eff5..6bd37aa 100644 --- a/package.json +++ b/package.json @@ -1,14 +1,17 @@ { "name": "auth-guardian", - "version": "2.1.0", + "version": "2.1.2", "description": "auth-guardian a library for enhancing application security", - "main": "./dist/index.js", - "types": "./dist/index.d.ts", - "typings": "./dist/index.d.ts", + "main": "./dist/cjs/index.js", + "module": "dist/esm/index.js", "scripts": { "test": "jest", - "build": "tsc" + "build": "tsc", + "compile": "tsc -b ./tsconfig.cjs.json ./tsconfig.esm.json ./tsconfig.types.json" }, + "files": [ + "dist" + ], "repository": { "type": "git", "url": "https://github.com/kajvan/guardian" @@ -33,5 +36,13 @@ "jest": "^29.7.0", "ts-jest": "^29.1.2", "ts-node": "^10.9.2" + }, + "exports": { + ".": { + "types": "./dist/types/index.d.ts", + "require": "./dist/cjs/index.js", + "import": "./dist/esm/index.js", + "default": "./dist/esm/index.js" + } } } diff --git a/src/passwordcheck.ts b/src/passwordcheck.ts index 34e4715..65da9ec 100644 --- a/src/passwordcheck.ts +++ b/src/passwordcheck.ts @@ -10,12 +10,12 @@ export default class PassCheck{ } async verifyPassword(password: string, hash: string): Promise { - return await bcrypt.compare(password, hash); + return Promise.resolve(await bcrypt.compare(password, hash)); } async hashPassword(password: string): Promise { const salt = await bcrypt.genSalt(this.BcryptSaltRounds); const hash = await bcrypt.hash(password, salt); - return hash; + return Promise.resolve(hash); } } \ No newline at end of file diff --git a/tsconfig.cjs.json b/tsconfig.cjs.json new file mode 100644 index 0000000..676f0a4 --- /dev/null +++ b/tsconfig.cjs.json @@ -0,0 +1,7 @@ +{ + "extends": "./tsconfig.json", + "compilerOptions": { + "outDir": "./dist/cjs", + "module": "commonjs" + } + } \ No newline at end of file diff --git a/tsconfig.esm.json b/tsconfig.esm.json new file mode 100644 index 0000000..3ca28be --- /dev/null +++ b/tsconfig.esm.json @@ -0,0 +1,7 @@ +{ + "extends": "./tsconfig.json", + "compilerOptions": { + "outDir": "./dist/esm", + "module": "esnext" + } + } \ No newline at end of file diff --git a/tsconfig.json b/tsconfig.json index 3322677..956b515 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -24,25 +24,6 @@ // "useDefineForClassFields": true, /* Emit ECMAScript-standard-compliant class fields. */ // "moduleDetection": "auto", /* Control what method is used to detect module-format JS files. */ - /* Modules */ - "module": "commonjs", /* Specify what module code is generated. */ - "rootDir": "./src", /* Specify the root folder within your source files. */ - // "moduleResolution": "node10", /* Specify how TypeScript looks up a file from a given module specifier. */ - // "baseUrl": "./", /* Specify the base directory to resolve non-relative module names. */ - // "paths": {}, /* Specify a set of entries that re-map imports to additional lookup locations. */ - // "rootDirs": [], /* Allow multiple folders to be treated as one when resolving modules. */ - // "typeRoots": [], /* Specify multiple folders that act like './node_modules/@types'. */ - // "types": [], /* Specify type package names to be included without being referenced in a source file. */ - // "allowUmdGlobalAccess": true, /* Allow accessing UMD globals from modules. */ - // "moduleSuffixes": [], /* List of file name suffixes to search when resolving a module. */ - // "allowImportingTsExtensions": true, /* Allow imports to include TypeScript file extensions. Requires '--moduleResolution bundler' and either '--noEmit' or '--emitDeclarationOnly' to be set. */ - // "resolvePackageJsonExports": true, /* Use the package.json 'exports' field when resolving package imports. */ - // "resolvePackageJsonImports": true, /* Use the package.json 'imports' field when resolving imports. */ - // "customConditions": [], /* Conditions to set in addition to the resolver-specific defaults when resolving imports. */ - // "resolveJsonModule": true, /* Enable importing .json files. */ - // "allowArbitraryExtensions": true, /* Enable importing files with any extension, provided a declaration file is present. */ - // "noResolve": true, /* Disallow 'import's, 'require's or ''s from expanding the number of files TypeScript should add to a project. */ - /* JavaScript Support */ // "allowJs": true, /* Allow JavaScript files to be a part of your program. Use the 'checkJS' option to get errors from these files. */ // "checkJs": true, /* Enable error reporting in type-checked JavaScript files. */ diff --git a/tsconfig.types.json b/tsconfig.types.json new file mode 100644 index 0000000..5fbd3bf --- /dev/null +++ b/tsconfig.types.json @@ -0,0 +1,8 @@ +{ + "extends": "./tsconfig.json", + "compilerOptions": { + "outDir": "./dist/types", + "declaration": true, + "emitDeclarationOnly": true + } + } \ No newline at end of file