Skip to content

Commit 85e20ca

Browse files
authored
[PoC] JWT-based project identification (#64)
1 parent f44a8e5 commit 85e20ca

6 files changed

Lines changed: 309 additions & 83 deletions

File tree

‎src/internal/api/authApi.ts‎

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -516,9 +516,9 @@ export class AuthApi {
516516
});
517517
}
518518
/**
519-
* This endpoint is used to test if authentication is working correctly.
520-
* @summary Test endpoint for validating middleware authentication
521-
* @param authorization Bearer token (API Key or JWT)
519+
* This endpoint validates a user JWT token and returns the associated user information if valid
520+
* @summary Validates user JWT and returns user data
521+
* @param authorization Bearer token (User JWT)
522522
*/
523523
public async authControllerTestAuth(
524524
authorization: string,
@@ -557,6 +557,11 @@ export class AuthApi {
557557
};
558558

559559
let authenticationPromise = Promise.resolve();
560+
if (this.authentications.API_Key.accessToken) {
561+
authenticationPromise = authenticationPromise.then(() =>
562+
this.authentications.API_Key.applyToRequest(localVarRequestOptions)
563+
);
564+
}
560565
authenticationPromise = authenticationPromise.then(() =>
561566
this.authentications.default.applyToRequest(localVarRequestOptions)
562567
);

‎src/lib/analytics.ts‎

Lines changed: 102 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ import {
1919
LogVisitEventRequest,
2020
VisitEventResponse,
2121
} from '../internal/api';
22-
22+
import { ApiCredentials } from './apiCredentials';
2323
import { validateString } from './validators';
2424

2525
export class AnalyticsAPI {
@@ -217,15 +217,28 @@ export class AnalyticsAPI {
217217
}
218218

219219
async getCustomEventTypesByProject(
220-
projectName: string
220+
projectName: string,
221+
credentials?: ApiCredentials
221222
): Promise<GetAllCustomEventTypeResponse> {
222223
validateString(
223224
projectName,
224225
'The projectName must be provided as an input and has to be nonempty.'
225226
);
226227

228+
const headers: any = {};
229+
if (credentials?.userJwt) {
230+
headers['X-User-JWT'] = credentials.userJwt;
231+
}
232+
if (
233+
credentials?.projectId !== undefined &&
234+
credentials.projectId !== null
235+
) {
236+
headers['X-Project-Id'] = String(credentials.projectId);
237+
}
238+
227239
const res = await this.internalApi.analyticsControllerGetCustomEventTypes(
228-
projectName
240+
projectName,
241+
{ headers }
229242
);
230243

231244
return res.body;
@@ -255,73 +268,121 @@ export class AnalyticsAPI {
255268
return res.body;
256269
}
257270

258-
async getAllClickEvents(event: {
259-
projectName: string;
260-
afterTime?: string;
261-
limit?: number;
262-
}): Promise<GetAllClickEventsResponse> {
271+
async getAllClickEvents(
272+
event: {
273+
projectName: string;
274+
afterTime?: string;
275+
limit?: number;
276+
},
277+
credentials?: ApiCredentials
278+
): Promise<GetAllClickEventsResponse> {
263279
const { projectName, afterTime, limit } = event;
264280

265281
validateString(
266282
projectName,
267283
'The projectName must be provided as an input and has to be nonempty.'
268284
);
269285

286+
const headers: any = {};
287+
if (credentials?.userJwt) {
288+
headers['X-User-JWT'] = credentials.userJwt;
289+
}
290+
if (
291+
credentials?.projectId !== undefined &&
292+
credentials.projectId !== null
293+
) {
294+
headers['X-Project-Id'] = String(credentials.projectId);
295+
}
296+
270297
const res = await this.internalApi.analyticsControllerGetAllClickEvents(
271298
projectName,
272299
afterTime,
273-
limit
300+
limit,
301+
{ headers }
274302
);
275303
return res.body;
276304
}
277305

278-
async getAllVisitEvents(event: {
279-
projectName: string;
280-
afterTime?: string;
281-
limit?: number;
282-
}): Promise<GetAllVisitEventsResponse> {
306+
async getAllVisitEvents(
307+
event: {
308+
projectName: string;
309+
afterTime?: string;
310+
limit?: number;
311+
},
312+
credentials?: ApiCredentials
313+
): Promise<GetAllVisitEventsResponse> {
283314
const { projectName, afterTime, limit } = event;
284315

285316
validateString(
286317
projectName,
287318
'The projectName must be provided as an input and has to be nonempty.'
288319
);
289320

321+
const headers: any = {};
322+
if (credentials?.userJwt) {
323+
headers['X-User-JWT'] = credentials.userJwt;
324+
}
325+
if (
326+
credentials?.projectId !== undefined &&
327+
credentials.projectId !== null
328+
) {
329+
headers['X-Project-Id'] = String(credentials.projectId);
330+
}
331+
290332
const res = await this.internalApi.analyticsControllerGetAllVisitEvents(
291333
projectName,
292334
afterTime,
293-
limit
335+
limit,
336+
{ headers }
294337
);
295338
return res.body;
296339
}
297340

298-
async getAllInputEvents(event: {
299-
projectName: string;
300-
afterTime?: string;
301-
limit?: number;
302-
}): Promise<GetAllInputEventsResponse> {
341+
async getAllInputEvents(
342+
event: {
343+
projectName: string;
344+
afterTime?: string;
345+
limit?: number;
346+
},
347+
credentials?: ApiCredentials
348+
): Promise<GetAllInputEventsResponse> {
303349
const { projectName, afterTime, limit } = event;
304350

305351
validateString(
306352
projectName,
307353
'The projectName must be provided as an input and has to be nonempty.'
308354
);
309355

356+
const headers: any = {};
357+
if (credentials?.userJwt) {
358+
headers['X-User-JWT'] = credentials.userJwt;
359+
}
360+
if (
361+
credentials?.projectId !== undefined &&
362+
credentials.projectId !== null
363+
) {
364+
headers['X-Project-Id'] = String(credentials.projectId);
365+
}
366+
310367
const res = await this.internalApi.analyticsControllerGetAllInputEvents(
311368
projectName,
312369
afterTime,
313-
limit
370+
limit,
371+
{ headers }
314372
);
315373
return res.body;
316374
}
317375

318-
async getAllCustomEvents(event: {
319-
projectName: string;
320-
category: string;
321-
subcategory: string;
322-
afterTime?: string;
323-
limit?: number;
324-
}): Promise<GetAllCustomEventsResponse> {
376+
async getAllCustomEvents(
377+
event: {
378+
projectName: string;
379+
category: string;
380+
subcategory: string;
381+
afterTime?: string;
382+
limit?: number;
383+
},
384+
credentials?: ApiCredentials
385+
): Promise<GetAllCustomEventsResponse> {
325386
const { projectName, category, subcategory, afterTime, limit } = event;
326387

327388
validateString(
@@ -339,12 +400,24 @@ export class AnalyticsAPI {
339400
'The subcategory must be provided as an input and has to be nonempty.'
340401
);
341402

403+
const headers: any = {};
404+
if (credentials?.userJwt) {
405+
headers['X-User-JWT'] = credentials.userJwt;
406+
}
407+
if (
408+
credentials?.projectId !== undefined &&
409+
credentials.projectId !== null
410+
) {
411+
headers['X-Project-Id'] = String(credentials.projectId);
412+
}
413+
342414
const res = await this.internalApi.analyticsControllerGetAllCustomEvents(
343415
projectName,
344416
category,
345417
subcategory,
346418
afterTime,
347-
limit
419+
limit,
420+
{ headers }
348421
);
349422
return res.body;
350423
}

‎src/lib/analyticsConfig.ts‎

Lines changed: 28 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ import {
44
CreateAnalyticsConfigModel,
55
UpdateAnalyticsConfigModel,
66
} from '../internal/api';
7+
import { ApiCredentials } from './apiCredentials';
78
import { validateString } from './validators';
89

910
export class AnalyticsConfigAPI {
@@ -14,7 +15,8 @@ export class AnalyticsConfigAPI {
1415
}
1516

1617
async createAnalyticsConfig(
17-
config: CreateAnalyticsConfigModel
18+
config: CreateAnalyticsConfigModel,
19+
credentials?: ApiCredentials
1820
): Promise<AnalyticsConfigResponse> {
1921
validateString(
2022
config.clientAnalyticsKey,
@@ -26,24 +28,46 @@ export class AnalyticsConfigAPI {
2628
'The serverAnalyticsKey must be provided as an input and has to be nonempty.'
2729
);
2830

31+
const headers: any = {};
32+
if (credentials?.userJwt) {
33+
headers['X-User-JWT'] = credentials.userJwt;
34+
}
35+
if (
36+
credentials?.projectId !== undefined &&
37+
credentials.projectId !== null
38+
) {
39+
headers['X-Project-Id'] = String(credentials.projectId);
40+
}
41+
2942
const res =
3043
await this.internalApi.analyticsConfigControllerCreateAnalyticsConfig(
31-
config
44+
config,
45+
{ headers }
3246
);
3347
return res.body;
3448
}
3549

3650
async getAnalyticsConfig(
37-
projectId: string
51+
projectId: string,
52+
credentials?: ApiCredentials
3853
): Promise<AnalyticsConfigResponse> {
3954
validateString(
4055
projectId,
4156
'The projectId must be provided as an input and has to be nonempty.'
4257
);
4358

59+
const headers: any = {};
60+
if (credentials?.userJwt) {
61+
headers['X-User-JWT'] = credentials.userJwt;
62+
}
63+
if (credentials?.projectId !== undefined) {
64+
headers['X-Project-Id'] = String(credentials.projectId);
65+
}
66+
4467
const res =
4568
await this.internalApi.analyticsConfigControllerGetAnalyticsConfig(
46-
projectId
69+
projectId,
70+
{ headers }
4771
);
4872
return res.body;
4973
}

‎src/lib/apiCredentials.ts‎

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
export interface ApiCredentials {
2+
userJwt?: string;
3+
projectId?: number | string;
4+
}

0 commit comments

Comments
 (0)