@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.
- package/dist/lib/kafka/events/locationGroupEmployees.d.ts +12 -0
- package/dist/lib/kafka/events/locationGroupEmployees.js +2 -0
- package/dist/lib/kafka/events.d.ts +4 -0
- package/dist/lib/kafka/events.js +2 -0
- package/dist/lib/serviceIdentity/serviceIdentity.d.ts +11 -5
- package/dist/lib/serviceIdentity/serviceIdentity.js +28 -21
- package/package.json +1 -1
|
@@ -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 };
|
|
@@ -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;
|
package/dist/lib/kafka/events.js
CHANGED
|
@@ -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 {
|
|
4
|
-
import {
|
|
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:
|
|
20
|
-
|
|
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
|
|
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
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
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,
|
|
107
|
-
const
|
|
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 (
|
|
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 => {
|