@autofleet/zehut 3.1.2 → 3.2.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/README.md +2 -76
- package/lib/check-permission.d.ts +3 -3
- package/lib/check-permission.js +7 -26
- package/lib/errors.d.ts +3 -3
- package/lib/errors.js +1 -1
- package/lib/exceptions/appDoesNotExist.d.ts +2 -1
- package/lib/exceptions/appDoesNotExist.js +5 -0
- package/lib/index.d.ts +16 -11
- package/lib/index.js +5 -3
- package/lib/secret-getter.d.ts +2 -2
- package/lib/services.d.ts +3 -2
- package/lib/tracer.js +2 -2
- package/lib/user/ApiUser.d.ts +9 -11
- package/lib/user/ApiUser.js +17 -18
- package/lib/user/index.d.ts +14 -6
- package/lib/user/index.js +58 -78
- package/lib/utils.d.ts +3 -0
- package/lib/utils.js +17 -13
- package/package.json +21 -21
- package/lib/secret-getter.test.d.ts +0 -1
- package/lib/secret-getter.test.js +0 -90
- package/lib/test-helpers/index.d.ts +0 -9
- package/lib/test-helpers/index.js +0 -35
- package/lib/user/api-user-flows.test.d.ts +0 -1
- package/lib/user/api-user-flows.test.js +0 -302
|
@@ -1,302 +0,0 @@
|
|
|
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 uuid_1 = require("uuid");
|
|
7
|
-
const express_1 = __importDefault(require("express"));
|
|
8
|
-
const axios_1 = __importDefault(require("axios"));
|
|
9
|
-
const index_1 = require("../index");
|
|
10
|
-
const index_2 = require("./index");
|
|
11
|
-
const services_1 = require("../services");
|
|
12
|
-
jest.spyOn(services_1.IdentityNetwork, 'get').mockImplementation(async (url) => {
|
|
13
|
-
if (url.includes('/api/v1/users/')) {
|
|
14
|
-
return {
|
|
15
|
-
data: {
|
|
16
|
-
accountType: 'user',
|
|
17
|
-
fleets: {},
|
|
18
|
-
businessModels: {},
|
|
19
|
-
demandSources: {},
|
|
20
|
-
},
|
|
21
|
-
};
|
|
22
|
-
}
|
|
23
|
-
return { data: {} };
|
|
24
|
-
});
|
|
25
|
-
const generateApp = async (addEndpoints, port) => {
|
|
26
|
-
const app = (0, express_1.default)();
|
|
27
|
-
addEndpoints(app);
|
|
28
|
-
const server = await new Promise((resolve) => {
|
|
29
|
-
const s = app.listen(port, () => {
|
|
30
|
-
console.log('Listen on port', port);
|
|
31
|
-
resolve(s);
|
|
32
|
-
});
|
|
33
|
-
});
|
|
34
|
-
return () => server.close();
|
|
35
|
-
};
|
|
36
|
-
describe('E2E', () => {
|
|
37
|
-
it('Basic functionality', async () => {
|
|
38
|
-
let server2TraceId = null;
|
|
39
|
-
const [uuid1, uuid2] = [(0, uuid_1.v4)(), (0, uuid_1.v4)()];
|
|
40
|
-
(0, index_1.enableTracing)({
|
|
41
|
-
outbreakOptions: {
|
|
42
|
-
headersPrefix: 'x-af-',
|
|
43
|
-
},
|
|
44
|
-
});
|
|
45
|
-
const closeServer1 = await generateApp((app) => {
|
|
46
|
-
app.use((0, index_2.middleware)());
|
|
47
|
-
app.get('/', async (req, res) => {
|
|
48
|
-
const user = (0, index_1.getUser)();
|
|
49
|
-
const closeElevation1 = user.elevatePermissions({
|
|
50
|
-
businessModels: {
|
|
51
|
-
[uuid1]: ['vehicle:write'],
|
|
52
|
-
},
|
|
53
|
-
});
|
|
54
|
-
const closeElevation2 = user.elevatePermissions({
|
|
55
|
-
businessModels: {
|
|
56
|
-
[uuid2]: ['vehicle:write'],
|
|
57
|
-
},
|
|
58
|
-
});
|
|
59
|
-
const { data: res1 } = await axios_1.default.post('http://localhost:8082');
|
|
60
|
-
closeElevation1();
|
|
61
|
-
const { data: res2 } = await axios_1.default.post('http://localhost:8082');
|
|
62
|
-
closeElevation2();
|
|
63
|
-
res.json([res1, res2]);
|
|
64
|
-
});
|
|
65
|
-
}, 8089);
|
|
66
|
-
const server2NumberOfPermissions = [];
|
|
67
|
-
const closeServer2 = await generateApp((app) => {
|
|
68
|
-
app.use((0, index_2.middleware)());
|
|
69
|
-
app.post('/', (req, res) => {
|
|
70
|
-
const user = (0, index_1.getUser)();
|
|
71
|
-
user.privatePermissions = {
|
|
72
|
-
businessModels: {},
|
|
73
|
-
fleets: {},
|
|
74
|
-
demandSources: {},
|
|
75
|
-
};
|
|
76
|
-
server2NumberOfPermissions.push(Object.keys(user.permissions.businessModels).length);
|
|
77
|
-
server2TraceId = req.headers['x-trace-id'];
|
|
78
|
-
res.json({
|
|
79
|
-
value: req.headers['x-af-header'],
|
|
80
|
-
wkanda: req.headers['x-af-id'],
|
|
81
|
-
addedPermissions: req.headers['x-af-elevated-permissions'],
|
|
82
|
-
});
|
|
83
|
-
});
|
|
84
|
-
}, 8082);
|
|
85
|
-
const { data: [res1, res2], headers } = await axios_1.default.get('http://localhost:8089', {
|
|
86
|
-
headers: {
|
|
87
|
-
'x-af-header': 'testHeader',
|
|
88
|
-
'x-af-id': 'my-wakanda-id',
|
|
89
|
-
'x-af-user-id': (0, uuid_1.v4)(),
|
|
90
|
-
},
|
|
91
|
-
});
|
|
92
|
-
closeServer1();
|
|
93
|
-
closeServer2();
|
|
94
|
-
expect(server2NumberOfPermissions).toEqual([2, 1]);
|
|
95
|
-
expect(headers['x-trace-id']).toEqual(server2TraceId);
|
|
96
|
-
expect(res1.value).toEqual('testHeader');
|
|
97
|
-
expect(res1.wkanda).toEqual('my-wakanda-id');
|
|
98
|
-
expect(JSON.parse(res1.addedPermissions).businessModels[uuid1]).toBeDefined();
|
|
99
|
-
expect(JSON.parse(res1.addedPermissions).businessModels[uuid2]).toBeDefined();
|
|
100
|
-
expect(JSON.parse(res2.addedPermissions).businessModels[uuid1]).not.toBeDefined();
|
|
101
|
-
expect(JSON.parse(res2.addedPermissions).businessModels[uuid2]).toBeDefined();
|
|
102
|
-
});
|
|
103
|
-
it('Should throw in case of invalid UUID', async () => {
|
|
104
|
-
let error = null;
|
|
105
|
-
(0, index_1.enableTracing)({
|
|
106
|
-
outbreakOptions: {
|
|
107
|
-
headersPrefix: 'x-af-',
|
|
108
|
-
},
|
|
109
|
-
});
|
|
110
|
-
const closeServer1 = await generateApp((app) => {
|
|
111
|
-
app.use((0, index_2.middleware)());
|
|
112
|
-
app.get('/', async (req, res) => {
|
|
113
|
-
const user = (0, index_1.getUser)();
|
|
114
|
-
try {
|
|
115
|
-
const closeElevation1 = user.elevatePermissions({
|
|
116
|
-
businessModels: {
|
|
117
|
-
nnn: ['vehicle:write'],
|
|
118
|
-
},
|
|
119
|
-
});
|
|
120
|
-
await axios_1.default.post('http://localhost:8082');
|
|
121
|
-
closeElevation1();
|
|
122
|
-
}
|
|
123
|
-
catch (e) {
|
|
124
|
-
error = e;
|
|
125
|
-
}
|
|
126
|
-
res.json({ status: 'ok' });
|
|
127
|
-
});
|
|
128
|
-
}, 8089);
|
|
129
|
-
await axios_1.default.get('http://localhost:8089', {
|
|
130
|
-
headers: {
|
|
131
|
-
'x-af-header': 'testHeader',
|
|
132
|
-
'x-af-id': 'my-wakanda-id',
|
|
133
|
-
'x-af-user-id': (0, uuid_1.v4)(),
|
|
134
|
-
},
|
|
135
|
-
});
|
|
136
|
-
closeServer1();
|
|
137
|
-
expect(error.message).toEqual('Entity id on elevatePermissions is not a valid UUID, provided: nnn');
|
|
138
|
-
});
|
|
139
|
-
it('should correctly handle elevation of permissions and their reversion', async () => {
|
|
140
|
-
let capturedError = null;
|
|
141
|
-
// Snapshots to capture state after each step
|
|
142
|
-
let afterFirstElevationElevated = {
|
|
143
|
-
fleets: {},
|
|
144
|
-
businessModels: {},
|
|
145
|
-
demandSources: {},
|
|
146
|
-
};
|
|
147
|
-
let afterFirstElevationCombined = {
|
|
148
|
-
fleets: {},
|
|
149
|
-
businessModels: {},
|
|
150
|
-
demandSources: {},
|
|
151
|
-
};
|
|
152
|
-
let afterSecondElevationElevated = {
|
|
153
|
-
fleets: {},
|
|
154
|
-
businessModels: {},
|
|
155
|
-
demandSources: {},
|
|
156
|
-
};
|
|
157
|
-
let afterSecondElevationCombined = {
|
|
158
|
-
fleets: {},
|
|
159
|
-
businessModels: {},
|
|
160
|
-
demandSources: {},
|
|
161
|
-
};
|
|
162
|
-
let afterCloseSecondElevated = {
|
|
163
|
-
fleets: {},
|
|
164
|
-
businessModels: {},
|
|
165
|
-
demandSources: {},
|
|
166
|
-
};
|
|
167
|
-
let afterCloseSecondCombined = {
|
|
168
|
-
fleets: {},
|
|
169
|
-
businessModels: {},
|
|
170
|
-
demandSources: {},
|
|
171
|
-
};
|
|
172
|
-
let afterCloseFirstElevated = {
|
|
173
|
-
fleets: {},
|
|
174
|
-
businessModels: {},
|
|
175
|
-
demandSources: {},
|
|
176
|
-
};
|
|
177
|
-
let afterCloseFirstCombined = {
|
|
178
|
-
fleets: {},
|
|
179
|
-
businessModels: {},
|
|
180
|
-
demandSources: {},
|
|
181
|
-
};
|
|
182
|
-
(0, index_1.enableTracing)({
|
|
183
|
-
outbreakOptions: {
|
|
184
|
-
headersPrefix: 'x-af-',
|
|
185
|
-
},
|
|
186
|
-
});
|
|
187
|
-
const userId = (0, uuid_1.v4)();
|
|
188
|
-
// Generate UUIDs for test entities
|
|
189
|
-
const fleetUUID1 = (0, uuid_1.v4)();
|
|
190
|
-
const fleetUUID2 = (0, uuid_1.v4)();
|
|
191
|
-
const bmUUID1 = (0, uuid_1.v4)();
|
|
192
|
-
const dsUUID1 = (0, uuid_1.v4)();
|
|
193
|
-
const dsUUID2 = (0, uuid_1.v4)();
|
|
194
|
-
// Spin up a test server
|
|
195
|
-
const closeServer = await generateApp((app) => {
|
|
196
|
-
app.use((0, index_2.middleware)());
|
|
197
|
-
app.get('/', async (req, res) => {
|
|
198
|
-
try {
|
|
199
|
-
const user = (0, index_1.getUser)();
|
|
200
|
-
// Load base permissions (mocked)
|
|
201
|
-
await user.getUserPermissions();
|
|
202
|
-
// Now user.privatePermissions is set
|
|
203
|
-
// 1. First Elevation
|
|
204
|
-
const closeElevation1 = user.elevatePermissions({
|
|
205
|
-
fleets: {
|
|
206
|
-
[fleetUUID1]: ['readF1'],
|
|
207
|
-
},
|
|
208
|
-
businessModels: {
|
|
209
|
-
[bmUUID1]: ['writeBM1'],
|
|
210
|
-
},
|
|
211
|
-
demandSources: {
|
|
212
|
-
[dsUUID1]: ['readDS1'],
|
|
213
|
-
},
|
|
214
|
-
});
|
|
215
|
-
// Capture elevated and combined permissions after first elevation
|
|
216
|
-
afterFirstElevationElevated = user.elevatedPermissions;
|
|
217
|
-
afterFirstElevationCombined = user.permissions; // Non-null assertion since privatePermissions is set
|
|
218
|
-
// 2. Second Elevation
|
|
219
|
-
const closeElevation2 = user.elevatePermissions({
|
|
220
|
-
fleets: {
|
|
221
|
-
[fleetUUID1]: ['manageF1'],
|
|
222
|
-
[fleetUUID2]: ['createF2'], // New fleet
|
|
223
|
-
},
|
|
224
|
-
businessModels: {
|
|
225
|
-
[bmUUID1]: ['writeBM2'], // Additional permission to existing business model
|
|
226
|
-
},
|
|
227
|
-
demandSources: {
|
|
228
|
-
[dsUUID2]: ['readDS2', 'readDS2'], // New demand source with duplicate permissions
|
|
229
|
-
},
|
|
230
|
-
});
|
|
231
|
-
// Capture elevated and combined permissions after second elevation
|
|
232
|
-
afterSecondElevationElevated = user.elevatedPermissions;
|
|
233
|
-
afterSecondElevationCombined = user.permissions;
|
|
234
|
-
// 3. Close Second Elevation
|
|
235
|
-
closeElevation2();
|
|
236
|
-
afterCloseSecondElevated = user.elevatedPermissions;
|
|
237
|
-
afterCloseSecondCombined = user.permissions;
|
|
238
|
-
// 4. Close First Elevation
|
|
239
|
-
closeElevation1();
|
|
240
|
-
afterCloseFirstElevated = user.elevatedPermissions;
|
|
241
|
-
afterCloseFirstCombined = user.permissions;
|
|
242
|
-
}
|
|
243
|
-
catch (e) {
|
|
244
|
-
capturedError = e;
|
|
245
|
-
}
|
|
246
|
-
res.json({ status: 'ok' });
|
|
247
|
-
});
|
|
248
|
-
}, 8089);
|
|
249
|
-
// Trigger the test route
|
|
250
|
-
const response = await axios_1.default.get('http://localhost:8089', {
|
|
251
|
-
headers: {
|
|
252
|
-
'x-af-user-id': userId,
|
|
253
|
-
},
|
|
254
|
-
});
|
|
255
|
-
closeServer();
|
|
256
|
-
// Basic assertions
|
|
257
|
-
expect(response.status).toEqual(200);
|
|
258
|
-
expect(capturedError).toBeNull();
|
|
259
|
-
// ---------------------
|
|
260
|
-
// Assertions After First Elevation
|
|
261
|
-
// ---------------------
|
|
262
|
-
expect(afterFirstElevationElevated.fleets?.[fleetUUID1]).toEqual(expect.arrayContaining(['readF1']));
|
|
263
|
-
expect(afterFirstElevationElevated.businessModels?.[bmUUID1]).toEqual(expect.arrayContaining(['writeBM1']));
|
|
264
|
-
expect(afterFirstElevationElevated.demandSources?.[dsUUID1]).toEqual(expect.arrayContaining(['readDS1']));
|
|
265
|
-
expect(afterFirstElevationCombined.fleets?.[fleetUUID1]).toEqual(expect.arrayContaining(['readF1']));
|
|
266
|
-
expect(afterFirstElevationCombined.businessModels?.[bmUUID1]).toEqual(expect.arrayContaining(['writeBM1']));
|
|
267
|
-
expect(afterFirstElevationCombined.demandSources?.[dsUUID1]).toEqual(expect.arrayContaining(['readDS1']));
|
|
268
|
-
// ---------------------
|
|
269
|
-
// Assertions After Second Elevation
|
|
270
|
-
// ---------------------
|
|
271
|
-
expect(afterSecondElevationElevated.fleets?.[fleetUUID1]).toEqual(expect.arrayContaining(['readF1', 'manageF1']));
|
|
272
|
-
expect(afterSecondElevationElevated.fleets?.[fleetUUID2]).toEqual(expect.arrayContaining(['createF2']));
|
|
273
|
-
expect(afterSecondElevationElevated.businessModels?.[bmUUID1]).toEqual(expect.arrayContaining(['writeBM1', 'writeBM2']));
|
|
274
|
-
expect(afterSecondElevationElevated.demandSources?.[dsUUID2]).toEqual(expect.arrayContaining(['readDS2', 'readDS2']));
|
|
275
|
-
expect(afterSecondElevationCombined.fleets?.[fleetUUID1]).toEqual(expect.arrayContaining(['readF1', 'manageF1']));
|
|
276
|
-
expect(afterSecondElevationCombined.fleets?.[fleetUUID2]).toEqual(expect.arrayContaining(['createF2']));
|
|
277
|
-
expect(afterSecondElevationCombined.businessModels?.[bmUUID1]).toEqual(expect.arrayContaining(['writeBM1', 'writeBM2']));
|
|
278
|
-
expect(afterSecondElevationCombined.demandSources?.[dsUUID2]).toEqual(expect.arrayContaining(['readDS2', 'readDS2']));
|
|
279
|
-
// ---------------------
|
|
280
|
-
// Assertions After Closing Second Elevation
|
|
281
|
-
// ---------------------
|
|
282
|
-
expect(afterCloseSecondElevated.fleets?.[fleetUUID1]).toEqual(expect.arrayContaining(['readF1']));
|
|
283
|
-
expect(afterCloseSecondElevated.fleets?.[fleetUUID2]).toBeUndefined();
|
|
284
|
-
expect(afterCloseSecondElevated.businessModels?.[bmUUID1]).toEqual(expect.arrayContaining(['writeBM1']));
|
|
285
|
-
expect(afterCloseSecondElevated.demandSources?.[dsUUID1]).toEqual(expect.arrayContaining(['readDS1']));
|
|
286
|
-
expect(afterCloseSecondElevated.demandSources?.[dsUUID2]).toBeUndefined();
|
|
287
|
-
expect(afterCloseSecondCombined.fleets?.[fleetUUID1]).toEqual(expect.arrayContaining(['readF1']));
|
|
288
|
-
expect(afterCloseSecondCombined.fleets?.[fleetUUID2]).toBeUndefined();
|
|
289
|
-
expect(afterCloseSecondCombined.businessModels?.[bmUUID1]).toEqual(expect.arrayContaining(['writeBM1']));
|
|
290
|
-
expect(afterCloseSecondCombined.demandSources?.[dsUUID1]).toEqual(expect.arrayContaining(['readDS1']));
|
|
291
|
-
expect(afterCloseSecondCombined.demandSources?.[dsUUID2]).toBeUndefined();
|
|
292
|
-
// ---------------------
|
|
293
|
-
// Assertions After Closing First Elevation
|
|
294
|
-
// ---------------------
|
|
295
|
-
expect(afterCloseFirstElevated.fleets).toEqual({});
|
|
296
|
-
expect(afterCloseFirstElevated.businessModels).toEqual({});
|
|
297
|
-
expect(afterCloseFirstElevated.demandSources).toEqual({});
|
|
298
|
-
expect(afterCloseFirstCombined.fleets).toEqual({});
|
|
299
|
-
expect(afterCloseFirstCombined.businessModels).toEqual({});
|
|
300
|
-
expect(afterCloseFirstCombined.demandSources).toEqual({});
|
|
301
|
-
});
|
|
302
|
-
});
|