@autofleet/outbreak 0.0.8 → 0.1.0-beta-1
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/src/http-wrapper/config.d.ts +18 -0
- package/dist/src/http-wrapper/config.js +39 -0
- package/dist/src/http-wrapper/config.js.map +1 -0
- package/dist/src/http-wrapper/index.d.ts +14 -0
- package/dist/src/http-wrapper/index.js +39 -0
- package/dist/src/http-wrapper/index.js.map +1 -0
- package/dist/src/http-wrapper/wrapper.d.ts +1 -0
- package/dist/src/http-wrapper/wrapper.js +98 -0
- package/dist/src/http-wrapper/wrapper.js.map +1 -0
- package/dist/src/identity/ApiUser.d.ts +25 -0
- package/dist/src/identity/ApiUser.js +73 -0
- package/dist/src/identity/ApiUser.js.map +1 -0
- package/dist/src/identity/index.d.ts +3 -0
- package/dist/src/identity/index.js +13 -0
- package/dist/src/identity/index.js.map +1 -0
- package/dist/src/identity/middlewares.d.ts +12 -0
- package/dist/src/identity/middlewares.js +69 -0
- package/dist/src/identity/middlewares.js.map +1 -0
- package/dist/src/identity/utils.d.ts +5 -0
- package/dist/src/identity/utils.js +79 -0
- package/dist/src/identity/utils.js.map +1 -0
- package/dist/src/index.d.ts +4 -0
- package/dist/src/index.js +17 -0
- package/dist/src/index.js.map +1 -0
- package/dist/src/network/index.d.ts +1 -0
- package/dist/src/network/index.js +17 -0
- package/dist/src/network/index.js.map +1 -0
- package/dist/src/tracer/index.d.ts +16 -0
- package/dist/src/tracer/index.js +48 -0
- package/dist/src/tracer/index.js.map +1 -0
- package/dist/tests/http-wrapper.test.d.ts +1 -0
- package/dist/tests/http-wrapper.test.js +76 -0
- package/dist/tests/http-wrapper.test.js.map +1 -0
- package/package.json +2 -1
- package/src/http-wrapper/config.ts +1 -1
- package/src/index.ts +0 -12
- package/src/tracer/index.ts +2 -2
- package/tests/http-wrapper.test.ts +1 -2
- package/src/identity/ApiUser.ts +0 -91
- package/src/identity/index.ts +0 -15
- package/src/identity/middlewares.ts +0 -76
- package/src/identity/utils.ts +0 -74
- package/src/network/index.ts +0 -13
@@ -0,0 +1,18 @@
|
|
1
|
+
interface Overrides {
|
2
|
+
setAndPropagateCorrelationId?: boolean;
|
3
|
+
propagateInResponses?: boolean;
|
4
|
+
headersToPropagate?: string[];
|
5
|
+
headersPrefix?: string;
|
6
|
+
}
|
7
|
+
declare const _default: {
|
8
|
+
load: (overrides?: Overrides) => {
|
9
|
+
setAndPropagateCorrelationId: boolean;
|
10
|
+
propagateInResponses: boolean;
|
11
|
+
correlationIdHeader: string;
|
12
|
+
headersToCollect: string[];
|
13
|
+
headersToInject: string[];
|
14
|
+
headersPrefix: string;
|
15
|
+
};
|
16
|
+
correlationIdHeader: string;
|
17
|
+
};
|
18
|
+
export default _default;
|
@@ -0,0 +1,39 @@
|
|
1
|
+
"use strict";
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
3
|
+
const correlationIdHeader = 'x-trace-id';
|
4
|
+
const validateHeaderList = (headers) => {
|
5
|
+
if (!Array.isArray(headers)) {
|
6
|
+
throw new Error('Header list is not an array');
|
7
|
+
}
|
8
|
+
// could be tighter - ASCII code between 33 and 126 at the moment
|
9
|
+
const headerNameRegex = /^[\x21-\x7e]+$/i;
|
10
|
+
const invalidHeaders = headers.filter((h) => typeof h !== 'string' || !headerNameRegex.test(h));
|
11
|
+
if (invalidHeaders.length > 0) {
|
12
|
+
throw new Error(`Header list contains invalid headers: ${invalidHeaders}`);
|
13
|
+
}
|
14
|
+
};
|
15
|
+
const load = (overrides = {}) => {
|
16
|
+
const { setAndPropagateCorrelationId = true, propagateInResponses = false, headersToPropagate = [
|
17
|
+
'x-request-id',
|
18
|
+
'x-variant-id',
|
19
|
+
], headersPrefix = 'x-af-', } = overrides;
|
20
|
+
validateHeaderList(headersToPropagate);
|
21
|
+
const headersToCollect = headersToPropagate;
|
22
|
+
let headersToInject = headersToCollect;
|
23
|
+
if (setAndPropagateCorrelationId === true) {
|
24
|
+
headersToInject = [correlationIdHeader].concat(headersToCollect);
|
25
|
+
}
|
26
|
+
return {
|
27
|
+
setAndPropagateCorrelationId,
|
28
|
+
propagateInResponses,
|
29
|
+
correlationIdHeader,
|
30
|
+
headersToCollect,
|
31
|
+
headersToInject,
|
32
|
+
headersPrefix,
|
33
|
+
};
|
34
|
+
};
|
35
|
+
exports.default = {
|
36
|
+
load,
|
37
|
+
correlationIdHeader,
|
38
|
+
};
|
39
|
+
//# sourceMappingURL=config.js.map
|
@@ -0,0 +1 @@
|
|
1
|
+
{"version":3,"file":"config.js","sourceRoot":"","sources":["../../../src/http-wrapper/config.ts"],"names":[],"mappings":";;AAAA,MAAM,mBAAmB,GAAG,YAAY,CAAC;AAEzC,MAAM,kBAAkB,GAAG,CAAC,OAAO,EAAQ,EAAE;IAC3C,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,OAAO,CAAC,EAAE;QAC3B,MAAM,IAAI,KAAK,CAAC,6BAA6B,CAAC,CAAC;KAChD;IAED,iEAAiE;IACjE,MAAM,eAAe,GAAG,iBAAiB,CAAC;IAE1C,MAAM,cAAc,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,OAAO,CAAC,KAAK,QAAQ,IAAI,CAAC,eAAe,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC;IAEhG,IAAI,cAAc,CAAC,MAAM,GAAG,CAAC,EAAE;QAC7B,MAAM,IAAI,KAAK,CAAC,yCAAyC,cAAc,EAAE,CAAC,CAAC;KAC5E;AACH,CAAC,CAAC;AASF,MAAM,IAAI,GAAG,CAAC,YAAuB,EAAE,EAAE,EAAE;IACzC,MAAM,EACJ,4BAA4B,GAAG,IAAI,EACnC,oBAAoB,GAAG,KAAK,EAC5B,kBAAkB,GAAG;QACnB,cAAc;QACd,cAAc;KACf,EACD,aAAa,GAAG,OAAO,GACxB,GAAG,SAAS,CAAC;IAEd,kBAAkB,CAAC,kBAAkB,CAAC,CAAC;IAEvC,MAAM,gBAAgB,GAAG,kBAAkB,CAAC;IAE5C,IAAI,eAAe,GAAG,gBAAgB,CAAC;IACvC,IAAI,4BAA4B,KAAK,IAAI,EAAE;QACzC,eAAe,GAAG,CAAC,mBAAmB,CAAC,CAAC,MAAM,CAAC,gBAAgB,CAAC,CAAC;KAClE;IAED,OAAO;QACL,4BAA4B;QAC5B,oBAAoB;QACpB,mBAAmB;QACnB,gBAAgB;QAChB,eAAe;QACf,aAAa;KACd,CAAC;AACJ,CAAC,CAAC;AAEF,kBAAe;IACb,IAAI;IACJ,mBAAmB;CACpB,CAAC"}
|
@@ -0,0 +1,14 @@
|
|
1
|
+
import winston from 'winston';
|
2
|
+
interface Options {
|
3
|
+
winstonLogger?: winston.Logger;
|
4
|
+
headersPrefix?: string;
|
5
|
+
setAndPropagateCorrelationId?: boolean;
|
6
|
+
headersToPropagate?: string[];
|
7
|
+
}
|
8
|
+
export default function (options: Options): void;
|
9
|
+
export declare const traceTypes: {
|
10
|
+
HTTP_REQUEST: string;
|
11
|
+
WEB_SOCKET: string;
|
12
|
+
RABBIT: string;
|
13
|
+
};
|
14
|
+
export {};
|
@@ -0,0 +1,39 @@
|
|
1
|
+
"use strict";
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
4
|
+
};
|
5
|
+
var __importStar = (this && this.__importStar) || function (mod) {
|
6
|
+
if (mod && mod.__esModule) return mod;
|
7
|
+
var result = {};
|
8
|
+
if (mod != null) for (var k in mod) if (Object.hasOwnProperty.call(mod, k)) result[k] = mod[k];
|
9
|
+
result["default"] = mod;
|
10
|
+
return result;
|
11
|
+
};
|
12
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
13
|
+
const winston_1 = require("winston");
|
14
|
+
const wrapper_1 = __importDefault(require("./wrapper"));
|
15
|
+
const config_1 = __importDefault(require("./config"));
|
16
|
+
const tracer = __importStar(require("../tracer"));
|
17
|
+
const addMetadataToLog = winston_1.format((info) => {
|
18
|
+
const currentTrace = tracer.getCurrentTrace();
|
19
|
+
if (currentTrace && currentTrace.context && currentTrace.context.get) {
|
20
|
+
// eslint-disable-next-line no-param-reassign
|
21
|
+
info.traceId = currentTrace.context.get(config_1.default.correlationIdHeader);
|
22
|
+
}
|
23
|
+
return info;
|
24
|
+
});
|
25
|
+
function default_1(options) {
|
26
|
+
wrapper_1.default(config_1.default.load(options));
|
27
|
+
tracer.enable();
|
28
|
+
if (options.winstonLogger) {
|
29
|
+
// eslint-disable-next-line no-param-reassign
|
30
|
+
options.winstonLogger.format = winston_1.format.combine(addMetadataToLog(), options.winstonLogger.format);
|
31
|
+
}
|
32
|
+
}
|
33
|
+
exports.default = default_1;
|
34
|
+
exports.traceTypes = {
|
35
|
+
HTTP_REQUEST: 'httpRequest',
|
36
|
+
WEB_SOCKET: 'webSocket',
|
37
|
+
RABBIT: 'rabbit',
|
38
|
+
};
|
39
|
+
//# sourceMappingURL=index.js.map
|
@@ -0,0 +1 @@
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/http-wrapper/index.ts"],"names":[],"mappings":";;;;;;;;;;;;AAAA,qCAA0C;AAE1C,wDAAoC;AACpC,sDAA8B;AAC9B,kDAAoC;AASpC,MAAM,gBAAgB,GAAG,gBAAM,CAAC,CAAC,IAAI,EAAE,EAAE;IACvC,MAAM,YAAY,GAAG,MAAM,CAAC,eAAe,EAAE,CAAC;IAC9C,IAAI,YAAY,IAAI,YAAY,CAAC,OAAO,IAAI,YAAY,CAAC,OAAO,CAAC,GAAG,EAAE;QACpE,6CAA6C;QAC7C,IAAI,CAAC,OAAO,GAAG,YAAY,CAAC,OAAO,CAAC,GAAG,CAAC,gBAAM,CAAC,mBAAmB,CAAC,CAAC;KACrE;IAED,OAAO,IAAI,CAAC;AACd,CAAC,CAAC,CAAC;AAEH,mBAAyB,OAAgB;IACvC,iBAAW,CAAC,gBAAM,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,CAAC;IAClC,MAAM,CAAC,MAAM,EAAE,CAAC;IAEhB,IAAI,OAAO,CAAC,aAAa,EAAE;QACzB,6CAA6C;QAC7C,OAAO,CAAC,aAAa,CAAC,MAAM,GAAG,gBAAM,CAAC,OAAO,CAC3C,gBAAgB,EAAE,EAClB,OAAO,CAAC,aAAa,CAAC,MAAM,CAC7B,CAAC;KACH;AACH,CAAC;AAXD,4BAWC;AAEY,QAAA,UAAU,GAAG;IACxB,YAAY,EAAE,aAAa;IAC3B,UAAU,EAAE,WAAW;IACvB,MAAM,EAAE,QAAQ;CACjB,CAAC"}
|
@@ -0,0 +1 @@
|
|
1
|
+
export default function wrapHttp(config: any): void;
|
@@ -0,0 +1,98 @@
|
|
1
|
+
"use strict";
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
4
|
+
};
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
6
|
+
/* eslint-disable max-len */
|
7
|
+
const http_1 = __importDefault(require("http"));
|
8
|
+
const shortid_1 = __importDefault(require("shortid"));
|
9
|
+
const tracer_1 = require("../tracer");
|
10
|
+
const originalHttpCreateServer = http_1.default.createServer;
|
11
|
+
const originalRequest = http_1.default.request;
|
12
|
+
const originalGet = http_1.default.get;
|
13
|
+
function setAndCollectCorrelationId(config, req, res) {
|
14
|
+
let correlationId = req.headers[config.correlationIdHeader];
|
15
|
+
if (typeof correlationId === 'undefined') {
|
16
|
+
correlationId = shortid_1.default.generate();
|
17
|
+
}
|
18
|
+
tracer_1.getCurrentTrace().context.set(config.correlationIdHeader, correlationId);
|
19
|
+
res.setHeader(config.correlationIdHeader, correlationId);
|
20
|
+
}
|
21
|
+
function collect(req, headers, headersPrefix) {
|
22
|
+
const prefixHeaders = headersPrefix
|
23
|
+
? Object.keys(req.headers).filter((hn) => hn.includes(headersPrefix))
|
24
|
+
: [];
|
25
|
+
[...headers, ...prefixHeaders].forEach((header) => {
|
26
|
+
if (typeof req.headers[header] !== 'undefined') {
|
27
|
+
tracer_1.getCurrentTrace().context.set(header, req.headers[header]);
|
28
|
+
}
|
29
|
+
});
|
30
|
+
}
|
31
|
+
function injectInResponse(response, headers) {
|
32
|
+
if (tracer_1.getCurrentTrace()) {
|
33
|
+
headers.forEach((header) => {
|
34
|
+
response.setHeader(header, tracer_1.getCurrentTrace().context.get(header));
|
35
|
+
});
|
36
|
+
}
|
37
|
+
}
|
38
|
+
function wrappedListener(config, listener) {
|
39
|
+
return (req, res, next, error) => {
|
40
|
+
tracer_1.newTrace('httpRequest');
|
41
|
+
if (config.setAndPropagateCorrelationId === true) {
|
42
|
+
setAndCollectCorrelationId(config, req, res);
|
43
|
+
}
|
44
|
+
collect(req, config.headersToCollect, config.headersPrefix);
|
45
|
+
if (config.propagateInResponses) {
|
46
|
+
injectInResponse(res, [config.correlationIdHeader]);
|
47
|
+
}
|
48
|
+
listener(req, res, next, error);
|
49
|
+
};
|
50
|
+
}
|
51
|
+
function wrapHttpCreateServer(config) {
|
52
|
+
// args of http.createServer are ([options<Object>], [listener<Fn>]) Express only sends listener
|
53
|
+
return function _wrappedHttpCreateServer(listener) {
|
54
|
+
return originalHttpCreateServer(wrappedListener(config, listener));
|
55
|
+
};
|
56
|
+
}
|
57
|
+
function inject(options) {
|
58
|
+
if (tracer_1.getCurrentTrace()) {
|
59
|
+
if (!options.headers) {
|
60
|
+
// eslint-disable-next-line no-param-reassign
|
61
|
+
options.headers = {};
|
62
|
+
}
|
63
|
+
[...(tracer_1.getCurrentTrace().context.keys())].forEach((header) => {
|
64
|
+
// eslint-disable-next-line no-param-reassign
|
65
|
+
options.headers[header] = tracer_1.getCurrentTrace().context.get(header);
|
66
|
+
});
|
67
|
+
}
|
68
|
+
}
|
69
|
+
function wrapHttpRequest(originalMethod) {
|
70
|
+
// Return type
|
71
|
+
function urlFirst(url, options, cb) {
|
72
|
+
inject(options);
|
73
|
+
return originalMethod(url, options, cb);
|
74
|
+
}
|
75
|
+
function optionsFirst(options, cb) {
|
76
|
+
inject(options);
|
77
|
+
return originalMethod(options, cb);
|
78
|
+
}
|
79
|
+
function wrappedHttpRequest(...args) {
|
80
|
+
let options = {};
|
81
|
+
let url;
|
82
|
+
let callback;
|
83
|
+
if (args.length === 3) {
|
84
|
+
[options, url, callback] = args;
|
85
|
+
return urlFirst(url, options, callback);
|
86
|
+
}
|
87
|
+
[options, callback] = args;
|
88
|
+
return optionsFirst(options, callback);
|
89
|
+
}
|
90
|
+
return wrappedHttpRequest;
|
91
|
+
}
|
92
|
+
function wrapHttp(config) {
|
93
|
+
http_1.default.createServer = wrapHttpCreateServer(config);
|
94
|
+
http_1.default.request = wrapHttpRequest(originalRequest);
|
95
|
+
http_1.default.get = wrapHttpRequest(originalGet);
|
96
|
+
}
|
97
|
+
exports.default = wrapHttp;
|
98
|
+
//# sourceMappingURL=wrapper.js.map
|
@@ -0,0 +1 @@
|
|
1
|
+
{"version":3,"file":"wrapper.js","sourceRoot":"","sources":["../../../src/http-wrapper/wrapper.ts"],"names":[],"mappings":"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"}
|
@@ -0,0 +1,25 @@
|
|
1
|
+
interface EntityPermissions {
|
2
|
+
[key: string]: string[];
|
3
|
+
}
|
4
|
+
export interface UserPayload {
|
5
|
+
businessModels: EntityPermissions;
|
6
|
+
fleets: EntityPermissions;
|
7
|
+
demandSources: EntityPermissions;
|
8
|
+
createdAt?: string;
|
9
|
+
}
|
10
|
+
export default class ApiUser {
|
11
|
+
id: string | undefined;
|
12
|
+
privatePermissions: UserPayload | undefined;
|
13
|
+
privatePermissionsLegacy: any;
|
14
|
+
emptyUser: boolean;
|
15
|
+
constructor(id?: string);
|
16
|
+
getUserPermissions(): Promise<UserPayload>;
|
17
|
+
get businessModels(): string[] | undefined;
|
18
|
+
get fleets(): string[] | undefined;
|
19
|
+
get demandSources(): string[] | undefined;
|
20
|
+
getUserProperty(key: any): string[] | undefined;
|
21
|
+
get permissions(): UserPayload | undefined;
|
22
|
+
getUserPermissionsLegacy(): Promise<any>;
|
23
|
+
get permissionsLegacy(): any;
|
24
|
+
}
|
25
|
+
export {};
|
@@ -0,0 +1,73 @@
|
|
1
|
+
"use strict";
|
2
|
+
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
3
|
+
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
4
|
+
return new (P || (P = Promise))(function (resolve, reject) {
|
5
|
+
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
6
|
+
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
7
|
+
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
8
|
+
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
9
|
+
});
|
10
|
+
};
|
11
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
12
|
+
const network_1 = require("../network");
|
13
|
+
class ApiUser {
|
14
|
+
constructor(id) {
|
15
|
+
this.id = id;
|
16
|
+
this.emptyUser = !!id;
|
17
|
+
}
|
18
|
+
getUserPermissions() {
|
19
|
+
return __awaiter(this, void 0, void 0, function* () {
|
20
|
+
if (!this.id) {
|
21
|
+
return null;
|
22
|
+
}
|
23
|
+
if (this.privatePermissions) {
|
24
|
+
return this.privatePermissions;
|
25
|
+
}
|
26
|
+
const { data } = yield network_1.IdentityNetwork.get(`/api/v1/users/${this.id}/authorization-payload`);
|
27
|
+
this.privatePermissions = data;
|
28
|
+
return this.privatePermissions;
|
29
|
+
});
|
30
|
+
}
|
31
|
+
get businessModels() {
|
32
|
+
return this.getUserProperty('businessModels');
|
33
|
+
}
|
34
|
+
get fleets() {
|
35
|
+
return this.getUserProperty('fleets');
|
36
|
+
}
|
37
|
+
get demandSources() {
|
38
|
+
return this.getUserProperty('demandSources');
|
39
|
+
}
|
40
|
+
getUserProperty(key) {
|
41
|
+
if (!this.privatePermissions) {
|
42
|
+
throw new Error(`Cannot get ${key} without calling (async) getUserPermissions before`);
|
43
|
+
}
|
44
|
+
return Object.keys(this.privatePermissions[key] || {});
|
45
|
+
}
|
46
|
+
get permissions() {
|
47
|
+
if (!this.privatePermissions) {
|
48
|
+
throw new Error('Cannot get permissions without calling (async) getUserPermissions before');
|
49
|
+
}
|
50
|
+
return this.privatePermissions;
|
51
|
+
}
|
52
|
+
getUserPermissionsLegacy() {
|
53
|
+
return __awaiter(this, void 0, void 0, function* () {
|
54
|
+
if (!this.id) {
|
55
|
+
return null;
|
56
|
+
}
|
57
|
+
if (this.privatePermissionsLegacy) {
|
58
|
+
return this.privatePermissionsLegacy;
|
59
|
+
}
|
60
|
+
const { data } = yield network_1.IdentityNetwork.get(`/api/v1/users/${this.id}/authorization-payload-legacy`);
|
61
|
+
this.privatePermissionsLegacy = data;
|
62
|
+
return this.privatePermissionsLegacy;
|
63
|
+
});
|
64
|
+
}
|
65
|
+
get permissionsLegacy() {
|
66
|
+
if (!this.privatePermissionsLegacy) {
|
67
|
+
throw new Error('Cannot get permissionsLegacy without calling (async) getUserPermissionsLegacy before');
|
68
|
+
}
|
69
|
+
return this.privatePermissionsLegacy;
|
70
|
+
}
|
71
|
+
}
|
72
|
+
exports.default = ApiUser;
|
73
|
+
//# sourceMappingURL=ApiUser.js.map
|
@@ -0,0 +1 @@
|
|
1
|
+
{"version":3,"file":"ApiUser.js","sourceRoot":"","sources":["../../../src/identity/ApiUser.ts"],"names":[],"mappings":";;;;;;;;;;;AAAA,wCAA6C;AAa7C,MAAqB,OAAO;IAS1B,YAAY,EAAY;QACtB,IAAI,CAAC,EAAE,GAAG,EAAE,CAAC;QACb,IAAI,CAAC,SAAS,GAAG,CAAC,CAAC,EAAE,CAAC;IACxB,CAAC;IAEK,kBAAkB;;YACtB,IAAI,CAAC,IAAI,CAAC,EAAE,EAAE;gBACZ,OAAO,IAAI,CAAC;aACb;YAED,IAAI,IAAI,CAAC,kBAAkB,EAAE;gBAC3B,OAAO,IAAI,CAAC,kBAAkB,CAAC;aAChC;YACD,MAAM,EAAE,IAAI,EAAE,GAAG,MAAM,yBAAe,CAAC,GAAG,CAAC,iBAAiB,IAAI,CAAC,EAAE,wBAAwB,CAAC,CAAC;YAE7F,IAAI,CAAC,kBAAkB,GAAG,IAAI,CAAC;YAC/B,OAAO,IAAI,CAAC,kBAAkB,CAAC;QACjC,CAAC;KAAA;IAED,IAAI,cAAc;QAChB,OAAO,IAAI,CAAC,eAAe,CAAC,gBAAgB,CAAC,CAAC;IAChD,CAAC;IAED,IAAI,MAAM;QACR,OAAO,IAAI,CAAC,eAAe,CAAC,QAAQ,CAAC,CAAC;IACxC,CAAC;IAED,IAAI,aAAa;QACf,OAAO,IAAI,CAAC,eAAe,CAAC,eAAe,CAAC,CAAC;IAC/C,CAAC;IAED,eAAe,CAAC,GAAG;QACjB,IAAI,CAAC,IAAI,CAAC,kBAAkB,EAAE;YAC5B,MAAM,IAAI,KAAK,CAAC,cAAc,GAAG,oDAAoD,CAAC,CAAC;SACxF;QAED,OAAO,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,kBAAkB,CAAC,GAAG,CAAC,IAAI,EAAE,CAAC,CAAC;IACzD,CAAC;IAED,IAAI,WAAW;QACb,IAAI,CAAC,IAAI,CAAC,kBAAkB,EAAE;YAC5B,MAAM,IAAI,KAAK,CAAC,0EAA0E,CAAC,CAAC;SAC7F;QAED,OAAO,IAAI,CAAC,kBAAkB,CAAC;IACjC,CAAC;IAEK,wBAAwB;;YAC5B,IAAI,CAAC,IAAI,CAAC,EAAE,EAAE;gBACZ,OAAO,IAAI,CAAC;aACb;YAED,IAAI,IAAI,CAAC,wBAAwB,EAAE;gBACjC,OAAO,IAAI,CAAC,wBAAwB,CAAC;aACtC;YAED,MAAM,EAAE,IAAI,EAAE,GAAG,MAAM,yBAAe,CAAC,GAAG,CAAC,iBAAiB,IAAI,CAAC,EAAE,+BAA+B,CAAC,CAAC;YAEpG,IAAI,CAAC,wBAAwB,GAAG,IAAI,CAAC;YACrC,OAAO,IAAI,CAAC,wBAAwB,CAAC;QACvC,CAAC;KAAA;IAED,IAAI,iBAAiB;QACnB,IAAI,CAAC,IAAI,CAAC,wBAAwB,EAAE;YAClC,MAAM,IAAI,KAAK,CAAC,sFAAsF,CAAC,CAAC;SACzG;QACD,OAAO,IAAI,CAAC,wBAAwB,CAAC;IACvC,CAAC;CACF;AA7ED,0BA6EC"}
|
@@ -0,0 +1,13 @@
|
|
1
|
+
"use strict";
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
4
|
+
};
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
6
|
+
const ApiUser_1 = __importDefault(require("./ApiUser"));
|
7
|
+
exports.ApiUser = ApiUser_1.default;
|
8
|
+
const middlewares_1 = require("./middlewares");
|
9
|
+
exports.middleware = middlewares_1.middleware;
|
10
|
+
exports.middlewareWithDecode = middlewares_1.middlewareWithDecode;
|
11
|
+
exports.eagerLoadPermissionsMiddleware = middlewares_1.eagerLoadPermissionsMiddleware;
|
12
|
+
exports.getDecodedBearer = middlewares_1.getDecodedBearer;
|
13
|
+
//# sourceMappingURL=index.js.map
|
@@ -0,0 +1 @@
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/identity/index.ts"],"names":[],"mappings":";;;;;AAAA,wDAAgC;AAS9B,kBATK,iBAAO,CASL;AART,+CAKuB;AAIrB,qBARA,wBAAU,CAQA;AACV,+BARA,kCAAoB,CAQA;AACpB,yCARA,4CAA8B,CAQA;AAC9B,2BARA,8BAAgB,CAQA"}
|
@@ -0,0 +1,12 @@
|
|
1
|
+
import ApiUser from './ApiUser';
|
2
|
+
export declare const middleware: (options?: {
|
3
|
+
eagerLoadUserPermissions?: boolean;
|
4
|
+
eagerLoadUserPermissionsLegacy?: boolean;
|
5
|
+
}) => (req: any, res: any, next: any) => Promise<void>;
|
6
|
+
export declare const middlewareWithDecode: (options?: {
|
7
|
+
eagerLoadUserPermissions?: boolean;
|
8
|
+
eagerLoadUserPermissionsLegacy?: boolean;
|
9
|
+
}) => (req: any, res: any, next: any) => Promise<void>;
|
10
|
+
export declare const eagerLoadPermissionsMiddleware: (req: any, res: any, next: any) => Promise<any>;
|
11
|
+
export declare const getDecodedBearer: (req: any) => any;
|
12
|
+
export default ApiUser;
|
@@ -0,0 +1,69 @@
|
|
1
|
+
"use strict";
|
2
|
+
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
3
|
+
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
4
|
+
return new (P || (P = Promise))(function (resolve, reject) {
|
5
|
+
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
6
|
+
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
7
|
+
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
8
|
+
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
9
|
+
});
|
10
|
+
};
|
11
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
12
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
13
|
+
};
|
14
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
15
|
+
const ApiUser_1 = __importDefault(require("./ApiUser"));
|
16
|
+
const tracer_1 = require("../tracer");
|
17
|
+
const utils_1 = require("./utils");
|
18
|
+
exports.middleware = (options = {}) => (req, res, next) => __awaiter(void 0, void 0, void 0, function* () {
|
19
|
+
const userId = req.headers['x-af-user-id'];
|
20
|
+
const trace = tracer_1.getCurrentTrace();
|
21
|
+
if (!userId) {
|
22
|
+
trace.context.set('userObject', {});
|
23
|
+
return next();
|
24
|
+
}
|
25
|
+
const userObject = new ApiUser_1.default(userId);
|
26
|
+
if (options.eagerLoadUserPermissions) {
|
27
|
+
yield userObject.getUserPermissions();
|
28
|
+
}
|
29
|
+
if (options.eagerLoadUserPermissionsLegacy) {
|
30
|
+
yield userObject.getUserPermissionsLegacy();
|
31
|
+
}
|
32
|
+
req.user = userObject;
|
33
|
+
trace.context.set('userObject', userObject);
|
34
|
+
return next();
|
35
|
+
});
|
36
|
+
exports.middlewareWithDecode = (options = {}) => (req, res, next) => __awaiter(void 0, void 0, void 0, function* () {
|
37
|
+
var _a, _b;
|
38
|
+
const trace = tracer_1.getCurrentTrace();
|
39
|
+
if (req.headers.authorization) {
|
40
|
+
const decoded = utils_1.decodeBearer(req.headers.authorization);
|
41
|
+
const userId = (_b = (_a = decoded) === null || _a === void 0 ? void 0 : _a.user) === null || _b === void 0 ? void 0 : _b.id;
|
42
|
+
if (userId) {
|
43
|
+
req.headers['X-AF-USER-ID'] = userId;
|
44
|
+
}
|
45
|
+
const userObject = new ApiUser_1.default(userId);
|
46
|
+
if (options.eagerLoadUserPermissions) {
|
47
|
+
yield userObject.getUserPermissions();
|
48
|
+
}
|
49
|
+
if (options.eagerLoadUserPermissionsLegacy) {
|
50
|
+
yield userObject.getUserPermissionsLegacy();
|
51
|
+
}
|
52
|
+
req.user = userObject;
|
53
|
+
trace.context.set('userObject', userObject);
|
54
|
+
}
|
55
|
+
trace.context.set('userObject', {});
|
56
|
+
return next();
|
57
|
+
});
|
58
|
+
exports.eagerLoadPermissionsMiddleware = (req, res, next) => __awaiter(void 0, void 0, void 0, function* () {
|
59
|
+
yield req.user.getUserPermissions();
|
60
|
+
return next();
|
61
|
+
});
|
62
|
+
exports.getDecodedBearer = (req) => {
|
63
|
+
if (req.headers.authorization) {
|
64
|
+
return utils_1.decodeBearer(req.headers.authorization);
|
65
|
+
}
|
66
|
+
return null;
|
67
|
+
};
|
68
|
+
exports.default = ApiUser_1.default;
|
69
|
+
//# sourceMappingURL=middlewares.js.map
|
@@ -0,0 +1 @@
|
|
1
|
+
{"version":3,"file":"middlewares.js","sourceRoot":"","sources":["../../../src/identity/middlewares.ts"],"names":[],"mappings":";;;;;;;;;;;;;;AAAA,wDAAgC;AAChC,sCAA4C;AAC5C,mCAAuC;AAE1B,QAAA,UAAU,GAAG,CAAC,UAGvB,EAAE,EAAE,EAAE,CAAC,CAAO,GAAG,EAAE,GAAG,EAAE,IAAI,EAAiB,EAAE;IACjD,MAAM,MAAM,GAAG,GAAG,CAAC,OAAO,CAAC,cAAc,CAAC,CAAC;IAC3C,MAAM,KAAK,GAAG,wBAAe,EAAE,CAAC;IAChC,IAAI,CAAC,MAAM,EAAE;QACX,KAAK,CAAC,OAAO,CAAC,GAAG,CAAC,YAAY,EAAE,EAAE,CAAC,CAAC;QACpC,OAAO,IAAI,EAAE,CAAC;KACf;IAED,MAAM,UAAU,GAAG,IAAI,iBAAO,CAAC,MAAM,CAAC,CAAC;IAEvC,IAAI,OAAO,CAAC,wBAAwB,EAAE;QACpC,MAAM,UAAU,CAAC,kBAAkB,EAAE,CAAC;KACvC;IAED,IAAI,OAAO,CAAC,8BAA8B,EAAE;QAC1C,MAAM,UAAU,CAAC,wBAAwB,EAAE,CAAC;KAC7C;IAED,GAAG,CAAC,IAAI,GAAG,UAAU,CAAC;IACtB,KAAK,CAAC,OAAO,CAAC,GAAG,CAAC,YAAY,EAAE,UAAU,CAAC,CAAC;IAE5C,OAAO,IAAI,EAAE,CAAC;AAChB,CAAC,CAAA,CAAC;AAEW,QAAA,oBAAoB,GAAG,CAAC,UAGjC,EAAE,EAAE,EAAE,CAAC,CAAO,GAAG,EAAE,GAAG,EAAE,IAAI,EAAiB,EAAE;;IACjD,MAAM,KAAK,GAAG,wBAAe,EAAE,CAAC;IAChC,IAAI,GAAG,CAAC,OAAO,CAAC,aAAa,EAAE;QAC7B,MAAM,OAAO,GAAG,oBAAY,CAAC,GAAG,CAAC,OAAO,CAAC,aAAa,CAAC,CAAC;QACxD,MAAM,MAAM,eAAG,OAAO,0CAAE,IAAI,0CAAE,EAAE,CAAC;QAEjC,IAAI,MAAM,EAAE;YACV,GAAG,CAAC,OAAO,CAAC,cAAc,CAAC,GAAG,MAAM,CAAC;SACtC;QAED,MAAM,UAAU,GAAG,IAAI,iBAAO,CAAC,MAAM,CAAC,CAAC;QAEvC,IAAI,OAAO,CAAC,wBAAwB,EAAE;YACpC,MAAM,UAAU,CAAC,kBAAkB,EAAE,CAAC;SACvC;QAED,IAAI,OAAO,CAAC,8BAA8B,EAAE;YAC1C,MAAM,UAAU,CAAC,wBAAwB,EAAE,CAAC;SAC7C;QAED,GAAG,CAAC,IAAI,GAAG,UAAU,CAAC;QACtB,KAAK,CAAC,OAAO,CAAC,GAAG,CAAC,YAAY,EAAE,UAAU,CAAC,CAAC;KAC7C;IAED,KAAK,CAAC,OAAO,CAAC,GAAG,CAAC,YAAY,EAAE,EAAE,CAAC,CAAC;IACpC,OAAO,IAAI,EAAE,CAAC;AAChB,CAAC,CAAA,CAAC;AAEW,QAAA,8BAA8B,GAAG,CAAO,GAAG,EAAE,GAAG,EAAE,IAAI,EAAE,EAAE;IACrE,MAAM,GAAG,CAAC,IAAI,CAAC,kBAAkB,EAAE,CAAC;IACpC,OAAO,IAAI,EAAE,CAAC;AAChB,CAAC,CAAA,CAAC;AAEW,QAAA,gBAAgB,GAAG,CAAC,GAAG,EAAE,EAAE;IACtC,IAAI,GAAG,CAAC,OAAO,CAAC,aAAa,EAAE;QAC7B,OAAO,oBAAY,CAAC,GAAG,CAAC,OAAO,CAAC,aAAa,CAAC,CAAC;KAChD;IAED,OAAO,IAAI,CAAC;AACd,CAAC,CAAC;AAEF,kBAAe,iBAAO,CAAC"}
|
@@ -0,0 +1,5 @@
|
|
1
|
+
export declare const getAuthFromBearer: (bearer: string) => string;
|
2
|
+
export declare const decodeBearer: (bearer: string) => any;
|
3
|
+
export declare const parsePermissions: (contextId: any, decodedToken: any) => any;
|
4
|
+
export declare const getEntitiesFromContext: (contextId: string, decodedToken: any) => any;
|
5
|
+
export declare const getContextAttributes: (contextId: string, decodedToken: any) => any;
|
@@ -0,0 +1,79 @@
|
|
1
|
+
"use strict";
|
2
|
+
var __importStar = (this && this.__importStar) || function (mod) {
|
3
|
+
if (mod && mod.__esModule) return mod;
|
4
|
+
var result = {};
|
5
|
+
if (mod != null) for (var k in mod) if (Object.hasOwnProperty.call(mod, k)) result[k] = mod[k];
|
6
|
+
result["default"] = mod;
|
7
|
+
return result;
|
8
|
+
};
|
9
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
10
|
+
/* eslint-disable prefer-destructuring */
|
11
|
+
const jwt = __importStar(require("jsonwebtoken"));
|
12
|
+
const CONTEXT_PROPS = ['fleetId', 'businessModelId', 'demandSourceId'];
|
13
|
+
const CONTEXT_MAP_PROPS = {
|
14
|
+
fleet: 'fleets',
|
15
|
+
business: 'businessModels',
|
16
|
+
demand: 'demandSources',
|
17
|
+
};
|
18
|
+
exports.getAuthFromBearer = (bearer) => bearer.replace('Bearer ', '');
|
19
|
+
exports.decodeBearer = (bearer) => {
|
20
|
+
const token = bearer.replace('Bearer ', '');
|
21
|
+
const decoded = jwt.decode(token);
|
22
|
+
return decoded;
|
23
|
+
};
|
24
|
+
exports.parsePermissions = (contextId, decodedToken) => {
|
25
|
+
var _a;
|
26
|
+
if (!decodedToken) {
|
27
|
+
return [];
|
28
|
+
}
|
29
|
+
const contexts = decodedToken.contexts;
|
30
|
+
const activeContext = contexts.find((context) => context.id === contextId);
|
31
|
+
const permissionsByContext = {};
|
32
|
+
const permissionsValue = `${(_a = activeContext.permissions) === null || _a === void 0 ? void 0 : _a.map((cp) => `${cp},`)}`;
|
33
|
+
return {
|
34
|
+
key: activeContext.entityId,
|
35
|
+
value: permissionsValue,
|
36
|
+
};
|
37
|
+
};
|
38
|
+
exports.getEntitiesFromContext = (contextId, decodedToken) => {
|
39
|
+
if (!decodedToken) {
|
40
|
+
return [];
|
41
|
+
}
|
42
|
+
let contexts = decodedToken.contexts;
|
43
|
+
if (contextId) {
|
44
|
+
contexts = contexts.filter((context) => context.id === contextId);
|
45
|
+
}
|
46
|
+
const attributes = {};
|
47
|
+
contexts.forEach((context) => {
|
48
|
+
const prop = CONTEXT_MAP_PROPS[context.subSystem || 'business'];
|
49
|
+
const permissions = exports.parsePermissions(context.id, decodedToken);
|
50
|
+
// eslint-disable-next-line no-unused-expressions
|
51
|
+
attributes[prop]
|
52
|
+
? attributes[prop][permissions.key] = permissions.value
|
53
|
+
: attributes[prop] = { [permissions.key]: permissions.value };
|
54
|
+
});
|
55
|
+
return attributes;
|
56
|
+
};
|
57
|
+
exports.getContextAttributes = (contextId, decodedToken) => {
|
58
|
+
if (!decodedToken) {
|
59
|
+
return [];
|
60
|
+
}
|
61
|
+
let contexts = decodedToken.contexts;
|
62
|
+
if (contextId) {
|
63
|
+
contexts = contexts.filter((context) => context.id === contextId);
|
64
|
+
}
|
65
|
+
const attributes = {};
|
66
|
+
contexts.forEach((context) => {
|
67
|
+
CONTEXT_PROPS.forEach((prop) => {
|
68
|
+
if (context[prop]) {
|
69
|
+
const contextPropWrapped = [context[prop]];
|
70
|
+
// eslint-disable-next-line no-unused-expressions
|
71
|
+
attributes[prop]
|
72
|
+
? attributes[prop] = attributes[prop].concat(contextPropWrapped)
|
73
|
+
: attributes[prop] = contextPropWrapped;
|
74
|
+
}
|
75
|
+
});
|
76
|
+
});
|
77
|
+
return attributes;
|
78
|
+
};
|
79
|
+
//# sourceMappingURL=utils.js.map
|
@@ -0,0 +1 @@
|
|
1
|
+
{"version":3,"file":"utils.js","sourceRoot":"","sources":["../../../src/identity/utils.ts"],"names":[],"mappings":"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"}
|
@@ -0,0 +1,4 @@
|
|
1
|
+
import headersTracer from './http-wrapper';
|
2
|
+
import { newTrace, getCurrentTrace } from './tracer';
|
3
|
+
import { ApiUser, middleware, middlewareWithDecode, eagerLoadPermissionsMiddleware, getDecodedBearer } from './identity';
|
4
|
+
export { headersTracer, getCurrentTrace, newTrace, ApiUser, middleware, middlewareWithDecode, eagerLoadPermissionsMiddleware, getDecodedBearer, };
|
@@ -0,0 +1,17 @@
|
|
1
|
+
"use strict";
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
4
|
+
};
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
6
|
+
const http_wrapper_1 = __importDefault(require("./http-wrapper"));
|
7
|
+
exports.headersTracer = http_wrapper_1.default;
|
8
|
+
const tracer_1 = require("./tracer");
|
9
|
+
exports.newTrace = tracer_1.newTrace;
|
10
|
+
exports.getCurrentTrace = tracer_1.getCurrentTrace;
|
11
|
+
const identity_1 = require("./identity");
|
12
|
+
exports.ApiUser = identity_1.ApiUser;
|
13
|
+
exports.middleware = identity_1.middleware;
|
14
|
+
exports.middlewareWithDecode = identity_1.middlewareWithDecode;
|
15
|
+
exports.eagerLoadPermissionsMiddleware = identity_1.eagerLoadPermissionsMiddleware;
|
16
|
+
exports.getDecodedBearer = identity_1.getDecodedBearer;
|
17
|
+
//# sourceMappingURL=index.js.map
|
@@ -0,0 +1 @@
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":";;;;;AAAA,kEAA2C;AAWzC,wBAXK,sBAAa,CAWL;AAVf,qCAAqD;AAYnD,mBAZO,iBAAQ,CAYP;AADR,0BAXiB,wBAAe,CAWjB;AAVjB,yCAMoB;AAMlB,kBAXA,kBAAO,CAWA;AACP,qBAXA,qBAAU,CAWA;AACV,+BAXA,+BAAoB,CAWA;AACpB,yCAXA,yCAA8B,CAWA;AAC9B,2BAXA,2BAAgB,CAWA"}
|
@@ -0,0 +1 @@
|
|
1
|
+
export declare const IdentityNetwork: any;
|
@@ -0,0 +1,17 @@
|
|
1
|
+
"use strict";
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
4
|
+
};
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
6
|
+
/* eslint-disable import/prefer-default-export */
|
7
|
+
const network_1 = __importDefault(require("@autofleet/network"));
|
8
|
+
const CACHE_LIFETIME_IN_SEC = 10;
|
9
|
+
exports.IdentityNetwork = new network_1.default({
|
10
|
+
serviceName: 'IDENTITY_MS',
|
11
|
+
retries: 3,
|
12
|
+
retryCondition: () => true,
|
13
|
+
cache: process.env.NODE_ENV !== 'test' ? {
|
14
|
+
maxAge: CACHE_LIFETIME_IN_SEC * 1000,
|
15
|
+
} : undefined,
|
16
|
+
});
|
17
|
+
//# sourceMappingURL=index.js.map
|
@@ -0,0 +1 @@
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/network/index.ts"],"names":[],"mappings":";;;;;AAAA,iDAAiD;AACjD,iEAAyC;AAEzC,MAAM,qBAAqB,GAAG,EAAE,CAAC;AAEpB,QAAA,eAAe,GAAG,IAAI,iBAAO,CAAC;IACzC,WAAW,EAAE,aAAa;IAC1B,OAAO,EAAE,CAAC;IACV,cAAc,EAAE,GAAG,EAAE,CAAC,IAAI;IAC1B,KAAK,EAAE,OAAO,CAAC,GAAG,CAAC,QAAQ,KAAK,MAAM,CAAC,CAAC,CAAC;QACvC,MAAM,EAAE,qBAAqB,GAAG,IAAI;KACrC,CAAC,CAAC,CAAC,SAAS;CACd,CAAC,CAAC"}
|
@@ -0,0 +1,16 @@
|
|
1
|
+
/// <reference types="node" />
|
2
|
+
import asyncHooks from 'async_hooks';
|
3
|
+
declare class Trace {
|
4
|
+
id: string;
|
5
|
+
type: string;
|
6
|
+
context: Map<string, any>;
|
7
|
+
hooks: {
|
8
|
+
[key: string]: Function[];
|
9
|
+
};
|
10
|
+
constructor(type: any);
|
11
|
+
}
|
12
|
+
declare const executionContextMap: Map<number, Trace>;
|
13
|
+
export declare const newTrace: (type: any) => Trace;
|
14
|
+
export declare const enable: () => asyncHooks.AsyncHook;
|
15
|
+
export declare const getCurrentTrace: () => Trace;
|
16
|
+
export default executionContextMap;
|
@@ -0,0 +1,48 @@
|
|
1
|
+
"use strict";
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
4
|
+
};
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
6
|
+
const async_hooks_1 = __importDefault(require("async_hooks"));
|
7
|
+
const uuid_1 = __importDefault(require("uuid"));
|
8
|
+
class Trace {
|
9
|
+
constructor(type) {
|
10
|
+
this.id = uuid_1.default.v1();
|
11
|
+
this.type = type;
|
12
|
+
this.context = new Map();
|
13
|
+
this.hooks = {
|
14
|
+
onDestroy: [],
|
15
|
+
};
|
16
|
+
}
|
17
|
+
}
|
18
|
+
const executionContextMap = new Map();
|
19
|
+
function init(asyncId, type, triggerAsyncId) {
|
20
|
+
if (executionContextMap.has(triggerAsyncId)) {
|
21
|
+
executionContextMap.set(asyncId, executionContextMap.get(triggerAsyncId));
|
22
|
+
}
|
23
|
+
}
|
24
|
+
function destroy(asyncId) {
|
25
|
+
const ecValue = executionContextMap.get(asyncId);
|
26
|
+
if (ecValue) {
|
27
|
+
ecValue.hooks.onDestroy.map((cb) => cb(asyncId, ecValue));
|
28
|
+
}
|
29
|
+
executionContextMap.delete(asyncId);
|
30
|
+
}
|
31
|
+
const hook = async_hooks_1.default.createHook({
|
32
|
+
init, destroy,
|
33
|
+
});
|
34
|
+
exports.newTrace = (type) => {
|
35
|
+
const trace = new Trace(type);
|
36
|
+
executionContextMap.set(async_hooks_1.default.executionAsyncId(), trace);
|
37
|
+
return trace;
|
38
|
+
};
|
39
|
+
exports.enable = () => hook.enable();
|
40
|
+
exports.getCurrentTrace = () => {
|
41
|
+
const currentContext = executionContextMap.get(async_hooks_1.default.executionAsyncId());
|
42
|
+
if (!currentContext) {
|
43
|
+
return exports.newTrace('initialContext');
|
44
|
+
}
|
45
|
+
return currentContext;
|
46
|
+
};
|
47
|
+
exports.default = executionContextMap;
|
48
|
+
//# sourceMappingURL=index.js.map
|
@@ -0,0 +1 @@
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/tracer/index.ts"],"names":[],"mappings":";;;;;AAAA,8DAAqC;AACrC,gDAAwB;AAExB,MAAM,KAAK;IAST,YAAY,IAAI;QACd,IAAI,CAAC,EAAE,GAAG,cAAI,CAAC,EAAE,EAAE,CAAC;QACpB,IAAI,CAAC,IAAI,GAAG,IAAI,CAAC;QACjB,IAAI,CAAC,OAAO,GAAG,IAAI,GAAG,EAAE,CAAC;QACzB,IAAI,CAAC,KAAK,GAAG;YACX,SAAS,EAAE,EAAE;SACd,CAAA;IACH,CAAC;CACF;AAED,MAAM,mBAAmB,GAAuB,IAAI,GAAG,EAAE,CAAC;AAE1D,SAAS,IAAI,CAAC,OAAO,EAAE,IAAI,EAAE,cAAc;IACzC,IAAI,mBAAmB,CAAC,GAAG,CAAC,cAAc,CAAC,EAAE;QAC3C,mBAAmB,CAAC,GAAG,CAAC,OAAO,EAAE,mBAAmB,CAAC,GAAG,CAAC,cAAc,CAAC,CAAC,CAAC;KAC3E;AACH,CAAC;AAED,SAAS,OAAO,CAAC,OAAO;IACtB,MAAM,OAAO,GAAG,mBAAmB,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC;IACjD,IAAI,OAAO,EAAE;QACX,OAAO,CAAC,KAAK,CAAC,SAAS,CAAC,GAAG,CAAC,CAAC,EAAE,EAAE,EAAE,CAAC,EAAE,CAAC,OAAO,EAAE,OAAO,CAAC,CAAC,CAAC;KAC3D;IACD,mBAAmB,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC;AACtC,CAAC;AAED,MAAM,IAAI,GAAG,qBAAU,CAAC,UAAU,CAAC;IACjC,IAAI,EAAE,OAAO;CACd,CAAC,CAAC;AAEU,QAAA,QAAQ,GAAG,CAAC,IAAI,EAAS,EAAE;IACtC,MAAM,KAAK,GAAG,IAAI,KAAK,CAAC,IAAI,CAAC,CAAC;IAC9B,mBAAmB,CAAC,GAAG,CAAC,qBAAU,CAAC,gBAAgB,EAAE,EAAE,KAAK,CAAC,CAAC;IAC9D,OAAO,KAAK,CAAC;AACf,CAAC,CAAC;AAEW,QAAA,MAAM,GAAG,GAAyB,EAAE,CAAC,IAAI,CAAC,MAAM,EAAE,CAAC;AAEnD,QAAA,eAAe,GAAG,GAAU,EAAE;IACzC,MAAM,cAAc,GAAG,mBAAmB,CAAC,GAAG,CAAC,qBAAU,CAAC,gBAAgB,EAAE,CAAC,CAAC;IAC9E,IAAI,CAAC,cAAc,EAAE;QACnB,OAAO,gBAAQ,CAAC,gBAAgB,CAAC,CAAC;KACnC;IAED,OAAO,cAAc,CAAC;AACxB,CAAC,CAAC;AAEF,kBAAe,mBAAmB,CAAC"}
|
@@ -0,0 +1 @@
|
|
1
|
+
export {};
|
@@ -0,0 +1,76 @@
|
|
1
|
+
"use strict";
|
2
|
+
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
3
|
+
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
4
|
+
return new (P || (P = Promise))(function (resolve, reject) {
|
5
|
+
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
6
|
+
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
7
|
+
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
8
|
+
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
9
|
+
});
|
10
|
+
};
|
11
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
12
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
13
|
+
};
|
14
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
15
|
+
const express_1 = __importDefault(require("express"));
|
16
|
+
const axios_1 = __importDefault(require("axios"));
|
17
|
+
const winston_1 = __importDefault(require("winston"));
|
18
|
+
const http_wrapper_1 = __importDefault(require("../src/http-wrapper"));
|
19
|
+
const index_1 = require("../src/index");
|
20
|
+
console.log(index_1.headersTracer.toString(), index_1.middlewareWithDecode.toString());
|
21
|
+
const logger = winston_1.default.createLogger({
|
22
|
+
transports: [
|
23
|
+
new winston_1.default.transports.Console(),
|
24
|
+
],
|
25
|
+
});
|
26
|
+
const generateApp = (addEndpoints, port) => __awaiter(void 0, void 0, void 0, function* () {
|
27
|
+
const app = express_1.default();
|
28
|
+
addEndpoints(app);
|
29
|
+
const server = yield new Promise((resolve) => {
|
30
|
+
const s = app.listen(port, () => {
|
31
|
+
console.log('Listen on port', port);
|
32
|
+
resolve(s);
|
33
|
+
});
|
34
|
+
});
|
35
|
+
return () => server.close();
|
36
|
+
});
|
37
|
+
describe('E2E', () => {
|
38
|
+
it('Basic functionality', () => __awaiter(void 0, void 0, void 0, function* () {
|
39
|
+
let server2TraceId = null;
|
40
|
+
http_wrapper_1.default({
|
41
|
+
setAndPropagateCorrelationId: true,
|
42
|
+
headersToPropagate: [
|
43
|
+
'x-test-header',
|
44
|
+
],
|
45
|
+
headersPrefix: 'x-wakanda-',
|
46
|
+
winstonLogger: logger,
|
47
|
+
});
|
48
|
+
const closeServer1 = yield generateApp((app) => {
|
49
|
+
app.get('/', (req, res) => __awaiter(void 0, void 0, void 0, function* () {
|
50
|
+
const { data: res1 } = yield axios_1.default.post(`http://localhost:8082`);
|
51
|
+
res.json(res1);
|
52
|
+
}));
|
53
|
+
}, 8081);
|
54
|
+
const closeServer2 = yield generateApp((app) => {
|
55
|
+
app.post('/', (req, res) => {
|
56
|
+
server2TraceId = req.headers['x-trace-id'];
|
57
|
+
res.json({
|
58
|
+
value: req.headers['x-test-header'],
|
59
|
+
wkanda: req.headers['x-wakanda-id']
|
60
|
+
});
|
61
|
+
});
|
62
|
+
}, 8082);
|
63
|
+
const { data: res1, headers } = yield axios_1.default.get(`http://localhost:8081`, {
|
64
|
+
headers: {
|
65
|
+
'x-test-header': 'testHeader',
|
66
|
+
'x-wakanda-id': 'my-wakanda-id'
|
67
|
+
}
|
68
|
+
});
|
69
|
+
closeServer1();
|
70
|
+
closeServer2();
|
71
|
+
expect(headers['x-trace-id']).toEqual(server2TraceId);
|
72
|
+
expect(res1.value).toEqual('testHeader');
|
73
|
+
expect(res1.wkanda).toEqual('my-wakanda-id');
|
74
|
+
}));
|
75
|
+
});
|
76
|
+
//# sourceMappingURL=http-wrapper.test.js.map
|
@@ -0,0 +1 @@
|
|
1
|
+
{"version":3,"file":"http-wrapper.test.js","sourceRoot":"","sources":["../../tests/http-wrapper.test.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
@@ -1,11 +1,12 @@
|
|
1
1
|
{
|
2
2
|
"name": "@autofleet/outbreak",
|
3
|
-
"version": "0.0
|
3
|
+
"version": "0.1.0-beta-1",
|
4
4
|
"description": "",
|
5
5
|
"main": "dist/index.js",
|
6
6
|
"types": "dist/index.d.ts",
|
7
7
|
"scripts": {
|
8
8
|
"build": "rm -rf ./dist && tsc",
|
9
|
+
"prepublish": "npm run build",
|
9
10
|
"start": "ts-node src/example.ts",
|
10
11
|
"dev": "./node_modules/nodemon/bin/nodemon.js",
|
11
12
|
"lint": "./node_modules/.bin/eslint src/**/*.ts",
|
package/src/index.ts
CHANGED
@@ -1,20 +1,8 @@
|
|
1
1
|
import headersTracer from './http-wrapper';
|
2
2
|
import { newTrace, getCurrentTrace } from './tracer';
|
3
|
-
import {
|
4
|
-
ApiUser,
|
5
|
-
middleware,
|
6
|
-
middlewareWithDecode,
|
7
|
-
eagerLoadPermissionsMiddleware,
|
8
|
-
getDecodedBearer,
|
9
|
-
} from './identity';
|
10
3
|
|
11
4
|
export {
|
12
5
|
headersTracer,
|
13
6
|
getCurrentTrace,
|
14
7
|
newTrace,
|
15
|
-
ApiUser,
|
16
|
-
middleware,
|
17
|
-
middlewareWithDecode,
|
18
|
-
eagerLoadPermissionsMiddleware,
|
19
|
-
getDecodedBearer,
|
20
8
|
};
|
package/src/tracer/index.ts
CHANGED
@@ -20,7 +20,7 @@ class Trace {
|
|
20
20
|
}
|
21
21
|
}
|
22
22
|
|
23
|
-
const executionContextMap: Map<
|
23
|
+
const executionContextMap: Map<number, Trace> = new Map();
|
24
24
|
|
25
25
|
function init(asyncId, type, triggerAsyncId): void {
|
26
26
|
if (executionContextMap.has(triggerAsyncId)) {
|
@@ -31,7 +31,7 @@ function init(asyncId, type, triggerAsyncId): void {
|
|
31
31
|
function destroy(asyncId): void {
|
32
32
|
const ecValue = executionContextMap.get(asyncId);
|
33
33
|
if (ecValue) {
|
34
|
-
ecValue.hooks.onDestroy.map(cb => cb(asyncId, ecValue))
|
34
|
+
ecValue.hooks.onDestroy.map((cb) => cb(asyncId, ecValue));
|
35
35
|
}
|
36
36
|
executionContextMap.delete(asyncId);
|
37
37
|
}
|
@@ -4,9 +4,8 @@ import axios from 'axios';
|
|
4
4
|
import winston from 'winston';
|
5
5
|
|
6
6
|
import headersTracer from '../src/http-wrapper';
|
7
|
-
import { headersTracer as a
|
7
|
+
import { headersTracer as a } from '../src/index';
|
8
8
|
|
9
|
-
console.log(a.toString(), b.toString());
|
10
9
|
|
11
10
|
const logger = winston.createLogger({
|
12
11
|
transports: [
|
package/src/identity/ApiUser.ts
DELETED
@@ -1,91 +0,0 @@
|
|
1
|
-
import { IdentityNetwork } from '../network';
|
2
|
-
|
3
|
-
interface EntityPermissions {
|
4
|
-
[key: string]: string[];
|
5
|
-
}
|
6
|
-
|
7
|
-
export interface UserPayload {
|
8
|
-
businessModels: EntityPermissions;
|
9
|
-
fleets: EntityPermissions;
|
10
|
-
demandSources: EntityPermissions;
|
11
|
-
createdAt?: string;
|
12
|
-
}
|
13
|
-
|
14
|
-
export default class ApiUser {
|
15
|
-
id: string | undefined;
|
16
|
-
|
17
|
-
privatePermissions: UserPayload | undefined;
|
18
|
-
|
19
|
-
privatePermissionsLegacy: any;
|
20
|
-
|
21
|
-
emptyUser: boolean;
|
22
|
-
|
23
|
-
constructor(id? : string) {
|
24
|
-
this.id = id;
|
25
|
-
this.emptyUser = !!id;
|
26
|
-
}
|
27
|
-
|
28
|
-
async getUserPermissions() {
|
29
|
-
if (!this.id) {
|
30
|
-
return null;
|
31
|
-
}
|
32
|
-
|
33
|
-
if (this.privatePermissions) {
|
34
|
-
return this.privatePermissions;
|
35
|
-
}
|
36
|
-
const { data } = await IdentityNetwork.get(`/api/v1/users/${this.id}/authorization-payload`);
|
37
|
-
|
38
|
-
this.privatePermissions = data;
|
39
|
-
return this.privatePermissions;
|
40
|
-
}
|
41
|
-
|
42
|
-
get businessModels(): string[] | undefined {
|
43
|
-
return this.getUserProperty('businessModels');
|
44
|
-
}
|
45
|
-
|
46
|
-
get fleets(): string[] | undefined {
|
47
|
-
return this.getUserProperty('fleets');
|
48
|
-
}
|
49
|
-
|
50
|
-
get demandSources(): string[] | undefined {
|
51
|
-
return this.getUserProperty('demandSources');
|
52
|
-
}
|
53
|
-
|
54
|
-
getUserProperty(key): string[] | undefined {
|
55
|
-
if (!this.privatePermissions) {
|
56
|
-
throw new Error(`Cannot get ${key} without calling (async) getUserPermissions before`);
|
57
|
-
}
|
58
|
-
|
59
|
-
return Object.keys(this.privatePermissions[key] || {});
|
60
|
-
}
|
61
|
-
|
62
|
-
get permissions(): UserPayload | undefined {
|
63
|
-
if (!this.privatePermissions) {
|
64
|
-
throw new Error('Cannot get permissions without calling (async) getUserPermissions before');
|
65
|
-
}
|
66
|
-
|
67
|
-
return this.privatePermissions;
|
68
|
-
}
|
69
|
-
|
70
|
-
async getUserPermissionsLegacy() {
|
71
|
-
if (!this.id) {
|
72
|
-
return null;
|
73
|
-
}
|
74
|
-
|
75
|
-
if (this.privatePermissionsLegacy) {
|
76
|
-
return this.privatePermissionsLegacy;
|
77
|
-
}
|
78
|
-
|
79
|
-
const { data } = await IdentityNetwork.get(`/api/v1/users/${this.id}/authorization-payload-legacy`);
|
80
|
-
|
81
|
-
this.privatePermissionsLegacy = data;
|
82
|
-
return this.privatePermissionsLegacy;
|
83
|
-
}
|
84
|
-
|
85
|
-
get permissionsLegacy(): any {
|
86
|
-
if (!this.privatePermissionsLegacy) {
|
87
|
-
throw new Error('Cannot get permissionsLegacy without calling (async) getUserPermissionsLegacy before');
|
88
|
-
}
|
89
|
-
return this.privatePermissionsLegacy;
|
90
|
-
}
|
91
|
-
}
|
package/src/identity/index.ts
DELETED
@@ -1,15 +0,0 @@
|
|
1
|
-
import ApiUser from './ApiUser';
|
2
|
-
import {
|
3
|
-
middleware,
|
4
|
-
middlewareWithDecode,
|
5
|
-
eagerLoadPermissionsMiddleware,
|
6
|
-
getDecodedBearer,
|
7
|
-
} from './middlewares';
|
8
|
-
|
9
|
-
export {
|
10
|
-
ApiUser,
|
11
|
-
middleware,
|
12
|
-
middlewareWithDecode,
|
13
|
-
eagerLoadPermissionsMiddleware,
|
14
|
-
getDecodedBearer,
|
15
|
-
};
|
@@ -1,76 +0,0 @@
|
|
1
|
-
import ApiUser from './ApiUser';
|
2
|
-
import { getCurrentTrace } from '../tracer';
|
3
|
-
import { decodeBearer } from './utils';
|
4
|
-
|
5
|
-
export const middleware = (options: {
|
6
|
-
eagerLoadUserPermissions?: boolean;
|
7
|
-
eagerLoadUserPermissionsLegacy?: boolean;
|
8
|
-
} = {}) => async (req, res, next): Promise<void> => {
|
9
|
-
const userId = req.headers['x-af-user-id'];
|
10
|
-
const trace = getCurrentTrace();
|
11
|
-
if (!userId) {
|
12
|
-
trace.context.set('userObject', {});
|
13
|
-
return next();
|
14
|
-
}
|
15
|
-
|
16
|
-
const userObject = new ApiUser(userId);
|
17
|
-
|
18
|
-
if (options.eagerLoadUserPermissions) {
|
19
|
-
await userObject.getUserPermissions();
|
20
|
-
}
|
21
|
-
|
22
|
-
if (options.eagerLoadUserPermissionsLegacy) {
|
23
|
-
await userObject.getUserPermissionsLegacy();
|
24
|
-
}
|
25
|
-
|
26
|
-
req.user = userObject;
|
27
|
-
trace.context.set('userObject', userObject);
|
28
|
-
|
29
|
-
return next();
|
30
|
-
};
|
31
|
-
|
32
|
-
export const middlewareWithDecode = (options: {
|
33
|
-
eagerLoadUserPermissions?: boolean;
|
34
|
-
eagerLoadUserPermissionsLegacy?: boolean;
|
35
|
-
} = {}) => async (req, res, next): Promise<void> => {
|
36
|
-
const trace = getCurrentTrace();
|
37
|
-
if (req.headers.authorization) {
|
38
|
-
const decoded = decodeBearer(req.headers.authorization);
|
39
|
-
const userId = decoded?.user?.id;
|
40
|
-
|
41
|
-
if (userId) {
|
42
|
-
req.headers['X-AF-USER-ID'] = userId;
|
43
|
-
}
|
44
|
-
|
45
|
-
const userObject = new ApiUser(userId);
|
46
|
-
|
47
|
-
if (options.eagerLoadUserPermissions) {
|
48
|
-
await userObject.getUserPermissions();
|
49
|
-
}
|
50
|
-
|
51
|
-
if (options.eagerLoadUserPermissionsLegacy) {
|
52
|
-
await userObject.getUserPermissionsLegacy();
|
53
|
-
}
|
54
|
-
|
55
|
-
req.user = userObject;
|
56
|
-
trace.context.set('userObject', userObject);
|
57
|
-
}
|
58
|
-
|
59
|
-
trace.context.set('userObject', {});
|
60
|
-
return next();
|
61
|
-
};
|
62
|
-
|
63
|
-
export const eagerLoadPermissionsMiddleware = async (req, res, next) => {
|
64
|
-
await req.user.getUserPermissions();
|
65
|
-
return next();
|
66
|
-
};
|
67
|
-
|
68
|
-
export const getDecodedBearer = (req) => {
|
69
|
-
if (req.headers.authorization) {
|
70
|
-
return decodeBearer(req.headers.authorization);
|
71
|
-
}
|
72
|
-
|
73
|
-
return null;
|
74
|
-
};
|
75
|
-
|
76
|
-
export default ApiUser;
|
package/src/identity/utils.ts
DELETED
@@ -1,74 +0,0 @@
|
|
1
|
-
/* eslint-disable prefer-destructuring */
|
2
|
-
import * as jwt from 'jsonwebtoken';
|
3
|
-
|
4
|
-
const CONTEXT_PROPS = ['fleetId', 'businessModelId', 'demandSourceId'];
|
5
|
-
const CONTEXT_MAP_PROPS = {
|
6
|
-
fleet: 'fleets',
|
7
|
-
business: 'businessModels',
|
8
|
-
demand: 'demandSources',
|
9
|
-
};
|
10
|
-
|
11
|
-
export const getAuthFromBearer = (bearer: string): string => bearer.replace('Bearer ', '');
|
12
|
-
|
13
|
-
export const decodeBearer = (bearer: string): any => {
|
14
|
-
const token = bearer.replace('Bearer ', '');
|
15
|
-
const decoded = jwt.decode(token);
|
16
|
-
return decoded;
|
17
|
-
};
|
18
|
-
|
19
|
-
export const parsePermissions = (contextId, decodedToken): any => {
|
20
|
-
if (!decodedToken) { return []; }
|
21
|
-
const contexts = decodedToken.contexts;
|
22
|
-
const activeContext = contexts.find((context) => context.id === contextId);
|
23
|
-
|
24
|
-
const permissionsByContext = {};
|
25
|
-
const permissionsValue = `${activeContext.permissions?.map((cp) => `${cp},`)}`;
|
26
|
-
|
27
|
-
|
28
|
-
return {
|
29
|
-
key: activeContext.entityId,
|
30
|
-
value: permissionsValue,
|
31
|
-
};
|
32
|
-
};
|
33
|
-
|
34
|
-
export const getEntitiesFromContext = (contextId: string, decodedToken: any): any => {
|
35
|
-
if (!decodedToken) { return []; }
|
36
|
-
let contexts = decodedToken.contexts;
|
37
|
-
if (contextId) {
|
38
|
-
contexts = contexts.filter((context) => context.id === contextId);
|
39
|
-
}
|
40
|
-
|
41
|
-
const attributes = {};
|
42
|
-
contexts.forEach((context) => {
|
43
|
-
const prop = CONTEXT_MAP_PROPS[context.subSystem || 'business'];
|
44
|
-
|
45
|
-
const permissions = parsePermissions(context.id, decodedToken);
|
46
|
-
// eslint-disable-next-line no-unused-expressions
|
47
|
-
attributes[prop]
|
48
|
-
? attributes[prop][permissions.key] = permissions.value
|
49
|
-
: attributes[prop] = { [permissions.key]: permissions.value };
|
50
|
-
});
|
51
|
-
|
52
|
-
return attributes;
|
53
|
-
};
|
54
|
-
|
55
|
-
export const getContextAttributes = (contextId: string, decodedToken: any): any => {
|
56
|
-
if (!decodedToken) { return []; }
|
57
|
-
let contexts = decodedToken.contexts;
|
58
|
-
if (contextId) {
|
59
|
-
contexts = contexts.filter((context) => context.id === contextId);
|
60
|
-
}
|
61
|
-
const attributes = {};
|
62
|
-
contexts.forEach((context) => {
|
63
|
-
CONTEXT_PROPS.forEach((prop) => {
|
64
|
-
if (context[prop]) {
|
65
|
-
const contextPropWrapped = [context[prop]];
|
66
|
-
// eslint-disable-next-line no-unused-expressions
|
67
|
-
attributes[prop]
|
68
|
-
? attributes[prop] = attributes[prop].concat(contextPropWrapped)
|
69
|
-
: attributes[prop] = contextPropWrapped;
|
70
|
-
}
|
71
|
-
});
|
72
|
-
});
|
73
|
-
return attributes;
|
74
|
-
};
|
package/src/network/index.ts
DELETED
@@ -1,13 +0,0 @@
|
|
1
|
-
/* eslint-disable import/prefer-default-export */
|
2
|
-
import Network from '@autofleet/network';
|
3
|
-
|
4
|
-
const CACHE_LIFETIME_IN_SEC = 10;
|
5
|
-
|
6
|
-
export const IdentityNetwork = new Network({
|
7
|
-
serviceName: 'IDENTITY_MS',
|
8
|
-
retries: 3,
|
9
|
-
retryCondition: () => true,
|
10
|
-
cache: process.env.NODE_ENV !== 'test' ? {
|
11
|
-
maxAge: CACHE_LIFETIME_IN_SEC * 1000,
|
12
|
-
} : undefined,
|
13
|
-
});
|