@lucaapp/service-utils 1.41.0 → 1.42.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.
@@ -1,66 +1,5 @@
1
1
  import { z } from 'zod';
2
- import { HTTPStatus } from './types/http';
3
2
  declare const noContentSchema: z.ZodVoid;
4
- declare const badRequestErrorSchema: z.ZodObject<{
5
- error: z.ZodLiteral<HTTPStatus.BAD_REQUEST>;
6
- message: z.ZodString;
7
- }, "strip", z.ZodTypeAny, {
8
- message: string;
9
- error: HTTPStatus.BAD_REQUEST;
10
- }, {
11
- message: string;
12
- error: HTTPStatus.BAD_REQUEST;
13
- }>;
14
- declare const unauthorizedErrorSchema: z.ZodObject<{
15
- error: z.ZodLiteral<HTTPStatus.UNAUTHORIZED>;
16
- message: z.ZodString;
17
- }, "strip", z.ZodTypeAny, {
18
- message: string;
19
- error: HTTPStatus.UNAUTHORIZED;
20
- }, {
21
- message: string;
22
- error: HTTPStatus.UNAUTHORIZED;
23
- }>;
24
- declare const forbiddenErrorSchema: z.ZodObject<{
25
- error: z.ZodLiteral<HTTPStatus.FORBIDDEN>;
26
- message: z.ZodString;
27
- }, "strip", z.ZodTypeAny, {
28
- message: string;
29
- error: HTTPStatus.FORBIDDEN;
30
- }, {
31
- message: string;
32
- error: HTTPStatus.FORBIDDEN;
33
- }>;
34
- declare const notFoundErrorSchema: z.ZodObject<{
35
- error: z.ZodLiteral<HTTPStatus.NOT_FOUND>;
36
- message: z.ZodString;
37
- }, "strip", z.ZodTypeAny, {
38
- message: string;
39
- error: HTTPStatus.NOT_FOUND;
40
- }, {
41
- message: string;
42
- error: HTTPStatus.NOT_FOUND;
43
- }>;
44
- declare const conflictErrorSchema: z.ZodObject<{
45
- error: z.ZodLiteral<HTTPStatus.CONFLICT>;
46
- message: z.ZodString;
47
- }, "strip", z.ZodTypeAny, {
48
- message: string;
49
- error: HTTPStatus.CONFLICT;
50
- }, {
51
- message: string;
52
- error: HTTPStatus.CONFLICT;
53
- }>;
54
- declare const tooManyRequestsErrorSchema: z.ZodObject<{
55
- error: z.ZodLiteral<HTTPStatus.TOO_MANY_REQUESTS>;
56
- message: z.ZodString;
57
- }, "strip", z.ZodTypeAny, {
58
- message: string;
59
- error: HTTPStatus.TOO_MANY_REQUESTS;
60
- }, {
61
- message: string;
62
- error: HTTPStatus.TOO_MANY_REQUESTS;
63
- }>;
64
3
  export declare const okResponse: <T>(schema: z.ZodType<T, z.ZodTypeDef, T>) => {
65
4
  status: 200;
66
5
  description: string;
@@ -76,34 +15,4 @@ export declare const noContentResponse: () => {
76
15
  description: string;
77
16
  schema: typeof noContentSchema;
78
17
  };
79
- export declare const badRequestResponse: () => {
80
- status: 400;
81
- description: string;
82
- schema: typeof badRequestErrorSchema;
83
- };
84
- export declare const unauthorizedResponse: () => {
85
- status: 401;
86
- description: string;
87
- schema: typeof unauthorizedErrorSchema;
88
- };
89
- export declare const forbiddenResponse: () => {
90
- status: 403;
91
- description: string;
92
- schema: typeof forbiddenErrorSchema;
93
- };
94
- export declare const notFoundResponse: () => {
95
- status: 404;
96
- description: string;
97
- schema: typeof notFoundErrorSchema;
98
- };
99
- export declare const conflictResponse: () => {
100
- status: 409;
101
- description: string;
102
- schema: typeof conflictErrorSchema;
103
- };
104
- export declare const tooManyRequestsResponse: () => {
105
- status: 429;
106
- description: string;
107
- schema: typeof tooManyRequestsErrorSchema;
108
- };
109
18
  export {};
@@ -1,36 +1,11 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.tooManyRequestsResponse = exports.conflictResponse = exports.notFoundResponse = exports.forbiddenResponse = exports.unauthorizedResponse = exports.badRequestResponse = exports.noContentResponse = exports.createdResponse = exports.okResponse = void 0;
3
+ exports.noContentResponse = exports.createdResponse = exports.okResponse = void 0;
4
4
  const zod_to_openapi_1 = require("@asteasolutions/zod-to-openapi");
5
5
  const zod_1 = require("zod");
6
- const http_1 = require("./types/http");
7
6
  (0, zod_to_openapi_1.extendZodWithOpenApi)(zod_1.z);
8
7
  // response schemas
9
8
  const noContentSchema = zod_1.z.void();
10
- const badRequestErrorSchema = zod_1.z.object({
11
- error: zod_1.z.literal(http_1.HTTPStatus.BAD_REQUEST),
12
- message: zod_1.z.string(),
13
- });
14
- const unauthorizedErrorSchema = zod_1.z.object({
15
- error: zod_1.z.literal(http_1.HTTPStatus.UNAUTHORIZED),
16
- message: zod_1.z.string(),
17
- });
18
- const forbiddenErrorSchema = zod_1.z.object({
19
- error: zod_1.z.literal(http_1.HTTPStatus.FORBIDDEN),
20
- message: zod_1.z.string(),
21
- });
22
- const notFoundErrorSchema = zod_1.z.object({
23
- error: zod_1.z.literal(http_1.HTTPStatus.NOT_FOUND),
24
- message: zod_1.z.string(),
25
- });
26
- const conflictErrorSchema = zod_1.z.object({
27
- error: zod_1.z.literal(http_1.HTTPStatus.CONFLICT),
28
- message: zod_1.z.string(),
29
- });
30
- const tooManyRequestsErrorSchema = zod_1.z.object({
31
- error: zod_1.z.literal(http_1.HTTPStatus.TOO_MANY_REQUESTS),
32
- message: zod_1.z.string(),
33
- });
34
9
  // response functions
35
10
  const okResponse = (schema) => ({
36
11
  status: 200,
@@ -46,43 +21,7 @@ const createdResponse = (schema) => ({
46
21
  exports.createdResponse = createdResponse;
47
22
  const noContentResponse = () => ({
48
23
  status: 204,
49
- description: 'No Content',
24
+ description: 'NO_CONTENT',
50
25
  schema: noContentSchema,
51
26
  });
52
27
  exports.noContentResponse = noContentResponse;
53
- const badRequestResponse = () => ({
54
- status: 400,
55
- description: 'Bad Request',
56
- schema: badRequestErrorSchema,
57
- });
58
- exports.badRequestResponse = badRequestResponse;
59
- const unauthorizedResponse = () => ({
60
- status: 401,
61
- description: 'Unauthorized',
62
- schema: unauthorizedErrorSchema,
63
- });
64
- exports.unauthorizedResponse = unauthorizedResponse;
65
- const forbiddenResponse = () => ({
66
- status: 403,
67
- description: 'Forbidden',
68
- schema: forbiddenErrorSchema,
69
- });
70
- exports.forbiddenResponse = forbiddenResponse;
71
- const notFoundResponse = () => ({
72
- status: 404,
73
- description: 'Not Found',
74
- schema: notFoundErrorSchema,
75
- });
76
- exports.notFoundResponse = notFoundResponse;
77
- const conflictResponse = () => ({
78
- status: 409,
79
- description: 'Conflict',
80
- schema: conflictErrorSchema,
81
- });
82
- exports.conflictResponse = conflictResponse;
83
- const tooManyRequestsResponse = () => ({
84
- status: 429,
85
- description: 'Too Many Requests',
86
- schema: tooManyRequestsErrorSchema,
87
- });
88
- exports.tooManyRequestsResponse = tooManyRequestsResponse;
@@ -1,4 +1,3 @@
1
- import { HTTPStatus } from './types/http';
2
1
  export declare const ok: <T>(body: T) => {
3
2
  status: 200;
4
3
  body: T;
@@ -11,45 +10,3 @@ export declare const noContent: () => {
11
10
  status: 204;
12
11
  body: void;
13
12
  };
14
- export declare const badRequest: (message?: string) => {
15
- status: 400;
16
- body: {
17
- error: HTTPStatus.BAD_REQUEST;
18
- message: string;
19
- };
20
- };
21
- export declare const unauthorized: (message?: string) => {
22
- status: 401;
23
- body: {
24
- error: HTTPStatus.UNAUTHORIZED;
25
- message: string;
26
- };
27
- };
28
- export declare const forbidden: (message?: string) => {
29
- status: 403;
30
- body: {
31
- error: HTTPStatus.FORBIDDEN;
32
- message: string;
33
- };
34
- };
35
- export declare const notFound: (message?: string) => {
36
- status: 404;
37
- body: {
38
- error: HTTPStatus.NOT_FOUND;
39
- message: string;
40
- };
41
- };
42
- export declare const conflict: (message?: string) => {
43
- status: 409;
44
- body: {
45
- error: HTTPStatus.CONFLICT;
46
- message: string;
47
- };
48
- };
49
- export declare const tooManyRequests: (message?: string) => {
50
- status: 429;
51
- body: {
52
- error: HTTPStatus.TOO_MANY_REQUESTS;
53
- message: string;
54
- };
55
- };
@@ -1,7 +1,6 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.tooManyRequests = exports.conflict = exports.notFound = exports.forbidden = exports.unauthorized = exports.badRequest = exports.noContent = exports.created = exports.ok = void 0;
4
- const http_1 = require("./types/http");
3
+ exports.noContent = exports.created = exports.ok = void 0;
5
4
  const ok = (body) => ({
6
5
  status: 200,
7
6
  body,
@@ -17,51 +16,3 @@ const noContent = () => ({
17
16
  body: undefined,
18
17
  });
19
18
  exports.noContent = noContent;
20
- const badRequest = (message) => ({
21
- status: 400,
22
- body: {
23
- error: http_1.HTTPStatus.BAD_REQUEST,
24
- message: message || 'Bad request',
25
- },
26
- });
27
- exports.badRequest = badRequest;
28
- const unauthorized = (message) => ({
29
- status: 401,
30
- body: {
31
- error: http_1.HTTPStatus.UNAUTHORIZED,
32
- message: message || 'Unauthorized',
33
- },
34
- });
35
- exports.unauthorized = unauthorized;
36
- const forbidden = (message) => ({
37
- status: 403,
38
- body: {
39
- error: http_1.HTTPStatus.FORBIDDEN,
40
- message: message || 'Forbidden',
41
- },
42
- });
43
- exports.forbidden = forbidden;
44
- const notFound = (message) => ({
45
- status: 404,
46
- body: {
47
- error: http_1.HTTPStatus.NOT_FOUND,
48
- message: message || 'Not found',
49
- },
50
- });
51
- exports.notFound = notFound;
52
- const conflict = (message) => ({
53
- status: 409,
54
- body: {
55
- error: http_1.HTTPStatus.CONFLICT,
56
- message: message || 'Conflict',
57
- },
58
- });
59
- exports.conflict = conflict;
60
- const tooManyRequests = (message) => ({
61
- status: 429,
62
- body: {
63
- error: http_1.HTTPStatus.TOO_MANY_REQUESTS,
64
- message: message || 'Too many requests',
65
- },
66
- });
67
- exports.tooManyRequests = tooManyRequests;
@@ -26,33 +26,7 @@ declare class ServiceIdentity {
26
26
  }>;
27
27
  getIdentityJWKS: () => Promise<JWKS>;
28
28
  requireServiceIdentity: (service: string) => RequestHandler;
29
- requireServiceIdentityV3: (service: string) => import("../api/types/middleware").Middleware<({
30
- status: 401;
31
- description: string;
32
- schema: z.ZodObject<{
33
- error: z.ZodLiteral<import("../api/types/http").HTTPStatus.UNAUTHORIZED>;
34
- message: z.ZodString;
35
- }, "strip", z.ZodTypeAny, {
36
- message: string;
37
- error: import("../api/types/http").HTTPStatus.UNAUTHORIZED;
38
- }, {
39
- message: string;
40
- error: import("../api/types/http").HTTPStatus.UNAUTHORIZED;
41
- }>;
42
- } | {
43
- status: 403;
44
- description: string;
45
- schema: z.ZodObject<{
46
- error: z.ZodLiteral<import("../api/types/http").HTTPStatus.FORBIDDEN>;
47
- message: z.ZodString;
48
- }, "strip", z.ZodTypeAny, {
49
- message: string;
50
- error: import("../api/types/http").HTTPStatus.FORBIDDEN;
51
- }, {
52
- message: string;
53
- error: import("../api/types/http").HTTPStatus.FORBIDDEN;
54
- }>;
55
- })[], undefined, undefined, undefined, z.ZodObject<{
29
+ requireServiceIdentityV3: (service: string) => import("../api/types/middleware").Middleware<never[], undefined, undefined, undefined, z.ZodObject<{
56
30
  'x-identity': z.ZodEffects<z.ZodString, string, string>;
57
31
  }, "strip", z.ZodTypeAny, {
58
32
  "x-identity": string;
@@ -42,6 +42,19 @@ const JWT_ALLOWED_ALGORITHMS = [JWT_ALGORITHM];
42
42
  const JWT_NBF = '0s';
43
43
  const JWT_EXP = '1m';
44
44
  const JWT_CLOCK_TOLERANCE = moment_1.default.duration(1, 'minute').asSeconds();
45
+ var ServiceIdentityErrorType;
46
+ (function (ServiceIdentityErrorType) {
47
+ ServiceIdentityErrorType["NO_JWT_PROVIDED"] = "SERVICE_IDENTITY_NO_JWT_PROVIDED";
48
+ ServiceIdentityErrorType["URL_MISMATCH"] = "SERVICE_IDENTITY_URL_MISMATCH";
49
+ ServiceIdentityErrorType["METHOD_MISMATCH"] = "SERVICE_IDENTITY_METHOD_MISMATCH";
50
+ })(ServiceIdentityErrorType || (ServiceIdentityErrorType = {}));
51
+ class ServiceIdentityError extends Error {
52
+ constructor(type, message, meta) {
53
+ super(message);
54
+ this.type = type;
55
+ this.meta = meta;
56
+ }
57
+ }
45
58
  class ServiceIdentity {
46
59
  constructor(identityName, identityKid, identityPrivateKey, identityPublicKey, debug = false) {
47
60
  this.jwksCache = {};
@@ -133,19 +146,24 @@ class ServiceIdentity {
133
146
  }),
134
147
  context: zod_1.z.object({ payload: zod_1.z.any() }),
135
148
  },
136
- responses: [(0, api_1.unauthorizedResponse)(), (0, api_1.forbiddenResponse)()],
149
+ responses: [],
150
+ errors: {
151
+ [ServiceIdentityErrorType.NO_JWT_PROVIDED]: 401,
152
+ [ServiceIdentityErrorType.METHOD_MISMATCH]: 403,
153
+ [ServiceIdentityErrorType.URL_MISMATCH]: 403,
154
+ },
137
155
  }, async (request, respond, next) => {
138
156
  const { headers, originalUrl, method } = request;
139
157
  const jwt = headers[JWT_HEADER_NAME];
140
158
  if (typeof jwt !== 'string') {
141
- return respond((0, api_1.unauthorized)());
159
+ throw new ServiceIdentityError(ServiceIdentityErrorType.NO_JWT_PROVIDED);
142
160
  }
143
161
  const { payload } = await jose.jwtVerify(jwt, this.getRemoteJWKS(service), this.getJwtVerifyOptions(service));
144
162
  if (request.originalUrl !== payload.url) {
145
- return respond((0, api_1.forbidden)(`${originalUrl} !== ${payload.url}`));
163
+ throw new ServiceIdentityError(ServiceIdentityErrorType.URL_MISMATCH, `${originalUrl} !== ${payload.url}`);
146
164
  }
147
165
  if (method !== payload.method) {
148
- return respond((0, api_1.forbidden)(`${method} !== ${payload.method}`));
166
+ throw new ServiceIdentityError(ServiceIdentityErrorType.METHOD_MISMATCH, `${method} !== ${payload.method}`);
149
167
  }
150
168
  return next({ payload: payload.data });
151
169
  });
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@lucaapp/service-utils",
3
- "version": "1.41.0",
3
+ "version": "1.42.0",
4
4
  "main": "dist/index.js",
5
5
  "types": "dist/index.d.ts",
6
6
  "files": [