@autofleet/zehut 2.0.1-alpha4 → 2.0.2
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/README.md +4 -0
- package/lib/app-auth.d.ts +2 -0
- package/lib/app-auth.js +21 -0
- package/lib/exceptions/appDoesNotExist.d.ts +3 -0
- package/lib/exceptions/appDoesNotExist.js +5 -0
- package/lib/index.d.ts +0 -1
- package/lib/user/ApiUser.d.ts +2 -3
- package/lib/user/ApiUser.js +32 -13
- package/lib/user/api-user-flows.test.js +57 -10
- package/lib/user/index.d.ts +0 -1
- package/lib/user/index.js +50 -27
- package/package.json +1 -1
package/README.md
CHANGED
package/lib/app-auth.js
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
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
|
+
exports.getClientSecret = exports.decodeAppBearer = void 0;
|
|
13
|
+
const services_1 = require("./services");
|
|
14
|
+
exports.decodeAppBearer = (bearer, appId) => __awaiter(void 0, void 0, void 0, function* () {
|
|
15
|
+
const { data: decoded } = yield services_1.AutofleetApiNetwork.post('/api/v1/auth', { bearer, appId });
|
|
16
|
+
return decoded;
|
|
17
|
+
});
|
|
18
|
+
exports.getClientSecret = (appId) => __awaiter(void 0, void 0, void 0, function* () {
|
|
19
|
+
const { data: secret } = yield services_1.AutofleetApiNetwork.get(`/api/v1/auth/client-secret/${appId}`);
|
|
20
|
+
return secret;
|
|
21
|
+
});
|
package/lib/index.d.ts
CHANGED
package/lib/user/ApiUser.d.ts
CHANGED
|
@@ -21,15 +21,13 @@ export declare type CustomPermissionLoader = (string: any) => Promise<UserPayloa
|
|
|
21
21
|
export default class ApiUser {
|
|
22
22
|
id: string | undefined;
|
|
23
23
|
privatePermissions: UserPayload | undefined;
|
|
24
|
-
|
|
24
|
+
privateElevatedPermissionsHash: Map<string, PartialUserPayload | undefined>;
|
|
25
25
|
privatePermissionsLegacy: any;
|
|
26
26
|
appPermission: {
|
|
27
27
|
[key: string]: any;
|
|
28
28
|
};
|
|
29
29
|
emptyUser: boolean;
|
|
30
30
|
accountType: AccountType | undefined;
|
|
31
|
-
elevationCallsCounter: number;
|
|
32
|
-
elevationInitialState: PartialUserPayload | undefined;
|
|
33
31
|
constructor(id?: string, accountType?: AccountType, elevatedPermissions?: PartialUserPayload);
|
|
34
32
|
getUserPermissions(): Promise<UserPayload>;
|
|
35
33
|
useCustomPermissionLoader(customPermissionLoader: any): Promise<UserPayload>;
|
|
@@ -37,6 +35,7 @@ export default class ApiUser {
|
|
|
37
35
|
get fleets(): string[] | undefined;
|
|
38
36
|
get demandSources(): string[] | undefined;
|
|
39
37
|
getUserProperty(key: any): string[] | undefined;
|
|
38
|
+
get elevatedPermissions(): UserPayload;
|
|
40
39
|
get permissions(): UserPayload | undefined;
|
|
41
40
|
elevatePermissions(addedPermissions: PartialUserPayload): () => void;
|
|
42
41
|
getUserPermissionsLegacy(): Promise<any>;
|
package/lib/user/ApiUser.js
CHANGED
|
@@ -15,6 +15,8 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
15
15
|
exports.ELEVATED_PERMISSIONS_HEADER = void 0;
|
|
16
16
|
/* eslint-disable consistent-return */
|
|
17
17
|
const node_cache_1 = __importDefault(require("node-cache"));
|
|
18
|
+
const merge_deep_1 = __importDefault(require("merge-deep"));
|
|
19
|
+
const uuid_1 = require("uuid");
|
|
18
20
|
const outbreak_1 = require("@autofleet/outbreak");
|
|
19
21
|
const services_1 = require("../services");
|
|
20
22
|
exports.ELEVATED_PERMISSIONS_HEADER = 'x-af-elevated-permissions';
|
|
@@ -24,9 +26,10 @@ class ApiUser {
|
|
|
24
26
|
this.id = id;
|
|
25
27
|
this.emptyUser = !!id;
|
|
26
28
|
this.appPermission = {};
|
|
27
|
-
this.
|
|
28
|
-
|
|
29
|
-
|
|
29
|
+
this.privateElevatedPermissionsHash = new Map();
|
|
30
|
+
if (elevatedPermissions) {
|
|
31
|
+
this.privateElevatedPermissionsHash.set('initial', elevatedPermissions);
|
|
32
|
+
}
|
|
30
33
|
if (accountType) {
|
|
31
34
|
this.accountType = accountType;
|
|
32
35
|
}
|
|
@@ -79,29 +82,45 @@ class ApiUser {
|
|
|
79
82
|
}
|
|
80
83
|
return Object.keys(this.privatePermissions[key] || {});
|
|
81
84
|
}
|
|
85
|
+
get elevatedPermissions() {
|
|
86
|
+
let permissions = {
|
|
87
|
+
fleets: {},
|
|
88
|
+
businessModels: {},
|
|
89
|
+
demandSources: {},
|
|
90
|
+
};
|
|
91
|
+
[...this.privateElevatedPermissionsHash.values()].forEach((p) => {
|
|
92
|
+
permissions = merge_deep_1.default(permissions, p);
|
|
93
|
+
});
|
|
94
|
+
return permissions;
|
|
95
|
+
}
|
|
82
96
|
get permissions() {
|
|
83
97
|
if (!this.privatePermissions) {
|
|
84
98
|
throw new Error('Cannot get permissions without calling (async) getUserPermissions before');
|
|
85
99
|
}
|
|
86
|
-
|
|
100
|
+
const permissions = merge_deep_1.default(this.privatePermissions, this.elevatedPermissions);
|
|
101
|
+
return permissions;
|
|
87
102
|
}
|
|
88
103
|
elevatePermissions(addedPermissions) {
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
104
|
+
const elevationId = uuid_1.v4();
|
|
105
|
+
// Validate that the added permissions are valid UUIDs
|
|
106
|
+
Object.keys(addedPermissions).forEach((entityType) => {
|
|
107
|
+
Object.keys(addedPermissions[entityType]).forEach((entityId) => {
|
|
108
|
+
if (!uuid_1.validate(entityId)) {
|
|
109
|
+
throw new Error(`Entity id on elevatePermissions is not a valid UUID, provided: ${entityId}`);
|
|
110
|
+
}
|
|
111
|
+
});
|
|
112
|
+
});
|
|
92
113
|
const currentUserTrace = outbreak_1.getCurrentContext();
|
|
93
114
|
if (!currentUserTrace) {
|
|
94
115
|
throw new Error('Cannot find current user cross services trace');
|
|
95
116
|
}
|
|
96
117
|
const currentElevation = JSON.parse(currentUserTrace.context[exports.ELEVATED_PERMISSIONS_HEADER] || '{}');
|
|
97
|
-
this.elevationInitialState = currentElevation;
|
|
98
118
|
const newElevation = Object.assign(currentElevation, addedPermissions);
|
|
99
|
-
this.
|
|
100
|
-
currentUserTrace.context.set(exports.ELEVATED_PERMISSIONS_HEADER, JSON.stringify(
|
|
101
|
-
this.elevationCallsCounter += 1;
|
|
119
|
+
this.privateElevatedPermissionsHash.set(elevationId, newElevation);
|
|
120
|
+
currentUserTrace.context.set(exports.ELEVATED_PERMISSIONS_HEADER, JSON.stringify(this.elevatedPermissions));
|
|
102
121
|
return () => {
|
|
103
|
-
this.
|
|
104
|
-
|
|
122
|
+
this.privateElevatedPermissionsHash.delete(elevationId);
|
|
123
|
+
currentUserTrace.context.set(exports.ELEVATED_PERMISSIONS_HEADER, JSON.stringify(this.elevatedPermissions));
|
|
105
124
|
};
|
|
106
125
|
}
|
|
107
126
|
getUserPermissionsLegacy() {
|
|
@@ -31,6 +31,7 @@ const generateApp = (addEndpoints, port) => __awaiter(void 0, void 0, void 0, fu
|
|
|
31
31
|
describe('E2E', () => {
|
|
32
32
|
it('Basic functionality', () => __awaiter(void 0, void 0, void 0, function* () {
|
|
33
33
|
let server2TraceId = null;
|
|
34
|
+
const [uuid1, uuid2] = [uuid_1.v4(), uuid_1.v4()];
|
|
34
35
|
index_1.enableTracing({
|
|
35
36
|
outbreakOptions: {
|
|
36
37
|
headersPrefix: 'x-af-',
|
|
@@ -40,17 +41,24 @@ describe('E2E', () => {
|
|
|
40
41
|
app.use(index_2.middleware());
|
|
41
42
|
app.get('/', (req, res) => __awaiter(void 0, void 0, void 0, function* () {
|
|
42
43
|
const user = index_1.getUser();
|
|
43
|
-
const
|
|
44
|
+
const closeElevation1 = user.elevatePermissions({
|
|
44
45
|
businessModels: {
|
|
45
|
-
[
|
|
46
|
+
[uuid1]: ['vehicle:write'],
|
|
47
|
+
},
|
|
48
|
+
});
|
|
49
|
+
const closeElevation2 = user.elevatePermissions({
|
|
50
|
+
businessModels: {
|
|
51
|
+
[uuid2]: ['vehicle:write'],
|
|
46
52
|
},
|
|
47
53
|
});
|
|
48
54
|
const { data: res1 } = yield axios_1.default.post('http://localhost:8082');
|
|
49
|
-
|
|
50
|
-
|
|
55
|
+
closeElevation1();
|
|
56
|
+
const { data: res2 } = yield axios_1.default.post('http://localhost:8082');
|
|
57
|
+
closeElevation2();
|
|
58
|
+
res.json([res1, res2]);
|
|
51
59
|
}));
|
|
52
|
-
},
|
|
53
|
-
|
|
60
|
+
}, 8089);
|
|
61
|
+
const server2NumberOfPermissions = [];
|
|
54
62
|
const closeServer2 = yield generateApp((app) => {
|
|
55
63
|
app.use(index_2.middleware());
|
|
56
64
|
app.post('/', (req, res) => {
|
|
@@ -60,7 +68,7 @@ describe('E2E', () => {
|
|
|
60
68
|
fleets: {},
|
|
61
69
|
demandSources: {},
|
|
62
70
|
};
|
|
63
|
-
server2NumberOfPermissions
|
|
71
|
+
server2NumberOfPermissions.push(Object.keys(user.permissions.businessModels).length);
|
|
64
72
|
server2TraceId = req.headers['x-trace-id'];
|
|
65
73
|
res.json({
|
|
66
74
|
value: req.headers['x-af-header'],
|
|
@@ -69,7 +77,7 @@ describe('E2E', () => {
|
|
|
69
77
|
});
|
|
70
78
|
});
|
|
71
79
|
}, 8082);
|
|
72
|
-
const { data: res1, headers } = yield axios_1.default.get('http://localhost:
|
|
80
|
+
const { data: [res1, res2], headers } = yield axios_1.default.get('http://localhost:8089', {
|
|
73
81
|
headers: {
|
|
74
82
|
'x-af-header': 'testHeader',
|
|
75
83
|
'x-af-id': 'my-wakanda-id',
|
|
@@ -78,10 +86,49 @@ describe('E2E', () => {
|
|
|
78
86
|
});
|
|
79
87
|
closeServer1();
|
|
80
88
|
closeServer2();
|
|
81
|
-
expect(server2NumberOfPermissions).toEqual(1);
|
|
89
|
+
expect(server2NumberOfPermissions).toEqual([2, 1]);
|
|
82
90
|
expect(headers['x-trace-id']).toEqual(server2TraceId);
|
|
83
91
|
expect(res1.value).toEqual('testHeader');
|
|
84
92
|
expect(res1.wkanda).toEqual('my-wakanda-id');
|
|
85
|
-
expect(JSON.parse(res1.addedPermissions).businessModels).toBeDefined();
|
|
93
|
+
expect(JSON.parse(res1.addedPermissions).businessModels[uuid1]).toBeDefined();
|
|
94
|
+
expect(JSON.parse(res1.addedPermissions).businessModels[uuid2]).toBeDefined();
|
|
95
|
+
expect(JSON.parse(res2.addedPermissions).businessModels[uuid1]).not.toBeDefined();
|
|
96
|
+
expect(JSON.parse(res2.addedPermissions).businessModels[uuid2]).toBeDefined();
|
|
97
|
+
}));
|
|
98
|
+
it('Should throw in case of invalid UUID', () => __awaiter(void 0, void 0, void 0, function* () {
|
|
99
|
+
let error = null;
|
|
100
|
+
index_1.enableTracing({
|
|
101
|
+
outbreakOptions: {
|
|
102
|
+
headersPrefix: 'x-af-',
|
|
103
|
+
},
|
|
104
|
+
});
|
|
105
|
+
const closeServer1 = yield generateApp((app) => {
|
|
106
|
+
app.use(index_2.middleware());
|
|
107
|
+
app.get('/', (req, res) => __awaiter(void 0, void 0, void 0, function* () {
|
|
108
|
+
const user = index_1.getUser();
|
|
109
|
+
try {
|
|
110
|
+
const closeElevation1 = user.elevatePermissions({
|
|
111
|
+
businessModels: {
|
|
112
|
+
nnn: ['vehicle:write'],
|
|
113
|
+
},
|
|
114
|
+
});
|
|
115
|
+
yield axios_1.default.post('http://localhost:8082');
|
|
116
|
+
closeElevation1();
|
|
117
|
+
}
|
|
118
|
+
catch (e) {
|
|
119
|
+
error = e;
|
|
120
|
+
}
|
|
121
|
+
res.json({ status: 'ok' });
|
|
122
|
+
}));
|
|
123
|
+
}, 8089);
|
|
124
|
+
yield axios_1.default.get('http://localhost:8089', {
|
|
125
|
+
headers: {
|
|
126
|
+
'x-af-header': 'testHeader',
|
|
127
|
+
'x-af-id': 'my-wakanda-id',
|
|
128
|
+
'x-af-user-id': uuid_1.v4(),
|
|
129
|
+
},
|
|
130
|
+
});
|
|
131
|
+
closeServer1();
|
|
132
|
+
expect(error.message).toEqual('Entity id on elevatePermissions is not a valid UUID, provided: nnn');
|
|
86
133
|
}));
|
|
87
134
|
});
|
package/lib/user/index.d.ts
CHANGED
|
@@ -12,7 +12,6 @@ export declare const middlewareWithDecode: (options?: {
|
|
|
12
12
|
export declare const appMiddleware: (options: {
|
|
13
13
|
appId: string;
|
|
14
14
|
clientSecret: string;
|
|
15
|
-
appSecret: string;
|
|
16
15
|
}) => (req: any, res: any, next: any) => Promise<void>;
|
|
17
16
|
export declare const eagerLoadPermissionsMiddleware: (req: any, res: any, next: any) => Promise<any>;
|
|
18
17
|
export declare const getDecodedBearer: (req: any) => any;
|
package/lib/user/index.js
CHANGED
|
@@ -27,39 +27,52 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
|
|
|
27
27
|
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
28
28
|
});
|
|
29
29
|
};
|
|
30
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
31
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
32
|
+
};
|
|
30
33
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
31
34
|
exports.getDecodedBearer = exports.eagerLoadPermissionsMiddleware = exports.appMiddleware = exports.middlewareWithDecode = exports.middleware = void 0;
|
|
32
35
|
const jsonwebtoken_1 = require("jsonwebtoken");
|
|
33
36
|
const ApiUser_1 = __importStar(require("./ApiUser"));
|
|
34
|
-
const utils_1 = require("../utils");
|
|
35
37
|
const tracer_1 = require("../tracer");
|
|
38
|
+
const app_auth_1 = require("../app-auth");
|
|
39
|
+
const appDoesNotExist_1 = __importDefault(require("../exceptions/appDoesNotExist"));
|
|
40
|
+
const utils_1 = require("../utils");
|
|
36
41
|
exports.middleware = (options = {}) => (req, res, next) => __awaiter(void 0, void 0, void 0, function* () {
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
const elevatedPermissionsFromHeader = req.headers[ApiUser_1.ELEVATED_PERMISSIONS_HEADER] && req.headers[ApiUser_1.ELEVATED_PERMISSIONS_HEADER].length > 0
|
|
44
|
-
? JSON.parse(req.headers[ApiUser_1.ELEVATED_PERMISSIONS_HEADER])
|
|
45
|
-
: {};
|
|
46
|
-
const userObject = new ApiUser_1.default(userId, 'user', elevatedPermissionsFromHeader);
|
|
47
|
-
if (eagerLoadUserPermissions) {
|
|
48
|
-
if (customPermissionLoader) {
|
|
49
|
-
yield userObject.useCustomPermissionLoader(customPermissionLoader);
|
|
42
|
+
try {
|
|
43
|
+
const { eagerLoadUserPermissions, eagerLoadUserPermissionsLegacy, customPermissionLoader, } = options;
|
|
44
|
+
const userId = req.headers['x-af-user-id'];
|
|
45
|
+
const trace = tracer_1.newTrace('userPayload');
|
|
46
|
+
if (!userId) {
|
|
47
|
+
return next();
|
|
50
48
|
}
|
|
51
|
-
|
|
52
|
-
|
|
49
|
+
const elevatedPermissionsFromHeader = req.headers[ApiUser_1.ELEVATED_PERMISSIONS_HEADER] && req.headers[ApiUser_1.ELEVATED_PERMISSIONS_HEADER].length > 0
|
|
50
|
+
? JSON.parse(req.headers[ApiUser_1.ELEVATED_PERMISSIONS_HEADER])
|
|
51
|
+
: {};
|
|
52
|
+
const userObject = new ApiUser_1.default(userId, 'user', elevatedPermissionsFromHeader);
|
|
53
|
+
if (eagerLoadUserPermissions) {
|
|
54
|
+
if (customPermissionLoader) {
|
|
55
|
+
yield userObject.useCustomPermissionLoader(customPermissionLoader);
|
|
56
|
+
}
|
|
57
|
+
else {
|
|
58
|
+
yield userObject.getUserPermissions();
|
|
59
|
+
}
|
|
53
60
|
}
|
|
61
|
+
if (eagerLoadUserPermissionsLegacy) {
|
|
62
|
+
yield userObject.getUserPermissionsLegacy();
|
|
63
|
+
}
|
|
64
|
+
req.user = userObject;
|
|
65
|
+
trace.context.set('userObject', userObject);
|
|
66
|
+
// Added in order to support outbreak.
|
|
67
|
+
req.headers['x-af-user-permissions'] = userObject;
|
|
68
|
+
return next();
|
|
54
69
|
}
|
|
55
|
-
|
|
56
|
-
|
|
70
|
+
catch (e) {
|
|
71
|
+
res.status(401);
|
|
72
|
+
return res.json({
|
|
73
|
+
error: 'cannot authenticate user',
|
|
74
|
+
});
|
|
57
75
|
}
|
|
58
|
-
req.user = userObject;
|
|
59
|
-
trace.context.set('userObject', userObject);
|
|
60
|
-
// Added in order to support outbreak.
|
|
61
|
-
req.headers['x-af-user-permissions'] = userObject;
|
|
62
|
-
return next();
|
|
63
76
|
});
|
|
64
77
|
exports.middlewareWithDecode = (options = {}) => (req, res, next) => __awaiter(void 0, void 0, void 0, function* () {
|
|
65
78
|
var _a, _b;
|
|
@@ -68,7 +81,7 @@ exports.middlewareWithDecode = (options = {}) => (req, res, next) => __awaiter(v
|
|
|
68
81
|
let decoded;
|
|
69
82
|
if (req.headers.authorization) {
|
|
70
83
|
try {
|
|
71
|
-
decoded = utils_1.decodeBearer(req.headers.authorization);
|
|
84
|
+
decoded = yield utils_1.decodeBearer(req.headers.authorization);
|
|
72
85
|
}
|
|
73
86
|
catch (e) {
|
|
74
87
|
if (e instanceof jsonwebtoken_1.TokenExpiredError) {
|
|
@@ -118,7 +131,7 @@ exports.middlewareWithDecode = (options = {}) => (req, res, next) => __awaiter(v
|
|
|
118
131
|
return next();
|
|
119
132
|
});
|
|
120
133
|
exports.appMiddleware = (options) => (req, res, next) => __awaiter(void 0, void 0, void 0, function* () {
|
|
121
|
-
const { appId, clientSecret,
|
|
134
|
+
const { appId, clientSecret, } = options;
|
|
122
135
|
const trace = tracer_1.newTrace('userPayload');
|
|
123
136
|
let decoded;
|
|
124
137
|
if (!req.headers.authorization) {
|
|
@@ -128,7 +141,10 @@ exports.appMiddleware = (options) => (req, res, next) => __awaiter(void 0, void
|
|
|
128
141
|
});
|
|
129
142
|
}
|
|
130
143
|
try {
|
|
131
|
-
decoded =
|
|
144
|
+
decoded = yield app_auth_1.decodeAppBearer(req.headers.authorization, appId);
|
|
145
|
+
if (!decoded) {
|
|
146
|
+
throw new appDoesNotExist_1.default();
|
|
147
|
+
}
|
|
132
148
|
}
|
|
133
149
|
catch (e) {
|
|
134
150
|
if (e instanceof jsonwebtoken_1.TokenExpiredError) {
|
|
@@ -143,6 +159,12 @@ exports.appMiddleware = (options) => (req, res, next) => __awaiter(void 0, void
|
|
|
143
159
|
errors: [e.message],
|
|
144
160
|
});
|
|
145
161
|
}
|
|
162
|
+
if (e instanceof appDoesNotExist_1.default) {
|
|
163
|
+
res.status(400);
|
|
164
|
+
return res.json({
|
|
165
|
+
errors: [e.message],
|
|
166
|
+
});
|
|
167
|
+
}
|
|
146
168
|
res.status(500);
|
|
147
169
|
return res.json({
|
|
148
170
|
errors: ['Server error while parsing token'],
|
|
@@ -153,13 +175,14 @@ exports.appMiddleware = (options) => (req, res, next) => __awaiter(void 0, void
|
|
|
153
175
|
req.headers['X-AF-USER-ID'] = userId;
|
|
154
176
|
}
|
|
155
177
|
const userObject = new ApiUser_1.default(userId);
|
|
156
|
-
if (appId
|
|
178
|
+
if (appId) {
|
|
157
179
|
req.headers['x-autofleet-apps-secret'] = clientSecret;
|
|
158
180
|
// Won't work until we find a better solution for identity ms
|
|
159
181
|
yield userObject.getUserAppPermissions(appId, clientSecret);
|
|
160
182
|
}
|
|
161
183
|
req.user = userObject;
|
|
162
184
|
trace.context.set('userObject', userObject);
|
|
185
|
+
trace.context.set('accessToken', utils_1.getAuthFromBearer(req.headers.authorization));
|
|
163
186
|
// Added in order to support outbreak.
|
|
164
187
|
req.headers['x-af-user-permissions'] = userObject;
|
|
165
188
|
return next();
|