@naman_deep_singh/security 1.1.0 → 1.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +358 -175
- package/dist/cjs/core/crypto/cryptoManager.d.ts +111 -0
- package/dist/cjs/core/crypto/cryptoManager.js +185 -0
- package/dist/cjs/core/crypto/index.d.ts +5 -4
- package/dist/cjs/core/crypto/index.js +12 -4
- package/dist/cjs/core/jwt/extractToken.d.ts +2 -2
- package/dist/cjs/core/jwt/extractToken.js +12 -7
- package/dist/cjs/core/jwt/generateTokens.d.ts +3 -6
- package/dist/cjs/core/jwt/generateTokens.js +10 -3
- package/dist/cjs/core/jwt/index.d.ts +1 -0
- package/dist/cjs/core/jwt/index.js +1 -0
- package/dist/cjs/core/jwt/jwtManager.d.ts +66 -0
- package/dist/cjs/core/jwt/jwtManager.js +319 -0
- package/dist/cjs/core/jwt/signToken.d.ts +1 -1
- package/dist/cjs/core/jwt/types.d.ts +22 -0
- package/dist/cjs/core/jwt/types.js +2 -0
- package/dist/cjs/core/jwt/validateToken.d.ts +1 -1
- package/dist/cjs/core/jwt/verify.d.ts +12 -7
- package/dist/cjs/core/jwt/verify.js +23 -3
- package/dist/cjs/core/password/passwordManager.d.ts +29 -0
- package/dist/cjs/core/password/passwordManager.js +242 -0
- package/dist/cjs/index.d.ts +11 -9
- package/dist/cjs/interfaces/jwt.interface.d.ts +47 -0
- package/dist/cjs/interfaces/jwt.interface.js +2 -0
- package/dist/cjs/interfaces/password.interface.d.ts +60 -0
- package/dist/cjs/interfaces/password.interface.js +2 -0
- package/dist/esm/core/crypto/cryptoManager.d.ts +111 -0
- package/dist/esm/core/crypto/cryptoManager.js +180 -0
- package/dist/esm/core/crypto/index.d.ts +5 -4
- package/dist/esm/core/crypto/index.js +5 -4
- package/dist/esm/core/jwt/extractToken.d.ts +2 -2
- package/dist/esm/core/jwt/extractToken.js +12 -7
- package/dist/esm/core/jwt/generateTokens.d.ts +3 -6
- package/dist/esm/core/jwt/generateTokens.js +10 -3
- package/dist/esm/core/jwt/index.d.ts +1 -0
- package/dist/esm/core/jwt/index.js +1 -0
- package/dist/esm/core/jwt/jwtManager.d.ts +66 -0
- package/dist/esm/core/jwt/jwtManager.js +312 -0
- package/dist/esm/core/jwt/signToken.d.ts +1 -1
- package/dist/esm/core/jwt/types.d.ts +22 -0
- package/dist/esm/core/jwt/types.js +1 -0
- package/dist/esm/core/jwt/validateToken.d.ts +1 -1
- package/dist/esm/core/jwt/verify.d.ts +12 -7
- package/dist/esm/core/jwt/verify.js +20 -2
- package/dist/esm/core/password/passwordManager.d.ts +29 -0
- package/dist/esm/core/password/passwordManager.js +235 -0
- package/dist/esm/index.d.ts +11 -9
- package/dist/esm/interfaces/jwt.interface.d.ts +47 -0
- package/dist/esm/interfaces/jwt.interface.js +1 -0
- package/dist/esm/interfaces/password.interface.d.ts +60 -0
- package/dist/esm/interfaces/password.interface.js +1 -0
- package/dist/types/core/crypto/cryptoManager.d.ts +111 -0
- package/dist/types/core/crypto/index.d.ts +5 -4
- package/dist/types/core/jwt/extractToken.d.ts +2 -2
- package/dist/types/core/jwt/generateTokens.d.ts +3 -6
- package/dist/types/core/jwt/index.d.ts +1 -0
- package/dist/types/core/jwt/jwtManager.d.ts +66 -0
- package/dist/types/core/jwt/signToken.d.ts +1 -1
- package/dist/types/core/jwt/types.d.ts +22 -0
- package/dist/types/core/jwt/validateToken.d.ts +1 -1
- package/dist/types/core/jwt/verify.d.ts +12 -7
- package/dist/types/core/password/passwordManager.d.ts +29 -0
- package/dist/types/index.d.ts +11 -9
- package/dist/types/interfaces/jwt.interface.d.ts +47 -0
- package/dist/types/interfaces/password.interface.d.ts +60 -0
- package/package.json +1 -1
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
import { JwtPayload, Secret } from "jsonwebtoken";
|
|
2
|
+
import { ITokenManager, TokenPair, AccessToken, RefreshToken, JWTConfig, TokenValidationOptions } from "../../interfaces/jwt.interface";
|
|
3
|
+
export declare class JWTManager implements ITokenManager {
|
|
4
|
+
private accessSecret;
|
|
5
|
+
private refreshSecret;
|
|
6
|
+
private accessExpiry;
|
|
7
|
+
private refreshExpiry;
|
|
8
|
+
private cache?;
|
|
9
|
+
constructor(config: JWTConfig);
|
|
10
|
+
/**
|
|
11
|
+
* Generate both access and refresh tokens
|
|
12
|
+
*/
|
|
13
|
+
generateTokens(payload: Record<string, unknown>): Promise<TokenPair>;
|
|
14
|
+
/**
|
|
15
|
+
* Generate access token
|
|
16
|
+
*/
|
|
17
|
+
generateAccessToken(payload: Record<string, unknown>): Promise<AccessToken>;
|
|
18
|
+
/**
|
|
19
|
+
* Generate refresh token
|
|
20
|
+
*/
|
|
21
|
+
generateRefreshToken(payload: Record<string, unknown>): Promise<RefreshToken>;
|
|
22
|
+
/**
|
|
23
|
+
* Verify access token
|
|
24
|
+
*/
|
|
25
|
+
verifyAccessToken(token: string): Promise<JwtPayload | string>;
|
|
26
|
+
/**
|
|
27
|
+
* Verify refresh token
|
|
28
|
+
*/
|
|
29
|
+
verifyRefreshToken(token: string): Promise<JwtPayload | string>;
|
|
30
|
+
/**
|
|
31
|
+
* Decode token without verification
|
|
32
|
+
*/
|
|
33
|
+
decodeToken(token: string, complete?: boolean): JwtPayload | string | null;
|
|
34
|
+
/**
|
|
35
|
+
* Extract token from Authorization header
|
|
36
|
+
*/
|
|
37
|
+
extractTokenFromHeader(authHeader: string): string | null;
|
|
38
|
+
/**
|
|
39
|
+
* Validate token without throwing exceptions
|
|
40
|
+
*/
|
|
41
|
+
validateToken(token: string, secret: Secret, options?: TokenValidationOptions): boolean;
|
|
42
|
+
/**
|
|
43
|
+
* Rotate refresh token
|
|
44
|
+
*/
|
|
45
|
+
rotateRefreshToken(oldToken: string): Promise<RefreshToken>;
|
|
46
|
+
/**
|
|
47
|
+
* Check if token is expired
|
|
48
|
+
*/
|
|
49
|
+
isTokenExpired(token: string): boolean;
|
|
50
|
+
/**
|
|
51
|
+
* Get token expiration date
|
|
52
|
+
*/
|
|
53
|
+
getTokenExpiration(token: string): Date | null;
|
|
54
|
+
/**
|
|
55
|
+
* Clear token cache
|
|
56
|
+
*/
|
|
57
|
+
clearCache(): void;
|
|
58
|
+
/**
|
|
59
|
+
* Get cache statistics
|
|
60
|
+
*/
|
|
61
|
+
getCacheStats(): {
|
|
62
|
+
size: number;
|
|
63
|
+
maxSize: number;
|
|
64
|
+
} | null;
|
|
65
|
+
private validatePayload;
|
|
66
|
+
}
|
|
@@ -1,2 +1,2 @@
|
|
|
1
1
|
import { Secret, SignOptions } from "jsonwebtoken";
|
|
2
|
-
export declare const signToken: (payload: Record<string,
|
|
2
|
+
export declare const signToken: (payload: Record<string, unknown>, secret: Secret, expiresIn?: string | number, options?: SignOptions) => string;
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import { JwtPayload } from "jsonwebtoken";
|
|
2
|
+
export interface AccessTokenBrand {
|
|
3
|
+
readonly access: unique symbol;
|
|
4
|
+
}
|
|
5
|
+
export interface RefreshTokenBrand {
|
|
6
|
+
readonly refresh: unique symbol;
|
|
7
|
+
}
|
|
8
|
+
export type AccessToken = string & AccessTokenBrand;
|
|
9
|
+
export type RefreshToken = string & RefreshTokenBrand;
|
|
10
|
+
export interface TokenPair {
|
|
11
|
+
accessToken: AccessToken;
|
|
12
|
+
refreshToken: RefreshToken;
|
|
13
|
+
}
|
|
14
|
+
export interface VerificationResult<T = JwtPayload> {
|
|
15
|
+
valid: boolean;
|
|
16
|
+
payload?: T | string;
|
|
17
|
+
error?: Error;
|
|
18
|
+
}
|
|
19
|
+
export interface TokenValidationOptions {
|
|
20
|
+
ignoreExpiration?: boolean;
|
|
21
|
+
ignoreIssuedAt?: boolean;
|
|
22
|
+
}
|
|
@@ -4,7 +4,7 @@ export interface TokenRequirements {
|
|
|
4
4
|
forbiddenFields?: string[];
|
|
5
5
|
validateTypes?: Record<string, "string" | "number" | "boolean">;
|
|
6
6
|
}
|
|
7
|
-
export declare function validateTokenPayload(payload: Record<string,
|
|
7
|
+
export declare function validateTokenPayload(payload: Record<string, unknown>, rules?: TokenRequirements): {
|
|
8
8
|
valid: true;
|
|
9
9
|
} | {
|
|
10
10
|
valid: false;
|
|
@@ -1,13 +1,18 @@
|
|
|
1
|
-
import { Secret, JwtPayload } from "jsonwebtoken";
|
|
1
|
+
import jwt, { Secret, JwtPayload } from "jsonwebtoken";
|
|
2
|
+
import { VerificationResult } from "./types";
|
|
2
3
|
/**
|
|
3
4
|
* Verify token (throws if invalid or expired)
|
|
4
5
|
*/
|
|
5
6
|
export declare const verifyToken: (token: string, secret: Secret) => string | JwtPayload;
|
|
6
7
|
/**
|
|
7
|
-
* Safe verify — never throws, returns
|
|
8
|
+
* Safe verify — never throws, returns structured result
|
|
8
9
|
*/
|
|
9
|
-
export declare const safeVerifyToken: (token: string, secret: Secret) =>
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
10
|
+
export declare const safeVerifyToken: (token: string, secret: Secret) => VerificationResult;
|
|
11
|
+
/**
|
|
12
|
+
* Verify token with validation options
|
|
13
|
+
*/
|
|
14
|
+
export declare const verifyTokenWithOptions: (token: string, secret: Secret, options?: jwt.VerifyOptions) => string | JwtPayload;
|
|
15
|
+
/**
|
|
16
|
+
* Safe verify with validation options
|
|
17
|
+
*/
|
|
18
|
+
export declare const safeVerifyTokenWithOptions: (token: string, secret: Secret, options?: jwt.VerifyOptions) => VerificationResult;
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import { IPasswordManager, PasswordConfig, PasswordValidationResult, HashedPassword, PasswordStrength } from "../../interfaces/password.interface";
|
|
2
|
+
export declare class PasswordManager implements IPasswordManager {
|
|
3
|
+
private defaultConfig;
|
|
4
|
+
constructor(config?: PasswordConfig);
|
|
5
|
+
/**
|
|
6
|
+
* Hash a password asynchronously using bcrypt
|
|
7
|
+
*/
|
|
8
|
+
hash(password: string, salt?: string): Promise<HashedPassword>;
|
|
9
|
+
/**
|
|
10
|
+
* Verify password against hash and salt
|
|
11
|
+
*/
|
|
12
|
+
verify(password: string, hash: string, salt: string): Promise<boolean>;
|
|
13
|
+
/**
|
|
14
|
+
* Generate a random password
|
|
15
|
+
*/
|
|
16
|
+
generate(length?: number, options?: PasswordConfig): string;
|
|
17
|
+
/**
|
|
18
|
+
* Validate password against configuration
|
|
19
|
+
*/
|
|
20
|
+
validate(password: string, config?: PasswordConfig): PasswordValidationResult;
|
|
21
|
+
/**
|
|
22
|
+
* Check password strength
|
|
23
|
+
*/
|
|
24
|
+
checkStrength(password: string): PasswordStrength;
|
|
25
|
+
/**
|
|
26
|
+
* Check if password hash needs upgrade (different salt rounds)
|
|
27
|
+
*/
|
|
28
|
+
needsUpgrade(hash: string, currentConfig: PasswordConfig): boolean;
|
|
29
|
+
}
|
package/dist/types/index.d.ts
CHANGED
|
@@ -3,6 +3,7 @@ export * from "./core/jwt";
|
|
|
3
3
|
export * from "./core/crypto";
|
|
4
4
|
export { BadRequestError, UnauthorizedError, ValidationError, InternalServerError } from "@naman_deep_singh/errors-utils";
|
|
5
5
|
import * as JWTUtils from "./core/jwt";
|
|
6
|
+
import * as CryptoUtils from "./core/crypto";
|
|
6
7
|
declare const _default: {
|
|
7
8
|
decrypt: (data: string, secret: string) => string;
|
|
8
9
|
encrypt: (text: string, secret: string) => string;
|
|
@@ -10,14 +11,17 @@ declare const _default: {
|
|
|
10
11
|
hmacVerify: (message: string, secret: string, signature: string) => boolean;
|
|
11
12
|
randomToken: (length?: number) => string;
|
|
12
13
|
generateStrongPassword: (length?: number) => string;
|
|
14
|
+
CryptoManager: typeof CryptoUtils.CryptoManager;
|
|
15
|
+
createCryptoManager: (config?: CryptoUtils.CryptoManagerConfig) => CryptoUtils.CryptoManager;
|
|
16
|
+
cryptoManager: CryptoUtils.CryptoManager;
|
|
13
17
|
decodeToken(token: string): null | string | import("node_modules/@types/jsonwebtoken").JwtPayload;
|
|
14
18
|
decodeTokenStrict(token: string): import("node_modules/@types/jsonwebtoken").JwtPayload;
|
|
15
19
|
extractToken(sources: JWTUtils.TokenSources): string | null;
|
|
16
|
-
rotateRefreshToken(oldToken: string, secret: import("node_modules/@types/jsonwebtoken").Secret):
|
|
17
|
-
generateTokens: (payload:
|
|
20
|
+
rotateRefreshToken(oldToken: string, secret: import("node_modules/@types/jsonwebtoken").Secret): JWTUtils.RefreshToken;
|
|
21
|
+
generateTokens: (payload: Record<string, unknown>, accessSecret: import("node_modules/@types/jsonwebtoken").Secret, refreshSecret: import("node_modules/@types/jsonwebtoken").Secret, accessExpiry?: string | number, refreshExpiry?: string | number) => JWTUtils.TokenPair;
|
|
18
22
|
parseDuration(input: string | number): number;
|
|
19
|
-
signToken: (payload: Record<string,
|
|
20
|
-
validateTokenPayload(payload: Record<string,
|
|
23
|
+
signToken: (payload: Record<string, unknown>, secret: import("node_modules/@types/jsonwebtoken").Secret, expiresIn?: string | number, options?: import("node_modules/@types/jsonwebtoken").SignOptions) => string;
|
|
24
|
+
validateTokenPayload(payload: Record<string, unknown>, rules?: JWTUtils.TokenRequirements): {
|
|
21
25
|
valid: true;
|
|
22
26
|
} | {
|
|
23
27
|
valid: false;
|
|
@@ -25,11 +29,9 @@ declare const _default: {
|
|
|
25
29
|
};
|
|
26
30
|
isTokenExpired(payload: import("node_modules/@types/jsonwebtoken").JwtPayload): boolean;
|
|
27
31
|
verifyToken: (token: string, secret: import("node_modules/@types/jsonwebtoken").Secret) => string | import("node_modules/@types/jsonwebtoken").JwtPayload;
|
|
28
|
-
safeVerifyToken: (token: string, secret: import("node_modules/@types/jsonwebtoken").Secret) =>
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
error?: unknown;
|
|
32
|
-
};
|
|
32
|
+
safeVerifyToken: (token: string, secret: import("node_modules/@types/jsonwebtoken").Secret) => JWTUtils.VerificationResult;
|
|
33
|
+
verifyTokenWithOptions: (token: string, secret: import("node_modules/@types/jsonwebtoken").Secret, options?: import("node_modules/@types/jsonwebtoken").VerifyOptions) => string | import("node_modules/@types/jsonwebtoken").JwtPayload;
|
|
34
|
+
safeVerifyTokenWithOptions: (token: string, secret: import("node_modules/@types/jsonwebtoken").Secret, options?: import("node_modules/@types/jsonwebtoken").VerifyOptions) => JWTUtils.VerificationResult;
|
|
33
35
|
hashPasswordWithPepper(password: string, pepper: string): Promise<string>;
|
|
34
36
|
hashPasswordWithPepperSync(password: string, pepper: string): string;
|
|
35
37
|
hashPassword: (password: string, saltRounds?: number) => Promise<string>;
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
import { JwtPayload, Secret } from "jsonwebtoken";
|
|
2
|
+
export interface AccessToken extends String {
|
|
3
|
+
readonly __type: 'AccessToken';
|
|
4
|
+
}
|
|
5
|
+
export interface RefreshToken extends String {
|
|
6
|
+
readonly __type: 'RefreshToken';
|
|
7
|
+
}
|
|
8
|
+
export interface TokenPair {
|
|
9
|
+
accessToken: AccessToken;
|
|
10
|
+
refreshToken: RefreshToken;
|
|
11
|
+
}
|
|
12
|
+
export interface JWTConfig {
|
|
13
|
+
accessSecret: Secret;
|
|
14
|
+
refreshSecret: Secret;
|
|
15
|
+
accessExpiry?: string | number;
|
|
16
|
+
refreshExpiry?: string | number;
|
|
17
|
+
enableCaching?: boolean;
|
|
18
|
+
maxCacheSize?: number;
|
|
19
|
+
}
|
|
20
|
+
export interface TokenValidationOptions {
|
|
21
|
+
ignoreExpiration?: boolean;
|
|
22
|
+
ignoreNotBefore?: boolean;
|
|
23
|
+
audience?: string | string[];
|
|
24
|
+
issuer?: string;
|
|
25
|
+
algorithms?: string[];
|
|
26
|
+
}
|
|
27
|
+
export interface TokenGenerationOptions {
|
|
28
|
+
algorithm?: string;
|
|
29
|
+
expiresIn?: string | number;
|
|
30
|
+
audience?: string | string[];
|
|
31
|
+
issuer?: string;
|
|
32
|
+
subject?: string;
|
|
33
|
+
kid?: string;
|
|
34
|
+
}
|
|
35
|
+
export interface ITokenManager {
|
|
36
|
+
generateTokens(payload: Record<string, unknown>): Promise<TokenPair>;
|
|
37
|
+
generateAccessToken(payload: Record<string, unknown>): Promise<AccessToken>;
|
|
38
|
+
generateRefreshToken(payload: Record<string, unknown>): Promise<RefreshToken>;
|
|
39
|
+
verifyAccessToken(token: string): Promise<JwtPayload | string>;
|
|
40
|
+
verifyRefreshToken(token: string): Promise<JwtPayload | string>;
|
|
41
|
+
decodeToken(token: string, complete?: boolean): JwtPayload | string | null;
|
|
42
|
+
extractTokenFromHeader(authHeader: string): string | null;
|
|
43
|
+
validateToken(token: string, secret: Secret, options?: TokenValidationOptions): boolean;
|
|
44
|
+
rotateRefreshToken(oldToken: string): Promise<RefreshToken>;
|
|
45
|
+
isTokenExpired(token: string): boolean;
|
|
46
|
+
getTokenExpiration(token: string): Date | null;
|
|
47
|
+
}
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
export interface PasswordConfig {
|
|
2
|
+
saltRounds?: number;
|
|
3
|
+
minLength?: number;
|
|
4
|
+
maxLength?: number;
|
|
5
|
+
requireUppercase?: boolean;
|
|
6
|
+
requireLowercase?: boolean;
|
|
7
|
+
requireNumbers?: boolean;
|
|
8
|
+
requireSpecialChars?: boolean;
|
|
9
|
+
customRules?: PasswordRule[];
|
|
10
|
+
}
|
|
11
|
+
export interface PasswordRule {
|
|
12
|
+
test: (password: string) => boolean;
|
|
13
|
+
message: string;
|
|
14
|
+
}
|
|
15
|
+
export interface PasswordStrength {
|
|
16
|
+
score: number;
|
|
17
|
+
label: 'very-weak' | 'weak' | 'fair' | 'good' | 'strong';
|
|
18
|
+
feedback: string[];
|
|
19
|
+
suggestions: string[];
|
|
20
|
+
}
|
|
21
|
+
export interface PasswordValidationResult {
|
|
22
|
+
isValid: boolean;
|
|
23
|
+
errors: string[];
|
|
24
|
+
strength: PasswordStrength;
|
|
25
|
+
}
|
|
26
|
+
export interface HashedPassword {
|
|
27
|
+
hash: string;
|
|
28
|
+
salt: string;
|
|
29
|
+
}
|
|
30
|
+
export interface IPasswordManager {
|
|
31
|
+
hash(password: string, salt?: string): Promise<HashedPassword>;
|
|
32
|
+
verify(password: string, hash: string, salt: string): Promise<boolean>;
|
|
33
|
+
generate(length?: number, options?: PasswordConfig): string;
|
|
34
|
+
validate(password: string, config?: PasswordConfig): PasswordValidationResult;
|
|
35
|
+
checkStrength(password: string): PasswordStrength;
|
|
36
|
+
needsUpgrade(hash: string, currentConfig: PasswordConfig): boolean;
|
|
37
|
+
}
|
|
38
|
+
export interface IPasswordStrengthChecker {
|
|
39
|
+
analyze(password: string): PasswordStrength;
|
|
40
|
+
checkLength(password: string): {
|
|
41
|
+
valid: boolean;
|
|
42
|
+
message: string;
|
|
43
|
+
};
|
|
44
|
+
checkComplexity(password: string, config: PasswordConfig): {
|
|
45
|
+
valid: boolean;
|
|
46
|
+
message: string;
|
|
47
|
+
}[];
|
|
48
|
+
checkCommonPasswords(password: string): {
|
|
49
|
+
valid: boolean;
|
|
50
|
+
message: string;
|
|
51
|
+
};
|
|
52
|
+
checkSequential(password: string): {
|
|
53
|
+
valid: boolean;
|
|
54
|
+
message: string;
|
|
55
|
+
};
|
|
56
|
+
checkRepetition(password: string): {
|
|
57
|
+
valid: boolean;
|
|
58
|
+
message: string;
|
|
59
|
+
};
|
|
60
|
+
}
|
package/package.json
CHANGED