@zudojs/auth 0.0.1
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 +37 -0
- package/dist/.tsbuildinfo +1 -0
- package/dist/authErrors/authError.base.d.ts +77 -0
- package/dist/authErrors/authError.base.d.ts.map +1 -0
- package/dist/authErrors/authError.base.js +108 -0
- package/dist/authErrors/authError.base.js.map +1 -0
- package/dist/authErrors/index.d.ts +7 -0
- package/dist/authErrors/index.d.ts.map +1 -0
- package/dist/authErrors/index.js +7 -0
- package/dist/authErrors/index.js.map +1 -0
- package/dist/authPassword/authPassword.core.d.ts +39 -0
- package/dist/authPassword/authPassword.core.d.ts.map +1 -0
- package/dist/authPassword/authPassword.core.js +86 -0
- package/dist/authPassword/authPassword.core.js.map +1 -0
- package/dist/authPassword/index.d.ts +7 -0
- package/dist/authPassword/index.d.ts.map +1 -0
- package/dist/authPassword/index.js +7 -0
- package/dist/authPassword/index.js.map +1 -0
- package/dist/authProvider/authProvider.core.d.ts +62 -0
- package/dist/authProvider/authProvider.core.d.ts.map +1 -0
- package/dist/authProvider/authProvider.core.js +125 -0
- package/dist/authProvider/authProvider.core.js.map +1 -0
- package/dist/authProvider/index.d.ts +7 -0
- package/dist/authProvider/index.d.ts.map +1 -0
- package/dist/authProvider/index.js +7 -0
- package/dist/authProvider/index.js.map +1 -0
- package/dist/authSession/authSession.core.d.ts +16 -0
- package/dist/authSession/authSession.core.d.ts.map +1 -0
- package/dist/authSession/authSession.core.js +73 -0
- package/dist/authSession/authSession.core.js.map +1 -0
- package/dist/authSession/index.d.ts +7 -0
- package/dist/authSession/index.d.ts.map +1 -0
- package/dist/authSession/index.js +7 -0
- package/dist/authSession/index.js.map +1 -0
- package/dist/authToken/authToken.core.d.ts +31 -0
- package/dist/authToken/authToken.core.d.ts.map +1 -0
- package/dist/authToken/authToken.core.js +69 -0
- package/dist/authToken/authToken.core.js.map +1 -0
- package/dist/authToken/authToken.signing.d.ts +21 -0
- package/dist/authToken/authToken.signing.d.ts.map +1 -0
- package/dist/authToken/authToken.signing.js +87 -0
- package/dist/authToken/authToken.signing.js.map +1 -0
- package/dist/authToken/index.d.ts +7 -0
- package/dist/authToken/index.d.ts.map +1 -0
- package/dist/authToken/index.js +7 -0
- package/dist/authToken/index.js.map +1 -0
- package/dist/authToken/jwt.namespace.d.ts +18 -0
- package/dist/authToken/jwt.namespace.d.ts.map +1 -0
- package/dist/authToken/jwt.namespace.js +17 -0
- package/dist/authToken/jwt.namespace.js.map +1 -0
- package/dist/authTypes/authRbac.type.d.ts +45 -0
- package/dist/authTypes/authRbac.type.d.ts.map +1 -0
- package/dist/authTypes/authRbac.type.js +10 -0
- package/dist/authTypes/authRbac.type.js.map +1 -0
- package/dist/authTypes/authSession.type.d.ts +57 -0
- package/dist/authTypes/authSession.type.d.ts.map +1 -0
- package/dist/authTypes/authSession.type.js +7 -0
- package/dist/authTypes/authSession.type.js.map +1 -0
- package/dist/authTypes/authStrategy.type.d.ts +83 -0
- package/dist/authTypes/authStrategy.type.d.ts.map +1 -0
- package/dist/authTypes/authStrategy.type.js +7 -0
- package/dist/authTypes/authStrategy.type.js.map +1 -0
- package/dist/authTypes/authToken.type.d.ts +72 -0
- package/dist/authTypes/authToken.type.d.ts.map +1 -0
- package/dist/authTypes/authToken.type.js +7 -0
- package/dist/authTypes/authToken.type.js.map +1 -0
- package/dist/authTypes/authUser.type.d.ts +47 -0
- package/dist/authTypes/authUser.type.d.ts.map +1 -0
- package/dist/authTypes/authUser.type.js +7 -0
- package/dist/authTypes/authUser.type.js.map +1 -0
- package/dist/authTypes/index.d.ts +11 -0
- package/dist/authTypes/index.d.ts.map +1 -0
- package/dist/authTypes/index.js +11 -0
- package/dist/authTypes/index.js.map +1 -0
- package/dist/authUtils/authUtils.helper.d.ts +40 -0
- package/dist/authUtils/authUtils.helper.d.ts.map +1 -0
- package/dist/authUtils/authUtils.helper.js +84 -0
- package/dist/authUtils/authUtils.helper.js.map +1 -0
- package/dist/authUtils/index.d.ts +7 -0
- package/dist/authUtils/index.d.ts.map +1 -0
- package/dist/authUtils/index.js +7 -0
- package/dist/authUtils/index.js.map +1 -0
- package/dist/index.d.ts +19 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +19 -0
- package/dist/index.js.map +1 -0
- package/package.json +55 -0
|
@@ -0,0 +1,108 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Authentication and authorization error classes.
|
|
3
|
+
*
|
|
4
|
+
* @module authErrors
|
|
5
|
+
*/
|
|
6
|
+
import { BaseError, ErrorCode, ErrorCategory, ErrorSeverity, } from "@zudojs/errors";
|
|
7
|
+
/**
|
|
8
|
+
* Base error for all auth-related failures.
|
|
9
|
+
*/
|
|
10
|
+
export class AuthError extends BaseError {
|
|
11
|
+
constructor(message, options) {
|
|
12
|
+
super(message, {
|
|
13
|
+
code: options?.code ?? ErrorCode.AUTHENTICATION,
|
|
14
|
+
category: ErrorCategory.AUTHENTICATION,
|
|
15
|
+
severity: ErrorSeverity.ERROR,
|
|
16
|
+
metadata: options?.metadata,
|
|
17
|
+
cause: options?.cause,
|
|
18
|
+
});
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
/**
|
|
22
|
+
* Invalid credentials (wrong password, unknown user).
|
|
23
|
+
*/
|
|
24
|
+
export class InvalidCredentialsError extends AuthError {
|
|
25
|
+
constructor(message = "Invalid credentials") {
|
|
26
|
+
super(message, { code: ErrorCode.INVALID_CREDENTIALS });
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
/**
|
|
30
|
+
* Token has expired.
|
|
31
|
+
*/
|
|
32
|
+
export class TokenExpiredError extends AuthError {
|
|
33
|
+
constructor(message = "Token has expired") {
|
|
34
|
+
super(message, { code: ErrorCode.TOKEN_EXPIRED });
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
/**
|
|
38
|
+
* Token is invalid or malformed.
|
|
39
|
+
*/
|
|
40
|
+
export class TokenInvalidError extends AuthError {
|
|
41
|
+
constructor(message = "Token is invalid") {
|
|
42
|
+
super(message, { code: ErrorCode.TOKEN_INVALID });
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
/**
|
|
46
|
+
* Token has been revoked.
|
|
47
|
+
*/
|
|
48
|
+
export class TokenRevokedError extends AuthError {
|
|
49
|
+
constructor(message = "Token has been revoked") {
|
|
50
|
+
super(message, { code: ErrorCode.FORBIDDEN });
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
/**
|
|
54
|
+
* User account is locked (too many failed attempts).
|
|
55
|
+
*/
|
|
56
|
+
export class AccountLockedError extends AuthError {
|
|
57
|
+
constructor(message = "Account is locked due to too many failed attempts", options) {
|
|
58
|
+
super(message, {
|
|
59
|
+
code: ErrorCode.FORBIDDEN,
|
|
60
|
+
metadata: {
|
|
61
|
+
retryAfterSeconds: options?.retryAfterSeconds ?? 900,
|
|
62
|
+
},
|
|
63
|
+
});
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
/**
|
|
67
|
+
* User account is deactivated.
|
|
68
|
+
*/
|
|
69
|
+
export class AccountDeactivatedError extends AuthError {
|
|
70
|
+
constructor(message = "User account is deactivated") {
|
|
71
|
+
super(message, { code: ErrorCode.FORBIDDEN });
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
/**
|
|
75
|
+
* Access denied (insufficient permissions).
|
|
76
|
+
*/
|
|
77
|
+
export class AccessDeniedError extends AuthError {
|
|
78
|
+
constructor(message = "Access denied", options) {
|
|
79
|
+
super(message, {
|
|
80
|
+
code: ErrorCode.ACCESS_DENIED,
|
|
81
|
+
metadata: {
|
|
82
|
+
requiredPermission: options?.requiredPermission,
|
|
83
|
+
},
|
|
84
|
+
});
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
/**
|
|
88
|
+
* Session has expired or is invalid.
|
|
89
|
+
*/
|
|
90
|
+
export class SessionExpiredError extends AuthError {
|
|
91
|
+
constructor(message = "Session has expired") {
|
|
92
|
+
super(message, { code: ErrorCode.SESSION_EXPIRED });
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
/**
|
|
96
|
+
* Rate limit exceeded for auth endpoint.
|
|
97
|
+
*/
|
|
98
|
+
export class AuthRateLimitError extends AuthError {
|
|
99
|
+
constructor(message = "Too many authentication attempts", options) {
|
|
100
|
+
super(message, {
|
|
101
|
+
code: ErrorCode.RATE_LIMITED,
|
|
102
|
+
metadata: {
|
|
103
|
+
retryAfterSeconds: options?.retryAfterSeconds ?? 60,
|
|
104
|
+
},
|
|
105
|
+
});
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
//# sourceMappingURL=authError.base.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"authError.base.js","sourceRoot":"","sources":["../../src/authErrors/authError.base.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Authentication and authorization error types.
|
|
3
|
+
*
|
|
4
|
+
* @module authErrors
|
|
5
|
+
*/
|
|
6
|
+
export { AuthError, InvalidCredentialsError, TokenExpiredError, TokenInvalidError, TokenRevokedError, AccountLockedError, AccountDeactivatedError, AccessDeniedError, SessionExpiredError, AuthRateLimitError, } from "./authError.base.js";
|
|
7
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/authErrors/index.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EACL,SAAS,EACT,uBAAuB,EACvB,iBAAiB,EACjB,iBAAiB,EACjB,iBAAiB,EACjB,kBAAkB,EAClB,uBAAuB,EACvB,iBAAiB,EACjB,mBAAmB,EACnB,kBAAkB,GACnB,MAAM,qBAAqB,CAAC"}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Authentication and authorization error types.
|
|
3
|
+
*
|
|
4
|
+
* @module authErrors
|
|
5
|
+
*/
|
|
6
|
+
export { AuthError, InvalidCredentialsError, TokenExpiredError, TokenInvalidError, TokenRevokedError, AccountLockedError, AccountDeactivatedError, AccessDeniedError, SessionExpiredError, AuthRateLimitError, } from "./authError.base.js";
|
|
7
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/authErrors/index.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EACL,SAAS,EACT,uBAAuB,EACvB,iBAAiB,EACjB,iBAAiB,EACjB,iBAAiB,EACjB,kBAAkB,EAClB,uBAAuB,EACvB,iBAAiB,EACjB,mBAAmB,EACnB,kBAAkB,GACnB,MAAM,qBAAqB,CAAC"}
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Password hashing and verification using Node.js crypto scrypt.
|
|
3
|
+
*
|
|
4
|
+
* @module authPassword/authPassword
|
|
5
|
+
*
|
|
6
|
+
* Uses scrypt with salt for secure password hashing.
|
|
7
|
+
* Compatible with Node.js ≥ 24 (no external dependencies).
|
|
8
|
+
*/
|
|
9
|
+
/**
|
|
10
|
+
* Hash a plain-text password.
|
|
11
|
+
*
|
|
12
|
+
* @param password - Plain-text password
|
|
13
|
+
* @param saltLength - Salt length in bytes (default: 32)
|
|
14
|
+
* @returns Hashed password string in format "scrypt$salt$hash"
|
|
15
|
+
*/
|
|
16
|
+
export declare function hashPassword(password: string, saltLength?: number): Promise<string>;
|
|
17
|
+
/**
|
|
18
|
+
* Verify a plain-text password against a hash.
|
|
19
|
+
*
|
|
20
|
+
* @param password - Plain-text password to verify
|
|
21
|
+
* @param hashedPassword - Previously hashed password
|
|
22
|
+
* @returns Whether the password matches
|
|
23
|
+
*/
|
|
24
|
+
export declare function verifyPassword(password: string, hashedPassword: string): Promise<boolean>;
|
|
25
|
+
/**
|
|
26
|
+
* Check if a password hash needs rehashing (e.g. after salt length change).
|
|
27
|
+
*
|
|
28
|
+
* @param hashedPassword - The stored hash
|
|
29
|
+
* @returns Whether the hash should be regenerated
|
|
30
|
+
*/
|
|
31
|
+
export declare function needsRehash(hashedPassword: string): boolean;
|
|
32
|
+
/**
|
|
33
|
+
* Generate a random token string (for password reset, etc.).
|
|
34
|
+
*
|
|
35
|
+
* @param length - Token length in bytes (default: 32)
|
|
36
|
+
* @returns Hex-encoded random string
|
|
37
|
+
*/
|
|
38
|
+
export declare function generateRandomToken(length?: number): string;
|
|
39
|
+
//# sourceMappingURL=authPassword.core.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"authPassword.core.d.ts","sourceRoot":"","sources":["../../src/authPassword/authPassword.core.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAeH;;;;;;GAMG;AACH,wBAAsB,YAAY,CAChC,QAAQ,EAAE,MAAM,EAChB,UAAU,GAAE,MAAoB,GAC/B,OAAO,CAAC,MAAM,CAAC,CAIjB;AAED;;;;;;GAMG;AACH,wBAAsB,cAAc,CAClC,QAAQ,EAAE,MAAM,EAChB,cAAc,EAAE,MAAM,GACrB,OAAO,CAAC,OAAO,CAAC,CAclB;AAED;;;;;GAKG;AACH,wBAAgB,WAAW,CAAC,cAAc,EAAE,MAAM,GAAG,OAAO,CAQ3D;AAED;;;;;GAKG;AACH,wBAAgB,mBAAmB,CAAC,MAAM,GAAE,MAAW,GAAG,MAAM,CAE/D"}
|
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Password hashing and verification using Node.js crypto scrypt.
|
|
3
|
+
*
|
|
4
|
+
* @module authPassword/authPassword
|
|
5
|
+
*
|
|
6
|
+
* Uses scrypt with salt for secure password hashing.
|
|
7
|
+
* Compatible with Node.js ≥ 24 (no external dependencies).
|
|
8
|
+
*/
|
|
9
|
+
import { randomBytes, scrypt, timingSafeEqual } from "node:crypto";
|
|
10
|
+
/** Default salt length in bytes. */
|
|
11
|
+
const SALT_LENGTH = 32;
|
|
12
|
+
/** Default key length for scrypt. */
|
|
13
|
+
const KEY_LENGTH = 64;
|
|
14
|
+
/** Scrypt parameters (N, r, p). */
|
|
15
|
+
const SCRYPT_N = 16384;
|
|
16
|
+
const SCRYPT_R = 8;
|
|
17
|
+
const SCRYPT_P = 1;
|
|
18
|
+
/**
|
|
19
|
+
* Hash a plain-text password.
|
|
20
|
+
*
|
|
21
|
+
* @param password - Plain-text password
|
|
22
|
+
* @param saltLength - Salt length in bytes (default: 32)
|
|
23
|
+
* @returns Hashed password string in format "scrypt$salt$hash"
|
|
24
|
+
*/
|
|
25
|
+
export async function hashPassword(password, saltLength = SALT_LENGTH) {
|
|
26
|
+
const salt = randomBytes(saltLength).toString("hex");
|
|
27
|
+
const derivedKey = await deriveKey(password, salt);
|
|
28
|
+
return `scrypt${salt}$${derivedKey}`;
|
|
29
|
+
}
|
|
30
|
+
/**
|
|
31
|
+
* Verify a plain-text password against a hash.
|
|
32
|
+
*
|
|
33
|
+
* @param password - Plain-text password to verify
|
|
34
|
+
* @param hashedPassword - Previously hashed password
|
|
35
|
+
* @returns Whether the password matches
|
|
36
|
+
*/
|
|
37
|
+
export async function verifyPassword(password, hashedPassword) {
|
|
38
|
+
const parts = hashedPassword.split("$");
|
|
39
|
+
if (parts.length !== 2 || !parts[0].startsWith("scrypt")) {
|
|
40
|
+
return false;
|
|
41
|
+
}
|
|
42
|
+
const salt = parts[0].slice(6);
|
|
43
|
+
const storedHash = parts[1];
|
|
44
|
+
const derivedKey = await deriveKey(password, salt);
|
|
45
|
+
const storedBuffer = Buffer.from(storedHash, "hex");
|
|
46
|
+
const derivedBuffer = Buffer.from(derivedKey, "hex");
|
|
47
|
+
if (storedBuffer.length !== derivedBuffer.length) {
|
|
48
|
+
return false;
|
|
49
|
+
}
|
|
50
|
+
return timingSafeEqual(storedBuffer, derivedBuffer);
|
|
51
|
+
}
|
|
52
|
+
/**
|
|
53
|
+
* Check if a password hash needs rehashing (e.g. after salt length change).
|
|
54
|
+
*
|
|
55
|
+
* @param hashedPassword - The stored hash
|
|
56
|
+
* @returns Whether the hash should be regenerated
|
|
57
|
+
*/
|
|
58
|
+
export function needsRehash(hashedPassword) {
|
|
59
|
+
const parts = hashedPassword.split("$");
|
|
60
|
+
if (parts.length !== 2 || !parts[0].startsWith("scrypt")) {
|
|
61
|
+
return true;
|
|
62
|
+
}
|
|
63
|
+
const salt = parts[0].slice(6);
|
|
64
|
+
const saltBytes = salt.length / 2;
|
|
65
|
+
return saltBytes !== SALT_LENGTH;
|
|
66
|
+
}
|
|
67
|
+
/**
|
|
68
|
+
* Generate a random token string (for password reset, etc.).
|
|
69
|
+
*
|
|
70
|
+
* @param length - Token length in bytes (default: 32)
|
|
71
|
+
* @returns Hex-encoded random string
|
|
72
|
+
*/
|
|
73
|
+
export function generateRandomToken(length = 32) {
|
|
74
|
+
return randomBytes(length).toString("hex");
|
|
75
|
+
}
|
|
76
|
+
function deriveKey(password, salt) {
|
|
77
|
+
return new Promise((resolve, reject) => {
|
|
78
|
+
scrypt(password, salt, KEY_LENGTH, { N: SCRYPT_N, r: SCRYPT_R, p: SCRYPT_P }, (err, derivedKey) => {
|
|
79
|
+
if (err)
|
|
80
|
+
reject(err);
|
|
81
|
+
else
|
|
82
|
+
resolve(derivedKey.toString("hex"));
|
|
83
|
+
});
|
|
84
|
+
});
|
|
85
|
+
}
|
|
86
|
+
//# sourceMappingURL=authPassword.core.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"authPassword.core.js","sourceRoot":"","sources":["../../src/authPassword/authPassword.core.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/authPassword/index.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EACL,YAAY,EACZ,cAAc,EACd,WAAW,EACX,mBAAmB,GACpB,MAAM,wBAAwB,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/authPassword/index.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EACL,YAAY,EACZ,cAAc,EACd,WAAW,EACX,mBAAmB,GACpB,MAAM,wBAAwB,CAAC"}
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Main auth service — coordinates password, token, session, and permissions.
|
|
3
|
+
*
|
|
4
|
+
* @module authProvider/authProvider
|
|
5
|
+
*/
|
|
6
|
+
import type { AuthUser, UserCredentials, UserId } from "../authTypes/authUser.type.js";
|
|
7
|
+
import type { TokenPair, TokenConfig } from "../authTypes/authToken.type.js";
|
|
8
|
+
import type { SessionStore, SessionId } from "../authTypes/authSession.type.js";
|
|
9
|
+
import type { GuardResult } from "../authTypes/authRbac.type.js";
|
|
10
|
+
import type { PermissionEngine } from "@zudojs/permissions";
|
|
11
|
+
/** User lookup function provided by the consumer. */
|
|
12
|
+
export type UserLookup = (identifier: string) => Promise<AuthUser | null>;
|
|
13
|
+
/** Password verifier function provided by the consumer. */
|
|
14
|
+
export type PasswordVerifier = (userId: UserId, password: string) => Promise<boolean>;
|
|
15
|
+
/**
|
|
16
|
+
* Auth service configuration.
|
|
17
|
+
*/
|
|
18
|
+
export interface AuthServiceConfig {
|
|
19
|
+
/** JWT token configuration */
|
|
20
|
+
readonly token: TokenConfig;
|
|
21
|
+
/** Session store */
|
|
22
|
+
readonly sessionStore: SessionStore;
|
|
23
|
+
/** User lookup function */
|
|
24
|
+
readonly findUser: UserLookup;
|
|
25
|
+
/** Password verifier function */
|
|
26
|
+
readonly verifyPassword: PasswordVerifier;
|
|
27
|
+
/** Session TTL in seconds */
|
|
28
|
+
readonly sessionTtlSeconds: number;
|
|
29
|
+
/** Optional permission engine */
|
|
30
|
+
readonly permissions?: PermissionEngine;
|
|
31
|
+
}
|
|
32
|
+
/**
|
|
33
|
+
* Auth service interface.
|
|
34
|
+
*/
|
|
35
|
+
export interface AuthService {
|
|
36
|
+
login(credentials: UserCredentials, context?: {
|
|
37
|
+
readonly userAgent?: string;
|
|
38
|
+
readonly ip?: string;
|
|
39
|
+
}): Promise<LoginResult>;
|
|
40
|
+
verifyToken(token: string): Record<string, unknown>;
|
|
41
|
+
refresh(refreshToken: string): Promise<TokenPair>;
|
|
42
|
+
logout(sessionId: SessionId): Promise<void>;
|
|
43
|
+
checkAccess(userId: UserId, userRoles: readonly string[], permission: string, resourceOwnerId?: UserId): Promise<GuardResult>;
|
|
44
|
+
hashPassword(password: string): Promise<string>;
|
|
45
|
+
verifyPasswordHash(password: string, hash: string): Promise<boolean>;
|
|
46
|
+
}
|
|
47
|
+
/**
|
|
48
|
+
* Result of a login attempt.
|
|
49
|
+
*/
|
|
50
|
+
export interface LoginResult {
|
|
51
|
+
/** Authenticated user */
|
|
52
|
+
readonly user: AuthUser;
|
|
53
|
+
/** Token pair */
|
|
54
|
+
readonly tokens: TokenPair;
|
|
55
|
+
/** Session ID */
|
|
56
|
+
readonly sessionId: SessionId;
|
|
57
|
+
}
|
|
58
|
+
/**
|
|
59
|
+
* Create an auth service.
|
|
60
|
+
*/
|
|
61
|
+
export declare function createAuthService(config: AuthServiceConfig): AuthService;
|
|
62
|
+
//# sourceMappingURL=authProvider.core.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"authProvider.core.d.ts","sourceRoot":"","sources":["../../src/authProvider/authProvider.core.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,KAAK,EACV,QAAQ,EACR,eAAe,EACf,MAAM,EACP,MAAM,+BAA+B,CAAC;AACvC,OAAO,KAAK,EAAE,SAAS,EAAE,WAAW,EAAE,MAAM,gCAAgC,CAAC;AAC7E,OAAO,KAAK,EACV,YAAY,EAEZ,SAAS,EACV,MAAM,kCAAkC,CAAC;AAC1C,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,+BAA+B,CAAC;AACjE,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,qBAAqB,CAAC;AAgB5D,qDAAqD;AACrD,MAAM,MAAM,UAAU,GAAG,CAAC,UAAU,EAAE,MAAM,KAAK,OAAO,CAAC,QAAQ,GAAG,IAAI,CAAC,CAAC;AAC1E,2DAA2D;AAC3D,MAAM,MAAM,gBAAgB,GAAG,CAC7B,MAAM,EAAE,MAAM,EACd,QAAQ,EAAE,MAAM,KACb,OAAO,CAAC,OAAO,CAAC,CAAC;AAEtB;;GAEG;AACH,MAAM,WAAW,iBAAiB;IAChC,8BAA8B;IAC9B,QAAQ,CAAC,KAAK,EAAE,WAAW,CAAC;IAC5B,oBAAoB;IACpB,QAAQ,CAAC,YAAY,EAAE,YAAY,CAAC;IACpC,2BAA2B;IAC3B,QAAQ,CAAC,QAAQ,EAAE,UAAU,CAAC;IAC9B,iCAAiC;IACjC,QAAQ,CAAC,cAAc,EAAE,gBAAgB,CAAC;IAC1C,6BAA6B;IAC7B,QAAQ,CAAC,iBAAiB,EAAE,MAAM,CAAC;IACnC,iCAAiC;IACjC,QAAQ,CAAC,WAAW,CAAC,EAAE,gBAAgB,CAAC;CACzC;AAED;;GAEG;AACH,MAAM,WAAW,WAAW;IAC1B,KAAK,CACH,WAAW,EAAE,eAAe,EAC5B,OAAO,CAAC,EAAE;QAAE,QAAQ,CAAC,SAAS,CAAC,EAAE,MAAM,CAAC;QAAC,QAAQ,CAAC,EAAE,CAAC,EAAE,MAAM,CAAA;KAAE,GAC9D,OAAO,CAAC,WAAW,CAAC,CAAC;IACxB,WAAW,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IACpD,OAAO,CAAC,YAAY,EAAE,MAAM,GAAG,OAAO,CAAC,SAAS,CAAC,CAAC;IAClD,MAAM,CAAC,SAAS,EAAE,SAAS,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAC5C,WAAW,CACT,MAAM,EAAE,MAAM,EACd,SAAS,EAAE,SAAS,MAAM,EAAE,EAC5B,UAAU,EAAE,MAAM,EAClB,eAAe,CAAC,EAAE,MAAM,GACvB,OAAO,CAAC,WAAW,CAAC,CAAC;IACxB,YAAY,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC;IAChD,kBAAkB,CAAC,QAAQ,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC;CACtE;AAED;;GAEG;AACH,MAAM,WAAW,WAAW;IAC1B,yBAAyB;IACzB,QAAQ,CAAC,IAAI,EAAE,QAAQ,CAAC;IACxB,iBAAiB;IACjB,QAAQ,CAAC,MAAM,EAAE,SAAS,CAAC;IAC3B,iBAAiB;IACjB,QAAQ,CAAC,SAAS,EAAE,SAAS,CAAC;CAC/B;AAED;;GAEG;AACH,wBAAgB,iBAAiB,CAAC,MAAM,EAAE,iBAAiB,GAAG,WAAW,CAqHxE"}
|
|
@@ -0,0 +1,125 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Main auth service — coordinates password, token, session, and permissions.
|
|
3
|
+
*
|
|
4
|
+
* @module authProvider/authProvider
|
|
5
|
+
*/
|
|
6
|
+
import { hashPassword, verifyPassword, } from "../authPassword/authPassword.core.js";
|
|
7
|
+
import { createTokenPair, verifyAccessToken, refreshAccessToken, } from "../authToken/authToken.core.js";
|
|
8
|
+
import { InvalidCredentialsError, TokenExpiredError, AccountDeactivatedError, } from "../authErrors/authError.base.js";
|
|
9
|
+
/**
|
|
10
|
+
* Create an auth service.
|
|
11
|
+
*/
|
|
12
|
+
export function createAuthService(config) {
|
|
13
|
+
const { token: tokenConfig, sessionStore, findUser, verifyPassword: verifyPwd, sessionTtlSeconds, permissions, } = config;
|
|
14
|
+
return {
|
|
15
|
+
/**
|
|
16
|
+
* Authenticate a user with credentials and return tokens + session.
|
|
17
|
+
*/
|
|
18
|
+
async login(credentials, context) {
|
|
19
|
+
const user = await findUser(credentials.identifier);
|
|
20
|
+
if (!user) {
|
|
21
|
+
throw new InvalidCredentialsError();
|
|
22
|
+
}
|
|
23
|
+
if (!user.active) {
|
|
24
|
+
throw new AccountDeactivatedError();
|
|
25
|
+
}
|
|
26
|
+
const valid = await verifyPwd(user.id, credentials.password);
|
|
27
|
+
if (!valid) {
|
|
28
|
+
throw new InvalidCredentialsError();
|
|
29
|
+
}
|
|
30
|
+
const tokens = createTokenPair(user.id, tokenConfig, {
|
|
31
|
+
roles: user.roles,
|
|
32
|
+
});
|
|
33
|
+
const session = await sessionStore.create({
|
|
34
|
+
userId: user.id,
|
|
35
|
+
userAgent: context?.userAgent,
|
|
36
|
+
ip: context?.ip,
|
|
37
|
+
ttlSeconds: sessionTtlSeconds,
|
|
38
|
+
});
|
|
39
|
+
return { user, tokens, sessionId: session.id };
|
|
40
|
+
},
|
|
41
|
+
/**
|
|
42
|
+
* Verify an access token and return the payload.
|
|
43
|
+
*/
|
|
44
|
+
verifyToken(token) {
|
|
45
|
+
const result = verifyAccessToken(token, tokenConfig);
|
|
46
|
+
if (!result.valid) {
|
|
47
|
+
throw new TokenExpiredError(result.error ?? "Token verification failed");
|
|
48
|
+
}
|
|
49
|
+
return result.payload;
|
|
50
|
+
},
|
|
51
|
+
/**
|
|
52
|
+
* Refresh an access token using a refresh token.
|
|
53
|
+
*/
|
|
54
|
+
async refresh(refreshToken) {
|
|
55
|
+
const result = refreshAccessToken(refreshToken, tokenConfig);
|
|
56
|
+
if (!result) {
|
|
57
|
+
throw new TokenExpiredError("Refresh token is invalid or expired");
|
|
58
|
+
}
|
|
59
|
+
return result;
|
|
60
|
+
},
|
|
61
|
+
/**
|
|
62
|
+
* Logout — destroy the session.
|
|
63
|
+
*/
|
|
64
|
+
async logout(sessionId) {
|
|
65
|
+
await sessionStore.destroy(sessionId);
|
|
66
|
+
},
|
|
67
|
+
/**
|
|
68
|
+
* Check if a user has a specific permission.
|
|
69
|
+
* Delegates to @zudojs/permissions engine when configured.
|
|
70
|
+
*/
|
|
71
|
+
async checkAccess(userId, userRoles, permission, resourceOwnerId) {
|
|
72
|
+
if (permissions) {
|
|
73
|
+
const actor = { id: userId, roles: [...userRoles] };
|
|
74
|
+
const resource = resourceOwnerId
|
|
75
|
+
? { ownerId: resourceOwnerId }
|
|
76
|
+
: undefined;
|
|
77
|
+
const decision = await permissions.check(actor, permission, resource);
|
|
78
|
+
return {
|
|
79
|
+
allowed: decision.allowed,
|
|
80
|
+
reason: decision.reason,
|
|
81
|
+
requiredPermission: permission,
|
|
82
|
+
userRoles: [...userRoles],
|
|
83
|
+
};
|
|
84
|
+
}
|
|
85
|
+
// Fallback: simple wildcard matching (no engine configured)
|
|
86
|
+
return simpleGuard(userRoles, permission, userId, resourceOwnerId);
|
|
87
|
+
},
|
|
88
|
+
/**
|
|
89
|
+
* Hash a password (for user registration).
|
|
90
|
+
*/
|
|
91
|
+
hashPassword(password) {
|
|
92
|
+
return hashPassword(password);
|
|
93
|
+
},
|
|
94
|
+
/**
|
|
95
|
+
* Verify a password against a hash.
|
|
96
|
+
*/
|
|
97
|
+
verifyPasswordHash(password, hash) {
|
|
98
|
+
return verifyPassword(password, hash);
|
|
99
|
+
},
|
|
100
|
+
};
|
|
101
|
+
}
|
|
102
|
+
/**
|
|
103
|
+
* Simple fallback guard when no permissions engine is configured.
|
|
104
|
+
* Performs basic wildcard matching without full ABAC support.
|
|
105
|
+
*/
|
|
106
|
+
function simpleGuard(userRoles, permission, userId, resourceOwnerId) {
|
|
107
|
+
// Ownership check
|
|
108
|
+
if (resourceOwnerId && resourceOwnerId === userId) {
|
|
109
|
+
return { allowed: true, userRoles: [...userRoles] };
|
|
110
|
+
}
|
|
111
|
+
const [requiredResource, requiredAction] = permission.split(":");
|
|
112
|
+
for (const role of userRoles) {
|
|
113
|
+
// Role-based — simplified check
|
|
114
|
+
if (role === "admin") {
|
|
115
|
+
return { allowed: true, userRoles: [...userRoles] };
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
return {
|
|
119
|
+
allowed: false,
|
|
120
|
+
reason: `User lacks required permission: ${permission}`,
|
|
121
|
+
requiredPermission: permission,
|
|
122
|
+
userRoles: [...userRoles],
|
|
123
|
+
};
|
|
124
|
+
}
|
|
125
|
+
//# sourceMappingURL=authProvider.core.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"authProvider.core.js","sourceRoot":"","sources":["../../src/authProvider/authProvider.core.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Main auth service: login, token verification, RBAC checks.
|
|
3
|
+
*
|
|
4
|
+
* @module authProvider
|
|
5
|
+
*/
|
|
6
|
+
export { createAuthService, type AuthServiceConfig, type LoginResult, type UserLookup, type PasswordVerifier, } from "./authProvider.core.js";
|
|
7
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/authProvider/index.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EACL,iBAAiB,EACjB,KAAK,iBAAiB,EACtB,KAAK,WAAW,EAChB,KAAK,UAAU,EACf,KAAK,gBAAgB,GACtB,MAAM,wBAAwB,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/authProvider/index.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EACL,iBAAiB,GAKlB,MAAM,wBAAwB,CAAC"}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* In-memory session store implementation.
|
|
3
|
+
*
|
|
4
|
+
* @module authSession/authSession
|
|
5
|
+
*
|
|
6
|
+
* For production, implement SessionStore backed by Redis, database, etc.
|
|
7
|
+
*/
|
|
8
|
+
import type { SessionStore } from "../authTypes/authSession.type.js";
|
|
9
|
+
/**
|
|
10
|
+
* Create an in-memory session store.
|
|
11
|
+
*
|
|
12
|
+
* Good for development and testing. For production,
|
|
13
|
+
* implement SessionStore with Redis or a database.
|
|
14
|
+
*/
|
|
15
|
+
export declare function createMemorySessionStore(): SessionStore;
|
|
16
|
+
//# sourceMappingURL=authSession.core.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"authSession.core.d.ts","sourceRoot":"","sources":["../../src/authSession/authSession.core.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,KAAK,EAIV,YAAY,EACb,MAAM,kCAAkC,CAAC;AAM1C;;;;;GAKG;AACH,wBAAgB,wBAAwB,IAAI,YAAY,CA0DvD"}
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* In-memory session store implementation.
|
|
3
|
+
*
|
|
4
|
+
* @module authSession/authSession
|
|
5
|
+
*
|
|
6
|
+
* For production, implement SessionStore backed by Redis, database, etc.
|
|
7
|
+
*/
|
|
8
|
+
import { randomBytes } from "node:crypto";
|
|
9
|
+
const DEFAULT_TTL_SECONDS = 86400; // 24 hours
|
|
10
|
+
/**
|
|
11
|
+
* Create an in-memory session store.
|
|
12
|
+
*
|
|
13
|
+
* Good for development and testing. For production,
|
|
14
|
+
* implement SessionStore with Redis or a database.
|
|
15
|
+
*/
|
|
16
|
+
export function createMemorySessionStore() {
|
|
17
|
+
const sessions = new Map();
|
|
18
|
+
return {
|
|
19
|
+
async create(options) {
|
|
20
|
+
const id = generateSessionId();
|
|
21
|
+
const now = new Date();
|
|
22
|
+
const ttlMs = (options.ttlSeconds ?? DEFAULT_TTL_SECONDS) * 1000;
|
|
23
|
+
const session = {
|
|
24
|
+
id,
|
|
25
|
+
userId: options.userId,
|
|
26
|
+
userAgent: options.userAgent,
|
|
27
|
+
ip: options.ip,
|
|
28
|
+
createdAt: now,
|
|
29
|
+
lastActivityAt: now,
|
|
30
|
+
expiresAt: new Date(now.getTime() + ttlMs),
|
|
31
|
+
active: true,
|
|
32
|
+
metadata: options.metadata,
|
|
33
|
+
};
|
|
34
|
+
sessions.set(id, session);
|
|
35
|
+
return session;
|
|
36
|
+
},
|
|
37
|
+
async get(sessionId) {
|
|
38
|
+
const session = sessions.get(sessionId);
|
|
39
|
+
if (!session)
|
|
40
|
+
return null;
|
|
41
|
+
if (!session.active)
|
|
42
|
+
return null;
|
|
43
|
+
if (new Date() > session.expiresAt) {
|
|
44
|
+
sessions.delete(sessionId);
|
|
45
|
+
return null;
|
|
46
|
+
}
|
|
47
|
+
return session;
|
|
48
|
+
},
|
|
49
|
+
async touch(sessionId) {
|
|
50
|
+
const session = sessions.get(sessionId);
|
|
51
|
+
if (session && session.active) {
|
|
52
|
+
sessions.set(sessionId, {
|
|
53
|
+
...session,
|
|
54
|
+
lastActivityAt: new Date(),
|
|
55
|
+
});
|
|
56
|
+
}
|
|
57
|
+
},
|
|
58
|
+
async destroy(sessionId) {
|
|
59
|
+
sessions.delete(sessionId);
|
|
60
|
+
},
|
|
61
|
+
async destroyAllForUser(userId) {
|
|
62
|
+
for (const [id, session] of sessions) {
|
|
63
|
+
if (session.userId === userId) {
|
|
64
|
+
sessions.delete(id);
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
},
|
|
68
|
+
};
|
|
69
|
+
}
|
|
70
|
+
function generateSessionId() {
|
|
71
|
+
return randomBytes(32).toString("hex");
|
|
72
|
+
}
|
|
73
|
+
//# sourceMappingURL=authSession.core.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"authSession.core.js","sourceRoot":"","sources":["../../src/authSession/authSession.core.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AASH,OAAO,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AAE1C,MAAM,mBAAmB,GAAG,KAAK,CAAC,CAAC,WAAW;AAE9C;;;;;GAKG;AACH,MAAM,UAAU,wBAAwB;IACtC,MAAM,QAAQ,GAAG,IAAI,GAAG,EAA0B,CAAC;IAEnD,OAAO;QACL,KAAK,CAAC,MAAM,CAAC,OAA6B;YACxC,MAAM,EAAE,GAAG,iBAAiB,EAAE,CAAC;YAC/B,MAAM,GAAG,GAAG,IAAI,IAAI,EAAE,CAAC;YACvB,MAAM,KAAK,GAAG,CAAC,OAAO,CAAC,UAAU,IAAI,mBAAmB,CAAC,GAAG,IAAI,CAAC;YAEjE,MAAM,OAAO,GAAgB;gBAC3B,EAAE;gBACF,MAAM,EAAE,OAAO,CAAC,MAAM;gBACtB,SAAS,EAAE,OAAO,CAAC,SAAS;gBAC5B,EAAE,EAAE,OAAO,CAAC,EAAE;gBACd,SAAS,EAAE,GAAG;gBACd,cAAc,EAAE,GAAG;gBACnB,SAAS,EAAE,IAAI,IAAI,CAAC,GAAG,CAAC,OAAO,EAAE,GAAG,KAAK,CAAC;gBAC1C,MAAM,EAAE,IAAI;gBACZ,QAAQ,EAAE,OAAO,CAAC,QAAQ;aAC3B,CAAC;YAEF,QAAQ,CAAC,GAAG,CAAC,EAAE,EAAE,OAAO,CAAC,CAAC;YAC1B,OAAO,OAAO,CAAC;QACjB,CAAC;QAED,KAAK,CAAC,GAAG,CAAC,SAAoB;YAC5B,MAAM,OAAO,GAAG,QAAQ,CAAC,GAAG,CAAC,SAAS,CAAC,CAAC;YACxC,IAAI,CAAC,OAAO;gBAAE,OAAO,IAAI,CAAC;YAC1B,IAAI,CAAC,OAAO,CAAC,MAAM;gBAAE,OAAO,IAAI,CAAC;YACjC,IAAI,IAAI,IAAI,EAAE,GAAG,OAAO,CAAC,SAAS,EAAE,CAAC;gBACnC,QAAQ,CAAC,MAAM,CAAC,SAAS,CAAC,CAAC;gBAC3B,OAAO,IAAI,CAAC;YACd,CAAC;YACD,OAAO,OAAO,CAAC;QACjB,CAAC;QAED,KAAK,CAAC,KAAK,CAAC,SAAoB;YAC9B,MAAM,OAAO,GAAG,QAAQ,CAAC,GAAG,CAAC,SAAS,CAAC,CAAC;YACxC,IAAI,OAAO,IAAI,OAAO,CAAC,MAAM,EAAE,CAAC;gBAC9B,QAAQ,CAAC,GAAG,CAAC,SAAS,EAAE;oBACtB,GAAG,OAAO;oBACV,cAAc,EAAE,IAAI,IAAI,EAAE;iBAC3B,CAAC,CAAC;YACL,CAAC;QACH,CAAC;QAED,KAAK,CAAC,OAAO,CAAC,SAAoB;YAChC,QAAQ,CAAC,MAAM,CAAC,SAAS,CAAC,CAAC;QAC7B,CAAC;QAED,KAAK,CAAC,iBAAiB,CAAC,MAAc;YACpC,KAAK,MAAM,CAAC,EAAE,EAAE,OAAO,CAAC,IAAI,QAAQ,EAAE,CAAC;gBACrC,IAAI,OAAO,CAAC,MAAM,KAAK,MAAM,EAAE,CAAC;oBAC9B,QAAQ,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC;gBACtB,CAAC;YACH,CAAC;QACH,CAAC;KACF,CAAC;AACJ,CAAC;AAED,SAAS,iBAAiB;IACxB,OAAO,WAAW,CAAC,EAAE,CAAC,CAAC,QAAQ,CAAC,KAAK,CAAc,CAAC;AACtD,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/authSession/index.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EAAE,wBAAwB,EAAE,MAAM,uBAAuB,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/authSession/index.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EAAE,wBAAwB,EAAE,MAAM,uBAAuB,CAAC"}
|