Skip to content

Commit 8bfb1ea

Browse files
committed
fix(pencil): issue with auto context & body parse
1 parent 53576c7 commit 8bfb1ea

10 files changed

Lines changed: 35 additions & 43 deletions

File tree

package-lock.json

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

src/api-manager.spec.ts

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ import AgentLoginEvent from './events/agent-login-event';
1616
import AgentLogoutEvent from './events/agent-logout-event';
1717
import { delay, fromEntries } from './utils/utils';
1818
import RequestEvent from './events/request-event';
19+
import { RequestOptions } from './types/request-options';
1920

2021
chai.use(chaiAsPromised);
2122
const expect = chai.expect;
@@ -265,19 +266,26 @@ describe('ApiManager', () => {
265266
it('Should call risk event', async () => {
266267
const options: SecureNativeOptions = {
267268
apiKey: 'YOUR_API_KEY',
269+
autoSend: true,
270+
interval: 10,
268271
};
269272

270273
const fetch = fetchMock.sandbox().mock(`${options.apiUrl}/${ApiRoute.Risk}`, 200);
271274
const eventManager = new EventManager(fetch, options);
275+
eventManager.startEventsPersist();
272276
const apiManager = new ApiManager(eventManager, options);
273277

274-
const riskEvent: EventOptions = {
278+
const riskEvent: RequestOptions = {
275279
event: EventType.RISK,
280+
context: {},
276281
};
277282

278283
try {
279284
// track async event
280-
await apiManager.risk(riskEvent);
285+
apiManager.risk(riskEvent);
286+
287+
// ensure event to be sent
288+
await delay(2 * options.interval);
281289

282290
const fetchOptions = fetch.lastOptions();
283291
const eventPayload: RequestEvent = JSON.parse(fetchOptions.body.toString());
@@ -307,6 +315,7 @@ describe('ApiManager', () => {
307315
expect(eventPayload.response).to.have.property('headers');
308316
expect(eventPayload.response).to.have.property('status');
309317
} finally {
318+
eventManager.stopEventsPersist();
310319
fetch.restore();
311320
}
312321
});
@@ -364,7 +373,7 @@ describe('ApiManager', () => {
364373

365374
const fetchOptions = fetch.lastOptions();
366375
const eventPayload: AgentLoginEvent = JSON.parse(fetchOptions.body.toString());
367-
376+
368377
expect(eventPayload).to.be.not.null;
369378
//timestamp
370379
expect(eventPayload).to.have.property('timestamp');

src/api-manager.ts

Lines changed: 3 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -55,25 +55,13 @@ export default class ApiManager {
5555
}
5656
}
5757

58-
public async risk(opts: RequestOptions): Promise<RiskResult> {
58+
public risk(opts: RequestOptions) {
5959
Logger.debug('Risk call', opts);
6060

6161
const requestUrl = `${this.options.apiUrl}/${ApiRoute.Risk}`;
6262
const event = createEvent(RequestEvent, opts, this.options);
63-
try {
64-
Logger.debug('Risk event', JSON.stringify(event));
65-
const result = await this.eventManager.sendSync<any>(event, requestUrl);
66-
const data = decrypt(result.data, this.options.apiKey);
67-
Logger.debug('Successfuly performed risk', data);
68-
return JSON.parse(data);
69-
} catch (ex) {
70-
Logger.error('Failed to perform risk call', ex);
71-
return {
72-
action: ActionType.ALLOW,
73-
riskLevel: 'low',
74-
score: 0,
75-
};
76-
}
63+
Logger.debug('Risk event', event);
64+
this.eventManager.sendAsync(event, requestUrl);
7765
}
7866

7967
public async heartBeat() {

src/event-manager.ts

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,6 @@ export default class EventManager {
3838
Logger.debug('Attempting to send event', eventOptions);
3939
try {
4040
const resp = await this.fetcher(requestUrl, eventOptions);
41-
4241
//special handling to unathorized status
4342
if (resp.status === 401) {
4443
Logger.fatal('Unauthorized call to SecureNative API, api key is invalid');

src/events/request-event.ts

Lines changed: 5 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,6 @@ import { v4 } from 'uuid';
55
import { SecureNativeOptions } from '../types/securenative-options';
66
import { IncomingHttpHeaders, OutgoingHttpHeaders } from 'http2';
77
import { RequestOptions } from '../types/request-options';
8-
import { CustomProperties } from '../types/custom-properties';
98

109
export default class RequestEvent implements IEvent {
1110
public rid: string;
@@ -25,7 +24,7 @@ export default class RequestEvent implements IEvent {
2524
headers: IncomingHttpHeaders;
2625
url: string;
2726
method: string;
28-
body: string;
27+
body: Object;
2928
};
3029
public response: {
3130
status: number;
@@ -34,15 +33,15 @@ export default class RequestEvent implements IEvent {
3433
public timestamp: string;
3534

3635
constructor(event: RequestOptions, options: SecureNativeOptions) {
37-
Logger.debug('Building SDK event');
38-
const decryptedToken = decrypt(event.reqContext?.clientToken, options.apiKey);
36+
Logger.debug('Building request event');
37+
const reqContext = event.context?.req || {};
38+
const resContext = event.context?.res || {};
39+
const decryptedToken = decrypt(reqContext?.clientToken, options.apiKey);
3940
Logger.debug('Decrypted client token', decryptedToken);
4041
const parsedToken = JSON.parse(decryptedToken) || {};
4142
Logger.debug('Parsed client token:', parsedToken);
4243

4344
const user: any = {};
44-
const reqContext = event.reqContext || {};
45-
const resContext = event.resContext || {};
4645

4746
this.rid = v4();
4847
this.eventType = event.event;

src/events/sdk-event.ts

Lines changed: 6 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import IEvent from './event';
22
import { EventOptions } from '../types/event-options';
3-
import { decrypt, mergeRequestContexts, contextFromRequest, contextFromResponse } from '../utils/utils';
3+
import { decrypt, mergeRequestContexts, contextFromRequest } from '../utils/utils';
44
import { Logger } from '../logger';
55
import { v4 } from 'uuid';
66
import { SecureNativeOptions } from '../types/securenative-options';
@@ -26,24 +26,23 @@ export default class SDKEvent implements IEvent {
2626
headers: IncomingHttpHeaders;
2727
url: string;
2828
method: string;
29-
body: string;
3029
};
3130
public timestamp: string;
3231
public properties?: CustomProperties;
3332

3433
constructor(event: EventOptions, options: SecureNativeOptions) {
3534
Logger.debug('Building SDK event');
36-
const decryptedToken = decrypt(event.context?.clientToken, options.apiKey);
35+
// extract info from session
36+
const { req } = SessionManager.getLastSession();
37+
const reqCtx = mergeRequestContexts(event.context || {}, contextFromRequest(req));
38+
39+
const decryptedToken = decrypt(reqCtx?.clientToken, options.apiKey);
3740
Logger.debug('Decrypted client token', decryptedToken);
3841
const parsedToken = JSON.parse(decryptedToken) || {};
3942
Logger.debug('Parsed client token:', parsedToken);
4043

4144
const user: any = event.userTraits || {};
4245

43-
// extract info from session
44-
const { req } = SessionManager.getLastSession();
45-
46-
const reqCtx = mergeRequestContexts(event.context || {}, contextFromRequest(req));
4746
this.rid = v4();
4847
this.eventType = event.event;
4948
this.userId = event.userId || '';
@@ -60,7 +59,6 @@ export default class SDKEvent implements IEvent {
6059
remoteIp: reqCtx.remoteIp || '',
6160
method: reqCtx.method || '',
6261
url: reqCtx.url,
63-
body: reqCtx.body || '',
6462
headers: reqCtx.headers || {},
6563
};
6664
this.timestamp = event.timestamp?.toISOString() || new Date().toISOString();

src/interceptors/http-server-interceptor.ts

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -92,7 +92,7 @@ export default class HttpServerInterceptor extends Interceptor implements IInter
9292

9393
wrap(exports && exports.ServerResponse && exports.ServerResponse.prototype, 'end', (original) => {
9494
const intercept = super.intercept.bind(this);
95-
const risk = this.apiManager.risk.bind(this);
95+
const risk = this.apiManager.risk.bind(this.apiManager);
9696

9797
return function () {
9898
if (this && this.sn_finished) {
@@ -103,10 +103,7 @@ export default class HttpServerInterceptor extends Interceptor implements IInter
103103
intercept(this.req && this.req.sn_uid, 'end');
104104
const { req, res } = SessionManager.getSession(this.req?.sn_uid);
105105
if (req && res) {
106-
const reqContext = contextFromRequest(req);
107-
const resContext = contextFromResponse(res);
108-
109-
risk({ eventType: EventType.RISK, context: { reqContext, resContext } });
106+
risk({ eventType: EventType.RISK, context: { req: contextFromRequest(req), res: contextFromResponse(res) } });
110107
}
111108

112109
SessionManager.cleanSession(this.req && this.req.sn_uid);

src/logger.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ export interface ILogger {
2626
export class Logger {
2727
private static log: ILogger;
2828
static initLogger(options: SecureNativeOptions) {
29-
const settings = Object.assign({}, { level: options.logLevel || 'error' }, defaultSettings);
29+
const settings = Object.assign({}, defaultSettings, { level: options.logLevel || 'fatal' });
3030
Logger.log = pino(settings);
3131
}
3232

src/types/request-options.ts

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,9 @@ import { RequestContext, ResponseContext } from './request-context';
33

44
export type RequestOptions = {
55
event: EventType | string;
6-
reqContext?: RequestContext;
7-
resContext?: ResponseContext;
6+
context: {
7+
req?: RequestContext;
8+
res?: ResponseContext;
9+
}
810
timestamp?: Date;
911
};

src/utils/utils.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -115,7 +115,7 @@ const contextFromRequest = (req: any): RequestContext => {
115115
return {
116116
url,
117117
method,
118-
body,
118+
body: JSON.stringify(body),
119119
clientToken: cookieValueFromRequest(req, '_sn') || secureheaderFromRequest(req) || '{}',
120120
headers: headersFromRequest(req),
121121
ip: clientIpFromRequest(req),

0 commit comments

Comments
 (0)