@nattyjs/core 0.0.1-beta.3 → 0.0.1-beta.31

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/dist/index.cjs CHANGED
@@ -60,10 +60,13 @@ const nattyContainer = new class {
60
60
  this.container = /* @__PURE__ */ new Map();
61
61
  this.containerState = /* @__PURE__ */ new Map();
62
62
  }
63
- setup(config, routes, types) {
63
+ get types() {
64
+ return common.commonContainer.types;
65
+ }
66
+ setup(config, routes, resolver) {
64
67
  this.config = config;
65
68
  this.routes = routes;
66
- this.types = types;
69
+ this.resolver = resolver;
67
70
  }
68
71
  getTypes() {
69
72
  return StaticContainer.types;
@@ -116,7 +119,7 @@ const nattyContainer = new class {
116
119
  function init(config, appConfig) {
117
120
  common.commonContainer.setupConfig(config);
118
121
  common.commonContainer.setEnvTsDefinition(appConfig.envTsDefinition);
119
- nattyContainer.setup(config, appConfig.routes, appConfig.types);
122
+ nattyContainer.setup(config, appConfig.routes, appConfig.resolver);
120
123
  return initializeModule(config);
121
124
  }
122
125
  function initializeModule(config) {
@@ -125,22 +128,26 @@ function initializeModule(config) {
125
128
  }
126
129
  }
127
130
 
128
- function getPreResponseBody(body) {
131
+ function getPreResponseBody(body, isBuffer = false) {
129
132
  let bodyInfo;
130
133
  if (body) {
131
- if (common.isObject(body) || Array.isArray(body))
132
- bodyInfo = { json: body };
133
- const typeText = typeof body;
134
- switch (typeText) {
135
- case "string":
136
- bodyInfo = { string: body };
137
- break;
138
- case "number":
139
- bodyInfo = { number: body };
140
- break;
141
- case "boolean":
142
- bodyInfo = { boolean: body };
143
- break;
134
+ if (isBuffer)
135
+ bodyInfo = { buffer: body };
136
+ else {
137
+ if (common.isObject(body) || Array.isArray(body))
138
+ bodyInfo = { json: body };
139
+ const typeText = typeof body;
140
+ switch (typeText) {
141
+ case "string":
142
+ bodyInfo = { string: body };
143
+ break;
144
+ case "number":
145
+ bodyInfo = { number: body };
146
+ break;
147
+ case "boolean":
148
+ bodyInfo = { boolean: body };
149
+ break;
150
+ }
144
151
  }
145
152
  }
146
153
  return bodyInfo;
@@ -154,6 +161,7 @@ class HttpResponse {
154
161
  }
155
162
  setValues(responseInit) {
156
163
  if (responseInit) {
164
+ this._isBuffer = responseInit.isBuffer;
157
165
  if (responseInit.headers)
158
166
  for (const [key, value] of Object.entries(responseInit.headers))
159
167
  this.headers.append(key, value);
@@ -185,7 +193,7 @@ class HttpResponse {
185
193
  return this._body;
186
194
  }
187
195
  set body(value) {
188
- this._body = getPreResponseBody(value);
196
+ this._body = getPreResponseBody(value, this._isBuffer);
189
197
  }
190
198
  write(responseInit) {
191
199
  this.setValues(responseInit);
@@ -207,6 +215,26 @@ var RequestPipeline = /* @__PURE__ */ ((RequestPipeline2) => {
207
215
  return RequestPipeline2;
208
216
  })(RequestPipeline || {});
209
217
 
218
+ function lessThan(value) {
219
+ return value ? value.replace(/</g, "&lt;") : value;
220
+ }
221
+ function greaterThan(value) {
222
+ return value ? value.replace(/>/g, "&gt;") : value;
223
+ }
224
+ function ampersand(value) {
225
+ return value ? value.replace(/&/g, "&amp;") : value;
226
+ }
227
+ function doubleDash(value) {
228
+ return value ? value.replace(/--/g, "") : value;
229
+ }
230
+ function sanitizeSpecialCodes(value) {
231
+ value = ampersand(value);
232
+ value = lessThan(value);
233
+ value = greaterThan(value);
234
+ value = doubleDash(value);
235
+ return value;
236
+ }
237
+
210
238
  function isBoolean(value) {
211
239
  return typeof value === "boolean" || value === "1" || value === "true" || value === "0" || value === "false";
212
240
  }
@@ -267,7 +295,7 @@ function toInt(value, radix = 0) {
267
295
  }
268
296
  function toString(value) {
269
297
  if (isNotBlank(value))
270
- return String(value);
298
+ return sanitizeSpecialCodes(String(value));
271
299
  return value;
272
300
  }
273
301
  function whitelist(value, chars) {
@@ -348,6 +376,7 @@ class BaseResult {
348
376
  }
349
377
 
350
378
  function getResponseBodyObject(body, props) {
379
+ const sensitiveProps = common.commonContainer.nattyConfig?.secure?.sensitiveProps;
351
380
  if (body instanceof common.List)
352
381
  return getResponseBodyObject(body.values, body.props);
353
382
  if (Array.isArray(body)) {
@@ -361,7 +390,8 @@ function getResponseBodyObject(body, props) {
361
390
  const keys = Object.keys(body);
362
391
  const getterProps = props ? Object.keys(props).map((key) => props[key]) : [];
363
392
  for (const key of [...keys, ...getterProps])
364
- jObject[key] = getResponseBodyObject(body[key]);
393
+ if (!sensitiveProps || sensitiveProps.filter((t) => t == key.toLowerCase()).length == 0)
394
+ jObject[key] = getResponseBodyObject(body[key]);
365
395
  return jObject;
366
396
  }
367
397
  return body;
@@ -524,12 +554,14 @@ class ParameterTypeConverter extends BaseResponse {
524
554
  } else {
525
555
  if (this.isArrayType(property.type) && Array.isArray(value)) {
526
556
  let arrayValue = body[property.name] = [];
527
- let arrayInvalidProps = invalidProps[property.name] = [];
528
557
  for (const item of value) {
529
558
  const sanitizeValue = this.sanitizer[property.type.toLowerCase()] ? this.sanitizer[property.type.toLowerCase()](item) : item;
530
- if (sanitizeValue === INVALID_VALUE)
559
+ if (sanitizeValue === INVALID_VALUE) {
560
+ let arrayInvalidProps = invalidProps[property.name];
561
+ if (!arrayInvalidProps)
562
+ arrayInvalidProps = invalidProps[property.name] = [];
531
563
  arrayInvalidProps.push(property);
532
- else
564
+ } else
533
565
  arrayValue.push(sanitizeValue);
534
566
  }
535
567
  } else
@@ -557,7 +589,7 @@ class ParameterTypeConverter extends BaseResponse {
557
589
  }
558
590
  convertToInstance(entityName, data) {
559
591
  const typesInfo = this.types[entityName];
560
- const target = this.getClassTarget(typesInfo.path) || entityContainer.getTarget(entityName);
592
+ const target = this.getClassTarget(typesInfo.path, entityName) || entityContainer.getTarget(entityName);
561
593
  let instance = null;
562
594
  if (target) {
563
595
  instance = new target();
@@ -566,11 +598,10 @@ class ParameterTypeConverter extends BaseResponse {
566
598
  instance = data;
567
599
  return instance;
568
600
  }
569
- getClassTarget(resolver) {
570
- if (resolver) {
571
- const classInfo = resolver();
572
- const name = Object.keys(classInfo)[0];
573
- return classInfo[name];
601
+ getClassTarget(path, entityName) {
602
+ if (path) {
603
+ const classInfo = nattyContainer.resolver(path);
604
+ return classInfo[entityName];
574
605
  }
575
606
  return void 0;
576
607
  }
@@ -847,6 +878,14 @@ class ActionExecutedContext extends AbstractExecutionContext {
847
878
  }
848
879
  }
849
880
 
881
+ class AuthorizationContext extends AbstractExecutionContext {
882
+ constructor(models, context, routeInfo, config) {
883
+ super(context, routeInfo);
884
+ this.models = models;
885
+ this.config = config;
886
+ }
887
+ }
888
+
850
889
  class RequestProcessor extends RouteParser {
851
890
  constructor() {
852
891
  super(...arguments);
@@ -857,9 +896,6 @@ class RequestProcessor extends RouteParser {
857
896
  case RequestPipeline.onAuthentication:
858
897
  await this.onAuthentication();
859
898
  break;
860
- case RequestPipeline.onAuthorization:
861
- await this.onAuthorization();
862
- break;
863
899
  }
864
900
  }
865
901
  resolveFilter(instance) {
@@ -885,21 +921,27 @@ class RequestProcessor extends RouteParser {
885
921
  this.httpContext.user = result;
886
922
  if (!result.isAuthenticate && !anonymousInfo.controllerConfig && !anonymousInfo.methodConfig)
887
923
  throw new UnauthorizedAccessException(authenticationFilter.onFailedResponse());
888
- await this.onAuthorization();
889
924
  }
890
925
  }
891
- async onAuthorization() {
926
+ async onAuthorization(methodParameters) {
892
927
  const authorization = common.commonContainer.globalConfig.authorization;
893
928
  const authorizationFilter = authorization ? this.resolveFilter(authorization) : void 0;
894
929
  const authorizeConfig = decoratorStateContainer.getInfo(this.routeInfo.controller.name, this.routeInfo.methodInfo.name, DecoratorType.authorize);
895
930
  const authenticationOnly = decoratorStateContainer.getInfo(this.routeInfo.controller.name, this.routeInfo.methodInfo.name, DecoratorType.authenticationOnly);
896
- if (this.httpContext.user?.isAuthenticate && authorizationFilter && (!authenticationOnly.controllerConfig && !authenticationOnly.methodConfig)) {
897
- const result = await authorizationFilter.onAuthorization(this.httpContext, authorizeConfig.methodConfig || authorizeConfig.controllerConfig);
931
+ if (this.httpContext.user?.isAuthenticate && authorizationFilter && (authorizeConfig.controllerConfig || authorizeConfig.methodConfig) && (!authenticationOnly.controllerConfig && !authenticationOnly.methodConfig)) {
932
+ const authorizationContext = new AuthorizationContext(
933
+ methodParameters.filter((t) => t instanceof ModelBindingContext),
934
+ this.httpContext,
935
+ this.routeInfo,
936
+ authorizeConfig.methodConfig || authorizeConfig.controllerConfig
937
+ );
938
+ const result = await authorizationFilter.onAuthorization(authorizationContext);
898
939
  if (!result)
899
940
  throw new ForbiddenAccessException(authorizationFilter.onFailedAuthorization());
900
941
  }
901
942
  }
902
943
  async onActionExecuting(methodParameters) {
944
+ await this.onAuthorization(methodParameters);
903
945
  let actionFilters = common.commonContainer.globalConfig.actionFilters || [];
904
946
  const actionFiltersConfig = decoratorStateContainer.getInfo(this.routeInfo.controller.name, this.routeInfo.methodInfo.name, DecoratorType.useFilter);
905
947
  actionFilters = [...actionFilters, ...actionFiltersConfig.controllerConfig?.actionFilters || [], ...actionFiltersConfig.methodConfig?.actionFilters || []];
@@ -1205,6 +1247,16 @@ function badRequest(value, response) {
1205
1247
  return new BadRequestResult(value || common.BLANK, response);
1206
1248
  }
1207
1249
 
1250
+ class FileResult extends BaseResult {
1251
+ constructor(value, response) {
1252
+ super({ ...{ isBuffer: true, body: value }, ...{ status: HttpStatusCode.success } }, response);
1253
+ this.value = value;
1254
+ }
1255
+ }
1256
+ function fileResult(value, response) {
1257
+ return new FileResult(value || common.BLANK, response);
1258
+ }
1259
+
1208
1260
  function base(params, type, additionaConfig) {
1209
1261
  decoratorStateContainer.register(params, type, additionaConfig);
1210
1262
  }
@@ -1231,12 +1283,31 @@ function authenticationOnly() {
1231
1283
  };
1232
1284
  }
1233
1285
 
1286
+ function setEnvInfo(envTsDefinition, envValueInfo) {
1287
+ if (envTsDefinition && envValueInfo) {
1288
+ common.commonContainer.setEnvTsDefinition(envTsDefinition);
1289
+ Object.keys(envValueInfo).forEach((key) => process.env[key] = envValueInfo[key]);
1290
+ }
1291
+ }
1292
+
1293
+ function authorize(permission) {
1294
+ return function(target, propertyKey, descriptor) {
1295
+ base({
1296
+ target,
1297
+ propertyKey,
1298
+ descriptor
1299
+ }, DecoratorType.authorize, permission);
1300
+ };
1301
+ }
1302
+
1234
1303
  exports.$request = $request;
1235
1304
  exports.AbstractModelState = AbstractModelState;
1236
1305
  exports.BadRequestResult = BadRequestResult;
1237
1306
  exports.BaseController = BaseController;
1307
+ exports.CreateProblemDetail = CreateProblemDetail;
1238
1308
  exports.CreatedResult = CreatedResult;
1239
1309
  exports.Delete = Delete;
1310
+ exports.FileResult = FileResult;
1240
1311
  exports.ForbiddenAccessException = ForbiddenAccessException;
1241
1312
  exports.ForbiddenAccessInfoResult = ForbiddenAccessInfoResult;
1242
1313
  exports.HttpBadRequestException = HttpBadRequestException;
@@ -1245,6 +1316,7 @@ exports.HttpException = HttpException;
1245
1316
  exports.HttpHandler = HttpHandler;
1246
1317
  exports.HttpNotFoundException = HttpNotFoundException;
1247
1318
  exports.HttpResponse = HttpResponse;
1319
+ exports.HttpStatusCode = HttpStatusCode;
1248
1320
  exports.ModelBindingContext = ModelBindingContext;
1249
1321
  exports.NoContentResult = NoContentResult;
1250
1322
  exports.NotFoundResult = NotFoundResult;
@@ -1253,10 +1325,12 @@ exports.RunOn = RunOn;
1253
1325
  exports.UnauthorizedAccessException = UnauthorizedAccessException;
1254
1326
  exports.anonymous = anonymous;
1255
1327
  exports.authenticationOnly = authenticationOnly;
1328
+ exports.authorize = authorize;
1256
1329
  exports.badRequest = badRequest;
1257
1330
  exports.created = created;
1258
1331
  exports.defineNattyConfig = defineNattyConfig;
1259
1332
  exports.entityContainer = entityContainer;
1333
+ exports.fileResult = fileResult;
1260
1334
  exports.filter = filter;
1261
1335
  exports.forbiddenAccessInfo = forbiddenAccessInfo;
1262
1336
  exports.get = get;
@@ -1269,4 +1343,5 @@ exports.post = post;
1269
1343
  exports.put = put;
1270
1344
  exports.registerDecorator = registerDecorator;
1271
1345
  exports.route = route;
1346
+ exports.setEnvInfo = setEnvInfo;
1272
1347
  exports.useFilter = useFilter;
package/dist/index.d.ts CHANGED
@@ -59,6 +59,64 @@ declare function put(path: string): (target: any, propertyKey?: string, descript
59
59
 
60
60
  declare function Delete(): (target: any, propertyKey?: string, descriptor?: any) => void;
61
61
 
62
+ interface RouteConfig {
63
+ controller: Function;
64
+ parameters: Array<{
65
+ name: string;
66
+ type: string;
67
+ }>;
68
+ get: {
69
+ [key: string]: {
70
+ name: string;
71
+ parameters: Array<{
72
+ name: string;
73
+ type: string;
74
+ }>;
75
+ returnType: string;
76
+ };
77
+ };
78
+ post: {
79
+ [key: string]: {
80
+ name: string;
81
+ parameters: Array<{
82
+ name: string;
83
+ type: string;
84
+ }>;
85
+ returnType: string;
86
+ };
87
+ };
88
+ put: {
89
+ [key: string]: {
90
+ name: string;
91
+ parameters: Array<{
92
+ name: string;
93
+ type: string;
94
+ }>;
95
+ returnType: string;
96
+ };
97
+ };
98
+ delete: {
99
+ [key: string]: {
100
+ name: string;
101
+ parameters: Array<{
102
+ name: string;
103
+ type: string;
104
+ }>;
105
+ returnType: string;
106
+ };
107
+ };
108
+ }
109
+
110
+ declare function init(config: NattyConfig, appConfig: {
111
+ routes: {
112
+ [key: string]: RouteConfig;
113
+ };
114
+ envTsDefinition: {
115
+ [key: string]: string;
116
+ };
117
+ resolver: (path: string) => {};
118
+ }): any;
119
+
62
120
  interface DecoratorInfo {
63
121
  httpMethod: string;
64
122
  route: string;
@@ -81,6 +139,7 @@ type HttpRequestBodyInfo = {
81
139
  number?: number | number[];
82
140
  boolean?: boolean | boolean[];
83
141
  FormData?: FormData;
142
+ buffer?: any;
84
143
  ArrayBuffer?: ArrayBuffer;
85
144
  Blob?: Blob;
86
145
  json?: {
@@ -120,6 +179,7 @@ interface HttpResponseInit {
120
179
  headers?: HeadersInit;
121
180
  cookies?: Cookie[];
122
181
  enableContentNegotiation?: boolean;
182
+ isBuffer?: boolean;
123
183
  }
124
184
 
125
185
  interface ProblemDetail {
@@ -190,64 +250,6 @@ interface IHttpResult {
190
250
  getResponse(): HttpResponseInit;
191
251
  }
192
252
 
193
- interface RouteConfig {
194
- controller: Function;
195
- parameters: Array<{
196
- name: string;
197
- type: string;
198
- }>;
199
- get: {
200
- [key: string]: {
201
- name: string;
202
- parameters: Array<{
203
- name: string;
204
- type: string;
205
- }>;
206
- returnType: string;
207
- };
208
- };
209
- post: {
210
- [key: string]: {
211
- name: string;
212
- parameters: Array<{
213
- name: string;
214
- type: string;
215
- }>;
216
- returnType: string;
217
- };
218
- };
219
- put: {
220
- [key: string]: {
221
- name: string;
222
- parameters: Array<{
223
- name: string;
224
- type: string;
225
- }>;
226
- returnType: string;
227
- };
228
- };
229
- delete: {
230
- [key: string]: {
231
- name: string;
232
- parameters: Array<{
233
- name: string;
234
- type: string;
235
- }>;
236
- returnType: string;
237
- };
238
- };
239
- }
240
-
241
- declare function init(config: NattyConfig, appConfig: {
242
- routes: {
243
- [key: string]: RouteConfig;
244
- };
245
- envTsDefinition: {
246
- [key: string]: string;
247
- };
248
- types?: TypesInfo;
249
- }): any;
250
-
251
253
  declare class HttpRequest {
252
254
  private httpRequest;
253
255
  constructor(http: HttpRequestInit);
@@ -264,6 +266,7 @@ declare class HttpResponse {
264
266
  private _headers;
265
267
  private _body;
266
268
  private _status;
269
+ private _isBuffer;
267
270
  constructor(response?: HttpResponseInit);
268
271
  private setValues;
269
272
  addCookie(cookie: Cookie): void;
@@ -435,6 +438,12 @@ declare class BadRequestResult extends BaseResult implements IHttpResult {
435
438
  }
436
439
  declare function badRequest(value?: ExceptionTypeInfo, response?: Pick<HttpResponseInit, "headers" | "cookies">): BadRequestResult;
437
440
 
441
+ declare class FileResult extends BaseResult {
442
+ value: any;
443
+ constructor(value: any, response?: Pick<HttpResponseInit, "headers" | "cookies">);
444
+ }
445
+ declare function fileResult(value?: any, response?: Pick<HttpResponseInit, "headers" | "cookies">): FileResult;
446
+
438
447
  declare class HttpException {
439
448
  private httpResponse;
440
449
  constructor(response: HttpResponseInit);
@@ -463,4 +472,27 @@ declare function anonymous(): (target: any, propertyKey?: string, descriptor?: a
463
472
 
464
473
  declare function authenticationOnly(): (target: any, propertyKey?: string, descriptor?: any) => void;
465
474
 
466
- export { $request, AbstractModelState, BadRequestResult, BaseController, BuildOptions, ClassTypeInfo, CreatedResult, Delete, ForbiddenAccessException, ForbiddenAccessInfoResult, HttpBadRequestException, HttpContext, HttpException, HttpHandler, HttpModule, HttpNotFoundException, HttpResponse, MethodInfo$1 as MethodInfo, ModelBindingContext, NoContentResult, NotFoundResult, OkResult, ParameterInfo, RunOn, TypeInfo$1 as TypeInfo, UnauthorizedAccessException, anonymous, authenticationOnly, badRequest, created, defineNattyConfig, entityContainer, filter, forbiddenAccessInfo, get, init, injectable, noContent, notFound, ok, post, put, registerDecorator, route, useFilter };
475
+ declare function setEnvInfo(envTsDefinition: {
476
+ [key: string]: string;
477
+ }, envValueInfo: {
478
+ [key: string]: any;
479
+ }): void;
480
+
481
+ declare enum HttpStatusCode {
482
+ success = 200,
483
+ created = 201,
484
+ noContent = 204,
485
+ notFound = 404,
486
+ unAuthorized = 401,
487
+ forbiddenAccess = 403,
488
+ badRequest = 400,
489
+ serverError = 500
490
+ }
491
+
492
+ declare function authorize(permission: {
493
+ [key: string]: any;
494
+ }): (target: any, propertyKey?: string, descriptor?: any) => void;
495
+
496
+ declare function CreateProblemDetail(modelName: string, detail: any): ProblemDetail;
497
+
498
+ export { $request, AbstractModelState, BadRequestResult, BaseController, BuildOptions, ClassTypeInfo, CreateProblemDetail, CreatedResult, Delete, FileResult, ForbiddenAccessException, ForbiddenAccessInfoResult, HttpBadRequestException, HttpContext, HttpException, HttpHandler, HttpModule, HttpNotFoundException, HttpResponse, HttpStatusCode, MethodInfo$1 as MethodInfo, ModelBindingContext, NoContentResult, NotFoundResult, OkResult, ParameterInfo, RunOn, TypeInfo$1 as TypeInfo, UnauthorizedAccessException, anonymous, authenticationOnly, authorize, badRequest, created, defineNattyConfig, entityContainer, fileResult, filter, forbiddenAccessInfo, get, init, injectable, noContent, notFound, ok, post, put, registerDecorator, route, setEnvInfo, useFilter };
package/dist/index.mjs CHANGED
@@ -58,10 +58,13 @@ const nattyContainer = new class {
58
58
  this.container = /* @__PURE__ */ new Map();
59
59
  this.containerState = /* @__PURE__ */ new Map();
60
60
  }
61
- setup(config, routes, types) {
61
+ get types() {
62
+ return commonContainer.types;
63
+ }
64
+ setup(config, routes, resolver) {
62
65
  this.config = config;
63
66
  this.routes = routes;
64
- this.types = types;
67
+ this.resolver = resolver;
65
68
  }
66
69
  getTypes() {
67
70
  return StaticContainer.types;
@@ -114,7 +117,7 @@ const nattyContainer = new class {
114
117
  function init(config, appConfig) {
115
118
  commonContainer.setupConfig(config);
116
119
  commonContainer.setEnvTsDefinition(appConfig.envTsDefinition);
117
- nattyContainer.setup(config, appConfig.routes, appConfig.types);
120
+ nattyContainer.setup(config, appConfig.routes, appConfig.resolver);
118
121
  return initializeModule(config);
119
122
  }
120
123
  function initializeModule(config) {
@@ -123,22 +126,26 @@ function initializeModule(config) {
123
126
  }
124
127
  }
125
128
 
126
- function getPreResponseBody(body) {
129
+ function getPreResponseBody(body, isBuffer = false) {
127
130
  let bodyInfo;
128
131
  if (body) {
129
- if (isObject(body) || Array.isArray(body))
130
- bodyInfo = { json: body };
131
- const typeText = typeof body;
132
- switch (typeText) {
133
- case "string":
134
- bodyInfo = { string: body };
135
- break;
136
- case "number":
137
- bodyInfo = { number: body };
138
- break;
139
- case "boolean":
140
- bodyInfo = { boolean: body };
141
- break;
132
+ if (isBuffer)
133
+ bodyInfo = { buffer: body };
134
+ else {
135
+ if (isObject(body) || Array.isArray(body))
136
+ bodyInfo = { json: body };
137
+ const typeText = typeof body;
138
+ switch (typeText) {
139
+ case "string":
140
+ bodyInfo = { string: body };
141
+ break;
142
+ case "number":
143
+ bodyInfo = { number: body };
144
+ break;
145
+ case "boolean":
146
+ bodyInfo = { boolean: body };
147
+ break;
148
+ }
142
149
  }
143
150
  }
144
151
  return bodyInfo;
@@ -152,6 +159,7 @@ class HttpResponse {
152
159
  }
153
160
  setValues(responseInit) {
154
161
  if (responseInit) {
162
+ this._isBuffer = responseInit.isBuffer;
155
163
  if (responseInit.headers)
156
164
  for (const [key, value] of Object.entries(responseInit.headers))
157
165
  this.headers.append(key, value);
@@ -183,7 +191,7 @@ class HttpResponse {
183
191
  return this._body;
184
192
  }
185
193
  set body(value) {
186
- this._body = getPreResponseBody(value);
194
+ this._body = getPreResponseBody(value, this._isBuffer);
187
195
  }
188
196
  write(responseInit) {
189
197
  this.setValues(responseInit);
@@ -205,6 +213,26 @@ var RequestPipeline = /* @__PURE__ */ ((RequestPipeline2) => {
205
213
  return RequestPipeline2;
206
214
  })(RequestPipeline || {});
207
215
 
216
+ function lessThan(value) {
217
+ return value ? value.replace(/</g, "&lt;") : value;
218
+ }
219
+ function greaterThan(value) {
220
+ return value ? value.replace(/>/g, "&gt;") : value;
221
+ }
222
+ function ampersand(value) {
223
+ return value ? value.replace(/&/g, "&amp;") : value;
224
+ }
225
+ function doubleDash(value) {
226
+ return value ? value.replace(/--/g, "") : value;
227
+ }
228
+ function sanitizeSpecialCodes(value) {
229
+ value = ampersand(value);
230
+ value = lessThan(value);
231
+ value = greaterThan(value);
232
+ value = doubleDash(value);
233
+ return value;
234
+ }
235
+
208
236
  function isBoolean(value) {
209
237
  return typeof value === "boolean" || value === "1" || value === "true" || value === "0" || value === "false";
210
238
  }
@@ -265,7 +293,7 @@ function toInt(value, radix = 0) {
265
293
  }
266
294
  function toString(value) {
267
295
  if (isNotBlank(value))
268
- return String(value);
296
+ return sanitizeSpecialCodes(String(value));
269
297
  return value;
270
298
  }
271
299
  function whitelist(value, chars) {
@@ -346,6 +374,7 @@ class BaseResult {
346
374
  }
347
375
 
348
376
  function getResponseBodyObject(body, props) {
377
+ const sensitiveProps = commonContainer.nattyConfig?.secure?.sensitiveProps;
349
378
  if (body instanceof List)
350
379
  return getResponseBodyObject(body.values, body.props);
351
380
  if (Array.isArray(body)) {
@@ -359,7 +388,8 @@ function getResponseBodyObject(body, props) {
359
388
  const keys = Object.keys(body);
360
389
  const getterProps = props ? Object.keys(props).map((key) => props[key]) : [];
361
390
  for (const key of [...keys, ...getterProps])
362
- jObject[key] = getResponseBodyObject(body[key]);
391
+ if (!sensitiveProps || sensitiveProps.filter((t) => t == key.toLowerCase()).length == 0)
392
+ jObject[key] = getResponseBodyObject(body[key]);
363
393
  return jObject;
364
394
  }
365
395
  return body;
@@ -522,12 +552,14 @@ class ParameterTypeConverter extends BaseResponse {
522
552
  } else {
523
553
  if (this.isArrayType(property.type) && Array.isArray(value)) {
524
554
  let arrayValue = body[property.name] = [];
525
- let arrayInvalidProps = invalidProps[property.name] = [];
526
555
  for (const item of value) {
527
556
  const sanitizeValue = this.sanitizer[property.type.toLowerCase()] ? this.sanitizer[property.type.toLowerCase()](item) : item;
528
- if (sanitizeValue === INVALID_VALUE)
557
+ if (sanitizeValue === INVALID_VALUE) {
558
+ let arrayInvalidProps = invalidProps[property.name];
559
+ if (!arrayInvalidProps)
560
+ arrayInvalidProps = invalidProps[property.name] = [];
529
561
  arrayInvalidProps.push(property);
530
- else
562
+ } else
531
563
  arrayValue.push(sanitizeValue);
532
564
  }
533
565
  } else
@@ -555,7 +587,7 @@ class ParameterTypeConverter extends BaseResponse {
555
587
  }
556
588
  convertToInstance(entityName, data) {
557
589
  const typesInfo = this.types[entityName];
558
- const target = this.getClassTarget(typesInfo.path) || entityContainer.getTarget(entityName);
590
+ const target = this.getClassTarget(typesInfo.path, entityName) || entityContainer.getTarget(entityName);
559
591
  let instance = null;
560
592
  if (target) {
561
593
  instance = new target();
@@ -564,11 +596,10 @@ class ParameterTypeConverter extends BaseResponse {
564
596
  instance = data;
565
597
  return instance;
566
598
  }
567
- getClassTarget(resolver) {
568
- if (resolver) {
569
- const classInfo = resolver();
570
- const name = Object.keys(classInfo)[0];
571
- return classInfo[name];
599
+ getClassTarget(path, entityName) {
600
+ if (path) {
601
+ const classInfo = nattyContainer.resolver(path);
602
+ return classInfo[entityName];
572
603
  }
573
604
  return void 0;
574
605
  }
@@ -845,6 +876,14 @@ class ActionExecutedContext extends AbstractExecutionContext {
845
876
  }
846
877
  }
847
878
 
879
+ class AuthorizationContext extends AbstractExecutionContext {
880
+ constructor(models, context, routeInfo, config) {
881
+ super(context, routeInfo);
882
+ this.models = models;
883
+ this.config = config;
884
+ }
885
+ }
886
+
848
887
  class RequestProcessor extends RouteParser {
849
888
  constructor() {
850
889
  super(...arguments);
@@ -855,9 +894,6 @@ class RequestProcessor extends RouteParser {
855
894
  case RequestPipeline.onAuthentication:
856
895
  await this.onAuthentication();
857
896
  break;
858
- case RequestPipeline.onAuthorization:
859
- await this.onAuthorization();
860
- break;
861
897
  }
862
898
  }
863
899
  resolveFilter(instance) {
@@ -883,21 +919,27 @@ class RequestProcessor extends RouteParser {
883
919
  this.httpContext.user = result;
884
920
  if (!result.isAuthenticate && !anonymousInfo.controllerConfig && !anonymousInfo.methodConfig)
885
921
  throw new UnauthorizedAccessException(authenticationFilter.onFailedResponse());
886
- await this.onAuthorization();
887
922
  }
888
923
  }
889
- async onAuthorization() {
924
+ async onAuthorization(methodParameters) {
890
925
  const authorization = commonContainer.globalConfig.authorization;
891
926
  const authorizationFilter = authorization ? this.resolveFilter(authorization) : void 0;
892
927
  const authorizeConfig = decoratorStateContainer.getInfo(this.routeInfo.controller.name, this.routeInfo.methodInfo.name, DecoratorType.authorize);
893
928
  const authenticationOnly = decoratorStateContainer.getInfo(this.routeInfo.controller.name, this.routeInfo.methodInfo.name, DecoratorType.authenticationOnly);
894
- if (this.httpContext.user?.isAuthenticate && authorizationFilter && (!authenticationOnly.controllerConfig && !authenticationOnly.methodConfig)) {
895
- const result = await authorizationFilter.onAuthorization(this.httpContext, authorizeConfig.methodConfig || authorizeConfig.controllerConfig);
929
+ if (this.httpContext.user?.isAuthenticate && authorizationFilter && (authorizeConfig.controllerConfig || authorizeConfig.methodConfig) && (!authenticationOnly.controllerConfig && !authenticationOnly.methodConfig)) {
930
+ const authorizationContext = new AuthorizationContext(
931
+ methodParameters.filter((t) => t instanceof ModelBindingContext),
932
+ this.httpContext,
933
+ this.routeInfo,
934
+ authorizeConfig.methodConfig || authorizeConfig.controllerConfig
935
+ );
936
+ const result = await authorizationFilter.onAuthorization(authorizationContext);
896
937
  if (!result)
897
938
  throw new ForbiddenAccessException(authorizationFilter.onFailedAuthorization());
898
939
  }
899
940
  }
900
941
  async onActionExecuting(methodParameters) {
942
+ await this.onAuthorization(methodParameters);
901
943
  let actionFilters = commonContainer.globalConfig.actionFilters || [];
902
944
  const actionFiltersConfig = decoratorStateContainer.getInfo(this.routeInfo.controller.name, this.routeInfo.methodInfo.name, DecoratorType.useFilter);
903
945
  actionFilters = [...actionFilters, ...actionFiltersConfig.controllerConfig?.actionFilters || [], ...actionFiltersConfig.methodConfig?.actionFilters || []];
@@ -1203,6 +1245,16 @@ function badRequest(value, response) {
1203
1245
  return new BadRequestResult(value || BLANK$1, response);
1204
1246
  }
1205
1247
 
1248
+ class FileResult extends BaseResult {
1249
+ constructor(value, response) {
1250
+ super({ ...{ isBuffer: true, body: value }, ...{ status: HttpStatusCode.success } }, response);
1251
+ this.value = value;
1252
+ }
1253
+ }
1254
+ function fileResult(value, response) {
1255
+ return new FileResult(value || BLANK$1, response);
1256
+ }
1257
+
1206
1258
  function base(params, type, additionaConfig) {
1207
1259
  decoratorStateContainer.register(params, type, additionaConfig);
1208
1260
  }
@@ -1229,4 +1281,21 @@ function authenticationOnly() {
1229
1281
  };
1230
1282
  }
1231
1283
 
1232
- export { $request, AbstractModelState, BadRequestResult, BaseController, CreatedResult, Delete, ForbiddenAccessException, ForbiddenAccessInfoResult, HttpBadRequestException, HttpContext, HttpException, HttpHandler, HttpNotFoundException, HttpResponse, ModelBindingContext, NoContentResult, NotFoundResult, OkResult, RunOn, UnauthorizedAccessException, anonymous, authenticationOnly, badRequest, created, defineNattyConfig, entityContainer, filter, forbiddenAccessInfo, get, init, injectable, noContent, notFound, ok, post, put, registerDecorator, route, useFilter };
1284
+ function setEnvInfo(envTsDefinition, envValueInfo) {
1285
+ if (envTsDefinition && envValueInfo) {
1286
+ commonContainer.setEnvTsDefinition(envTsDefinition);
1287
+ Object.keys(envValueInfo).forEach((key) => process.env[key] = envValueInfo[key]);
1288
+ }
1289
+ }
1290
+
1291
+ function authorize(permission) {
1292
+ return function(target, propertyKey, descriptor) {
1293
+ base({
1294
+ target,
1295
+ propertyKey,
1296
+ descriptor
1297
+ }, DecoratorType.authorize, permission);
1298
+ };
1299
+ }
1300
+
1301
+ export { $request, AbstractModelState, BadRequestResult, BaseController, CreateProblemDetail, CreatedResult, Delete, FileResult, ForbiddenAccessException, ForbiddenAccessInfoResult, HttpBadRequestException, HttpContext, HttpException, HttpHandler, HttpNotFoundException, HttpResponse, HttpStatusCode, ModelBindingContext, NoContentResult, NotFoundResult, OkResult, RunOn, UnauthorizedAccessException, anonymous, authenticationOnly, authorize, badRequest, created, defineNattyConfig, entityContainer, fileResult, filter, forbiddenAccessInfo, get, init, injectable, noContent, notFound, ok, post, put, registerDecorator, route, setEnvInfo, useFilter };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@nattyjs/core",
3
- "version": "0.0.1-beta.3",
3
+ "version": "0.0.1-beta.31",
4
4
  "description": "",
5
5
  "keywords": [],
6
6
  "author": "ajayojha",
@@ -17,7 +17,7 @@
17
17
  "dependencies": {
18
18
  "tsyringe": "^4.7.0",
19
19
  "path-to-regexp": "6.2.1",
20
- "@nattyjs/common": "0.0.1-beta.3"
20
+ "@nattyjs/common": "0.0.1-beta.31"
21
21
  },
22
22
  "devDependencies": {
23
23
  "unbuild": "1.2.1"