@veloxts/auth 0.3.3 → 0.3.5
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 +1157 -30
- package/dist/__integration__/fixtures.d.ts +41 -0
- package/dist/__integration__/fixtures.d.ts.map +1 -0
- package/dist/__integration__/fixtures.js +79 -0
- package/dist/__integration__/fixtures.js.map +1 -0
- package/dist/__integration__/setup.d.ts +26 -0
- package/dist/__integration__/setup.d.ts.map +1 -0
- package/dist/__integration__/setup.js +28 -0
- package/dist/__integration__/setup.js.map +1 -0
- package/dist/adapter.d.ts +710 -0
- package/dist/adapter.d.ts.map +1 -0
- package/dist/adapter.js +581 -0
- package/dist/adapter.js.map +1 -0
- package/dist/adapters/better-auth.d.ts +271 -0
- package/dist/adapters/better-auth.d.ts.map +1 -0
- package/dist/adapters/better-auth.js +341 -0
- package/dist/adapters/better-auth.js.map +1 -0
- package/dist/adapters/index.d.ts +28 -0
- package/dist/adapters/index.d.ts.map +1 -0
- package/dist/adapters/index.js +28 -0
- package/dist/adapters/index.js.map +1 -0
- package/dist/csrf.d.ts +300 -0
- package/dist/csrf.d.ts.map +1 -0
- package/dist/csrf.js +402 -0
- package/dist/csrf.js.map +1 -0
- package/dist/guards.d.ts +142 -0
- package/dist/guards.d.ts.map +1 -0
- package/dist/guards.js +259 -0
- package/dist/guards.js.map +1 -0
- package/dist/hash.d.ts +91 -0
- package/dist/hash.d.ts.map +1 -0
- package/dist/hash.js +236 -0
- package/dist/hash.js.map +1 -0
- package/dist/index.d.ts +27 -32
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +94 -36
- package/dist/index.js.map +1 -1
- package/dist/jwt.d.ts +157 -0
- package/dist/jwt.d.ts.map +1 -0
- package/dist/jwt.js +489 -0
- package/dist/jwt.js.map +1 -0
- package/dist/middleware.d.ts +99 -0
- package/dist/middleware.d.ts.map +1 -0
- package/dist/middleware.js +253 -0
- package/dist/middleware.js.map +1 -0
- package/dist/plugin.d.ts +125 -0
- package/dist/plugin.d.ts.map +1 -0
- package/dist/plugin.js +193 -0
- package/dist/plugin.js.map +1 -0
- package/dist/policies.d.ts +137 -0
- package/dist/policies.d.ts.map +1 -0
- package/dist/policies.js +240 -0
- package/dist/policies.js.map +1 -0
- package/dist/rate-limit.d.ts +231 -0
- package/dist/rate-limit.d.ts.map +1 -0
- package/dist/rate-limit.js +352 -0
- package/dist/rate-limit.js.map +1 -0
- package/dist/session.d.ts +500 -0
- package/dist/session.d.ts.map +1 -0
- package/dist/session.js +801 -0
- package/dist/session.js.map +1 -0
- package/dist/types.d.ts +261 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +33 -0
- package/dist/types.js.map +1 -0
- package/package.json +61 -7
|
@@ -0,0 +1,137 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Resource-level authorization policies for @veloxts/auth
|
|
3
|
+
* @module auth/policies
|
|
4
|
+
*/
|
|
5
|
+
import type { PolicyAction, PolicyDefinition, User } from './types.js';
|
|
6
|
+
/**
|
|
7
|
+
* Registers a policy for a resource type
|
|
8
|
+
*
|
|
9
|
+
* @example
|
|
10
|
+
* ```typescript
|
|
11
|
+
* registerPolicy('Post', {
|
|
12
|
+
* view: (user, post) => true, // Anyone can view
|
|
13
|
+
* update: (user, post) => user.id === post.authorId,
|
|
14
|
+
* delete: (user, post) => user.id === post.authorId || user.role === 'admin',
|
|
15
|
+
* });
|
|
16
|
+
* ```
|
|
17
|
+
*/
|
|
18
|
+
export declare function registerPolicy<TUser = User, TResource = unknown>(resourceName: string, policy: PolicyDefinition<TUser, TResource>): void;
|
|
19
|
+
/**
|
|
20
|
+
* Gets a registered policy by resource name
|
|
21
|
+
*/
|
|
22
|
+
export declare function getPolicy(resourceName: string): PolicyDefinition | undefined;
|
|
23
|
+
/**
|
|
24
|
+
* Clears all registered policies (useful for testing)
|
|
25
|
+
*/
|
|
26
|
+
export declare function clearPolicies(): void;
|
|
27
|
+
/**
|
|
28
|
+
* Defines a policy for a resource type
|
|
29
|
+
*
|
|
30
|
+
* @example
|
|
31
|
+
* ```typescript
|
|
32
|
+
* const PostPolicy = definePolicy<User, Post>({
|
|
33
|
+
* view: () => true,
|
|
34
|
+
* create: (user) => user.emailVerified,
|
|
35
|
+
* update: (user, post) => user.id === post.authorId,
|
|
36
|
+
* delete: (user, post) => user.id === post.authorId || user.role === 'admin',
|
|
37
|
+
* publish: (user, post) => user.role === 'editor' && user.id === post.authorId,
|
|
38
|
+
* });
|
|
39
|
+
*
|
|
40
|
+
* // Register it
|
|
41
|
+
* registerPolicy('Post', PostPolicy);
|
|
42
|
+
* ```
|
|
43
|
+
*/
|
|
44
|
+
export declare function definePolicy<TUser = User, TResource = unknown>(actions: PolicyDefinition<TUser, TResource>): PolicyDefinition<TUser, TResource>;
|
|
45
|
+
/**
|
|
46
|
+
* Checks if a user can perform an action on a resource
|
|
47
|
+
*
|
|
48
|
+
* @example
|
|
49
|
+
* ```typescript
|
|
50
|
+
* const canEdit = await can(user, 'update', 'Post', post);
|
|
51
|
+
* if (!canEdit) {
|
|
52
|
+
* throw new ForbiddenError('Cannot edit this post');
|
|
53
|
+
* }
|
|
54
|
+
* ```
|
|
55
|
+
*/
|
|
56
|
+
export declare function can<TResource = unknown>(user: User | null | undefined, action: string, resourceName: string, resource?: TResource): Promise<boolean>;
|
|
57
|
+
/**
|
|
58
|
+
* Checks if a user cannot perform an action (inverse of can)
|
|
59
|
+
*/
|
|
60
|
+
export declare function cannot<TResource = unknown>(user: User | null | undefined, action: string, resourceName: string, resource?: TResource): Promise<boolean>;
|
|
61
|
+
/**
|
|
62
|
+
* Throws an error if user cannot perform action
|
|
63
|
+
*
|
|
64
|
+
* @example
|
|
65
|
+
* ```typescript
|
|
66
|
+
* await authorize(ctx.user, 'delete', 'Post', post);
|
|
67
|
+
* // If we get here, user is authorized
|
|
68
|
+
* await db.post.delete({ where: { id: post.id } });
|
|
69
|
+
* ```
|
|
70
|
+
*/
|
|
71
|
+
export declare function authorize<TResource = unknown>(user: User | null | undefined, action: string, resourceName: string, resource?: TResource): Promise<void>;
|
|
72
|
+
/**
|
|
73
|
+
* Fluent policy builder for complex policies
|
|
74
|
+
*
|
|
75
|
+
* @example
|
|
76
|
+
* ```typescript
|
|
77
|
+
* const CommentPolicy = createPolicyBuilder<User, Comment>()
|
|
78
|
+
* .allow('view', () => true)
|
|
79
|
+
* .allow('create', (user) => user.emailVerified)
|
|
80
|
+
* .allow('update', (user, comment) => user.id === comment.authorId)
|
|
81
|
+
* .allow('delete', (user, comment) =>
|
|
82
|
+
* user.id === comment.authorId || user.role === 'admin'
|
|
83
|
+
* )
|
|
84
|
+
* .build();
|
|
85
|
+
* ```
|
|
86
|
+
*/
|
|
87
|
+
export declare function createPolicyBuilder<TUser = User, TResource = unknown>(): PolicyBuilder<TUser, TResource>;
|
|
88
|
+
declare class PolicyBuilder<TUser = User, TResource = unknown> {
|
|
89
|
+
private actions;
|
|
90
|
+
/**
|
|
91
|
+
* Allows an action based on the check function
|
|
92
|
+
*/
|
|
93
|
+
allow(action: string, check: PolicyAction<TUser, TResource>): this;
|
|
94
|
+
/**
|
|
95
|
+
* Denies an action (always returns false)
|
|
96
|
+
*/
|
|
97
|
+
deny(action: string): this;
|
|
98
|
+
/**
|
|
99
|
+
* Allows action only for resource owner
|
|
100
|
+
* Assumes resource has a userId or authorId field
|
|
101
|
+
*/
|
|
102
|
+
allowOwner(action: string, ownerField?: keyof TResource): this;
|
|
103
|
+
/**
|
|
104
|
+
* Allows action for owner OR users with specific role
|
|
105
|
+
*/
|
|
106
|
+
allowOwnerOr(action: string, roles: string[], ownerField?: keyof TResource): this;
|
|
107
|
+
/**
|
|
108
|
+
* Builds the final policy definition
|
|
109
|
+
*/
|
|
110
|
+
build(): PolicyDefinition<TUser, TResource>;
|
|
111
|
+
/**
|
|
112
|
+
* Builds and registers the policy
|
|
113
|
+
*/
|
|
114
|
+
register(resourceName: string): PolicyDefinition<TUser, TResource>;
|
|
115
|
+
}
|
|
116
|
+
/**
|
|
117
|
+
* Creates a policy that allows all actions for admins
|
|
118
|
+
* and owner-only for regular users
|
|
119
|
+
*/
|
|
120
|
+
export declare function createOwnerOrAdminPolicy<TResource extends {
|
|
121
|
+
userId?: string;
|
|
122
|
+
authorId?: string;
|
|
123
|
+
}>(ownerField?: 'userId' | 'authorId'): PolicyDefinition<User & {
|
|
124
|
+
role?: string;
|
|
125
|
+
}, TResource>;
|
|
126
|
+
/**
|
|
127
|
+
* Creates a read-only policy (only view allowed)
|
|
128
|
+
*/
|
|
129
|
+
export declare function createReadOnlyPolicy<TResource>(): PolicyDefinition<User, TResource>;
|
|
130
|
+
/**
|
|
131
|
+
* Creates a policy for admin-only resources
|
|
132
|
+
*/
|
|
133
|
+
export declare function createAdminOnlyPolicy<TResource>(): PolicyDefinition<User & {
|
|
134
|
+
role?: string;
|
|
135
|
+
}, TResource>;
|
|
136
|
+
export {};
|
|
137
|
+
//# sourceMappingURL=policies.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"policies.d.ts","sourceRoot":"","sources":["../src/policies.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,KAAK,EAAE,YAAY,EAAE,gBAAgB,EAAE,IAAI,EAAE,MAAM,YAAY,CAAC;AAYvE;;;;;;;;;;;GAWG;AACH,wBAAgB,cAAc,CAAC,KAAK,GAAG,IAAI,EAAE,SAAS,GAAG,OAAO,EAC9D,YAAY,EAAE,MAAM,EACpB,MAAM,EAAE,gBAAgB,CAAC,KAAK,EAAE,SAAS,CAAC,GACzC,IAAI,CAEN;AAED;;GAEG;AACH,wBAAgB,SAAS,CAAC,YAAY,EAAE,MAAM,GAAG,gBAAgB,GAAG,SAAS,CAE5E;AAED;;GAEG;AACH,wBAAgB,aAAa,IAAI,IAAI,CAEpC;AAMD;;;;;;;;;;;;;;;;GAgBG;AACH,wBAAgB,YAAY,CAAC,KAAK,GAAG,IAAI,EAAE,SAAS,GAAG,OAAO,EAC5D,OAAO,EAAE,gBAAgB,CAAC,KAAK,EAAE,SAAS,CAAC,GAC1C,gBAAgB,CAAC,KAAK,EAAE,SAAS,CAAC,CAEpC;AAMD;;;;;;;;;;GAUG;AACH,wBAAsB,GAAG,CAAC,SAAS,GAAG,OAAO,EAC3C,IAAI,EAAE,IAAI,GAAG,IAAI,GAAG,SAAS,EAC7B,MAAM,EAAE,MAAM,EACd,YAAY,EAAE,MAAM,EACpB,QAAQ,CAAC,EAAE,SAAS,GACnB,OAAO,CAAC,OAAO,CAAC,CAoBlB;AAED;;GAEG;AACH,wBAAsB,MAAM,CAAC,SAAS,GAAG,OAAO,EAC9C,IAAI,EAAE,IAAI,GAAG,IAAI,GAAG,SAAS,EAC7B,MAAM,EAAE,MAAM,EACd,YAAY,EAAE,MAAM,EACpB,QAAQ,CAAC,EAAE,SAAS,GACnB,OAAO,CAAC,OAAO,CAAC,CAElB;AAED;;;;;;;;;GASG;AACH,wBAAsB,SAAS,CAAC,SAAS,GAAG,OAAO,EACjD,IAAI,EAAE,IAAI,GAAG,IAAI,GAAG,SAAS,EAC7B,MAAM,EAAE,MAAM,EACd,YAAY,EAAE,MAAM,EACpB,QAAQ,CAAC,EAAE,SAAS,GACnB,OAAO,CAAC,IAAI,CAAC,CASf;AAMD;;;;;;;;;;;;;;GAcG;AACH,wBAAgB,mBAAmB,CAAC,KAAK,GAAG,IAAI,EAAE,SAAS,GAAG,OAAO,KAAK,aAAa,CACrF,KAAK,EACL,SAAS,CACV,CAEA;AAED,cAAM,aAAa,CAAC,KAAK,GAAG,IAAI,EAAE,SAAS,GAAG,OAAO;IACnD,OAAO,CAAC,OAAO,CAA0C;IAEzD;;OAEG;IACH,KAAK,CAAC,MAAM,EAAE,MAAM,EAAE,KAAK,EAAE,YAAY,CAAC,KAAK,EAAE,SAAS,CAAC,GAAG,IAAI;IAKlE;;OAEG;IACH,IAAI,CAAC,MAAM,EAAE,MAAM,GAAG,IAAI;IAK1B;;;OAGG;IACH,UAAU,CAAC,MAAM,EAAE,MAAM,EAAE,UAAU,GAAE,MAAM,SAAuC,GAAG,IAAI;IAQ3F;;OAEG;IACH,YAAY,CACV,MAAM,EAAE,MAAM,EACd,KAAK,EAAE,MAAM,EAAE,EACf,UAAU,GAAE,MAAM,SAAuC,GACxD,IAAI;IAWP;;OAEG;IACH,KAAK,IAAI,gBAAgB,CAAC,KAAK,EAAE,SAAS,CAAC;IAI3C;;OAEG;IACH,QAAQ,CAAC,YAAY,EAAE,MAAM,GAAG,gBAAgB,CAAC,KAAK,EAAE,SAAS,CAAC;CAKnE;AAMD;;;GAGG;AACH,wBAAgB,wBAAwB,CAAC,SAAS,SAAS;IAAE,MAAM,CAAC,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,EAAE,MAAM,CAAA;CAAE,EAC/F,UAAU,GAAE,QAAQ,GAAG,UAAqB,GAC3C,gBAAgB,CAAC,IAAI,GAAG;IAAE,IAAI,CAAC,EAAE,MAAM,CAAA;CAAE,EAAE,SAAS,CAAC,CAevD;AAED;;GAEG;AACH,wBAAgB,oBAAoB,CAAC,SAAS,KAAK,gBAAgB,CAAC,IAAI,EAAE,SAAS,CAAC,CAOnF;AAED;;GAEG;AACH,wBAAgB,qBAAqB,CAAC,SAAS,KAAK,gBAAgB,CAClE,IAAI,GAAG;IAAE,IAAI,CAAC,EAAE,MAAM,CAAA;CAAE,EACxB,SAAS,CACV,CASA"}
|
package/dist/policies.js
ADDED
|
@@ -0,0 +1,240 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Resource-level authorization policies for @veloxts/auth
|
|
3
|
+
* @module auth/policies
|
|
4
|
+
*/
|
|
5
|
+
// ============================================================================
|
|
6
|
+
// Policy Registry
|
|
7
|
+
// ============================================================================
|
|
8
|
+
/**
|
|
9
|
+
* Global policy registry
|
|
10
|
+
* Maps resource names to their policy definitions
|
|
11
|
+
*/
|
|
12
|
+
const policyRegistry = new Map();
|
|
13
|
+
/**
|
|
14
|
+
* Registers a policy for a resource type
|
|
15
|
+
*
|
|
16
|
+
* @example
|
|
17
|
+
* ```typescript
|
|
18
|
+
* registerPolicy('Post', {
|
|
19
|
+
* view: (user, post) => true, // Anyone can view
|
|
20
|
+
* update: (user, post) => user.id === post.authorId,
|
|
21
|
+
* delete: (user, post) => user.id === post.authorId || user.role === 'admin',
|
|
22
|
+
* });
|
|
23
|
+
* ```
|
|
24
|
+
*/
|
|
25
|
+
export function registerPolicy(resourceName, policy) {
|
|
26
|
+
policyRegistry.set(resourceName, policy);
|
|
27
|
+
}
|
|
28
|
+
/**
|
|
29
|
+
* Gets a registered policy by resource name
|
|
30
|
+
*/
|
|
31
|
+
export function getPolicy(resourceName) {
|
|
32
|
+
return policyRegistry.get(resourceName);
|
|
33
|
+
}
|
|
34
|
+
/**
|
|
35
|
+
* Clears all registered policies (useful for testing)
|
|
36
|
+
*/
|
|
37
|
+
export function clearPolicies() {
|
|
38
|
+
policyRegistry.clear();
|
|
39
|
+
}
|
|
40
|
+
// ============================================================================
|
|
41
|
+
// Policy Definition Helper
|
|
42
|
+
// ============================================================================
|
|
43
|
+
/**
|
|
44
|
+
* Defines a policy for a resource type
|
|
45
|
+
*
|
|
46
|
+
* @example
|
|
47
|
+
* ```typescript
|
|
48
|
+
* const PostPolicy = definePolicy<User, Post>({
|
|
49
|
+
* view: () => true,
|
|
50
|
+
* create: (user) => user.emailVerified,
|
|
51
|
+
* update: (user, post) => user.id === post.authorId,
|
|
52
|
+
* delete: (user, post) => user.id === post.authorId || user.role === 'admin',
|
|
53
|
+
* publish: (user, post) => user.role === 'editor' && user.id === post.authorId,
|
|
54
|
+
* });
|
|
55
|
+
*
|
|
56
|
+
* // Register it
|
|
57
|
+
* registerPolicy('Post', PostPolicy);
|
|
58
|
+
* ```
|
|
59
|
+
*/
|
|
60
|
+
export function definePolicy(actions) {
|
|
61
|
+
return actions;
|
|
62
|
+
}
|
|
63
|
+
// ============================================================================
|
|
64
|
+
// Authorization Checks
|
|
65
|
+
// ============================================================================
|
|
66
|
+
/**
|
|
67
|
+
* Checks if a user can perform an action on a resource
|
|
68
|
+
*
|
|
69
|
+
* @example
|
|
70
|
+
* ```typescript
|
|
71
|
+
* const canEdit = await can(user, 'update', 'Post', post);
|
|
72
|
+
* if (!canEdit) {
|
|
73
|
+
* throw new ForbiddenError('Cannot edit this post');
|
|
74
|
+
* }
|
|
75
|
+
* ```
|
|
76
|
+
*/
|
|
77
|
+
export async function can(user, action, resourceName, resource) {
|
|
78
|
+
// No user = no permission
|
|
79
|
+
if (!user) {
|
|
80
|
+
return false;
|
|
81
|
+
}
|
|
82
|
+
const policy = policyRegistry.get(resourceName);
|
|
83
|
+
if (!policy) {
|
|
84
|
+
// No policy registered = deny by default
|
|
85
|
+
console.warn(`No policy registered for resource: ${resourceName}`);
|
|
86
|
+
return false;
|
|
87
|
+
}
|
|
88
|
+
const actionHandler = policy[action];
|
|
89
|
+
if (!actionHandler) {
|
|
90
|
+
// Action not defined = deny by default
|
|
91
|
+
return false;
|
|
92
|
+
}
|
|
93
|
+
return actionHandler(user, resource);
|
|
94
|
+
}
|
|
95
|
+
/**
|
|
96
|
+
* Checks if a user cannot perform an action (inverse of can)
|
|
97
|
+
*/
|
|
98
|
+
export async function cannot(user, action, resourceName, resource) {
|
|
99
|
+
return !(await can(user, action, resourceName, resource));
|
|
100
|
+
}
|
|
101
|
+
/**
|
|
102
|
+
* Throws an error if user cannot perform action
|
|
103
|
+
*
|
|
104
|
+
* @example
|
|
105
|
+
* ```typescript
|
|
106
|
+
* await authorize(ctx.user, 'delete', 'Post', post);
|
|
107
|
+
* // If we get here, user is authorized
|
|
108
|
+
* await db.post.delete({ where: { id: post.id } });
|
|
109
|
+
* ```
|
|
110
|
+
*/
|
|
111
|
+
export async function authorize(user, action, resourceName, resource) {
|
|
112
|
+
const allowed = await can(user, action, resourceName, resource);
|
|
113
|
+
if (!allowed) {
|
|
114
|
+
const error = new Error(`Unauthorized: cannot ${action} ${resourceName}${resource ? ` (id: ${resource.id ?? 'unknown'})` : ''}`);
|
|
115
|
+
error.statusCode = 403;
|
|
116
|
+
throw error;
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
// ============================================================================
|
|
120
|
+
// Policy Builder
|
|
121
|
+
// ============================================================================
|
|
122
|
+
/**
|
|
123
|
+
* Fluent policy builder for complex policies
|
|
124
|
+
*
|
|
125
|
+
* @example
|
|
126
|
+
* ```typescript
|
|
127
|
+
* const CommentPolicy = createPolicyBuilder<User, Comment>()
|
|
128
|
+
* .allow('view', () => true)
|
|
129
|
+
* .allow('create', (user) => user.emailVerified)
|
|
130
|
+
* .allow('update', (user, comment) => user.id === comment.authorId)
|
|
131
|
+
* .allow('delete', (user, comment) =>
|
|
132
|
+
* user.id === comment.authorId || user.role === 'admin'
|
|
133
|
+
* )
|
|
134
|
+
* .build();
|
|
135
|
+
* ```
|
|
136
|
+
*/
|
|
137
|
+
export function createPolicyBuilder() {
|
|
138
|
+
return new PolicyBuilder();
|
|
139
|
+
}
|
|
140
|
+
class PolicyBuilder {
|
|
141
|
+
actions = {};
|
|
142
|
+
/**
|
|
143
|
+
* Allows an action based on the check function
|
|
144
|
+
*/
|
|
145
|
+
allow(action, check) {
|
|
146
|
+
this.actions[action] = check;
|
|
147
|
+
return this;
|
|
148
|
+
}
|
|
149
|
+
/**
|
|
150
|
+
* Denies an action (always returns false)
|
|
151
|
+
*/
|
|
152
|
+
deny(action) {
|
|
153
|
+
this.actions[action] = () => false;
|
|
154
|
+
return this;
|
|
155
|
+
}
|
|
156
|
+
/**
|
|
157
|
+
* Allows action only for resource owner
|
|
158
|
+
* Assumes resource has a userId or authorId field
|
|
159
|
+
*/
|
|
160
|
+
allowOwner(action, ownerField = 'userId') {
|
|
161
|
+
this.actions[action] = (user, resource) => {
|
|
162
|
+
const ownerId = resource?.[ownerField];
|
|
163
|
+
return ownerId === user.id;
|
|
164
|
+
};
|
|
165
|
+
return this;
|
|
166
|
+
}
|
|
167
|
+
/**
|
|
168
|
+
* Allows action for owner OR users with specific role
|
|
169
|
+
*/
|
|
170
|
+
allowOwnerOr(action, roles, ownerField = 'userId') {
|
|
171
|
+
this.actions[action] = (user, resource) => {
|
|
172
|
+
const ownerId = resource?.[ownerField];
|
|
173
|
+
const userRole = user.role;
|
|
174
|
+
const isOwner = ownerId === user.id;
|
|
175
|
+
const hasRole = typeof userRole === 'string' && roles.includes(userRole);
|
|
176
|
+
return isOwner || hasRole;
|
|
177
|
+
};
|
|
178
|
+
return this;
|
|
179
|
+
}
|
|
180
|
+
/**
|
|
181
|
+
* Builds the final policy definition
|
|
182
|
+
*/
|
|
183
|
+
build() {
|
|
184
|
+
return { ...this.actions };
|
|
185
|
+
}
|
|
186
|
+
/**
|
|
187
|
+
* Builds and registers the policy
|
|
188
|
+
*/
|
|
189
|
+
register(resourceName) {
|
|
190
|
+
const policy = this.build();
|
|
191
|
+
registerPolicy(resourceName, policy);
|
|
192
|
+
return policy;
|
|
193
|
+
}
|
|
194
|
+
}
|
|
195
|
+
// ============================================================================
|
|
196
|
+
// Common Policy Patterns
|
|
197
|
+
// ============================================================================
|
|
198
|
+
/**
|
|
199
|
+
* Creates a policy that allows all actions for admins
|
|
200
|
+
* and owner-only for regular users
|
|
201
|
+
*/
|
|
202
|
+
export function createOwnerOrAdminPolicy(ownerField = 'userId') {
|
|
203
|
+
const isOwnerOrAdmin = (user, resource) => {
|
|
204
|
+
if (user.role === 'admin') {
|
|
205
|
+
return true;
|
|
206
|
+
}
|
|
207
|
+
const ownerId = resource[ownerField];
|
|
208
|
+
return ownerId === user.id;
|
|
209
|
+
};
|
|
210
|
+
return {
|
|
211
|
+
view: () => true,
|
|
212
|
+
create: () => true,
|
|
213
|
+
update: isOwnerOrAdmin,
|
|
214
|
+
delete: isOwnerOrAdmin,
|
|
215
|
+
};
|
|
216
|
+
}
|
|
217
|
+
/**
|
|
218
|
+
* Creates a read-only policy (only view allowed)
|
|
219
|
+
*/
|
|
220
|
+
export function createReadOnlyPolicy() {
|
|
221
|
+
return {
|
|
222
|
+
view: () => true,
|
|
223
|
+
create: () => false,
|
|
224
|
+
update: () => false,
|
|
225
|
+
delete: () => false,
|
|
226
|
+
};
|
|
227
|
+
}
|
|
228
|
+
/**
|
|
229
|
+
* Creates a policy for admin-only resources
|
|
230
|
+
*/
|
|
231
|
+
export function createAdminOnlyPolicy() {
|
|
232
|
+
const isAdmin = (user) => user.role === 'admin';
|
|
233
|
+
return {
|
|
234
|
+
view: isAdmin,
|
|
235
|
+
create: isAdmin,
|
|
236
|
+
update: isAdmin,
|
|
237
|
+
delete: isAdmin,
|
|
238
|
+
};
|
|
239
|
+
}
|
|
240
|
+
//# sourceMappingURL=policies.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"policies.js","sourceRoot":"","sources":["../src/policies.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,231 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Authentication-specific rate limiting
|
|
3
|
+
*
|
|
4
|
+
* Provides specialized rate limiters for authentication endpoints with:
|
|
5
|
+
* - Per-email+IP tracking (prevents brute force on specific accounts)
|
|
6
|
+
* - Account lockout detection
|
|
7
|
+
* - Separate limits for login, register, and password reset
|
|
8
|
+
* - Progressive backoff support
|
|
9
|
+
*
|
|
10
|
+
* @module auth/rate-limit
|
|
11
|
+
*/
|
|
12
|
+
import type { BaseContext } from '@veloxts/core';
|
|
13
|
+
import type { MiddlewareFunction } from '@veloxts/router';
|
|
14
|
+
/**
|
|
15
|
+
* Configuration for auth rate limiting
|
|
16
|
+
*/
|
|
17
|
+
export interface AuthRateLimitConfig {
|
|
18
|
+
/**
|
|
19
|
+
* Maximum attempts before lockout
|
|
20
|
+
* @default 5
|
|
21
|
+
*/
|
|
22
|
+
maxAttempts?: number;
|
|
23
|
+
/**
|
|
24
|
+
* Window duration in milliseconds
|
|
25
|
+
* @default 900000 (15 minutes)
|
|
26
|
+
*/
|
|
27
|
+
windowMs?: number;
|
|
28
|
+
/**
|
|
29
|
+
* Lockout duration in milliseconds after max attempts exceeded
|
|
30
|
+
* @default 900000 (15 minutes)
|
|
31
|
+
*/
|
|
32
|
+
lockoutDurationMs?: number;
|
|
33
|
+
/**
|
|
34
|
+
* Custom key generator for rate limiting
|
|
35
|
+
* Default uses IP + identifier (email)
|
|
36
|
+
*/
|
|
37
|
+
keyGenerator?: (ctx: BaseContext, identifier?: string) => string;
|
|
38
|
+
/**
|
|
39
|
+
* Error message when rate limited
|
|
40
|
+
* @default 'Too many attempts. Please try again later.'
|
|
41
|
+
*/
|
|
42
|
+
message?: string;
|
|
43
|
+
/**
|
|
44
|
+
* Enable progressive backoff (double lockout on repeated violations)
|
|
45
|
+
* @default false
|
|
46
|
+
*/
|
|
47
|
+
progressiveBackoff?: boolean;
|
|
48
|
+
}
|
|
49
|
+
/**
|
|
50
|
+
* Configuration for the auth rate limiter factory
|
|
51
|
+
*/
|
|
52
|
+
export interface AuthRateLimiterConfig {
|
|
53
|
+
/**
|
|
54
|
+
* Rate limit for login attempts
|
|
55
|
+
* @default { maxAttempts: 5, windowMs: 900000 }
|
|
56
|
+
*/
|
|
57
|
+
login?: AuthRateLimitConfig;
|
|
58
|
+
/**
|
|
59
|
+
* Rate limit for registration attempts
|
|
60
|
+
* @default { maxAttempts: 3, windowMs: 3600000 }
|
|
61
|
+
*/
|
|
62
|
+
register?: AuthRateLimitConfig;
|
|
63
|
+
/**
|
|
64
|
+
* Rate limit for password reset requests
|
|
65
|
+
* @default { maxAttempts: 3, windowMs: 3600000 }
|
|
66
|
+
*/
|
|
67
|
+
passwordReset?: AuthRateLimitConfig;
|
|
68
|
+
/**
|
|
69
|
+
* Rate limit for token refresh
|
|
70
|
+
* @default { maxAttempts: 10, windowMs: 60000 }
|
|
71
|
+
*/
|
|
72
|
+
refresh?: AuthRateLimitConfig;
|
|
73
|
+
}
|
|
74
|
+
/**
|
|
75
|
+
* Stop cleanup interval (for testing)
|
|
76
|
+
*/
|
|
77
|
+
export declare function stopAuthRateLimitCleanup(): void;
|
|
78
|
+
/**
|
|
79
|
+
* Clear all rate limit entries (for testing)
|
|
80
|
+
*/
|
|
81
|
+
export declare function clearAuthRateLimitStore(): void;
|
|
82
|
+
/**
|
|
83
|
+
* Creates an authentication rate limiter
|
|
84
|
+
*
|
|
85
|
+
* This factory returns rate limit middlewares configured for different
|
|
86
|
+
* auth operations with sensible defaults.
|
|
87
|
+
*
|
|
88
|
+
* @example
|
|
89
|
+
* ```typescript
|
|
90
|
+
* const authRateLimiter = createAuthRateLimiter({
|
|
91
|
+
* login: { maxAttempts: 5, windowMs: 15 * 60 * 1000 },
|
|
92
|
+
* register: { maxAttempts: 3, windowMs: 60 * 60 * 1000 },
|
|
93
|
+
* });
|
|
94
|
+
*
|
|
95
|
+
* // Apply to procedures
|
|
96
|
+
* const login = procedure()
|
|
97
|
+
* .use(authRateLimiter.login(ctx => ctx.input.email))
|
|
98
|
+
* .mutation(loginHandler);
|
|
99
|
+
*
|
|
100
|
+
* const register = procedure()
|
|
101
|
+
* .use(authRateLimiter.register())
|
|
102
|
+
* .mutation(registerHandler);
|
|
103
|
+
* ```
|
|
104
|
+
*/
|
|
105
|
+
export declare function createAuthRateLimiter(config?: AuthRateLimiterConfig): {
|
|
106
|
+
/**
|
|
107
|
+
* Rate limiter for login attempts
|
|
108
|
+
*
|
|
109
|
+
* @param identifierFn - Function to extract identifier (email) from context
|
|
110
|
+
*
|
|
111
|
+
* @example
|
|
112
|
+
* ```typescript
|
|
113
|
+
* login: procedure()
|
|
114
|
+
* .use(authRateLimiter.login((ctx) => (ctx.input as { email: string }).email))
|
|
115
|
+
* .input(LoginSchema)
|
|
116
|
+
* .mutation(handler)
|
|
117
|
+
* ```
|
|
118
|
+
*/
|
|
119
|
+
login: <TInput, TContext extends BaseContext, TOutput>(identifierFn?: (ctx: TContext & {
|
|
120
|
+
input?: unknown;
|
|
121
|
+
}) => string) => MiddlewareFunction<TInput, TContext, TContext, TOutput>;
|
|
122
|
+
/**
|
|
123
|
+
* Rate limiter for registration attempts
|
|
124
|
+
* Uses IP-only by default (no identifier needed)
|
|
125
|
+
*/
|
|
126
|
+
register: <TInput, TContext extends BaseContext, TOutput>() => MiddlewareFunction<TInput, TContext, TContext, TOutput>;
|
|
127
|
+
/**
|
|
128
|
+
* Rate limiter for password reset requests
|
|
129
|
+
*
|
|
130
|
+
* @param identifierFn - Optional function to extract identifier (email)
|
|
131
|
+
*/
|
|
132
|
+
passwordReset: <TInput, TContext extends BaseContext, TOutput>(identifierFn?: (ctx: TContext & {
|
|
133
|
+
input?: unknown;
|
|
134
|
+
}) => string) => MiddlewareFunction<TInput, TContext, TContext, TOutput>;
|
|
135
|
+
/**
|
|
136
|
+
* Rate limiter for token refresh
|
|
137
|
+
*/
|
|
138
|
+
refresh: <TInput, TContext extends BaseContext, TOutput>() => MiddlewareFunction<TInput, TContext, TContext, TOutput>;
|
|
139
|
+
/**
|
|
140
|
+
* Record a failed attempt (call after authentication fails)
|
|
141
|
+
*
|
|
142
|
+
* This allows tracking failures even when rate limit hasn't been hit,
|
|
143
|
+
* enabling account lockout after X failed passwords.
|
|
144
|
+
*
|
|
145
|
+
* @param key - Rate limit key (usually IP:email or IP)
|
|
146
|
+
* @param operation - Operation type for key namespacing
|
|
147
|
+
*/
|
|
148
|
+
recordFailure: (key: string, operation: "login" | "register" | "password-reset") => void;
|
|
149
|
+
/**
|
|
150
|
+
* Reset rate limit for a key (call after successful auth)
|
|
151
|
+
*/
|
|
152
|
+
resetLimit: (key: string, operation: "login" | "register" | "password-reset") => void;
|
|
153
|
+
/**
|
|
154
|
+
* Check if a key is currently locked out
|
|
155
|
+
*/
|
|
156
|
+
isLockedOut: (key: string, operation: "login" | "register" | "password-reset") => boolean;
|
|
157
|
+
/**
|
|
158
|
+
* Get remaining attempts for a key
|
|
159
|
+
*/
|
|
160
|
+
getRemainingAttempts: (key: string, operation: "login" | "register" | "password-reset" | "refresh") => number;
|
|
161
|
+
};
|
|
162
|
+
/**
|
|
163
|
+
* Pre-configured auth rate limiter with sensible defaults
|
|
164
|
+
*
|
|
165
|
+
* @example
|
|
166
|
+
* ```typescript
|
|
167
|
+
* import { authRateLimiter } from '@veloxts/auth';
|
|
168
|
+
*
|
|
169
|
+
* const login = procedure()
|
|
170
|
+
* .use(authRateLimiter.login((ctx) => ctx.input.email))
|
|
171
|
+
* .mutation(handler);
|
|
172
|
+
* ```
|
|
173
|
+
*/
|
|
174
|
+
export declare const authRateLimiter: {
|
|
175
|
+
/**
|
|
176
|
+
* Rate limiter for login attempts
|
|
177
|
+
*
|
|
178
|
+
* @param identifierFn - Function to extract identifier (email) from context
|
|
179
|
+
*
|
|
180
|
+
* @example
|
|
181
|
+
* ```typescript
|
|
182
|
+
* login: procedure()
|
|
183
|
+
* .use(authRateLimiter.login((ctx) => (ctx.input as { email: string }).email))
|
|
184
|
+
* .input(LoginSchema)
|
|
185
|
+
* .mutation(handler)
|
|
186
|
+
* ```
|
|
187
|
+
*/
|
|
188
|
+
login: <TInput, TContext extends BaseContext, TOutput>(identifierFn?: (ctx: TContext & {
|
|
189
|
+
input?: unknown;
|
|
190
|
+
}) => string) => MiddlewareFunction<TInput, TContext, TContext, TOutput>;
|
|
191
|
+
/**
|
|
192
|
+
* Rate limiter for registration attempts
|
|
193
|
+
* Uses IP-only by default (no identifier needed)
|
|
194
|
+
*/
|
|
195
|
+
register: <TInput, TContext extends BaseContext, TOutput>() => MiddlewareFunction<TInput, TContext, TContext, TOutput>;
|
|
196
|
+
/**
|
|
197
|
+
* Rate limiter for password reset requests
|
|
198
|
+
*
|
|
199
|
+
* @param identifierFn - Optional function to extract identifier (email)
|
|
200
|
+
*/
|
|
201
|
+
passwordReset: <TInput, TContext extends BaseContext, TOutput>(identifierFn?: (ctx: TContext & {
|
|
202
|
+
input?: unknown;
|
|
203
|
+
}) => string) => MiddlewareFunction<TInput, TContext, TContext, TOutput>;
|
|
204
|
+
/**
|
|
205
|
+
* Rate limiter for token refresh
|
|
206
|
+
*/
|
|
207
|
+
refresh: <TInput, TContext extends BaseContext, TOutput>() => MiddlewareFunction<TInput, TContext, TContext, TOutput>;
|
|
208
|
+
/**
|
|
209
|
+
* Record a failed attempt (call after authentication fails)
|
|
210
|
+
*
|
|
211
|
+
* This allows tracking failures even when rate limit hasn't been hit,
|
|
212
|
+
* enabling account lockout after X failed passwords.
|
|
213
|
+
*
|
|
214
|
+
* @param key - Rate limit key (usually IP:email or IP)
|
|
215
|
+
* @param operation - Operation type for key namespacing
|
|
216
|
+
*/
|
|
217
|
+
recordFailure: (key: string, operation: "login" | "register" | "password-reset") => void;
|
|
218
|
+
/**
|
|
219
|
+
* Reset rate limit for a key (call after successful auth)
|
|
220
|
+
*/
|
|
221
|
+
resetLimit: (key: string, operation: "login" | "register" | "password-reset") => void;
|
|
222
|
+
/**
|
|
223
|
+
* Check if a key is currently locked out
|
|
224
|
+
*/
|
|
225
|
+
isLockedOut: (key: string, operation: "login" | "register" | "password-reset") => boolean;
|
|
226
|
+
/**
|
|
227
|
+
* Get remaining attempts for a key
|
|
228
|
+
*/
|
|
229
|
+
getRemainingAttempts: (key: string, operation: "login" | "register" | "password-reset" | "refresh") => number;
|
|
230
|
+
};
|
|
231
|
+
//# sourceMappingURL=rate-limit.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"rate-limit.d.ts","sourceRoot":"","sources":["../src/rate-limit.ts"],"names":[],"mappings":"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"}
|