@stonecrop/casl-middleware 0.7.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.
Files changed (66) hide show
  1. package/README.md +149 -0
  2. package/dist/casl-middleware.d.ts +158 -0
  3. package/dist/casl-middleware.js +40571 -0
  4. package/dist/casl-middleware.js.map +1 -0
  5. package/dist/casl_middleware.tsbuildinfo +1 -0
  6. package/dist/src/index.d.ts +6 -0
  7. package/dist/src/index.d.ts.map +1 -0
  8. package/dist/src/index.js +3 -0
  9. package/dist/src/middleware/ability.d.ts +55 -0
  10. package/dist/src/middleware/ability.d.ts.map +1 -0
  11. package/dist/src/middleware/ability.js +139 -0
  12. package/dist/src/middleware/graphql.d.ts +11 -0
  13. package/dist/src/middleware/graphql.d.ts.map +1 -0
  14. package/dist/src/middleware/graphql.js +120 -0
  15. package/dist/src/middleware/introspection.d.ts +71 -0
  16. package/dist/src/middleware/introspection.d.ts.map +1 -0
  17. package/dist/src/middleware/introspection.js +169 -0
  18. package/dist/src/middleware/jwt.d.ts +114 -0
  19. package/dist/src/middleware/jwt.d.ts.map +1 -0
  20. package/dist/src/middleware/jwt.js +291 -0
  21. package/dist/src/middleware/postgraphile.d.ts +7 -0
  22. package/dist/src/middleware/postgraphile.d.ts.map +1 -0
  23. package/dist/src/middleware/postgraphile.js +80 -0
  24. package/dist/src/middleware/yoga.d.ts +15 -0
  25. package/dist/src/middleware/yoga.d.ts.map +1 -0
  26. package/dist/src/middleware/yoga.js +32 -0
  27. package/dist/src/tsdoc-metadata.json +11 -0
  28. package/dist/src/types/index.d.ts +114 -0
  29. package/dist/src/types/index.d.ts.map +1 -0
  30. package/dist/src/types/index.js +0 -0
  31. package/dist/tests/ability.test.d.ts +2 -0
  32. package/dist/tests/ability.test.d.ts.map +1 -0
  33. package/dist/tests/ability.test.js +125 -0
  34. package/dist/tests/helpers/test-utils.d.ts +46 -0
  35. package/dist/tests/helpers/test-utils.d.ts.map +1 -0
  36. package/dist/tests/helpers/test-utils.js +92 -0
  37. package/dist/tests/introspection.test.d.ts +2 -0
  38. package/dist/tests/introspection.test.d.ts.map +1 -0
  39. package/dist/tests/introspection.test.js +368 -0
  40. package/dist/tests/jwt.test.d.ts +2 -0
  41. package/dist/tests/jwt.test.d.ts.map +1 -0
  42. package/dist/tests/jwt.test.js +371 -0
  43. package/dist/tests/middleware.test.d.ts +2 -0
  44. package/dist/tests/middleware.test.d.ts.map +1 -0
  45. package/dist/tests/middleware.test.js +184 -0
  46. package/dist/tests/postgraphile-plugin.test.d.ts +2 -0
  47. package/dist/tests/postgraphile-plugin.test.d.ts.map +1 -0
  48. package/dist/tests/postgraphile-plugin.test.js +56 -0
  49. package/dist/tests/setup.d.ts +2 -0
  50. package/dist/tests/setup.d.ts.map +1 -0
  51. package/dist/tests/setup.js +11 -0
  52. package/dist/tests/user-roles.test.d.ts +2 -0
  53. package/dist/tests/user-roles.test.d.ts.map +1 -0
  54. package/dist/tests/user-roles.test.js +157 -0
  55. package/dist/tests/yoga-plugin.test.d.ts +2 -0
  56. package/dist/tests/yoga-plugin.test.d.ts.map +1 -0
  57. package/dist/tests/yoga-plugin.test.js +47 -0
  58. package/package.json +91 -0
  59. package/src/index.ts +15 -0
  60. package/src/middleware/ability.ts +191 -0
  61. package/src/middleware/graphql.ts +157 -0
  62. package/src/middleware/introspection.ts +258 -0
  63. package/src/middleware/jwt.ts +394 -0
  64. package/src/middleware/postgraphile.ts +93 -0
  65. package/src/middleware/yoga.ts +39 -0
  66. package/src/types/index.ts +133 -0
package/README.md ADDED
@@ -0,0 +1,149 @@
1
+ # CASL GraphQL Middleware
2
+
3
+ A middleware solution for integrating CASL authorization with GraphQL servers, with specific support for Postgraphile and Nuxt GraphQL Server.
4
+
5
+ ## Features
6
+
7
+ - CASL integration with GraphQL resolvers
8
+ - Framework-specific helpers for Postgraphile and Nuxt
9
+ - Type-safe ability definitions
10
+ - Support for field-level permissions
11
+ - Ability to combine multiple authorization rules
12
+
13
+ ## Installation
14
+
15
+ ```bash
16
+ pnpm add @stonecrop/casl-middleware
17
+ ```
18
+
19
+ ## Basic Usage
20
+
21
+ ### Core Middleware
22
+
23
+ ```typescript
24
+ import { createCaslMiddleware } from '@stonecrop/casl-middleware'
25
+
26
+ const middleware = createCaslMiddleware({
27
+ subjectMap: {
28
+ User: 'User',
29
+ Item: 'Item'
30
+ },
31
+ fieldPermissions: {
32
+ 'Item.price': [{ action: 'read', subject: 'item' }]
33
+ }
34
+ })
35
+ ```
36
+
37
+ ### Postgraphile Integration
38
+
39
+ ```typescript
40
+ // graphile.config.js
41
+ import { pglCaslPlugin } from '@stonecrop/casl-middleware'
42
+ import { postgraphile } from 'postgraphile'
43
+
44
+ export default {
45
+ pgServices: [
46
+ makePgService({
47
+ connectionString: 'postgres://testuser:testpass@postgres:5432/testdb',
48
+ schemas: ['public'],
49
+ }),
50
+ ],
51
+ plugins: [pglCaslPlugin],
52
+ }
53
+ ```
54
+
55
+ ### Testing Abilities in GraphiQL
56
+
57
+ Create an ability:
58
+ ```graphql
59
+ mutation CreateAbility {
60
+ createAbility(input: {
61
+ userId: "123",
62
+ roles: ["admin"]
63
+ }) {
64
+ success
65
+ ability
66
+ message
67
+ }
68
+ }
69
+ ```
70
+
71
+ Test protected queries:
72
+ ```graphql
73
+ query GetSecretData {
74
+ getSecretData {
75
+ id
76
+ content
77
+ }
78
+ }
79
+ ```
80
+
81
+ ## Development
82
+
83
+ ### Prerequisites
84
+
85
+ - Node.js >= 20
86
+ - pnpm
87
+ - Docker and Docker Compose
88
+
89
+ ### Local Development
90
+
91
+ 1. Clone the repository:
92
+ ```bash
93
+ git clone <repository-url>
94
+ cd casl-middleware
95
+ ```
96
+
97
+ 2. Install dependencies:
98
+ ```bash
99
+ pnpm install
100
+ ```
101
+
102
+ 3. Run the Postgraphile example:
103
+ ```bash
104
+ pnpm dev:postgraphile
105
+ ```
106
+
107
+ ### Project Structure
108
+
109
+ ```
110
+ .
111
+ ├── examples/
112
+ │ └── postgraphile/ # Postgraphile example implementation
113
+ ├── src/
114
+ │ ├── middleware/ # Core CASL middleware
115
+ │ ├── types/ # TypeScript types
116
+ │ └── index.ts # Main exports
117
+ ```
118
+
119
+ ## Framework Support
120
+
121
+ ### Postgraphile
122
+ - Implements CASL as a Postgraphile plugin
123
+ - Supports ability creation and management
124
+ - Integrates with Postgraphile's schema extension system
125
+
126
+ ### Nuxt GraphQL Server
127
+ - Provides middleware for Nuxt's GraphQL module
128
+ - Handles ability creation on request
129
+ - Integrates with Nuxt's context system
130
+
131
+ ## Contributing
132
+
133
+ 1. Fork the repository
134
+ 2. Create your feature branch
135
+ 3. Commit your changes
136
+ 4. Push to the branch
137
+ 5. Create a new Pull Request
138
+
139
+ ## License
140
+
141
+ MIT License
142
+
143
+ ## TODOs
144
+
145
+ - [ ] Add comprehensive test suite
146
+ - [ ] Add more framework integrations
147
+ - [ ] Implement ability persistence
148
+ - [ ] Add more examples for different use cases
149
+ - [ ] Add documentation for advanced usage scenarios
@@ -0,0 +1,158 @@
1
+ import { GraphileConfig as GraphileConfig_2 } from 'postgraphile/graphile-build';
2
+ import { GraphQLResolveInfo } from 'graphql';
3
+ import { PureAbility } from '@casl/ability';
4
+
5
+ /**
6
+ * Function type for building user abilities
7
+ * @public
8
+ */
9
+ declare type AbilityBuilderFunction = (user?: Context['user']) => Promise<AppAbility> | AppAbility;
10
+
11
+ /**
12
+ * Response type for ability creation mutations
13
+ * @public
14
+ */
15
+ export declare interface AbilityResponse {
16
+ /** Whether the ability was created successfully */
17
+ success: boolean;
18
+ /** The created ability rules */
19
+ ability: any;
20
+ /** Success or error message */
21
+ message: string;
22
+ }
23
+
24
+ /**
25
+ * CASL ability type for authorization with flexible subject types
26
+ * @public
27
+ */
28
+ export declare type AppAbility = PureAbility<[string, any], any>;
29
+
30
+ /**
31
+ * GraphQL context with CASL ability and user information
32
+ * @public
33
+ */
34
+ export declare interface Context {
35
+ /** CASL ability instance for authorization checks */
36
+ ability?: AppAbility;
37
+ /** Current authenticated user */
38
+ user?: User;
39
+ /** Additional context properties */
40
+ [key: string]: any;
41
+ }
42
+
43
+ /**
44
+ * Create ability using a provided builder function
45
+ * @param user - User information for building the ability
46
+ * @param builderFn - Function to build the ability
47
+ * @returns Promise resolving to the created ability
48
+ * @public
49
+ */
50
+ export declare const createAbility: (user?: Context["user"], builderFn?: AbilityBuilderFunction) => Promise<AppAbility>;
51
+
52
+ /**
53
+ * Input type for creating a new ability
54
+ * @public
55
+ */
56
+ export declare interface CreateAbilityInput {
57
+ /** User ID to create ability for */
58
+ userId: string;
59
+ /** Array of role names to assign */
60
+ roles: string[];
61
+ }
62
+
63
+ /**
64
+ * Creates CASL authorization middleware for GraphQL resolvers
65
+ * @param options - Configuration options for the middleware
66
+ * @returns Middleware function that wraps resolvers with authorization checks
67
+ * @public
68
+ */
69
+ export declare const createCaslMiddleware: (options?: MiddlewareOptions) => (resolve: ResolverFn, root: any, args: any, context: Context, info: GraphQLResolveInfo) => Promise<any>;
70
+
71
+ /**
72
+ * Detects the subject type from an object for CASL authorization
73
+ * @param object - The object to detect the subject type from
74
+ * @returns The subject type string
75
+ * @public
76
+ */
77
+ export declare const detectSubjectType: (object: any) => string;
78
+
79
+ /**
80
+ * Field-level permission definition for fine-grained access control
81
+ * @public
82
+ */
83
+ export declare interface FieldPermission {
84
+ /** CASL action (e.g., 'read', 'write') */
85
+ action: string;
86
+ /** Subject/resource type to apply permission to */
87
+ subject: string;
88
+ /** Specific field name (optional) */
89
+ field?: string;
90
+ /** Conditional rules for permission */
91
+ conditions?: any;
92
+ }
93
+
94
+ /**
95
+ * Middleware function that wraps a GraphQL resolver with authorization logic
96
+ * @public
97
+ */
98
+ export declare type MiddlewareFn = (resolve: ResolverFn, root: any, args: any, context: Context, info: GraphQLResolveInfo) => Promise<any> | any;
99
+
100
+ /**
101
+ * Configuration options for CASL middleware
102
+ * @public
103
+ */
104
+ export declare interface MiddlewareOptions {
105
+ /** Mapping of GraphQL types to authorization subjects */
106
+ subjectMap?: Record<string, string>;
107
+ /** Mapping of GraphQL operations to CASL actions */
108
+ actionMap?: Record<string, string>;
109
+ /** Field-level permission rules */
110
+ fieldPermissions?: Record<string, FieldPermission[]>;
111
+ /** Custom function to build user abilities */
112
+ abilityBuilder?: AbilityBuilderFunction;
113
+ /** Enable debug logging */
114
+ debug?: boolean;
115
+ }
116
+
117
+ /**
118
+ * PostGraphile plugin for CASL authorization
119
+ * @public
120
+ */
121
+ export declare const pglCaslPlugin: GraphileConfig_2.Plugin;
122
+
123
+ /**
124
+ * Plugin configuration options for framework integrations
125
+ * @public
126
+ */
127
+ export declare interface PluginOptions extends MiddlewareOptions {
128
+ /** Custom function to build user abilities */
129
+ abilityBuilder?: AbilityBuilderFunction;
130
+ /** Ability caching configuration */
131
+ cacheOptions?: {
132
+ /** Time-to-live in milliseconds */
133
+ ttl?: number;
134
+ /** Function to generate cache key from user */
135
+ key?: (user?: User) => string;
136
+ };
137
+ }
138
+
139
+ /**
140
+ * GraphQL resolver function type
141
+ * @public
142
+ */
143
+ export declare type ResolverFn = (root: any, args: any, context: Context, info: GraphQLResolveInfo) => Promise<any> | any;
144
+
145
+ /**
146
+ * User information for authorization
147
+ * @public
148
+ */
149
+ export declare interface User {
150
+ /** Unique identifier for the user */
151
+ id: string;
152
+ /** Array of role names assigned to the user */
153
+ roles?: string[];
154
+ /** Additional user properties */
155
+ [key: string]: any;
156
+ }
157
+
158
+ export { }