@lucaapp/service-utils 1.13.0 → 1.14.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.
@@ -0,0 +1,12 @@
1
+ declare type LocationGroupEmployees = {
2
+ uuid: string;
3
+ firstName: string;
4
+ lastName: string | null;
5
+ employeeNumber: string | null;
6
+ locationGroupId: string;
7
+ lucaPayConsumerEmail: string | null;
8
+ ambassadorShares: number | null;
9
+ createdAt: Date;
10
+ updatedAt: Date;
11
+ };
12
+ export type { LocationGroupEmployees };
@@ -0,0 +1,2 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
@@ -1,12 +1,14 @@
1
1
  import type { Payment } from './events/payment';
2
2
  import type { Consumer } from './events/consumer';
3
3
  import type { Operator } from './events/operator';
4
+ import type { LocationGroupEmployees } from './events/locationGroupEmployees';
4
5
  import type { WsEvent } from './events/wsEvent';
5
6
  import { Service } from '../serviceIdentity';
6
7
  declare enum KafkaTopic {
7
8
  PAYMENTS = "payments",
8
9
  CONSUMERS = "consumers",
9
10
  OPERATORS = "operators",
11
+ LOCATION_GROUP_EMPLOYEES = "location_group_employees",
10
12
  WS_EVENT_backend = "wsevent_backend",
11
13
  WS_EVENT_backend_pay = "wsevent_backend-pay",
12
14
  WS_EVENT_backend_pos = "wsevent_backend-pos"
@@ -15,6 +17,7 @@ declare type MessageFormats = {
15
17
  [KafkaTopic.PAYMENTS]: Payment;
16
18
  [KafkaTopic.CONSUMERS]: Consumer;
17
19
  [KafkaTopic.OPERATORS]: Operator;
20
+ [KafkaTopic.LOCATION_GROUP_EMPLOYEES]: LocationGroupEmployees;
18
21
  [KafkaTopic.WS_EVENT_backend]: WsEvent;
19
22
  [KafkaTopic.WS_EVENT_backend_pay]: WsEvent;
20
23
  [KafkaTopic.WS_EVENT_backend_pos]: WsEvent;
@@ -23,6 +26,7 @@ declare const MessageIssuer: {
23
26
  payments: Service;
24
27
  consumers: Service;
25
28
  operators: Service;
29
+ location_group_employees: Service;
26
30
  wsevent_backend: Service;
27
31
  "wsevent_backend-pay": Service;
28
32
  "wsevent_backend-pos": Service;
@@ -7,6 +7,7 @@ var KafkaTopic;
7
7
  KafkaTopic["PAYMENTS"] = "payments";
8
8
  KafkaTopic["CONSUMERS"] = "consumers";
9
9
  KafkaTopic["OPERATORS"] = "operators";
10
+ KafkaTopic["LOCATION_GROUP_EMPLOYEES"] = "location_group_employees";
10
11
  KafkaTopic["WS_EVENT_backend"] = "wsevent_backend";
11
12
  KafkaTopic["WS_EVENT_backend_pay"] = "wsevent_backend-pay";
12
13
  KafkaTopic["WS_EVENT_backend_pos"] = "wsevent_backend-pos";
@@ -16,6 +17,7 @@ const MessageIssuer = {
16
17
  [KafkaTopic.PAYMENTS]: serviceIdentity_1.Service.BACKEND_PAY,
17
18
  [KafkaTopic.CONSUMERS]: serviceIdentity_1.Service.BACKEND,
18
19
  [KafkaTopic.OPERATORS]: serviceIdentity_1.Service.BACKEND,
20
+ [KafkaTopic.LOCATION_GROUP_EMPLOYEES]: serviceIdentity_1.Service.BACKEND,
19
21
  [KafkaTopic.WS_EVENT_backend]: serviceIdentity_1.Service.BACKEND,
20
22
  [KafkaTopic.WS_EVENT_backend_pay]: serviceIdentity_1.Service.BACKEND_PAY,
21
23
  [KafkaTopic.WS_EVENT_backend_pos]: serviceIdentity_1.Service.BACKEND_POS,
@@ -1,13 +1,15 @@
1
1
  import * as jose from 'jose';
2
2
  import { HttpMethod } from 'types/http';
3
- import { Json } from 'types/json';
4
- import { RequestHandler } from 'express';
3
+ import { Request, RequestHandler } from 'express';
4
+ import { Service } from './service';
5
+ declare type JWKS = {
6
+ keys: jose.JWK[];
7
+ };
5
8
  declare class ServiceIdentity {
6
9
  readonly identityName: string;
7
10
  readonly identityKid: string;
8
11
  private readonly identityPrivateKey;
9
12
  private readonly identityPublicKey;
10
- private readonly debug;
11
13
  private readonly jwksCache;
12
14
  private readonly keyCache;
13
15
  private readonly axiosClient;
@@ -16,8 +18,12 @@ declare class ServiceIdentity {
16
18
  private getJwtVerifyOptions;
17
19
  getIdentityPublicKey: () => Promise<jose.KeyLike>;
18
20
  getIdentityPrivateKey: () => Promise<jose.KeyLike>;
19
- callService: <T>(service: string, method: HttpMethod, url: string, data?: Json) => Promise<T>;
20
- private getIdentityJWKS;
21
+ callService: <T>(service: Service, method: HttpMethod, url: string, data?: unknown) => Promise<T>;
22
+ signJWT: (service: string, method: HttpMethod, url: string, data?: unknown) => Promise<string>;
23
+ verifyJWT: (request: Request, service: string) => Promise<{
24
+ payload: jose.JWTPayload;
25
+ }>;
26
+ getIdentityJWKS: () => Promise<JWKS>;
21
27
  requireServiceIdentity: (service: string) => RequestHandler;
22
28
  identityJWKSRoute: RequestHandler;
23
29
  }
@@ -69,9 +69,24 @@ class ServiceIdentity {
69
69
  return this.keyCache.private;
70
70
  };
71
71
  this.callService = async (service, method, url, data) => {
72
- const jwt = await new jose.SignJWT({
72
+ const jwt = await this.signJWT(service, method, url, data);
73
+ const request = {
74
+ headers: {
75
+ [JWT_HEADER_NAME]: jwt,
76
+ ...(0, requestTracer_1.getRequestIdHeader)(),
77
+ },
78
+ baseURL: `http://${service}:8080/`,
79
+ url,
80
+ method,
81
+ };
82
+ const response = await this.axiosClient.request(request);
83
+ return response.data;
84
+ };
85
+ this.signJWT = async (service, method, url, data) => {
86
+ return await new jose.SignJWT({
73
87
  method,
74
88
  url,
89
+ data,
75
90
  })
76
91
  .setProtectedHeader({
77
92
  alg: JWT_ALGORITHM,
@@ -84,18 +99,14 @@ class ServiceIdentity {
84
99
  .setNotBefore(JWT_NBF)
85
100
  .setExpirationTime(JWT_EXP)
86
101
  .sign(await this.getIdentityPrivateKey());
87
- const request = {
88
- headers: {
89
- [JWT_HEADER_NAME]: jwt,
90
- ...(0, requestTracer_1.getRequestIdHeader)(),
91
- },
92
- baseURL: `http://${service}:8080/`,
93
- url,
94
- method,
95
- data,
96
- };
97
- const response = await this.axiosClient.request(request);
98
- return response.data;
102
+ };
103
+ this.verifyJWT = async (request, service) => {
104
+ const jwt = request.header(JWT_HEADER_NAME);
105
+ if (typeof jwt !== 'string') {
106
+ throw (0, boom_1.unauthorized)();
107
+ }
108
+ const { payload } = await jose.jwtVerify(jwt, this.getRemoteJWKS(service), this.getJwtVerifyOptions(service));
109
+ return { payload };
99
110
  };
100
111
  this.getIdentityJWKS = async () => {
101
112
  const publicKey = await this.getIdentityPublicKey();
@@ -103,26 +114,22 @@ class ServiceIdentity {
103
114
  jwk.kid = this.identityKid;
104
115
  return { keys: [jwk] };
105
116
  };
106
- this.requireServiceIdentity = (service) => async (request, response, next) => {
107
- const jwt = request.header(JWT_HEADER_NAME);
108
- if (typeof jwt !== 'string') {
109
- throw (0, boom_1.unauthorized)();
110
- }
111
- const { payload } = await jose.jwtVerify(jwt, this.getRemoteJWKS(service), this.getJwtVerifyOptions(service));
117
+ this.requireServiceIdentity = (service) => async (request, _, next) => {
118
+ const { payload } = await this.verifyJWT(request, service);
112
119
  if (request.originalUrl !== payload.url)
113
120
  throw (0, boom_1.forbidden)(`${request.originalUrl} !== ${payload.url}`);
114
121
  if (request.method !== payload.method)
115
122
  throw (0, boom_1.forbidden)(`${request.method} !== ${payload.method}`);
123
+ request.body = payload.data;
116
124
  next();
117
125
  };
118
- this.identityJWKSRoute = async (request, response) => {
126
+ this.identityJWKSRoute = async (_, response) => {
119
127
  response.send(await this.getIdentityJWKS());
120
128
  };
121
129
  this.identityName = identityName;
122
130
  this.identityKid = identityKid;
123
131
  this.identityPrivateKey = identityPrivateKey;
124
132
  this.identityPublicKey = identityPublicKey;
125
- this.debug = debug;
126
133
  this.axiosClient = axios_1.default.create({ proxy: false });
127
134
  if (!debug) {
128
135
  this.axiosClient.interceptors.response.use(response => response, error => {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@lucaapp/service-utils",
3
- "version": "1.13.0",
3
+ "version": "1.14.0",
4
4
  "main": "dist/index.js",
5
5
  "types": "dist/index.d.ts",
6
6
  "files": [