@adaptic/backend-legacy 0.0.44 → 0.0.45

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 (181) hide show
  1. package/Allocation.cjs +19 -0
  2. package/esm/Allocation.d.ts.map +1 -1
  3. package/esm/Allocation.js.map +1 -1
  4. package/esm/Allocation.mjs +19 -0
  5. package/esm/config/jwtConfig.d.ts +16 -0
  6. package/esm/config/jwtConfig.d.ts.map +1 -0
  7. package/esm/config/jwtConfig.js.map +1 -0
  8. package/esm/config/jwtConfig.mjs +47 -0
  9. package/esm/generated/typegraphql-prisma/models/Trade.d.ts +1 -1
  10. package/esm/generated/typegraphql-prisma/models/Trade.d.ts.map +1 -1
  11. package/esm/generated/typegraphql-prisma/models/Trade.js.map +1 -1
  12. package/esm/generated/typegraphql-prisma/models/Trade.mjs +1 -1
  13. package/esm/generated/typegraphql-prisma/resolvers/crud/User/args/CreateOneUserArgs.d.ts +1 -1
  14. package/esm/generated/typegraphql-prisma/resolvers/crud/User/args/CreateOneUserArgs.d.ts.map +1 -1
  15. package/esm/generated/typegraphql-prisma/resolvers/crud/User/args/CreateOneUserArgs.js.map +1 -1
  16. package/esm/generated/typegraphql-prisma/resolvers/crud/User/args/CreateOneUserArgs.mjs +2 -2
  17. package/esm/generated/typegraphql-prisma/resolvers/inputs/TradeCreateInput.d.ts +1 -1
  18. package/esm/generated/typegraphql-prisma/resolvers/inputs/TradeCreateInput.d.ts.map +1 -1
  19. package/esm/generated/typegraphql-prisma/resolvers/inputs/TradeCreateInput.js.map +1 -1
  20. package/esm/generated/typegraphql-prisma/resolvers/inputs/TradeCreateInput.mjs +1 -1
  21. package/esm/generated/typegraphql-prisma/resolvers/inputs/TradeCreateManyInput.d.ts +1 -1
  22. package/esm/generated/typegraphql-prisma/resolvers/inputs/TradeCreateManyInput.d.ts.map +1 -1
  23. package/esm/generated/typegraphql-prisma/resolvers/inputs/TradeCreateManyInput.js.map +1 -1
  24. package/esm/generated/typegraphql-prisma/resolvers/inputs/TradeCreateManyInput.mjs +1 -1
  25. package/esm/generated/typegraphql-prisma/resolvers/inputs/TradeCreateWithoutActionsInput.d.ts +1 -1
  26. package/esm/generated/typegraphql-prisma/resolvers/inputs/TradeCreateWithoutActionsInput.d.ts.map +1 -1
  27. package/esm/generated/typegraphql-prisma/resolvers/inputs/TradeCreateWithoutActionsInput.js.map +1 -1
  28. package/esm/generated/typegraphql-prisma/resolvers/inputs/TradeCreateWithoutActionsInput.mjs +1 -1
  29. package/esm/generated/typegraphql-prisma/resolvers/inputs/TradeScalarWhereWithAggregatesInput.d.ts +1 -1
  30. package/esm/generated/typegraphql-prisma/resolvers/inputs/TradeScalarWhereWithAggregatesInput.d.ts.map +1 -1
  31. package/esm/generated/typegraphql-prisma/resolvers/inputs/TradeScalarWhereWithAggregatesInput.js.map +1 -1
  32. package/esm/generated/typegraphql-prisma/resolvers/inputs/TradeScalarWhereWithAggregatesInput.mjs +1 -1
  33. package/esm/generated/typegraphql-prisma/resolvers/inputs/TradeUpdateInput.d.ts +1 -1
  34. package/esm/generated/typegraphql-prisma/resolvers/inputs/TradeUpdateInput.d.ts.map +1 -1
  35. package/esm/generated/typegraphql-prisma/resolvers/inputs/TradeUpdateInput.js.map +1 -1
  36. package/esm/generated/typegraphql-prisma/resolvers/inputs/TradeUpdateInput.mjs +1 -1
  37. package/esm/generated/typegraphql-prisma/resolvers/inputs/TradeUpdateManyMutationInput.d.ts +1 -1
  38. package/esm/generated/typegraphql-prisma/resolvers/inputs/TradeUpdateManyMutationInput.d.ts.map +1 -1
  39. package/esm/generated/typegraphql-prisma/resolvers/inputs/TradeUpdateManyMutationInput.js.map +1 -1
  40. package/esm/generated/typegraphql-prisma/resolvers/inputs/TradeUpdateManyMutationInput.mjs +1 -1
  41. package/esm/generated/typegraphql-prisma/resolvers/inputs/TradeUpdateWithoutActionsInput.d.ts +1 -1
  42. package/esm/generated/typegraphql-prisma/resolvers/inputs/TradeUpdateWithoutActionsInput.d.ts.map +1 -1
  43. package/esm/generated/typegraphql-prisma/resolvers/inputs/TradeUpdateWithoutActionsInput.js.map +1 -1
  44. package/esm/generated/typegraphql-prisma/resolvers/inputs/TradeUpdateWithoutActionsInput.mjs +1 -1
  45. package/esm/generated/typegraphql-prisma/resolvers/inputs/TradeWhereInput.d.ts +1 -1
  46. package/esm/generated/typegraphql-prisma/resolvers/inputs/TradeWhereInput.d.ts.map +1 -1
  47. package/esm/generated/typegraphql-prisma/resolvers/inputs/TradeWhereInput.js.map +1 -1
  48. package/esm/generated/typegraphql-prisma/resolvers/inputs/TradeWhereInput.mjs +1 -1
  49. package/esm/generated/typegraphql-prisma/resolvers/inputs/TradeWhereUniqueInput.d.ts +1 -1
  50. package/esm/generated/typegraphql-prisma/resolvers/inputs/TradeWhereUniqueInput.d.ts.map +1 -1
  51. package/esm/generated/typegraphql-prisma/resolvers/inputs/TradeWhereUniqueInput.js.map +1 -1
  52. package/esm/generated/typegraphql-prisma/resolvers/inputs/TradeWhereUniqueInput.mjs +1 -1
  53. package/esm/generated/typegraphql-prisma/resolvers/outputs/CreateManyAndReturnTrade.d.ts +1 -1
  54. package/esm/generated/typegraphql-prisma/resolvers/outputs/CreateManyAndReturnTrade.d.ts.map +1 -1
  55. package/esm/generated/typegraphql-prisma/resolvers/outputs/CreateManyAndReturnTrade.js.map +1 -1
  56. package/esm/generated/typegraphql-prisma/resolvers/outputs/CreateManyAndReturnTrade.mjs +1 -1
  57. package/esm/generated/typegraphql-prisma/resolvers/outputs/TradeGroupBy.d.ts +1 -1
  58. package/esm/generated/typegraphql-prisma/resolvers/outputs/TradeGroupBy.d.ts.map +1 -1
  59. package/esm/generated/typegraphql-prisma/resolvers/outputs/TradeGroupBy.js.map +1 -1
  60. package/esm/generated/typegraphql-prisma/resolvers/outputs/TradeGroupBy.mjs +1 -1
  61. package/esm/generated/typegraphql-prisma/resolvers/outputs/TradeMaxAggregate.d.ts +1 -1
  62. package/esm/generated/typegraphql-prisma/resolvers/outputs/TradeMaxAggregate.d.ts.map +1 -1
  63. package/esm/generated/typegraphql-prisma/resolvers/outputs/TradeMaxAggregate.js.map +1 -1
  64. package/esm/generated/typegraphql-prisma/resolvers/outputs/TradeMaxAggregate.mjs +1 -1
  65. package/esm/generated/typegraphql-prisma/resolvers/outputs/TradeMinAggregate.d.ts +1 -1
  66. package/esm/generated/typegraphql-prisma/resolvers/outputs/TradeMinAggregate.d.ts.map +1 -1
  67. package/esm/generated/typegraphql-prisma/resolvers/outputs/TradeMinAggregate.js.map +1 -1
  68. package/esm/generated/typegraphql-prisma/resolvers/outputs/TradeMinAggregate.mjs +1 -1
  69. package/esm/getToken.d.ts.map +1 -1
  70. package/esm/getToken.js.map +1 -1
  71. package/esm/getToken.mjs +2 -1
  72. package/esm/middleware/auth.d.ts.map +1 -1
  73. package/esm/middleware/auth.js.map +1 -1
  74. package/esm/middleware/auth.mjs +8 -8
  75. package/esm/middleware/graphql-validation-plugin.d.ts +37 -0
  76. package/esm/middleware/graphql-validation-plugin.d.ts.map +1 -0
  77. package/esm/middleware/graphql-validation-plugin.js.map +1 -0
  78. package/esm/middleware/graphql-validation-plugin.mjs +163 -0
  79. package/esm/middleware/index.d.ts +12 -0
  80. package/esm/middleware/index.d.ts.map +1 -0
  81. package/esm/middleware/index.js.map +1 -0
  82. package/esm/middleware/index.mjs +16 -0
  83. package/esm/middleware/input-validator.d.ts +63 -0
  84. package/esm/middleware/input-validator.d.ts.map +1 -0
  85. package/esm/middleware/input-validator.js.map +1 -0
  86. package/esm/middleware/input-validator.mjs +210 -0
  87. package/esm/middleware/rate-limiter.d.ts +12 -0
  88. package/esm/middleware/rate-limiter.d.ts.map +1 -0
  89. package/esm/middleware/rate-limiter.js.map +1 -0
  90. package/esm/middleware/rate-limiter.mjs +68 -0
  91. package/esm/middleware/types.d.ts +87 -0
  92. package/esm/middleware/types.d.ts.map +1 -0
  93. package/esm/middleware/types.js.map +1 -0
  94. package/esm/middleware/types.mjs +13 -0
  95. package/esm/middleware/validation-examples.d.ts +76 -0
  96. package/esm/middleware/validation-examples.d.ts.map +1 -0
  97. package/esm/middleware/validation-examples.js.map +1 -0
  98. package/esm/middleware/validation-examples.mjs +373 -0
  99. package/esm/plugins/error-sanitizer.d.ts +37 -0
  100. package/esm/plugins/error-sanitizer.d.ts.map +1 -0
  101. package/esm/plugins/error-sanitizer.js.map +1 -0
  102. package/esm/plugins/error-sanitizer.mjs +184 -0
  103. package/esm/plugins/index.d.ts +8 -0
  104. package/esm/plugins/index.d.ts.map +1 -0
  105. package/esm/plugins/index.js.map +1 -0
  106. package/esm/plugins/index.mjs +8 -0
  107. package/esm/plugins/integration-example.d.ts +53 -0
  108. package/esm/plugins/integration-example.d.ts.map +1 -0
  109. package/esm/plugins/integration-example.js.map +1 -0
  110. package/esm/plugins/integration-example.mjs +88 -0
  111. package/esm/plugins/query-depth-limiter.d.ts +47 -0
  112. package/esm/plugins/query-depth-limiter.d.ts.map +1 -0
  113. package/esm/plugins/query-depth-limiter.js.map +1 -0
  114. package/esm/plugins/query-depth-limiter.mjs +146 -0
  115. package/esm/validators/allocation-validator.d.ts +32 -0
  116. package/esm/validators/allocation-validator.d.ts.map +1 -0
  117. package/esm/validators/allocation-validator.js.map +1 -0
  118. package/esm/validators/allocation-validator.mjs +80 -0
  119. package/generated/typegraphql-prisma/models/Trade.cjs +1 -1
  120. package/generated/typegraphql-prisma/models/Trade.d.ts +1 -1
  121. package/generated/typegraphql-prisma/models/Trade.d.ts.map +1 -1
  122. package/generated/typegraphql-prisma/models/Trade.js.map +1 -1
  123. package/generated/typegraphql-prisma/resolvers/crud/User/args/CreateOneUserArgs.cjs +2 -2
  124. package/generated/typegraphql-prisma/resolvers/crud/User/args/CreateOneUserArgs.d.ts +1 -1
  125. package/generated/typegraphql-prisma/resolvers/crud/User/args/CreateOneUserArgs.d.ts.map +1 -1
  126. package/generated/typegraphql-prisma/resolvers/crud/User/args/CreateOneUserArgs.js.map +1 -1
  127. package/generated/typegraphql-prisma/resolvers/inputs/TradeCreateInput.cjs +1 -1
  128. package/generated/typegraphql-prisma/resolvers/inputs/TradeCreateInput.d.ts +1 -1
  129. package/generated/typegraphql-prisma/resolvers/inputs/TradeCreateInput.d.ts.map +1 -1
  130. package/generated/typegraphql-prisma/resolvers/inputs/TradeCreateInput.js.map +1 -1
  131. package/generated/typegraphql-prisma/resolvers/inputs/TradeCreateManyInput.cjs +1 -1
  132. package/generated/typegraphql-prisma/resolvers/inputs/TradeCreateManyInput.d.ts +1 -1
  133. package/generated/typegraphql-prisma/resolvers/inputs/TradeCreateManyInput.d.ts.map +1 -1
  134. package/generated/typegraphql-prisma/resolvers/inputs/TradeCreateManyInput.js.map +1 -1
  135. package/generated/typegraphql-prisma/resolvers/inputs/TradeCreateWithoutActionsInput.cjs +1 -1
  136. package/generated/typegraphql-prisma/resolvers/inputs/TradeCreateWithoutActionsInput.d.ts +1 -1
  137. package/generated/typegraphql-prisma/resolvers/inputs/TradeCreateWithoutActionsInput.d.ts.map +1 -1
  138. package/generated/typegraphql-prisma/resolvers/inputs/TradeCreateWithoutActionsInput.js.map +1 -1
  139. package/generated/typegraphql-prisma/resolvers/inputs/TradeScalarWhereWithAggregatesInput.cjs +1 -1
  140. package/generated/typegraphql-prisma/resolvers/inputs/TradeScalarWhereWithAggregatesInput.d.ts +1 -1
  141. package/generated/typegraphql-prisma/resolvers/inputs/TradeScalarWhereWithAggregatesInput.d.ts.map +1 -1
  142. package/generated/typegraphql-prisma/resolvers/inputs/TradeScalarWhereWithAggregatesInput.js.map +1 -1
  143. package/generated/typegraphql-prisma/resolvers/inputs/TradeUpdateInput.cjs +1 -1
  144. package/generated/typegraphql-prisma/resolvers/inputs/TradeUpdateInput.d.ts +1 -1
  145. package/generated/typegraphql-prisma/resolvers/inputs/TradeUpdateInput.d.ts.map +1 -1
  146. package/generated/typegraphql-prisma/resolvers/inputs/TradeUpdateInput.js.map +1 -1
  147. package/generated/typegraphql-prisma/resolvers/inputs/TradeUpdateManyMutationInput.cjs +1 -1
  148. package/generated/typegraphql-prisma/resolvers/inputs/TradeUpdateManyMutationInput.d.ts +1 -1
  149. package/generated/typegraphql-prisma/resolvers/inputs/TradeUpdateManyMutationInput.d.ts.map +1 -1
  150. package/generated/typegraphql-prisma/resolvers/inputs/TradeUpdateManyMutationInput.js.map +1 -1
  151. package/generated/typegraphql-prisma/resolvers/inputs/TradeUpdateWithoutActionsInput.cjs +1 -1
  152. package/generated/typegraphql-prisma/resolvers/inputs/TradeUpdateWithoutActionsInput.d.ts +1 -1
  153. package/generated/typegraphql-prisma/resolvers/inputs/TradeUpdateWithoutActionsInput.d.ts.map +1 -1
  154. package/generated/typegraphql-prisma/resolvers/inputs/TradeUpdateWithoutActionsInput.js.map +1 -1
  155. package/generated/typegraphql-prisma/resolvers/inputs/TradeWhereInput.cjs +1 -1
  156. package/generated/typegraphql-prisma/resolvers/inputs/TradeWhereInput.d.ts +1 -1
  157. package/generated/typegraphql-prisma/resolvers/inputs/TradeWhereInput.d.ts.map +1 -1
  158. package/generated/typegraphql-prisma/resolvers/inputs/TradeWhereInput.js.map +1 -1
  159. package/generated/typegraphql-prisma/resolvers/inputs/TradeWhereUniqueInput.cjs +1 -1
  160. package/generated/typegraphql-prisma/resolvers/inputs/TradeWhereUniqueInput.d.ts +1 -1
  161. package/generated/typegraphql-prisma/resolvers/inputs/TradeWhereUniqueInput.d.ts.map +1 -1
  162. package/generated/typegraphql-prisma/resolvers/inputs/TradeWhereUniqueInput.js.map +1 -1
  163. package/generated/typegraphql-prisma/resolvers/outputs/CreateManyAndReturnTrade.cjs +1 -1
  164. package/generated/typegraphql-prisma/resolvers/outputs/CreateManyAndReturnTrade.d.ts +1 -1
  165. package/generated/typegraphql-prisma/resolvers/outputs/CreateManyAndReturnTrade.d.ts.map +1 -1
  166. package/generated/typegraphql-prisma/resolvers/outputs/CreateManyAndReturnTrade.js.map +1 -1
  167. package/generated/typegraphql-prisma/resolvers/outputs/TradeGroupBy.cjs +1 -1
  168. package/generated/typegraphql-prisma/resolvers/outputs/TradeGroupBy.d.ts +1 -1
  169. package/generated/typegraphql-prisma/resolvers/outputs/TradeGroupBy.d.ts.map +1 -1
  170. package/generated/typegraphql-prisma/resolvers/outputs/TradeGroupBy.js.map +1 -1
  171. package/generated/typegraphql-prisma/resolvers/outputs/TradeMaxAggregate.cjs +1 -1
  172. package/generated/typegraphql-prisma/resolvers/outputs/TradeMaxAggregate.d.ts +1 -1
  173. package/generated/typegraphql-prisma/resolvers/outputs/TradeMaxAggregate.d.ts.map +1 -1
  174. package/generated/typegraphql-prisma/resolvers/outputs/TradeMaxAggregate.js.map +1 -1
  175. package/generated/typegraphql-prisma/resolvers/outputs/TradeMinAggregate.cjs +1 -1
  176. package/generated/typegraphql-prisma/resolvers/outputs/TradeMinAggregate.d.ts +1 -1
  177. package/generated/typegraphql-prisma/resolvers/outputs/TradeMinAggregate.d.ts.map +1 -1
  178. package/generated/typegraphql-prisma/resolvers/outputs/TradeMinAggregate.js.map +1 -1
  179. package/getToken.cjs +2 -1
  180. package/package.json +1 -1
  181. package/server.cjs +35 -17
@@ -0,0 +1,163 @@
1
+ import { GraphQLError } from 'graphql';
2
+ import { validatePercentage, validatePositiveNumber, validateNonEmpty, ValidationError, } from './input-validator.mjs';
3
+ /**
4
+ * Predefined validation rules for common field patterns
5
+ */
6
+ const VALIDATION_RULES = [
7
+ // Percentage fields (0-100)
8
+ {
9
+ pattern: /.*Pct$/i,
10
+ validator: (value, fieldName) => {
11
+ if (typeof value === 'number') {
12
+ validatePercentage(value, fieldName);
13
+ }
14
+ },
15
+ description: 'Percentage fields ending with Pct',
16
+ },
17
+ {
18
+ pattern: /.*Percent(age)?$/i,
19
+ validator: (value, fieldName) => {
20
+ if (typeof value === 'number') {
21
+ validatePercentage(value, fieldName);
22
+ }
23
+ },
24
+ description: 'Percentage fields ending with Percent or Percentage',
25
+ },
26
+ // Quantity fields (must be positive)
27
+ {
28
+ pattern: /^quantity$/i,
29
+ validator: (value, fieldName) => {
30
+ if (typeof value === 'number') {
31
+ validatePositiveNumber(value, fieldName);
32
+ }
33
+ },
34
+ description: 'Quantity fields',
35
+ },
36
+ {
37
+ pattern: /.*Threshold$/i,
38
+ validator: (value, fieldName) => {
39
+ if (typeof value === 'number' && value !== 0) {
40
+ validatePositiveNumber(value, fieldName);
41
+ }
42
+ },
43
+ description: 'Threshold fields',
44
+ },
45
+ {
46
+ pattern: /^count$/i,
47
+ validator: (value, fieldName) => {
48
+ if (typeof value === 'number') {
49
+ validatePositiveNumber(value, fieldName);
50
+ }
51
+ },
52
+ description: 'Count fields',
53
+ },
54
+ // Required string fields (non-empty)
55
+ {
56
+ pattern: /^(name|title|description|symbol|type|status)$/i,
57
+ validator: (value, fieldName) => {
58
+ if (typeof value === 'string') {
59
+ validateNonEmpty(value, fieldName);
60
+ }
61
+ },
62
+ description: 'Common required string fields',
63
+ },
64
+ ];
65
+ /**
66
+ * Recursively validates an object's fields based on predefined rules
67
+ */
68
+ function validateObject(obj, path = '') {
69
+ const errors = [];
70
+ for (const [key, value] of Object.entries(obj)) {
71
+ const fieldPath = path ? `${path}.${key}` : key;
72
+ // Skip null or undefined values
73
+ if (value === null || value === undefined) {
74
+ continue;
75
+ }
76
+ // Recursively validate nested objects
77
+ if (typeof value === 'object' && !Array.isArray(value)) {
78
+ const nestedErrors = validateObject(value, fieldPath);
79
+ errors.push(...nestedErrors);
80
+ continue;
81
+ }
82
+ // Apply validation rules to the field
83
+ for (const rule of VALIDATION_RULES) {
84
+ if (rule.pattern.test(key)) {
85
+ try {
86
+ rule.validator(value, fieldPath);
87
+ }
88
+ catch (error) {
89
+ if (error instanceof ValidationError) {
90
+ errors.push(...error.fields);
91
+ }
92
+ }
93
+ break; // Only apply the first matching rule
94
+ }
95
+ }
96
+ }
97
+ return errors;
98
+ }
99
+ /**
100
+ * Apollo Server plugin that validates GraphQL mutation inputs
101
+ *
102
+ * This plugin intercepts all mutation operations and validates input fields
103
+ * before they reach the resolver. It applies validation rules based on field
104
+ * name patterns to ensure data integrity.
105
+ *
106
+ * @example
107
+ * ```typescript
108
+ * const server = new ApolloServer({
109
+ * schema,
110
+ * plugins: [
111
+ * ApolloServerPluginDrainHttpServer({ httpServer }),
112
+ * createValidationPlugin(),
113
+ * ],
114
+ * });
115
+ * ```
116
+ */
117
+ export function createValidationPlugin() {
118
+ return {
119
+ async requestDidStart() {
120
+ return {
121
+ async didResolveOperation(requestContext) {
122
+ const { operation, request } = requestContext;
123
+ // Only validate mutations
124
+ if (!operation || operation.operation !== 'mutation') {
125
+ return;
126
+ }
127
+ const variables = request.variables || {};
128
+ const errors = [];
129
+ // Validate each mutation's variables
130
+ for (const [variableName, variableValue] of Object.entries(variables)) {
131
+ if (variableValue && typeof variableValue === 'object') {
132
+ // Check if this is a data object (common pattern in mutations)
133
+ const dataObj = variableValue;
134
+ if ('data' in dataObj && typeof dataObj.data === 'object') {
135
+ const validationErrors = validateObject(dataObj.data, variableName);
136
+ errors.push(...validationErrors);
137
+ }
138
+ else {
139
+ // Validate the entire variable object
140
+ const validationErrors = validateObject(dataObj, variableName);
141
+ errors.push(...validationErrors);
142
+ }
143
+ }
144
+ }
145
+ // If there are validation errors, throw before resolver execution
146
+ if (errors.length > 0) {
147
+ throw new GraphQLError(`Input validation failed for ${errors.length} field${errors.length > 1 ? 's' : ''}`, {
148
+ extensions: {
149
+ code: 'BAD_USER_INPUT',
150
+ validationErrors: errors,
151
+ },
152
+ });
153
+ }
154
+ },
155
+ };
156
+ },
157
+ };
158
+ }
159
+ /**
160
+ * Export validation rules for testing and documentation
161
+ */
162
+ export { VALIDATION_RULES };
163
+ //# sourceMappingURL=graphql-validation-plugin.js.map
@@ -0,0 +1,12 @@
1
+ /**
2
+ * Input Validation Middleware
3
+ *
4
+ * Provides GraphQL mutation input validation through:
5
+ * 1. Manual validation functions for custom resolvers
6
+ * 2. Automatic validation plugin for pattern-based rules
7
+ */
8
+ export { validatePercentage, validatePositiveNumber, validateEmail, validateUrl, validateNonEmpty, validateConfidenceScore, validateFields, ValidationError, ValidationErrorDetail, } from './input-validator';
9
+ export { createValidationPlugin, VALIDATION_RULES, } from './graphql-validation-plugin';
10
+ export { authMiddleware, AuthenticatedRequest, } from './auth';
11
+ export { CustomValidators } from './validation-examples';
12
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/middleware/index.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAGH,OAAO,EACL,kBAAkB,EAClB,sBAAsB,EACtB,aAAa,EACb,WAAW,EACX,gBAAgB,EAChB,uBAAuB,EACvB,cAAc,EACd,eAAe,EACf,qBAAqB,GACtB,MAAM,mBAAmB,CAAC;AAG3B,OAAO,EACL,sBAAsB,EACtB,gBAAgB,GACjB,MAAM,6BAA6B,CAAC;AAGrC,OAAO,EACL,cAAc,EACd,oBAAoB,GACrB,MAAM,QAAQ,CAAC;AAGhB,OAAO,EAAE,gBAAgB,EAAE,MAAM,uBAAuB,CAAC"}
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/middleware/index.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,8BAA8B;AAC9B,OAAO,EACL,kBAAkB,EAClB,sBAAsB,EACtB,aAAa,EACb,WAAW,EACX,gBAAgB,EAChB,uBAAuB,EACvB,cAAc,EACd,eAAe,GAEhB,MAAM,mBAAmB,CAAC;AAE3B,mCAAmC;AACnC,OAAO,EACL,sBAAsB,EACtB,gBAAgB,GACjB,MAAM,6BAA6B,CAAC;AAErC,mCAAmC;AACnC,OAAO,EACL,cAAc,GAEf,MAAM,QAAQ,CAAC;AAEhB,0CAA0C;AAC1C,OAAO,EAAE,gBAAgB,EAAE,MAAM,uBAAuB,CAAC"}
@@ -0,0 +1,16 @@
1
+ /**
2
+ * Input Validation Middleware
3
+ *
4
+ * Provides GraphQL mutation input validation through:
5
+ * 1. Manual validation functions for custom resolvers
6
+ * 2. Automatic validation plugin for pattern-based rules
7
+ */
8
+ // Export validation functions
9
+ export { validatePercentage, validatePositiveNumber, validateEmail, validateUrl, validateNonEmpty, validateConfidenceScore, validateFields, ValidationError, } from './input-validator.mjs';
10
+ // Export GraphQL validation plugin
11
+ export { createValidationPlugin, VALIDATION_RULES, } from './graphql-validation-plugin.mjs';
12
+ // Export authentication middleware
13
+ export { authMiddleware, } from './auth.mjs';
14
+ // Export example validators for reference
15
+ export { CustomValidators } from './validation-examples.mjs';
16
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1,63 @@
1
+ import { GraphQLError } from 'graphql';
2
+ /**
3
+ * Validation error details for field-level error reporting
4
+ */
5
+ export interface ValidationErrorDetail {
6
+ field: string;
7
+ value: unknown;
8
+ message: string;
9
+ constraint: string;
10
+ }
11
+ /**
12
+ * Custom error class for validation failures
13
+ */
14
+ export declare class ValidationError extends GraphQLError {
15
+ readonly fields: ValidationErrorDetail[];
16
+ constructor(message: string, fields: ValidationErrorDetail[]);
17
+ }
18
+ /**
19
+ * Validates that a number is within the 0-100 percentage range
20
+ * @param value - The numeric value to validate
21
+ * @param fieldName - The name of the field for error reporting
22
+ * @throws ValidationError if the value is not between 0 and 100
23
+ */
24
+ export declare function validatePercentage(value: number, fieldName: string): void;
25
+ /**
26
+ * Validates that a number is positive (greater than 0)
27
+ * @param value - The numeric value to validate
28
+ * @param fieldName - The name of the field for error reporting
29
+ * @throws ValidationError if the value is not positive
30
+ */
31
+ export declare function validatePositiveNumber(value: number, fieldName: string): void;
32
+ /**
33
+ * Validates that a string is a valid email format
34
+ * @param value - The string value to validate
35
+ * @throws ValidationError if the value is not a valid email
36
+ */
37
+ export declare function validateEmail(value: string): void;
38
+ /**
39
+ * Validates that a string is a valid URL format
40
+ * @param value - The string value to validate
41
+ * @throws ValidationError if the value is not a valid URL
42
+ */
43
+ export declare function validateUrl(value: string): void;
44
+ /**
45
+ * Validates that a string is non-empty
46
+ * @param value - The string value to validate
47
+ * @param fieldName - The name of the field for error reporting
48
+ * @throws ValidationError if the value is empty or not a string
49
+ */
50
+ export declare function validateNonEmpty(value: string, fieldName: string): void;
51
+ /**
52
+ * Validates that a confidence score is within the 0-1 range
53
+ * @param value - The numeric value to validate
54
+ * @throws ValidationError if the value is not between 0 and 1
55
+ */
56
+ export declare function validateConfidenceScore(value: number): void;
57
+ /**
58
+ * Validates multiple fields and accumulates all validation errors
59
+ * @param validations - Array of validation functions to execute
60
+ * @throws ValidationError with all accumulated field errors
61
+ */
62
+ export declare function validateFields(validations: Array<() => void>): void;
63
+ //# sourceMappingURL=input-validator.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"input-validator.d.ts","sourceRoot":"","sources":["../../../src/middleware/input-validator.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AAEvC;;GAEG;AACH,MAAM,WAAW,qBAAqB;IACpC,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,EAAE,OAAO,CAAC;IACf,OAAO,EAAE,MAAM,CAAC;IAChB,UAAU,EAAE,MAAM,CAAC;CACpB;AAED;;GAEG;AACH,qBAAa,eAAgB,SAAQ,YAAY;IAC/C,SAAgB,MAAM,EAAE,qBAAqB,EAAE,CAAC;gBAEpC,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,qBAAqB,EAAE;CAS7D;AAED;;;;;GAKG;AACH,wBAAgB,kBAAkB,CAAC,KAAK,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,GAAG,IAAI,CAsBzE;AAED;;;;;GAKG;AACH,wBAAgB,sBAAsB,CAAC,KAAK,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,GAAG,IAAI,CAsB7E;AAED;;;;GAIG;AACH,wBAAgB,aAAa,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI,CAwBjD;AAED;;;;GAIG;AACH,wBAAgB,WAAW,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI,CAwB/C;AAED;;;;;GAKG;AACH,wBAAgB,gBAAgB,CAAC,KAAK,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,GAAG,IAAI,CAsBvE;AAED;;;;GAIG;AACH,wBAAgB,uBAAuB,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI,CAsB3D;AAED;;;;GAIG;AACH,wBAAgB,cAAc,CAAC,WAAW,EAAE,KAAK,CAAC,MAAM,IAAI,CAAC,GAAG,IAAI,CAkBnE"}
@@ -0,0 +1 @@
1
+ {"version":3,"file":"input-validator.js","sourceRoot":"","sources":["../../../src/middleware/input-validator.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AAYvC;;GAEG;AACH,MAAM,OAAO,eAAgB,SAAQ,YAAY;IAC/B,MAAM,CAA0B;IAEhD,YAAY,OAAe,EAAE,MAA+B;QAC1D,KAAK,CAAC,OAAO,EAAE;YACb,UAAU,EAAE;gBACV,IAAI,EAAE,gBAAgB;gBACtB,gBAAgB,EAAE,MAAM;aACzB;SACF,CAAC,CAAC;QACH,IAAI,CAAC,MAAM,GAAG,MAAM,CAAC;IACvB,CAAC;CACF;AAED;;;;;GAKG;AACH,MAAM,UAAU,kBAAkB,CAAC,KAAa,EAAE,SAAiB;IACjE,IAAI,OAAO,KAAK,KAAK,QAAQ,IAAI,KAAK,CAAC,KAAK,CAAC,EAAE,CAAC;QAC9C,MAAM,IAAI,eAAe,CAAC,0BAA0B,EAAE;YACpD;gBACE,KAAK,EAAE,SAAS;gBAChB,KAAK;gBACL,OAAO,EAAE,wBAAwB;gBACjC,UAAU,EAAE,UAAU;aACvB;SACF,CAAC,CAAC;IACL,CAAC;IAED,IAAI,KAAK,GAAG,CAAC,IAAI,KAAK,GAAG,GAAG,EAAE,CAAC;QAC7B,MAAM,IAAI,eAAe,CAAC,yBAAyB,EAAE;YACnD;gBACE,KAAK,EAAE,SAAS;gBAChB,KAAK;gBACL,OAAO,EAAE,2BAA2B;gBACpC,UAAU,EAAE,OAAO;aACpB;SACF,CAAC,CAAC;IACL,CAAC;AACH,CAAC;AAED;;;;;GAKG;AACH,MAAM,UAAU,sBAAsB,CAAC,KAAa,EAAE,SAAiB;IACrE,IAAI,OAAO,KAAK,KAAK,QAAQ,IAAI,KAAK,CAAC,KAAK,CAAC,EAAE,CAAC;QAC9C,MAAM,IAAI,eAAe,CAAC,uBAAuB,EAAE;YACjD;gBACE,KAAK,EAAE,SAAS;gBAChB,KAAK;gBACL,OAAO,EAAE,wBAAwB;gBACjC,UAAU,EAAE,UAAU;aACvB;SACF,CAAC,CAAC;IACL,CAAC;IAED,IAAI,KAAK,IAAI,CAAC,EAAE,CAAC;QACf,MAAM,IAAI,eAAe,CAAC,yBAAyB,EAAE;YACnD;gBACE,KAAK,EAAE,SAAS;gBAChB,KAAK;gBACL,OAAO,EAAE,wBAAwB;gBACjC,UAAU,EAAE,UAAU;aACvB;SACF,CAAC,CAAC;IACL,CAAC;AACH,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,aAAa,CAAC,KAAa;IACzC,MAAM,UAAU,GAAG,4BAA4B,CAAC;IAEhD,IAAI,OAAO,KAAK,KAAK,QAAQ,EAAE,CAAC;QAC9B,MAAM,IAAI,eAAe,CAAC,qBAAqB,EAAE;YAC/C;gBACE,KAAK,EAAE,OAAO;gBACd,KAAK;gBACL,OAAO,EAAE,kBAAkB;gBAC3B,UAAU,EAAE,UAAU;aACvB;SACF,CAAC,CAAC;IACL,CAAC;IAED,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC,KAAK,CAAC,EAAE,CAAC;QAC5B,MAAM,IAAI,eAAe,CAAC,sBAAsB,EAAE;YAChD;gBACE,KAAK,EAAE,OAAO;gBACd,KAAK;gBACL,OAAO,EAAE,+BAA+B;gBACxC,UAAU,EAAE,OAAO;aACpB;SACF,CAAC,CAAC;IACL,CAAC;AACH,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,WAAW,CAAC,KAAa;IACvC,IAAI,OAAO,KAAK,KAAK,QAAQ,EAAE,CAAC;QAC9B,MAAM,IAAI,eAAe,CAAC,mBAAmB,EAAE;YAC7C;gBACE,KAAK,EAAE,KAAK;gBACZ,KAAK;gBACL,OAAO,EAAE,kBAAkB;gBAC3B,UAAU,EAAE,UAAU;aACvB;SACF,CAAC,CAAC;IACL,CAAC;IAED,IAAI,CAAC;QACH,IAAI,GAAG,CAAC,KAAK,CAAC,CAAC;IACjB,CAAC;IAAC,MAAM,CAAC;QACP,MAAM,IAAI,eAAe,CAAC,oBAAoB,EAAE;YAC9C;gBACE,KAAK,EAAE,KAAK;gBACZ,KAAK;gBACL,OAAO,EAAE,qBAAqB;gBAC9B,UAAU,EAAE,KAAK;aAClB;SACF,CAAC,CAAC;IACL,CAAC;AACH,CAAC;AAED;;;;;GAKG;AACH,MAAM,UAAU,gBAAgB,CAAC,KAAa,EAAE,SAAiB;IAC/D,IAAI,OAAO,KAAK,KAAK,QAAQ,EAAE,CAAC;QAC9B,MAAM,IAAI,eAAe,CAAC,sBAAsB,EAAE;YAChD;gBACE,KAAK,EAAE,SAAS;gBAChB,KAAK;gBACL,OAAO,EAAE,kBAAkB;gBAC3B,UAAU,EAAE,UAAU;aACvB;SACF,CAAC,CAAC;IACL,CAAC;IAED,IAAI,KAAK,CAAC,IAAI,EAAE,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QAC9B,MAAM,IAAI,eAAe,CAAC,wBAAwB,EAAE;YAClD;gBACE,KAAK,EAAE,SAAS;gBAChB,KAAK;gBACL,OAAO,EAAE,mBAAmB;gBAC5B,UAAU,EAAE,UAAU;aACvB;SACF,CAAC,CAAC;IACL,CAAC;AACH,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,uBAAuB,CAAC,KAAa;IACnD,IAAI,OAAO,KAAK,KAAK,QAAQ,IAAI,KAAK,CAAC,KAAK,CAAC,EAAE,CAAC;QAC9C,MAAM,IAAI,eAAe,CAAC,0BAA0B,EAAE;YACpD;gBACE,KAAK,EAAE,iBAAiB;gBACxB,KAAK;gBACL,OAAO,EAAE,wBAAwB;gBACjC,UAAU,EAAE,UAAU;aACvB;SACF,CAAC,CAAC;IACL,CAAC;IAED,IAAI,KAAK,GAAG,CAAC,IAAI,KAAK,GAAG,CAAC,EAAE,CAAC;QAC3B,MAAM,IAAI,eAAe,CAAC,+BAA+B,EAAE;YACzD;gBACE,KAAK,EAAE,iBAAiB;gBACxB,KAAK;gBACL,OAAO,EAAE,yBAAyB;gBAClC,UAAU,EAAE,OAAO;aACpB;SACF,CAAC,CAAC;IACL,CAAC;AACH,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,cAAc,CAAC,WAA8B;IAC3D,MAAM,MAAM,GAA4B,EAAE,CAAC;IAE3C,KAAK,MAAM,UAAU,IAAI,WAAW,EAAE,CAAC;QACrC,IAAI,CAAC;YACH,UAAU,EAAE,CAAC;QACf,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,IAAI,KAAK,YAAY,eAAe,EAAE,CAAC;gBACrC,MAAM,CAAC,IAAI,CAAC,GAAG,KAAK,CAAC,MAAM,CAAC,CAAC;YAC/B,CAAC;iBAAM,CAAC;gBACN,MAAM,KAAK,CAAC;YACd,CAAC;QACH,CAAC;IACH,CAAC;IAED,IAAI,MAAM,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QACtB,MAAM,IAAI,eAAe,CAAC,uCAAuC,EAAE,MAAM,CAAC,CAAC;IAC7E,CAAC;AACH,CAAC"}
@@ -0,0 +1,210 @@
1
+ import { GraphQLError } from 'graphql';
2
+ /**
3
+ * Custom error class for validation failures
4
+ */
5
+ export class ValidationError extends GraphQLError {
6
+ fields;
7
+ constructor(message, fields) {
8
+ super(message, {
9
+ extensions: {
10
+ code: 'BAD_USER_INPUT',
11
+ validationErrors: fields,
12
+ },
13
+ });
14
+ this.fields = fields;
15
+ }
16
+ }
17
+ /**
18
+ * Validates that a number is within the 0-100 percentage range
19
+ * @param value - The numeric value to validate
20
+ * @param fieldName - The name of the field for error reporting
21
+ * @throws ValidationError if the value is not between 0 and 100
22
+ */
23
+ export function validatePercentage(value, fieldName) {
24
+ if (typeof value !== 'number' || isNaN(value)) {
25
+ throw new ValidationError('Invalid percentage value', [
26
+ {
27
+ field: fieldName,
28
+ value,
29
+ message: 'Must be a valid number',
30
+ constraint: 'isNumber',
31
+ },
32
+ ]);
33
+ }
34
+ if (value < 0 || value > 100) {
35
+ throw new ValidationError('Percentage out of range', [
36
+ {
37
+ field: fieldName,
38
+ value,
39
+ message: 'Must be between 0 and 100',
40
+ constraint: 'range',
41
+ },
42
+ ]);
43
+ }
44
+ }
45
+ /**
46
+ * Validates that a number is positive (greater than 0)
47
+ * @param value - The numeric value to validate
48
+ * @param fieldName - The name of the field for error reporting
49
+ * @throws ValidationError if the value is not positive
50
+ */
51
+ export function validatePositiveNumber(value, fieldName) {
52
+ if (typeof value !== 'number' || isNaN(value)) {
53
+ throw new ValidationError('Invalid numeric value', [
54
+ {
55
+ field: fieldName,
56
+ value,
57
+ message: 'Must be a valid number',
58
+ constraint: 'isNumber',
59
+ },
60
+ ]);
61
+ }
62
+ if (value <= 0) {
63
+ throw new ValidationError('Number must be positive', [
64
+ {
65
+ field: fieldName,
66
+ value,
67
+ message: 'Must be greater than 0',
68
+ constraint: 'positive',
69
+ },
70
+ ]);
71
+ }
72
+ }
73
+ /**
74
+ * Validates that a string is a valid email format
75
+ * @param value - The string value to validate
76
+ * @throws ValidationError if the value is not a valid email
77
+ */
78
+ export function validateEmail(value) {
79
+ const emailRegex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
80
+ if (typeof value !== 'string') {
81
+ throw new ValidationError('Invalid email value', [
82
+ {
83
+ field: 'email',
84
+ value,
85
+ message: 'Must be a string',
86
+ constraint: 'isString',
87
+ },
88
+ ]);
89
+ }
90
+ if (!emailRegex.test(value)) {
91
+ throw new ValidationError('Invalid email format', [
92
+ {
93
+ field: 'email',
94
+ value,
95
+ message: 'Must be a valid email address',
96
+ constraint: 'email',
97
+ },
98
+ ]);
99
+ }
100
+ }
101
+ /**
102
+ * Validates that a string is a valid URL format
103
+ * @param value - The string value to validate
104
+ * @throws ValidationError if the value is not a valid URL
105
+ */
106
+ export function validateUrl(value) {
107
+ if (typeof value !== 'string') {
108
+ throw new ValidationError('Invalid URL value', [
109
+ {
110
+ field: 'url',
111
+ value,
112
+ message: 'Must be a string',
113
+ constraint: 'isString',
114
+ },
115
+ ]);
116
+ }
117
+ try {
118
+ new URL(value);
119
+ }
120
+ catch {
121
+ throw new ValidationError('Invalid URL format', [
122
+ {
123
+ field: 'url',
124
+ value,
125
+ message: 'Must be a valid URL',
126
+ constraint: 'url',
127
+ },
128
+ ]);
129
+ }
130
+ }
131
+ /**
132
+ * Validates that a string is non-empty
133
+ * @param value - The string value to validate
134
+ * @param fieldName - The name of the field for error reporting
135
+ * @throws ValidationError if the value is empty or not a string
136
+ */
137
+ export function validateNonEmpty(value, fieldName) {
138
+ if (typeof value !== 'string') {
139
+ throw new ValidationError('Invalid string value', [
140
+ {
141
+ field: fieldName,
142
+ value,
143
+ message: 'Must be a string',
144
+ constraint: 'isString',
145
+ },
146
+ ]);
147
+ }
148
+ if (value.trim().length === 0) {
149
+ throw new ValidationError('String cannot be empty', [
150
+ {
151
+ field: fieldName,
152
+ value,
153
+ message: 'Must not be empty',
154
+ constraint: 'notEmpty',
155
+ },
156
+ ]);
157
+ }
158
+ }
159
+ /**
160
+ * Validates that a confidence score is within the 0-1 range
161
+ * @param value - The numeric value to validate
162
+ * @throws ValidationError if the value is not between 0 and 1
163
+ */
164
+ export function validateConfidenceScore(value) {
165
+ if (typeof value !== 'number' || isNaN(value)) {
166
+ throw new ValidationError('Invalid confidence score', [
167
+ {
168
+ field: 'confidenceScore',
169
+ value,
170
+ message: 'Must be a valid number',
171
+ constraint: 'isNumber',
172
+ },
173
+ ]);
174
+ }
175
+ if (value < 0 || value > 1) {
176
+ throw new ValidationError('Confidence score out of range', [
177
+ {
178
+ field: 'confidenceScore',
179
+ value,
180
+ message: 'Must be between 0 and 1',
181
+ constraint: 'range',
182
+ },
183
+ ]);
184
+ }
185
+ }
186
+ /**
187
+ * Validates multiple fields and accumulates all validation errors
188
+ * @param validations - Array of validation functions to execute
189
+ * @throws ValidationError with all accumulated field errors
190
+ */
191
+ export function validateFields(validations) {
192
+ const errors = [];
193
+ for (const validation of validations) {
194
+ try {
195
+ validation();
196
+ }
197
+ catch (error) {
198
+ if (error instanceof ValidationError) {
199
+ errors.push(...error.fields);
200
+ }
201
+ else {
202
+ throw error;
203
+ }
204
+ }
205
+ }
206
+ if (errors.length > 0) {
207
+ throw new ValidationError('Validation failed for multiple fields', errors);
208
+ }
209
+ }
210
+ //# sourceMappingURL=input-validator.js.map
@@ -0,0 +1,12 @@
1
+ import { Request, Response, NextFunction } from 'express';
2
+ /**
3
+ * Rate limiter for GraphQL endpoint
4
+ * Allows 1000 requests per 15 minutes by default (configurable via RATE_LIMIT_MAX env var)
5
+ */
6
+ export declare const graphqlRateLimiter: (req: Request, res: Response, next: NextFunction) => void;
7
+ /**
8
+ * Rate limiter for authentication endpoints
9
+ * Allows 50 requests per 15 minutes (stricter for auth)
10
+ */
11
+ export declare const authRateLimiter: (req: Request, res: Response, next: NextFunction) => void;
12
+ //# sourceMappingURL=rate-limiter.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"rate-limiter.d.ts","sourceRoot":"","sources":["../../../src/middleware/rate-limiter.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,OAAO,EAAE,QAAQ,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AAoE1D;;;GAGG;AACH,eAAO,MAAM,kBAAkB,QArChB,OAAO,OAAO,QAAQ,QAAQ,YAAY,KAAG,IA2C1D,CAAC;AAEH;;;GAGG;AACH,eAAO,MAAM,eAAe,QAjDb,OAAO,OAAO,QAAQ,QAAQ,YAAY,KAAG,IAuD1D,CAAC"}
@@ -0,0 +1 @@
1
+ {"version":3,"file":"rate-limiter.js","sourceRoot":"","sources":["../../../src/middleware/rate-limiter.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,68 @@
1
+ // Integration: add to server.ts - app.use('/graphql', graphqlRateLimiter) and app.use('/auth', authRateLimiter)
2
+ /**
3
+ * Creates a simple in-memory rate limiter middleware
4
+ * @param config - Rate limit configuration
5
+ * @returns Express middleware function
6
+ */
7
+ function createRateLimiter(config) {
8
+ const store = {};
9
+ // Clean up expired entries every minute
10
+ setInterval(() => {
11
+ const now = Date.now();
12
+ Object.keys(store).forEach((key) => {
13
+ if (store[key].resetTime < now) {
14
+ delete store[key];
15
+ }
16
+ });
17
+ }, 60000);
18
+ return (req, res, next) => {
19
+ const identifier = req.ip || req.connection.remoteAddress || 'unknown';
20
+ const now = Date.now();
21
+ if (!store[identifier] || store[identifier].resetTime < now) {
22
+ store[identifier] = {
23
+ count: 1,
24
+ resetTime: now + config.windowMs,
25
+ };
26
+ }
27
+ else {
28
+ store[identifier].count += 1;
29
+ }
30
+ const current = store[identifier];
31
+ const remaining = Math.max(0, config.max - current.count);
32
+ const resetTime = Math.ceil((current.resetTime - now) / 1000);
33
+ // Add rate limit headers
34
+ if (config.standardHeaders !== false) {
35
+ res.setHeader('X-RateLimit-Limit', config.max.toString());
36
+ res.setHeader('X-RateLimit-Remaining', remaining.toString());
37
+ res.setHeader('X-RateLimit-Reset', resetTime.toString());
38
+ }
39
+ if (current.count > config.max) {
40
+ res.status(429).json(config.message);
41
+ return;
42
+ }
43
+ next();
44
+ };
45
+ }
46
+ /**
47
+ * Rate limiter for GraphQL endpoint
48
+ * Allows 1000 requests per 15 minutes by default (configurable via RATE_LIMIT_MAX env var)
49
+ */
50
+ export const graphqlRateLimiter = createRateLimiter({
51
+ windowMs: 15 * 60 * 1000, // 15 minutes
52
+ max: parseInt(process.env.RATE_LIMIT_MAX || '1000', 10),
53
+ standardHeaders: true,
54
+ legacyHeaders: false,
55
+ message: { errors: [{ message: 'Too many requests, please try again later.' }] },
56
+ });
57
+ /**
58
+ * Rate limiter for authentication endpoints
59
+ * Allows 50 requests per 15 minutes (stricter for auth)
60
+ */
61
+ export const authRateLimiter = createRateLimiter({
62
+ windowMs: 15 * 60 * 1000, // 15 minutes
63
+ max: 50,
64
+ standardHeaders: true,
65
+ legacyHeaders: false,
66
+ message: { errors: [{ message: 'Too many authentication attempts.' }] },
67
+ });
68
+ //# sourceMappingURL=rate-limiter.js.map
@@ -0,0 +1,87 @@
1
+ /**
2
+ * Type definitions for validation middleware
3
+ */
4
+ import { GraphQLError } from 'graphql';
5
+ import { ValidationErrorDetail } from './input-validator';
6
+ /**
7
+ * Configuration options for the validation plugin
8
+ */
9
+ export interface ValidationPluginOptions {
10
+ /**
11
+ * Whether to skip validation for specific operations
12
+ */
13
+ skipOperations?: string[];
14
+ /**
15
+ * Custom validation rules to add to the default set
16
+ */
17
+ customRules?: FieldValidationRule[];
18
+ /**
19
+ * Whether to log validation errors for debugging
20
+ */
21
+ debug?: boolean;
22
+ }
23
+ /**
24
+ * Field validation rule definition
25
+ */
26
+ export interface FieldValidationRule {
27
+ /**
28
+ * Regular expression pattern to match field names
29
+ */
30
+ pattern: RegExp;
31
+ /**
32
+ * Validation function to apply to matching fields
33
+ * @param value - The field value to validate
34
+ * @param fieldName - The name of the field being validated
35
+ */
36
+ validator: (value: unknown, fieldName: string) => void;
37
+ /**
38
+ * Human-readable description of what this rule validates
39
+ */
40
+ description: string;
41
+ }
42
+ /**
43
+ * GraphQL operation context with validation information
44
+ */
45
+ export interface ValidationContext {
46
+ /**
47
+ * The GraphQL operation being executed
48
+ */
49
+ operation: {
50
+ operation: 'query' | 'mutation' | 'subscription';
51
+ name?: {
52
+ value: string;
53
+ };
54
+ };
55
+ /**
56
+ * The request variables
57
+ */
58
+ request: {
59
+ variables?: Record<string, unknown>;
60
+ };
61
+ }
62
+ /**
63
+ * Result of a validation check
64
+ */
65
+ export interface ValidationResult {
66
+ /**
67
+ * Whether validation passed
68
+ */
69
+ valid: boolean;
70
+ /**
71
+ * Array of validation errors (empty if valid)
72
+ */
73
+ errors: ValidationErrorDetail[];
74
+ }
75
+ /**
76
+ * Type guard to check if an error is a ValidationError
77
+ */
78
+ export declare function isValidationError(error: unknown): error is GraphQLError;
79
+ /**
80
+ * Type-safe validator function signature
81
+ */
82
+ export type Validator<T> = (value: T, fieldName: string) => void;
83
+ /**
84
+ * Validation constraint types
85
+ */
86
+ export type ValidationConstraint = 'isNumber' | 'isString' | 'range' | 'positive' | 'negative' | 'notEmpty' | 'email' | 'url' | 'minimum' | 'maximum' | 'sum' | 'comparison' | 'userLimit' | 'maxLength' | 'custom';
87
+ //# sourceMappingURL=types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../src/middleware/types.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AACvC,OAAO,EAAE,qBAAqB,EAAE,MAAM,mBAAmB,CAAC;AAE1D;;GAEG;AACH,MAAM,WAAW,uBAAuB;IACtC;;OAEG;IACH,cAAc,CAAC,EAAE,MAAM,EAAE,CAAC;IAE1B;;OAEG;IACH,WAAW,CAAC,EAAE,mBAAmB,EAAE,CAAC;IAEpC;;OAEG;IACH,KAAK,CAAC,EAAE,OAAO,CAAC;CACjB;AAED;;GAEG;AACH,MAAM,WAAW,mBAAmB;IAClC;;OAEG;IACH,OAAO,EAAE,MAAM,CAAC;IAEhB;;;;OAIG;IACH,SAAS,EAAE,CAAC,KAAK,EAAE,OAAO,EAAE,SAAS,EAAE,MAAM,KAAK,IAAI,CAAC;IAEvD;;OAEG;IACH,WAAW,EAAE,MAAM,CAAC;CACrB;AAED;;GAEG;AACH,MAAM,WAAW,iBAAiB;IAChC;;OAEG;IACH,SAAS,EAAE;QACT,SAAS,EAAE,OAAO,GAAG,UAAU,GAAG,cAAc,CAAC;QACjD,IAAI,CAAC,EAAE;YACL,KAAK,EAAE,MAAM,CAAC;SACf,CAAC;KACH,CAAC;IAEF;;OAEG;IACH,OAAO,EAAE;QACP,SAAS,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;KACrC,CAAC;CACH;AAED;;GAEG;AACH,MAAM,WAAW,gBAAgB;IAC/B;;OAEG;IACH,KAAK,EAAE,OAAO,CAAC;IAEf;;OAEG;IACH,MAAM,EAAE,qBAAqB,EAAE,CAAC;CACjC;AAED;;GAEG;AACH,wBAAgB,iBAAiB,CAAC,KAAK,EAAE,OAAO,GAAG,KAAK,IAAI,YAAY,CAMvE;AAED;;GAEG;AACH,MAAM,MAAM,SAAS,CAAC,CAAC,IAAI,CAAC,KAAK,EAAE,CAAC,EAAE,SAAS,EAAE,MAAM,KAAK,IAAI,CAAC;AAEjE;;GAEG;AACH,MAAM,MAAM,oBAAoB,GAC5B,UAAU,GACV,UAAU,GACV,OAAO,GACP,UAAU,GACV,UAAU,GACV,UAAU,GACV,OAAO,GACP,KAAK,GACL,SAAS,GACT,SAAS,GACT,KAAK,GACL,YAAY,GACZ,WAAW,GACX,WAAW,GACX,QAAQ,CAAC"}
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.js","sourceRoot":"","sources":["../../../src/middleware/types.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AAkFvC;;GAEG;AACH,MAAM,UAAU,iBAAiB,CAAC,KAAc;IAC9C,OAAO,CACL,KAAK,YAAY,YAAY;QAC7B,KAAK,CAAC,UAAU,EAAE,IAAI,KAAK,gBAAgB;QAC3C,kBAAkB,IAAI,CAAC,KAAK,CAAC,UAAU,IAAI,EAAE,CAAC,CAC/C,CAAC;AACJ,CAAC"}