@netacea/cloudfront 6.0.14 → 6.0.15
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/index.d.ts +3 -66
- package/dist/index.js +1 -1
- package/package.json +2 -2
package/dist/index.d.ts
CHANGED
|
@@ -309,55 +309,6 @@ interface IngestArgs {
|
|
|
309
309
|
mitigationStatus?: number;
|
|
310
310
|
netaceaCookieStatus?: number;
|
|
311
311
|
}
|
|
312
|
-
interface WebLog {
|
|
313
|
-
Request: string;
|
|
314
|
-
TimeLocal: string;
|
|
315
|
-
RealIp: string;
|
|
316
|
-
UserAgent: string;
|
|
317
|
-
Status: string;
|
|
318
|
-
RequestTime: string;
|
|
319
|
-
BytesSent: string;
|
|
320
|
-
Referer: string;
|
|
321
|
-
NetaceaUserIdCookie: string;
|
|
322
|
-
NetaceaMitigationApplied: string;
|
|
323
|
-
IntegrationType?: string;
|
|
324
|
-
IntegrationVersion?: string;
|
|
325
|
-
XForwardedFor?: string;
|
|
326
|
-
optional?: Record<string, unknown>;
|
|
327
|
-
ProtectionMode?: string;
|
|
328
|
-
RequestHost?: string;
|
|
329
|
-
ProtectorLatencyMs?: number;
|
|
330
|
-
ProtectorStatus?: number;
|
|
331
|
-
NetaceaUserIdCookieStatus?: number;
|
|
332
|
-
}
|
|
333
|
-
interface V2WebLog {
|
|
334
|
-
'@timestamp': string;
|
|
335
|
-
bc_type?: string;
|
|
336
|
-
bytes_sent: number;
|
|
337
|
-
client: string;
|
|
338
|
-
domain_name?: string;
|
|
339
|
-
domain_name_orig?: string;
|
|
340
|
-
hour: number;
|
|
341
|
-
integration_type?: string;
|
|
342
|
-
integration_version?: string;
|
|
343
|
-
protection_mode?: string;
|
|
344
|
-
method: string;
|
|
345
|
-
minute: number;
|
|
346
|
-
protector_latency_ms?: number;
|
|
347
|
-
protector_status?: number;
|
|
348
|
-
path: string;
|
|
349
|
-
protocol: string | null;
|
|
350
|
-
query?: string;
|
|
351
|
-
referrer?: string;
|
|
352
|
-
request: string;
|
|
353
|
-
request_time: number;
|
|
354
|
-
request_host?: string;
|
|
355
|
-
status: string;
|
|
356
|
-
user_agent: string;
|
|
357
|
-
user_id?: string;
|
|
358
|
-
x_forwarded_for?: string;
|
|
359
|
-
optional?: Record<string, unknown>;
|
|
360
|
-
}
|
|
361
312
|
interface NetaceaResponseBase {
|
|
362
313
|
/**
|
|
363
314
|
* Cookies that should be set back to the user.
|
|
@@ -369,6 +320,7 @@ interface NetaceaResponseBase {
|
|
|
369
320
|
sessionStatus: string;
|
|
370
321
|
apiCallLatency?: number;
|
|
371
322
|
apiCallStatus?: number;
|
|
323
|
+
cookieSessionStatus?: string | undefined;
|
|
372
324
|
}
|
|
373
325
|
interface MitigateResponse<T = any> extends NetaceaResponseBase {
|
|
374
326
|
/**
|
|
@@ -391,16 +343,6 @@ interface InjectResponse<T = any> extends MitigateResponse<T> {
|
|
|
391
343
|
response?: T | undefined;
|
|
392
344
|
}
|
|
393
345
|
type NetaceaMitigationResponse<T> = MitigateResponse<T> | InjectResponse<T> | undefined;
|
|
394
|
-
interface FindBestMitigationResponse {
|
|
395
|
-
sessionStatus: string;
|
|
396
|
-
mitigation: string;
|
|
397
|
-
parts: NetaceaParts;
|
|
398
|
-
}
|
|
399
|
-
interface NetaceaParts {
|
|
400
|
-
match: number;
|
|
401
|
-
mitigate: number;
|
|
402
|
-
captcha: number;
|
|
403
|
-
}
|
|
404
346
|
interface APICallResponse {
|
|
405
347
|
status: number;
|
|
406
348
|
body?: string;
|
|
@@ -423,6 +365,7 @@ interface CloudfrontConstructorArgs extends NetaceaBaseArgs, KinesisIngestArgs {
|
|
|
423
365
|
dynamicCaptchaContentType?: boolean;
|
|
424
366
|
netaceaCookieAttributes?: string;
|
|
425
367
|
netaceaCaptchaCookieAttributes?: string;
|
|
368
|
+
logBatchSize?: number | undefined;
|
|
426
369
|
/**
|
|
427
370
|
* The name of the header from which to retrieve the client's IP address.
|
|
428
371
|
*/
|
|
@@ -447,6 +390,7 @@ declare class Cloudfront {
|
|
|
447
390
|
private readonly captchaHeader?;
|
|
448
391
|
private readonly dynamicCaptchaContentType;
|
|
449
392
|
private readonly ipHeaderName?;
|
|
393
|
+
private readonly requestAnalyser;
|
|
450
394
|
protected mitataCookieExpirySeconds: number;
|
|
451
395
|
protected apiKey: string;
|
|
452
396
|
protected secretKey?: string;
|
|
@@ -500,8 +444,6 @@ declare class Cloudfront {
|
|
|
500
444
|
accept: string;
|
|
501
445
|
host: string;
|
|
502
446
|
}): Promise<ComposeResultResponse>;
|
|
503
|
-
protected isUrlCaptchaPost(url: string, method: string): boolean;
|
|
504
|
-
protected isUrlCaptchaGet(url: string, method: string): boolean;
|
|
505
447
|
protected shouldSetCaptchaPass(request: CloudFrontRequest, response: CloudFrontResponse | CloudFrontResultResponse): boolean;
|
|
506
448
|
private processCaptcha;
|
|
507
449
|
private makeCaptchaAPICall;
|
|
@@ -511,14 +453,9 @@ declare class Cloudfront {
|
|
|
511
453
|
protected createMitataCaptcha(headers: Record<string, string | string[]>): Promise<string | undefined>;
|
|
512
454
|
private buildCookieFromValues;
|
|
513
455
|
protected callIngest(args: IngestArgs): Promise<void>;
|
|
514
|
-
protected constructWebLog(args: IngestArgs): WebLog | V2WebLog;
|
|
515
|
-
private constructV2WebLog;
|
|
516
|
-
private constructV1WebLog;
|
|
517
456
|
private makeIngestApiCall;
|
|
518
457
|
protected processIngest(request: CloudFrontRequest): Promise<NetaceaResponseBase>;
|
|
519
458
|
protected setIngestOnlyMitataCookie(userId: string | undefined): Promise<NetaceaResponseBase>;
|
|
520
|
-
protected findBestMitigation(match: number, mitigate: number, captcha: number, isCaptchaPost: boolean): FindBestMitigationResponse;
|
|
521
|
-
private adjustCaptchaCode;
|
|
522
459
|
protected check(netaceaCookie: string | undefined, clientIP: string, userAgent: string, accept: string, host: string, captchaCookie?: string): Promise<ComposeResultResponse>;
|
|
523
460
|
private makeMitigateAPICall;
|
|
524
461
|
private buildCookieHeader;
|
package/dist/index.js
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
"use strict";var e=require("node:crypto"),t=require("node:buffer"),a=require("axios"),i=require("aws4");function s(e){var t=Object.create(null);return e&&Object.keys(e).forEach((function(a){if("default"!==a){var i=Object.getOwnPropertyDescriptor(e,a);Object.defineProperty(t,a,i.get?i:{enumerable:!0,get:function(){return e[a]}})}})),t.default=e,Object.freeze(t)}var o,r,n,c,h=s(require("jose"));!function(e){e.ORIGIN="ORIGIN",e.HTTP="HTTP",e.KINESIS="KINESIS",e.NATIVE="NATIVE"}(o||(o={})),function(e){e.V1="V1",e.V2="V2"}(r||(r={})),function(e){e.MITIGATE="MITIGATE",e.INJECT="INJECT",e.INGEST="INGEST"}(n||(n={})),function(e){e.CAPTCHA_GET="captcha_get",e.CAPTCHA_POST="captcha_post",e.EXPIRED_SESSION="expired_session",e.FORCED_REVALIDATION="forced_revalidation",e.INVALID_SESSION="invalid_session",e.IP_CHANGE="ip_change",e.NO_SESSION="no_session"}(c||(c={}));function u(e,t=0){return isNaN(e)?t:parseInt(e)}const d=3e3;const p="_/@#/",l={none:"",block:"block",captcha:"captcha",allow:"allow",captchaPass:"captchapass"},m={0:l.none,1:l.block,2:l.none,3:l.block,4:l.block},g={1:l.captcha,2:l.captchaPass,3:l.captcha,4:l.allow,5:l.captcha};var y=Object.freeze({__proto__:null,COOKIEDELIMITER:p,bestMitigationCaptchaMap:g,bestMitigationMap:m,captchaMap:{0:"",1:"captcha_serve",2:"captcha_pass",3:"captcha_fail",4:"captcha_cookiepass",5:"captcha_cookiefail"},captchaStatusCodes:{"":0,captchaServe:1,captchaPass:2,captchaFail:3,captchaCookiePass:4,captchaCookieFail:5},matchMap:{0:"",1:"ua_",2:"ip_",3:"visitor_",4:"datacenter_",5:"sev_",6:"organisation_",7:"asn_",8:"country_",9:"combination_"},mitigateMap:{0:"",1:"blocked",2:"allow",3:"hardblocked",4:"block"},mitigationTypes:l,netaceaCookieV3KeyMap:{clientIP:"cip",userId:"uid",gracePeriod:"grp",cookieId:"cid",match:"mat",mitigate:"mit",captcha:"cap",issueTimestamp:"ist",issueReason:"isr"},netaceaCookieV3OptionalKeyMap:{checkAllPostRequests:"fCAPR"},netaceaHeaders:{match:"x-netacea-match",mitigate:"x-netacea-mitigate",captcha:"x-netacea-captcha",mitata:"x-netacea-mitata-value",mitataExpiry:"x-netacea-mitata-expiry",mitataCaptcha:"x-netacea-mitatacaptcha-value",mitataCaptchaExpiry:"x-netacea-mitatacaptcha-expiry",eventId:"x-netacea-event-id"},netaceaSettingsMap:{checkAllPostRequests:"checkAllPostRequests"}});const C="ignored",k="1234567890abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ".split(""),f=/^(.*)_\/@#\/(.*)_\/@#\/(.*)_\/@#\/(.*)_\/@#\/((\d)(\d)(\d))$/;function v(e){if(void 0===e)return;const t=e.match(f);if(null!=t){const[,e,a,i,s,o,r,n,c]=t;return{signature:e,expiry:a,userId:i,ipHash:s,mitigationType:o,match:parseInt(r),mitigate:parseInt(n),captcha:parseInt(c)}}}function S(t,a,i,s,o="000"){void 0===a&&(a=function(t=16,a=k){const i=e.randomBytes(t-1);return`c${Array.from(i).map((e=>a[e%a.length])).join("")}`}());const r=[i,a,N(t+"|"+String(i),s),o].join(p);return`${N(r,s)}${p}${r}`}function N(a,i){const s=e.createHmac("sha256",i);return s.update(a),t.Buffer.from(s.digest("hex")).toString("base64")}function I(e,t,a){const i={mitata:void 0,requiresReissue:!1,isExpired:!1,shouldExpire:!1,isSameIP:!1,isPrimaryHashValid:!1,captcha:0,match:0,mitigate:0};if("string"!=typeof e||""===e)return i;const s=v(e);if(void 0!==s){const e=[s.expiry,s.userId,s.ipHash,s.mitigationType].join(p),i=Math.floor(Date.now()/1e3),o=parseInt(s.expiry)<i,r=[1,3,5].includes(s.captcha),n=3===s.mitigate,c=r||n,h=N(t+"|"+s.expiry,a),u=s.ipHash===h;return{mitata:s,requiresReissue:o||!u,isExpired:o,shouldExpire:c,isSameIP:u,isPrimaryHashValid:s.signature===N(e,a),match:s.match,mitigate:s.mitigate,captcha:s.captcha}}return i}function A(e,t){const a=e.split(";").map((e=>e.trim())).filter((e=>e.toLowerCase().startsWith(t.toLowerCase())))[0];return void 0!==a&&a.length>0?a?.replace(`${t}=`,""):void 0}function b(e,t=!1){return"string"!=typeof e&&(e=e.join("; ")),""===e?"":w(e.split(";"),t).join("; ")}function w(e,t=!1){if(t)return w(e.reverse()).reverse();const a=new Set,i=[];for(let t of e){if(t=t.trimStart(),""===t.trim())continue;const e=t.split("=")[0].toUpperCase();a.has(e)||(a.add(e),i.push(t))}return i}var E=Object.freeze({__proto__:null,configureCookiesDomain:function(e,t){let a=e=b(e??"",!0),i=t=b(t??"",!0);if(void 0!==e&&void 0!==t){const s=A(e,"Domain"),o=A(t,"Domain");void 0!==s&&void 0!==o?i=t.replace(o,s):void 0!==s&&void 0===o?i=t+(""!==t?`; Domain=${s}`:`Domain=${s}`):void 0===s&&void 0!==o&&(a=e+(""!==e?`; Domain=${o}`:`Domain=${o}`))}else if(void 0!==e&&void 0===t){const t=A(e,"Domain");void 0!==t&&(i=`Domain=${t}`)}else if(void 0===e&&void 0!==t){const e=A(t,"Domain");void 0!==e&&(a=`Domain=${e}`)}return{cookieAttributes:""!==a?a:void 0,captchaCookieAttributes:""!==i?i:void 0}},extractAndRemoveCookieAttr:function(e,t){const a=A(e,t);if(void 0!==a){return{extractedAttribute:a,cookieAttributes:e.replace(/ /g,"").replace(`${t}=${a}`,"").split(";").filter((e=>e.length>0)).join("; ")}}return{extractedAttribute:void 0,cookieAttributes:e}},extractCookieAttr:A,removeDuplicateAttrs:b});function T(e){const t=b([e.otherAttributes??"",`Max-Age=${e.maxAgeAttribute??86400}`,"Path=/"].join("; "));return`${e.cookieName}=${e.cookieValue}; ${t}`}var K=Object.freeze({__proto__:null,createNetaceaCaptchaSetCookieString:function(e){return T({...e,cookieName:e.cookieName??"_mitatacaptcha"})},createNetaceaSetCookieString:function(e){return T({...e,cookieName:e.cookieName??"_mitata"})},createSetCookieString:T});var x=Object.freeze({__proto__:null,parseSetCookie:function(e){const t=e.indexOf("=");if(t<0)throw new Error("Could not parse the given set-cookie value.");const a=e.slice(0,t),i=e.slice(t+1),s=i.indexOf(";");return{name:a,value:i.slice(0,s),attributes:i.slice(s).trimStart()}}});const P={cookie:{parse:x,attributes:E,netaceaSession:K}};var R={},_={},M={},H={};Object.defineProperty(H,"__esModule",{value:!0}),H.API_VERSION=H.REGION=H.PAYLOAD_TYPE=H.STATE=void 0,H.STATE={ACTIVE:"ACTIVE",UPDATING:"UPDATING",CREATING:"CREATING",DELETING:"DELETING"},H.PAYLOAD_TYPE="string",H.REGION="eu-west-1",H.API_VERSION="2013-12-02",Object.defineProperty(M,"__esModule",{value:!0}),M.signRequest=void 0;const O=i,q=H;function D(e,t){const a=[];for(let i=0;i<e.length;i+=t){const s=e.slice(i,i+t);a.push({Data:Buffer.from(JSON.stringify(s)).toString("base64"),PartitionKey:Date.now().toString()})}return a}M.signRequest=function(e,t,a){const{accessKeyId:i,secretAccessKey:s}=e,o={Records:D(t,a),PartitionKey:Date.now().toString(),StreamName:e.streamName};return O.sign({service:"kinesis",body:JSON.stringify(o),headers:{"Content-Type":"application/x-amz-json-1.1","X-Amz-Target":"Kinesis_20131202.PutRecords"},region:q.REGION},{accessKeyId:i,secretAccessKey:s})},Object.defineProperty(_,"__esModule",{value:!0});const V=M;_.default=class{constructor({kinesisStreamName:e,kinesisAccessKey:t,kinesisSecretKey:a,maxLogAgeSeconds:i,logBatchSize:s}){this.logBatchSize=20,this.maxLogAgeSeconds=10,this.logCache=[],this.intervalSet=!1,this.kinesisStreamName=e,this.kinesisAccessKey=t,this.kinesisSecretKey=a,void 0!==i&&i<this.maxLogAgeSeconds&&i>0&&(this.maxLogAgeSeconds=i),void 0!==s&&(this.logBatchSize=s)}async putToKinesis(e){if(0===this.logCache.length)return;const t=[...this.logCache];this.logCache=[];try{const a=(0,V.signRequest)({streamName:this.kinesisStreamName,accessKeyId:this.kinesisAccessKey,secretAccessKey:this.kinesisSecretKey},t,this.logBatchSize);await e({headers:a.headers,host:`https://${a.hostname}`,method:a.method,path:a.path,body:a.body})}catch(e){this.logCache.push(...t),console.error(e)}}async ingest(e,t){this.logCache.push(e),this.intervalSet||(this.intervalSet=!0,await async function(e){await new Promise((t=>{setTimeout(t,e)}))}(1e3*this.maxLogAgeSeconds),await this.putToKinesis(t),this.intervalSet=!1),this.logCache.length>=this.logBatchSize&&await this.putToKinesis(t)}},Object.defineProperty(R,"__esModule",{value:!0});const F=_;var $=R.default=F.default;async function L(e,t){const a=h.base64url.decode(t),{plaintext:i}=await h.compactDecrypt(e,a,{keyManagementAlgorithms:["dir"],contentEncryptionAlgorithms:["A256GCM"]});return(new TextDecoder).decode(i)}function j(e,t){const{clientIp:a}=e;if(void 0===t||""===t)return a;const i=e.headers[t]?.[0]?.value;return void 0===i||""===i?a:"x-forwarded-for"===t?i.split(/, ?/).pop()??a:i}function U(e,t){G(e,t.protectorApiResponse.status,t.latencyMs),e.headers["x-netacea-session-status"]=[{key:"x-netacea-session-status",value:"error_open"}]}function G(e,t,a){a!==t&&(e.headers["x-netacea-api-call-status"]=[{key:"x-netacea-api-call-status",value:String(t)}]),void 0!==a&&(e.headers["x-netacea-api-call-latency"]=[{key:"x-netacea-api-call-latency",value:String(a)}])}function B(e,t){if(void 0!==e?.[t]){const a=e[t];if(void 0!==a)return a[0].value}}async function X(e,t,a){const i=t.cookie?.[0].value.split(";"),s=i?.find((t=>t.includes(`${e}=`)))?.trimStart()?.replace(`${e}=`,"");if(void 0!==s){if(void 0!==a)try{return await L(s,a)}catch(e){return}return s}}function J(e){const t={"set-cookie":[]};for(const a of e)t["set-cookie"]?.push({key:"set-cookie",value:a});return t}function z(e,t){const a=e[t];return"string"==typeof a?a:a?.[0]}function W(e,t){const a=z(e,t);if(void 0!==a)return parseInt(a)}function Y(e,t,a){"/"!==t[0]&&(t=`/${t}`);const i=t.split("?"),s=i[0],o=i.length>1?`?${i[1]}`:void 0;return{path:s,query:o,request:`${e} ${s}${o??""}${""!==(a??"")?` ${a}`:""}`}}class Z extends Error{protectorApiResponse;latencyMs;constructor(e,t){super(`Got status ${e.status} when calling protector API with ${t}ms latency.`),this.protectorApiResponse=e,this.latencyMs=t}}const{extractCookieAttr:Q,extractAndRemoveCookieAttr:ee,removeDuplicateAttrs:te}=P.cookie.attributes,ae=P.cookie.parse.parseSetCookie,{configureCookiesDomain:ie}=P.cookie.attributes,{matchMap:se,mitigationTypes:oe,mitigateMap:re,bestMitigationMap:ne,bestMitigationCaptchaMap:ce,captchaMap:he,netaceaHeaders:ue}=y;class de{static NetaceaCookieHeader="x-netacea-cloudfront-mitata-cookie";static NetaceaTrueUserAgentHeader="x-netacea-true-useragent-header";cookieEncryptionKey;ingestEnabled=!0;netaceaCaptchaPath;captchaHeader;dynamicCaptchaContentType;ipHeaderName;mitataCookieExpirySeconds;apiKey;secretKey;mitigationServiceUrl;ingestServiceUrl;timeout;captchaSiteKey;captchaSecretKey;ingestType;logVersion;kinesis;mitigationType;encryptedCookies=[];netaceaCookieName;netaceaCaptchaCookieName;netaceaCookieAttributes;netaceaCaptchaCookieAttributes;constructor(e){if(e.ingestType=o.KINESIS,void 0===e.kinesis&&(console.warn(['NETACEA :: Please move kinesis params to "kinesis" object in config.',"Backwards compatibility will soon be removed."].join(" ")),e.kinesis={kinesisStreamName:e.kinesisStreamName,kinesisAccessKey:e.kinesisAccessKey,kinesisSecretKey:e.kinesisSecretKey,maxLogAgeSeconds:1}),null===e.apiKey||void 0===e.apiKey)throw new Error("apiKey is a required parameter");var t;this.apiKey=e.apiKey,this.secretKey=e.secretKey,this.mitigationServiceUrl=e.mitigationServiceUrl??"https://mitigations.netacea.net",this.ingestServiceUrl=e.ingestServiceUrl??"https://ingest.netacea.net",this.mitigationType=e.mitigationType??n.INGEST,this.ingestType=e.ingestType??o.HTTP,this.logVersion=e.logVersion??r.V1,this.ingestType===o.KINESIS&&(void 0===e.kinesis?console.warn(`NETACEA WARN: no kinesis args provided, when ingestType is ${this.ingestType}`):this.kinesis=new $({...e.kinesis,apiKey:this.apiKey})),void 0===e.captchaSiteKey&&void 0===e.captchaSecretKey||(this.captchaSiteKey=e.captchaSiteKey,this.captchaSecretKey=e.captchaSecretKey),this.timeout=(t=e.timeout??3e3)<=0?d:t,this.netaceaCookieName=e.netaceaCookieName??"_mitata",this.netaceaCaptchaCookieName=e.netaceaCaptchaCookieName??"_mitatacaptcha",this.netaceaCaptchaPath=e.netaceaCaptchaPath,this.dynamicCaptchaContentType=e.dynamicCaptchaContentType??!1;const a=ie(e.netaceaCookieAttributes??"",e.netaceaCaptchaCookieAttributes??"");var i,s;this.netaceaCookieAttributes=a.cookieAttributes??"",this.netaceaCaptchaCookieAttributes=a.captchaCookieAttributes??"",this.captchaHeader=e.captchaHeader,this.ipHeaderName=e.ipHeaderName?.toLowerCase()?.trim(),this.encryptedCookies=[this.netaceaCookieName,this.netaceaCaptchaCookieName],this.mitataCookieExpirySeconds=(i=this.mitigationType,void 0===(s=e.netaceaCookieExpirySeconds??e.mitataCookieExpirySeconds)?i===n.INGEST?3600:60:s),this.ingestEnabled=e.ingestEnabled??!0,this.cookieEncryptionKey=e.cookieEncryptionKey}async run(e){let t;try{t=this.getRequestResponseFromEvent(e).request;const{uri:a,method:i}=t;if(this.isUrlCaptchaGet(a,i)){const a=await async function({request:e,secretKey:t,mitigationCallFn:a,composeResultFn:i,cookieEncryptionKey:s,netaceaCookieName:o,netaceaCaptchaCookieName:r,ipHeaderName:n}){const{querystring:c}=e,h=j(e,n),u=e.headers["user-agent"]?.[0].value??"",d=e.headers.accept?.[0].value??"text/html",p=e.headers.host?.[0].value??"";if(void 0===t)throw new Error("Secret key needs to be defined to make mitigation calls.");const l=c.split("&").find((e=>e.includes("trackingId=")))?.replace("trackingId=",""),{headers:m}=e,g=await X(o,m,s),y=await X(r,m,s),{userId:C}=v(g)??{},k=await async function({userId:e,clientIp:t,userAgent:a,trackingId:i,accept:s,host:o,captchaCookie:r,mitigationCallFn:n,composeResultFn:c}){const h={match:0,mitigate:0,captcha:1},u=await n({userId:e,clientIP:t,userAgent:a,captchaCookie:r,accept:s,host:o,isCaptchaGet:!0,defaultMitataCodes:h,trackingId:i});return c(u.body,u.setCookie,u.status,u.match,u.mitigate,u.captcha,!0,u.latency??0)}({userId:C,clientIp:h,userAgent:u,captchaCookie:y,accept:d,host:p,trackingId:l,mitigationCallFn:a,composeResultFn:i});return G(e,k.apiCallStatus,k.apiCallLatency),{headers:J(k.setCookie),status:"403",body:k.body,statusDescription:"Forbidden"}}({request:t,secretKey:this.secretKey,mitigationCallFn:this.makeMitigateAPICall.bind(this),composeResultFn:this.composeResult.bind(this),cookieEncryptionKey:this.cookieEncryptionKey,netaceaCookieName:this.netaceaCookieName,netaceaCaptchaCookieName:this.netaceaCaptchaCookieName,ipHeaderName:this.ipHeaderName});return this.ingest(e,a),{respondWith:a}}const s=await this.runMitigation(t);return this.addNetaceaCookiesToRequest(t,s),t.headers[de.NetaceaTrueUserAgentHeader]=[{key:de.NetaceaTrueUserAgentHeader,value:this.getValueFromHeaderOrDefault(t.headers,"user-agent","-")}],void 0!==s&&this.ingestType===o.KINESIS&&G(t,s.apiCallStatus,s.apiCallLatency),{respondWith:s?.response}}catch(e){return console.error("Netacea FailOpen - ",e.message),void 0!==t&&e instanceof Z&&U(t,e),{}}}async makeRequest({host:e,path:t,method:i,body:s,headers:o,timeout:r}){const n=`${e}${t}`,c=await a.request({url:n,data:s,headers:o,method:i,timeout:r,transformResponse:e=>e});return{headers:c.headers,status:c.status,body:c.data}}async mitigate(e){try{const{netaceaResult:a,request:i}=await this.getMitigationResponse(e);let s;if(a.mitigated){const e={"set-cookie":[]};for(const t of a.setCookie)e["set-cookie"]=e["set-cookie"]??[],e["set-cookie"].push({key:"set-cookie",value:t});"captcha"===a.mitigation&&void 0!==this.captchaHeader&&(e[this.captchaHeader.name]=[{key:this.captchaHeader.name,value:this.captchaHeader.value}]);s={headers:e,...this.isUrlCaptchaPost(i.uri,i.method)?{status:"200",statusDescription:"OK",body:""}:{status:"403",statusDescription:"Forbidden",body:"Forbidden"}};let o=0;if(void 0!==a.body&&a.body.length>0){o=a.body.length;const e=(t=a.body).includes("captchaRelativeURL")&&t.includes("captchaAbsoluteURL");s.status=e?"403":"200",s.statusDescription=e?"Forbidden":"OK",s.body=a.body,s.bodyEncoding="text"}const r={status:s.status,statusDescription:s.statusDescription??"",headers:{"content-length":[{key:"content-length",value:o.toString()}],"set-cookie":a.setCookie.map((e=>({key:"set-cookie",value:e})))}};this.ingest(i,r)}return this.addNetaceaCookiesToRequest(i,a),{response:s,sessionStatus:a.sessionStatus,setCookie:a.setCookie,apiCallLatency:a.apiCallLatency,apiCallStatus:a.apiCallStatus}}catch(t){if(t instanceof Z&&U(e,t),this.isUrlCaptchaPost(e.uri,e.method)){const t={status:"500",statusDescription:"Internal Server Error",body:"",headers:{}},a={response:t,sessionStatus:"error_open"};return this.ingest(e,t),a}return console.error("Netacea FailOpen Error: ",t),{sessionStatus:"error_open"}}var t}async inject(e){try{const{netaceaResult:t}=await this.getMitigationResponse(e);return{injectHeaders:t.injectHeaders,sessionStatus:t.sessionStatus,setCookie:t.setCookie,apiCallLatency:t.apiCallLatency,apiCallStatus:t.apiCallStatus}}catch(e){return console.error("Netacea FailOpen Error: ",e),{sessionStatus:"",injectHeaders:void 0,setCookie:void 0}}}async ingest(e,t=void 0){let a;if(Object.prototype.hasOwnProperty.call(e,"Records")){const i=this.getRequestResponseFromEvent(e);a=i.request,void 0===t&&(t=i.response)}else a=e;if(!this.ingestEnabled)return;if(null==t)throw new Error("Cloudfront response is required to ingest");const i=this.getMitataValueFromHeaderOrDefault(t.headers,"set-cookie"),s=""!==i?i:this.getMitataValueFromHeaderOrDefault(a.headers,"cookie");let o=await this.readCookie(this.netaceaCookieName,s)??"";if(void 0===o||""===o){const e=this.getMitataValueFromHeaderOrDefault(a.headers,"cookie");o=await this.readCookie(this.netaceaCookieName,e)??""}let r=0,n=0,c=0;const h=v(o);void 0!==h&&(r=h.match,n=h.mitigate,c=h.captcha);const{sessionStatus:d,mitigationLatency:p,mitigationStatus:l}=function(e){return{sessionStatus:B(e.headers,"x-netacea-session-status"),mitigationLatency:B(e.headers,"x-netacea-api-call-latency"),mitigationStatus:B(e.headers,"x-netacea-api-call-status")}}(a),m=this.shouldSetCaptchaPass(a,t),{sessionStatus:g}=this.findBestMitigation(r,n,c,m);await this.callIngest({bytesSent:this.getValueFromHeaderOrDefault(t.headers,"content-length","0"),ip:j(a,this.ipHeaderName),method:a.method,path:a.uri,protocol:null,referer:this.getValueFromHeaderOrDefault(a.headers,"referer"),requestTime:"0",status:t.status,userAgent:this.getValueFromHeaderOrDefault(a.headers,de.NetaceaTrueUserAgentHeader,this.getValueFromHeaderOrDefault(a.headers,"user-agent")),mitataCookie:o,sessionStatus:d??g,integrationType:"@netacea/cloudfront".replace("@netacea/",""),integrationVersion:"6.0.14",xForwardedFor:this.getValueFromHeaderOrDefault(a.headers,"x-forwarded-for"),integrationMode:this.mitigationType,requestHost:this.getValueFromHeaderOrDefault(a.headers,"host",void 0),mitigationLatency:void 0!==p?u(p):void 0,mitigationStatus:void 0!==l?u(l):void 0})}addNetaceaCookiesToResponse(e){const{response:t,request:a}=this.getRequestResponseFromEvent(e);if(void 0===t)throw new Error("Response required to add cookies to response");const i=a.headers[de.NetaceaCookieHeader];if(null!=i&&null!=t.headers){let e=!1;if(void 0===t.headers["set-cookie"]?t.headers["set-cookie"]=[]:e=void 0!==t.headers["set-cookie"].find((e=>e.value.includes(this.netaceaCookieName)||e.value.includes(this.netaceaCaptchaCookieName))),!e)for(const e of i)t.headers["set-cookie"].push({key:"set-cookie",value:e.value})}this.setInjectHeaders(e)}setInjectHeaders(e){const{response:t,request:a}=this.getRequestResponseFromEvent(e);void 0!==t&&(a.headers["x-netacea-captcha"]=this.shouldSetCaptchaPass(a,t)?[{key:"x-netacea-captcha",value:"2"}]:a.headers["x-netacea-captcha"])}getValueFromHeaderOrDefault(e,t,a=""){if(void 0!==e?.[t]){const a=e[t];if(void 0!==a)return a[0].value}return a}getMitataValueFromHeaderOrDefault(e,t,a=""){if(void 0!==e?.[t]){const a=e[t];if(void 0!==a){const e=a.find((e=>e.value.includes(this.netaceaCookieName)));if(void 0!==e)return e.value}}return a}getRequestResponseFromEvent(e){return e.Records[0].cf}async getMitigationResponse(e){const t=this.getMitataValueFromHeaderOrDefault(e.headers,"cookie"),a=await this.readCookie(this.netaceaCookieName,t),i=await this.readCookie(this.netaceaCaptchaCookieName,t),s=j(e,this.ipHeaderName),o=this.getValueFromHeaderOrDefault(e.headers,"user-agent"),r=this.getValueFromHeaderOrDefault(e.headers,"accept","text/html"),n=this.getValueFromHeaderOrDefault(e.headers,"host");return{netaceaResult:await this.processMitigateRequest({getBodyFn:async()=>await Promise.resolve(Buffer.from(e.body?.data??"","base64").toString()),clientIp:s,method:e.method,url:e.uri,userAgent:o,accept:r,host:n,mitata:a,mitataCaptcha:i}),request:e}}addNetaceaCookiesToRequest(e,t){if(void 0===t)return e;if(e.headers[de.NetaceaCookieHeader]=[],void 0!==t.setCookie)for(const a of t.setCookie){const t=e.headers[de.NetaceaCookieHeader]??[];t.push({key:de.NetaceaCookieHeader,value:a}),e.headers[de.NetaceaCookieHeader]=t}if(this.mitigationType===n.INJECT)for(const[a,i]of Object.entries(t.injectHeaders??{}))e.headers[a]=[{key:a,value:i}];return e}getCookieHeader(e){return this.getMitataValueFromHeaderOrDefault(e.headers,"cookie")}async encryptCookieValue(e){return void 0!==this.cookieEncryptionKey?await async function(e,t){const a=h.base64url.decode(t),i=(new TextEncoder).encode(e);return await new h.CompactEncrypt(i).setProtectedHeader({alg:"dir",enc:"A256GCM"}).encrypt(a)}(e,this.cookieEncryptionKey):e}async decryptCookieValue(e){return void 0!==this.cookieEncryptionKey?await L(e,this.cookieEncryptionKey):e}async runMitigation(e){try{switch(this.mitigationType){case n.MITIGATE:return await this.mitigate(e);case n.INJECT:return await this.inject(e);case n.INGEST:return await this.processIngest(e);default:throw new Error(`Netacea Error: Mitigation type ${this.mitigationType} not recognised`)}}catch(e){return console.error("Netacea FAILOPEN Error:",e),{injectHeaders:{"x-netacea-captcha":"0","x-netacea-match":"0","x-netacea-mitigate":"0"},sessionStatus:""}}}async readCookie(e,t){if(null==t)return;if("string"==typeof t)return await this.readCookie(e,t.split(";"));const a=`${e}=`;for(const i of t){const t=i.split(";")[0].trimStart();if(t.startsWith(a)){const i=t.slice(a.length);if(this.encryptedCookies.includes(e))try{return await this.decryptCookieValue(i)}catch(e){return}return i}}}async processMitigateRequest(e){const t=this.isUrlCaptchaPost(e.url,e.method);return await(t?this.processCaptcha(e.mitata,e.clientIp,e.userAgent,await e.getBodyFn()):this.check(e.mitata,e.clientIp,e.userAgent,e.accept,e.host,e.mitataCaptcha))}isUrlCaptchaPost(e,t){return e.includes("/AtaVerifyCaptcha")&&"post"===t.toLowerCase()}isUrlCaptchaGet(e,t){return void 0!==this.netaceaCaptchaPath&&(e.toLowerCase().includes(this.netaceaCaptchaPath.toLowerCase())&&"get"===t.toLowerCase())}shouldSetCaptchaPass(e,t){if(this.isUrlCaptchaPost(e.uri,e.method))return!0;if(void 0===t)return!1;const a=null!=t.headers?t.headers["set-cookie"]:void 0,i=a?.find((e=>e.value.split("=")[0]===this.netaceaCaptchaCookieName)),s=void 0!==i;return this.mitigationType===n.INJECT&&s}async processCaptcha(e,t,a,i){const{status:s,match:o,mitigate:r,captcha:n,body:c,setCookie:h,latency:u}=await this.makeCaptchaAPICall(e,t,a,i);return this.composeResult(c,h,s,o,r,n,!0,u)}async makeCaptchaAPICall(e,t,a,i){const s={"X-Netacea-API-Key":this.apiKey,"X-Netacea-Client-IP":t,"user-agent":a,"Content-Type":"application/x-www-form-urlencoded; charset=UTF-8"},o=v(e);void 0!==o&&(s["X-Netacea-UserId"]=o.userId),void 0!==this.captchaSiteKey&&void 0!==this.captchaSecretKey&&(s["X-Netacea-Captcha-Site-Key"]=this.captchaSiteKey,s["X-Netacea-Captcha-Secret-Key"]=this.captchaSecretKey);const r=Date.now(),n=await this.makeRequest({host:this.mitigationServiceUrl,path:"/AtaVerifyCaptcha",headers:s,method:"POST",body:i,timeout:this.timeout}),c=Date.now()-r;return await this.getApiCallResponseFromResponse(n,o?.userId,t,c)}async getApiCallResponseFromResponse(e,t,a,i,s){if(200!==e.status)throw new Z(e,i);let o=W(e.headers,ue.match)??NaN,r=W(e.headers,ue.mitigate)??NaN,n=W(e.headers,ue.captcha)??NaN;isNaN(o)&&(o=s?.match??0),isNaN(r)&&(r=s?.mitigate??0),isNaN(n)&&(n=s?.captcha??0);let c=W(e.headers,ue.mitataExpiry)??NaN;isNaN(c)&&(c=86400);const h=[await this.createMitata(a,t,o,r,n),await this.createMitataCaptcha(e.headers)].filter((e=>void 0!==e)),u=z(e.headers,ue.eventId);return{status:e.status,match:o,mitigate:r,captcha:n,setCookie:h,body:e.body,eventId:u,mitataMaxAge:c,latency:i}}APIError(e){let t="Unknown error";switch(e.status){case 403:t="Invalid credentials";break;case 500:t="Server error";break;case 502:t="Bad Gateway";break;case 503:t="Service Unavailable";break;case 400:t="Invalid request"}return new Error(`Error reaching Netacea API (${t}), status: ${e.status}`)}async createMitata(e,t,a,i,s,o=86400,r=void 0){const n=[1,3,5].includes(s)||3===i?-60:this.mitataCookieExpirySeconds,c=r??Math.floor(Date.now()/1e3)+n;if(void 0===this.secretKey)throw new Error("Cannot build cookie without secret key.");const h=[a,i,s].join(""),u=S(e,t,c,this.secretKey,h);let d,p,l=o;if(""!==this.netaceaCookieAttributes){const{extractedAttribute:e,cookieAttributes:t}=ee(this.netaceaCookieAttributes,"Max-Age");l=void 0!==e?Number(e):o;const{extractedAttribute:a,cookieAttributes:i}=ee(t,"Path");d=a??"/",p=i??void 0}return await this.buildCookieFromValues(this.netaceaCookieName,u,l,p,d)}async createMitataCaptcha(e){let t=e["set-cookie"]??[];t="string"==typeof t?[t]:t;const a=t.find((e=>e.startsWith("_mitatacaptcha=")));let i,s="86400";if(void 0!==a&&""!==a)try{const e=ae(a);i=e.value,s=Q(e.attributes,"Max-Age")??"86400"}catch(e){return}if(""===i||void 0===i)return;const o=te([this.netaceaCaptchaCookieAttributes,"Path=/",`Max-Age=${s}`]);return i=this.encryptedCookies.includes(this.netaceaCaptchaCookieName)?await this.encryptCookieValue(i):i,`${this.netaceaCaptchaCookieName}=${i}; ${o}`}async buildCookieFromValues(e,t,a,i,s="/"){const o=`${e}=${this.encryptedCookies.includes(e)?await this.encryptCookieValue(t):t}; Max-Age=${a}; Path=${s}`;return void 0!==i&&""!==i?`${o}; ${i}`:o}async callIngest(e){const t=this.constructWebLog(e);if(this.ingestType===o.KINESIS){if(void 0===this.kinesis)return void console.error("Netacea Error: Unable to log as Kinesis has not been defined.");try{await this.kinesis.ingest({...t,apiKey:this.apiKey},this.makeRequest.bind(this))}catch(e){console.error("NETACEA Error: ",e.message)}}else{const e={"X-Netacea-API-Key":this.apiKey,"content-type":"application/json"},a=await this.makeIngestApiCall(e,t);if(200!==a.status)throw this.APIError(a)}}constructWebLog(e){return e.bytesSent=""===e.bytesSent?"0":e.bytesSent,this.logVersion===r.V2?this.constructV2WebLog(e):this.constructV1WebLog(e)}constructV2WebLog({ip:e,userAgent:t,status:a,method:i,path:s,protocol:r,referer:n,bytesSent:c,requestTime:h,mitataCookie:d,sessionStatus:p,integrationType:l,integrationVersion:m,xForwardedFor:g,integrationMode:y,requestHost:C,mitigationLatency:k,mitigationStatus:f}){const S=new Date,{path:N,query:I,request:A}=Y(i,s,r),b=v(d)?.userId,w={status:a,method:i,bytes_sent:u(c),referrer:""===n?void 0:n,request:A,request_time:u(h),integration_type:l,integration_version:m,client:e,user_agent:t,bc_type:""===p?void 0:p,hour:S.getUTCHours(),minute:S.getUTCMinutes(),"@timestamp":S.toISOString().replace("Z","+00:00"),path:N,protocol:r,query:I,user_id:b,x_forwarded_for:g};return this.ingestType===o.KINESIS&&(w.protection_mode=y,w.protector_latency_ms=k,w.protector_status=f,w.request_host=C),w}constructV1WebLog({ip:e,userAgent:t,status:a,method:i,path:s,protocol:r,referer:n,bytesSent:c,requestTime:h,mitataCookie:u,sessionStatus:d,integrationType:p,integrationVersion:l,xForwardedFor:m,integrationMode:g,requestHost:y,mitigationLatency:C,mitigationStatus:k}){const f=(new Date).toUTCString(),{request:v}=Y(i,s,r),S={Request:v,TimeLocal:f,RealIp:e,UserAgent:t,Status:a,RequestTime:h?.toString(),BytesSent:c?.toString(),Referer:""===n?"-":n,NetaceaUserIdCookie:u??"",NetaceaMitigationApplied:d??"",IntegrationType:p??"",IntegrationVersion:l??"",XForwardedFor:m};return this.ingestType===o.KINESIS&&(S.ProtectionMode=g,S.ProtectorLatencyMs=C,S.ProtectorStatus=k,S.RequestHost=y),S}async makeIngestApiCall(e,t){return await this.makeRequest({host:this.ingestServiceUrl,method:"POST",path:"/",headers:e,body:JSON.stringify(t),timeout:this.timeout})}async processIngest(e){if(void 0===this.secretKey)throw new Error("Secret key is required for ingest");const t=this.getCookieHeader(e),a=I(await this.readCookie(this.netaceaCookieName,t),C,this.secretKey);return a.isPrimaryHashValid?a.requiresReissue?await this.setIngestOnlyMitataCookie(a.mitata?.userId):{sessionStatus:"",setCookie:[]}:await this.setIngestOnlyMitataCookie(void 0)}async setIngestOnlyMitataCookie(e){return{sessionStatus:"",setCookie:[await this.createMitata(C,e,0,0,0,86400)]}}findBestMitigation(e,t,a,i){const s="unknown";a=this.adjustCaptchaCode(a,i);let o=se[e]??s+"_";o+=re[t]??s;let r=ne[t];if(0!==a){o+=","+(he[a]??s);const e=ce[a];void 0!==e&&(r=e)}return this.mitigationType===n.INJECT&&(r=oe.none),{sessionStatus:o,mitigation:r,parts:{match:e,mitigate:t,captcha:a}}}adjustCaptchaCode(e,t){let a=e;return t||(2===e?a=4:3===e&&(a=5)),a}async check(e,t,a,i,s,o){let r,n,c,h,u,d,p,l;if(void 0===this.secretKey)throw new Error("Secret key is required to mitigate");const m=I(e,t,this.secretKey);if(!m.isPrimaryHashValid||m.requiresReissue){const e=await this.makeMitigateAPICall({userId:m.mitata?.userId,clientIP:t,userAgent:a,captchaCookie:o,accept:i,host:s});r=e.status,n=e.match,c=e.mitigate,h=e.captcha,u=e.body,l=e.latency,d=[await this.createMitata(t,m.mitata?.userId,n,c,h,e.mitataMaxAge)],p=e.eventId}else n=m.match,c=m.mitigate,h=m.captcha,u=void 0,d=[];return this.composeResult(u,d,r,n,c,h,!1,l,p)}async makeMitigateAPICall({userId:e,clientIP:t,userAgent:a,captchaCookie:i,accept:s,host:o,isCaptchaGet:r=!1,defaultMitataCodes:n,trackingId:c}){const h={"X-Netacea-API-Key":this.apiKey,"X-Netacea-Client-IP":t,"user-agent":a,cookie:this.buildCookieHeader({_mitatacaptcha:i})};void 0!==e&&(h["X-Netacea-UserId"]=e),void 0!==this.captchaSiteKey&&void 0!==this.captchaSecretKey&&(h["X-Netacea-Captcha-Site-Key"]=this.captchaSiteKey,h["X-Netacea-Captcha-Secret-Key"]=this.captchaSecretKey),this.dynamicCaptchaContentType&&void 0!==this.netaceaCaptchaPath&&(h["X-Netacea-Captcha-Content-Type"]=function(e){const t=e?.toLowerCase()??"text/html",a=t?.includes("text/html")||t?.includes("application/html"),i=t?.includes("application/json");return i&&!a?"application/json":"text/html"}(s));const u="application/json"===h["X-Netacea-Captcha-Content-Type"],d=void 0!==c?`?trackingId=${c}`:"",p=Date.now(),l=await this.makeRequest({host:this.mitigationServiceUrl,path:r?`/captcha${d}`:"/",headers:h,method:"GET",timeout:this.timeout}),m=Date.now()-p;return u&&void 0!==this.netaceaCaptchaPath&&(l.body=function(e,t,a){let i;if(void 0===e||""===e)return"";if("string"==typeof e&&(i=JSON.parse(e)),!function(e){if(null==e)return!1;const t=e;return void 0!==t?.captchaSiteKey&&void 0!==t?.trackingId&&void 0!==t?.captchaURL}(i))throw new Error("Body is not a Mitigation Service JSON response!");const s=`${a}?trackingId=${i.trackingId}`,o=`https://${t}${s}`;return JSON.stringify({captchaRelativeURL:s,captchaAbsoluteURL:o})}(l.body,o,this.netaceaCaptchaPath)),await this.getApiCallResponseFromResponse(l,e,t,m,n)}buildCookieHeader(e){let t="",a="";for(const i in e){const s=e[i];void 0!==s&&(t=`${t}${a}${i}=${s}`,a="; ")}return t}composeResult(e,t,a,i,s,o,r,c,h){const u=this.findBestMitigation(i,s,o,r),d={body:e,apiCallStatus:a,apiCallLatency:c,setCookie:t,sessionStatus:u.sessionStatus,mitigation:u.mitigation,mitigated:[oe.block,oe.captcha,oe.captchaPass].includes(u.mitigation)};if(this.mitigationType===n.INJECT){const e={"x-netacea-match":u.parts.match.toString(),"x-netacea-mitigate":u.parts.mitigate.toString(),"x-netacea-captcha":u.parts.captcha.toString()};void 0!==h&&(e["x-netacea-event-id"]=h),d.injectHeaders=e}return d}}exports.Cloudfront=de;
|
|
1
|
+
"use strict";var e=require("node:crypto"),t=require("node:buffer"),a=require("axios"),i=require("aws4");function s(e){var t=Object.create(null);return e&&Object.keys(e).forEach((function(a){if("default"!==a){var i=Object.getOwnPropertyDescriptor(e,a);Object.defineProperty(t,a,i.get?i:{enumerable:!0,get:function(){return e[a]}})}})),t.default=e,Object.freeze(t)}var o,n,r,c,h=s(require("jose"));!function(e){e.ORIGIN="ORIGIN",e.HTTP="HTTP",e.KINESIS="KINESIS",e.NATIVE="NATIVE"}(o||(o={})),function(e){e.V1="V1",e.V2="V2"}(n||(n={})),function(e){e.MITIGATE="MITIGATE",e.INJECT="INJECT",e.INGEST="INGEST"}(r||(r={})),function(e){e.CAPTCHA_GET="captcha_get",e.CAPTCHA_POST="captcha_post",e.EXPIRED_SESSION="expired_session",e.FORCED_REVALIDATION="forced_revalidation",e.INVALID_SESSION="invalid_session",e.IP_CHANGE="ip_change",e.NO_SESSION="no_session"}(c||(c={}));function u(e,t=0){return isNaN(e)?t:parseInt(e)}const d=3e3;const p="_/@#/",l={none:"",block:"block",captcha:"captcha",allow:"allow",captchaPass:"captchapass"},m={0:l.none,1:l.block,2:l.none,3:l.block,4:l.block},y={1:l.captcha,2:l.captchaPass,3:l.captcha,4:l.allow,5:l.captcha};var g=Object.freeze({__proto__:null,COOKIEDELIMITER:p,bestMitigationCaptchaMap:y,bestMitigationMap:m,captchaMap:{0:"",1:"captcha_serve",2:"captcha_pass",3:"captcha_fail",4:"captcha_cookiepass",5:"captcha_cookiefail"},captchaStatusCodes:{"":0,captchaServe:1,captchaPass:2,captchaFail:3,captchaCookiePass:4,captchaCookieFail:5},matchMap:{0:"",1:"ua_",2:"ip_",3:"visitor_",4:"datacenter_",5:"sev_",6:"organisation_",7:"asn_",8:"country_",9:"combination_"},mitigateMap:{0:"",1:"blocked",2:"allow",3:"hardblocked",4:"block"},mitigationTypes:l,netaceaCookieV3KeyMap:{clientIP:"cip",userId:"uid",gracePeriod:"grp",cookieId:"cid",match:"mat",mitigate:"mit",captcha:"cap",issueTimestamp:"ist",issueReason:"isr"},netaceaCookieV3OptionalKeyMap:{checkAllPostRequests:"fCAPR"},netaceaHeaders:{match:"x-netacea-match",mitigate:"x-netacea-mitigate",captcha:"x-netacea-captcha",mitata:"x-netacea-mitata-value",mitataExpiry:"x-netacea-mitata-expiry",mitataCaptcha:"x-netacea-mitatacaptcha-value",mitataCaptchaExpiry:"x-netacea-mitatacaptcha-expiry",eventId:"x-netacea-event-id"},netaceaSettingsMap:{checkAllPostRequests:"checkAllPostRequests"}});const k="ignored",C="1234567890abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ".split(""),f=/^(.*)_\/@#\/(.*)_\/@#\/(.*)_\/@#\/(.*)_\/@#\/((\d)(\d)(\d))$/;function S(e){if(void 0===e)return;const t=e.match(f);if(null!=t){const[,e,a,i,s,o,n,r,c]=t;return{signature:e,expiry:a,userId:i,ipHash:s,mitigationType:o,match:parseInt(n),mitigate:parseInt(r),captcha:parseInt(c)}}}function v(t=16,a=C){const i=e.randomBytes(t-1);return`c${Array.from(i).map((e=>a[e%a.length])).join("")}`}function N(a,i){const s=e.createHmac("sha256",i);return s.update(a),t.Buffer.from(s.digest("hex")).toString("base64")}function I(e,t,a){const i={mitata:void 0,requiresReissue:!1,isExpired:!1,shouldExpire:!1,isSameIP:!1,isPrimaryHashValid:!1,captcha:0,match:0,mitigate:0};if("string"!=typeof e||""===e)return i;const s=S(e);if(void 0!==s){const e=[s.expiry,s.userId,s.ipHash,s.mitigationType].join(p),i=Math.floor(Date.now()/1e3),o=parseInt(s.expiry)<i,n=[1,3,5].includes(s.captcha),r=3===s.mitigate,c=n||r,h=N(t+"|"+s.expiry,a),u=s.ipHash===h;return{mitata:s,requiresReissue:o||!u,isExpired:o,shouldExpire:c,isSameIP:u,isPrimaryHashValid:s.signature===N(e,a),match:s.match,mitigate:s.mitigate,captcha:s.captcha,userId:s.userId}}return i}function E(e,t){const a=e.split(";").map((e=>e.trim())).filter((e=>e.toLowerCase().startsWith(t.toLowerCase())))[0];return void 0!==a&&a.length>0?a?.replace(`${t}=`,""):void 0}function A(e,t=!1){return"string"!=typeof e&&(e=e.join("; ")),""===e?"":w(e.split(";"),t).join("; ")}function w(e,t=!1){if(t)return w(e.reverse()).reverse();const a=new Set,i=[];for(let t of e){if(t=t.trimStart(),""===t.trim())continue;const e=t.split("=")[0].toUpperCase();a.has(e)||(a.add(e),i.push(t))}return i}var b=Object.freeze({__proto__:null,configureCookiesDomain:function(e,t){let a=e=A(e??"",!0),i=t=A(t??"",!0);if(void 0!==e&&void 0!==t){const s=E(e,"Domain"),o=E(t,"Domain");void 0!==s&&void 0!==o?i=t.replace(o,s):void 0!==s&&void 0===o?i=t+(""!==t?`; Domain=${s}`:`Domain=${s}`):void 0===s&&void 0!==o&&(a=e+(""!==e?`; Domain=${o}`:`Domain=${o}`))}else if(void 0!==e&&void 0===t){const t=E(e,"Domain");void 0!==t&&(i=`Domain=${t}`)}else if(void 0===e&&void 0!==t){const e=E(t,"Domain");void 0!==e&&(a=`Domain=${e}`)}return{cookieAttributes:""!==a?a:void 0,captchaCookieAttributes:""!==i?i:void 0}},extractAndRemoveCookieAttr:function(e,t){const a=E(e,t);if(void 0!==a){return{extractedAttribute:a,cookieAttributes:e.replace(/ /g,"").replace(`${t}=${a}`,"").split(";").filter((e=>e.length>0)).join("; ")}}return{extractedAttribute:void 0,cookieAttributes:e}},extractCookieAttr:E,removeDuplicateAttrs:A});function T(e){const t=A([e.otherAttributes??"",`Max-Age=${e.maxAgeAttribute??86400}`,"Path=/"].join("; "));return`${e.cookieName}=${e.cookieValue}; ${t}`}var K=Object.freeze({__proto__:null,createNetaceaCaptchaSetCookieString:function(e){return T({...e,cookieName:e.cookieName??"_mitatacaptcha"})},createNetaceaSetCookieString:function(e){return T({...e,cookieName:e.cookieName??"_mitata"})},createSetCookieString:T});var x=Object.freeze({__proto__:null,parseSetCookie:function(e){const t=e.indexOf("=");if(t<0)throw new Error("Could not parse the given set-cookie value.");const a=e.slice(0,t),i=e.slice(t+1),s=i.indexOf(";");return{name:a,value:i.slice(0,s),attributes:i.slice(s).trimStart()}}});const R={cookie:{parse:x,attributes:b,netaceaSession:K}};var _={},P={},O={},H={};Object.defineProperty(H,"__esModule",{value:!0}),H.API_VERSION=H.REGION=H.PAYLOAD_TYPE=H.STATE=void 0,H.STATE={ACTIVE:"ACTIVE",UPDATING:"UPDATING",CREATING:"CREATING",DELETING:"DELETING"},H.PAYLOAD_TYPE="string",H.REGION="eu-west-1",H.API_VERSION="2013-12-02",Object.defineProperty(O,"__esModule",{value:!0}),O.signRequest=void 0;const M=i,D=H;function q(e,t){const a=[];for(let i=0;i<e.length;i+=t){const s=e.slice(i,i+t);a.push({Data:Buffer.from(JSON.stringify(s)).toString("base64"),PartitionKey:Date.now().toString()})}return a}O.signRequest=function(e,t,a){const{accessKeyId:i,secretAccessKey:s}=e,o={Records:q(t,a),PartitionKey:Date.now().toString(),StreamName:e.streamName};return M.sign({service:"kinesis",body:JSON.stringify(o),headers:{"Content-Type":"application/x-amz-json-1.1","X-Amz-Target":"Kinesis_20131202.PutRecords"},region:D.REGION},{accessKeyId:i,secretAccessKey:s})},Object.defineProperty(P,"__esModule",{value:!0});const $=O;P.default=class{constructor({kinesisStreamName:e,kinesisAccessKey:t,kinesisSecretKey:a,maxLogAgeSeconds:i,logBatchSize:s}){this.logBatchSize=20,this.maxLogAgeSeconds=10,this.logCache=[],this.intervalSet=!1,this.kinesisStreamName=e,this.kinesisAccessKey=t,this.kinesisSecretKey=a,void 0!==i&&i<this.maxLogAgeSeconds&&i>0&&(this.maxLogAgeSeconds=i),void 0!==s&&(this.logBatchSize=s)}async putToKinesis(e){if(0===this.logCache.length)return;const t=[...this.logCache];this.logCache=[];try{const a=(0,$.signRequest)({streamName:this.kinesisStreamName,accessKeyId:this.kinesisAccessKey,secretAccessKey:this.kinesisSecretKey},t,this.logBatchSize);await e({headers:a.headers,host:`https://${a.hostname}`,method:a.method,path:a.path,body:a.body})}catch(e){this.logCache.push(...t),console.error(e)}}async ingest(e,t){this.logCache.push(e),this.logCache.length>=this.logBatchSize?await this.putToKinesis(t):this.intervalSet||(this.intervalSet=!0,async function(e){await new Promise((t=>{setTimeout(t,e)}))}(1e3*this.maxLogAgeSeconds).then((async()=>{await this.putToKinesis(t),this.intervalSet=!1})).catch((()=>{})))}},Object.defineProperty(_,"__esModule",{value:!0});const F=P;var V=_.default=F.default;async function L(e,t){const a=h.base64url.decode(t),{plaintext:i}=await h.compactDecrypt(e,a,{keyManagementAlgorithms:["dir"],contentEncryptionAlgorithms:["A256GCM"]});return(new TextDecoder).decode(i)}function j(e,t){const{clientIp:a}=e;if(void 0===t||""===t)return a;const i=e.headers[t]?.[0]?.value;return void 0===i||""===i?a:"x-forwarded-for"===t?i.split(/, ?/).pop()??a:i}function U(e,t){G(e,t.protectorApiResponse.status,t.latencyMs),e.headers["x-netacea-session-status"]=[{key:"x-netacea-session-status",value:"error_open"}]}function G(e,t,a){a!==t&&(e.headers["x-netacea-api-call-status"]=[{key:"x-netacea-api-call-status",value:String(t)}]),void 0!==a&&(e.headers["x-netacea-api-call-latency"]=[{key:"x-netacea-api-call-latency",value:String(a)}])}function X(e,t){if(void 0!==e?.[t]){const a=e[t];if(void 0!==a)return a[0].value}}async function B(e,t,a){const i=t.cookie?.[0].value.split(";"),s=i?.find((t=>t.includes(`${e}=`)))?.trimStart()?.replace(`${e}=`,"");if(void 0!==s){if(void 0!==a)try{return await L(s,a)}catch(e){return}return s}}function z(e){const t={"set-cookie":[]};for(const a of e)t["set-cookie"]?.push({key:"set-cookie",value:a});return t}function J(e,t){return e.includes("/AtaVerifyCaptcha")&&"post"===t.toLowerCase()}function W(e,t){const a=e[t];return"string"==typeof a?a:a?.[0]}function Y(e,t){const a=W(e,t);if(void 0!==a)return parseInt(a)}function Z(e,t,a){"/"!==t[0]&&(t=`/${t}`);const i=t.split("?"),s=i[0],o=i.length>1?`?${i[1]}`:void 0;return{path:s,query:o,request:`${e} ${s}${o??""}${""!==(a??"")?` ${a}`:""}`}}function Q(e,t){return t.bytesSent=""===t.bytesSent?"0":t.bytesSent,e===n.V2?function({ip:e,userAgent:t,status:a,method:i,path:s,protocol:o,referer:n,bytesSent:r,requestTime:c,mitataCookie:h,sessionStatus:d,integrationType:p,integrationVersion:l,xForwardedFor:m,integrationMode:y,requestHost:g,mitigationLatency:k,mitigationStatus:C}){const f=new Date,{path:v,query:N,request:I}=Z(i,s,o),E=S(h)?.userId;return{status:a,method:i,bytes_sent:u(r),referrer:""===n?void 0:n,request:I,request_time:u(c),integration_type:p,integration_version:l,protection_mode:y,protector_latency_ms:k,protector_status:C,request_host:g,client:e,user_agent:t,bc_type:""===d?void 0:d,hour:f.getUTCHours(),minute:f.getUTCMinutes(),"@timestamp":f.toISOString().replace("Z","+00:00"),path:v,protocol:o,query:N,user_id:E,x_forwarded_for:m}}(t):function({ip:e,userAgent:t,status:a,method:i,path:s,protocol:o,referer:n,bytesSent:r,requestTime:c,mitataCookie:h,sessionStatus:u,integrationType:d,integrationVersion:p,xForwardedFor:l,integrationMode:m,requestHost:y,mitigationLatency:g,mitigationStatus:k,netaceaCookieStatus:C}){const f=(new Date).toUTCString(),{request:S}=Z(i,s,o);return{Request:S,TimeLocal:f,RealIp:e,UserAgent:t,Status:a,RequestTime:c?.toString(),BytesSent:r?.toString(),Referer:""===n?"-":n,NetaceaUserIdCookie:h??"",NetaceaMitigationApplied:u??"",IntegrationType:d??"",IntegrationVersion:p??"",ProtectionMode:m,ProtectorLatencyMs:g,ProtectorStatus:k,RequestHost:y,XForwardedFor:l,NetaceaUserIdCookieStatus:C}}(t)}const ee="unknown";function te(e,t,a,i,s){i=function(e,t){let a=e;return t||(2===e?a=4:3===e&&(a=5)),a}(i,s);let o=g.matchMap[t]??ee+"_";o+=g.mitigateMap[a]??ee;let n=g.bestMitigationMap[a];if(0!==i){o+=","+(g.captchaMap[i]??ee);const e=g.bestMitigationCaptchaMap[i];void 0!==e&&(n=e)}return e===r.INJECT&&(n=g.mitigationTypes.none),{sessionStatus:o,mitigation:n,parts:{match:t,mitigate:a,captcha:i}}}class ae extends Error{protectorApiResponse;latencyMs;constructor(e,t){super(`Got status ${e.status} when calling protector API with ${t}ms latency.`),this.protectorApiResponse=e,this.latencyMs=t}}var ie;!function(e){e[e.NEW_SESSION=1]="NEW_SESSION",e[e.EXISTING_SESSION=2]="EXISTING_SESSION",e[e.RENEW_SESSION=3]="RENEW_SESSION"}(ie||(ie={}));class se{config;constructor(e){this.config=e}async getNetaceaRequestDetails(e){const{uri:t,method:a}=e,i=await this.readCookie(e,this.config.sessionCookieName),s=await this.readCookie(e,this.config.captchaCookieName),o=j(e,this.config.ipHeaderName),{sessionCookieDetails:n,sessionCookieStatus:c,sessionStatus:h,userId:u}=function(e,t,a,i,s){const o=I(i,s,e.secretKey);if(void 0!==o.userId&&o.isPrimaryHashValid){const i=o.userId,{isExpired:s,shouldExpire:n,isSameIP:c}=o,h=s||n||!c&&e.mitigationType!==r.INGEST?ie.RENEW_SESSION:ie.EXISTING_SESSION,{sessionStatus:u}=te(e.mitigationType,o.match,o.mitigate,o.captcha,J(t,a));return{userId:i,sessionCookieStatus:h,sessionStatus:u,sessionCookieDetails:o}}return{sessionStatus:"",userId:v(),sessionCookieStatus:ie.NEW_SESSION,sessionCookieDetails:void 0}}(this.config,t,a,i,o);return{clientIp:o,method:a,url:t,userAgent:ne(e.headers,"user-agent"),sessionDetails:{sessionStatus:h,captchaToken:s,sessionCookieDetails:n,sessionCookieStatus:c,userId:u}}}async readCookie(e,t){const a=oe(e.headers,t,"set-cookie"),i=""!==a?a:oe(e.headers,t,"cookie");if(null==i)return;const s=i.split(/; ?/g),o=`${t}=`;for(const e of s)if(e.startsWith(o)){const a=e.slice(o.length),i=this.config.encryptedCookies??[];if(void 0!==this.config.cookieEncryptionKey&&i.includes(t))try{return await L(a,this.config.cookieEncryptionKey)}catch(e){return}return a}}}function oe(e,t,a,i=""){if(void 0!==e?.[a]){const i=e[a];if(void 0!==i){const e=i.find((e=>e.value.includes(t)));if(void 0!==e)return e.value}}return i}function ne(e,t,a=""){if(void 0!==e?.[t]){const a=e[t];if(void 0!==a)return a[0].value}return a}const{extractCookieAttr:re,extractAndRemoveCookieAttr:ce,removeDuplicateAttrs:he}=R.cookie.attributes,ue=R.cookie.parse.parseSetCookie,{configureCookiesDomain:de}=R.cookie.attributes,{mitigationTypes:pe,netaceaHeaders:le}=g;class me{static NetaceaCookieHeader="x-netacea-cloudfront-mitata-cookie";static NetaceaTrueUserAgentHeader="x-netacea-true-useragent-header";cookieEncryptionKey;ingestEnabled=!0;netaceaCaptchaPath;captchaHeader;dynamicCaptchaContentType;ipHeaderName;requestAnalyser;mitataCookieExpirySeconds;apiKey;secretKey;mitigationServiceUrl;ingestServiceUrl;timeout;captchaSiteKey;captchaSecretKey;ingestType;logVersion;kinesis;mitigationType;encryptedCookies=[];netaceaCookieName;netaceaCaptchaCookieName;netaceaCookieAttributes;netaceaCaptchaCookieAttributes;constructor(e){if(e.ingestType=o.KINESIS,void 0===e.kinesis&&(console.warn(['NETACEA :: Please move kinesis params to "kinesis" object in config.',"Backwards compatibility will soon be removed."].join(" ")),e.kinesis={kinesisStreamName:e.kinesisStreamName,kinesisAccessKey:e.kinesisAccessKey,kinesisSecretKey:e.kinesisSecretKey,maxLogAgeSeconds:1},void 0!==e.logBatchSize&&(e.kinesis.logBatchSize=e.logBatchSize)),null===e.apiKey||void 0===e.apiKey)throw new Error("apiKey is a required parameter");var t;this.apiKey=e.apiKey,this.secretKey=e.secretKey,this.mitigationServiceUrl=e.mitigationServiceUrl??"https://mitigations.netacea.net",this.ingestServiceUrl=e.ingestServiceUrl??"https://ingest.netacea.net",this.mitigationType=e.mitigationType??r.INGEST,this.ingestType=e.ingestType??o.HTTP,this.logVersion=e.logVersion??n.V1,this.ingestType===o.KINESIS&&(void 0===e.kinesis?console.warn(`NETACEA WARN: no kinesis args provided, when ingestType is ${this.ingestType}`):this.kinesis=new V({...e.kinesis,apiKey:this.apiKey})),void 0===e.captchaSiteKey&&void 0===e.captchaSecretKey||(this.captchaSiteKey=e.captchaSiteKey,this.captchaSecretKey=e.captchaSecretKey),this.timeout=(t=e.timeout??3e3)<=0?d:t,this.netaceaCookieName=e.netaceaCookieName??"_mitata",this.netaceaCaptchaCookieName=e.netaceaCaptchaCookieName??"_mitatacaptcha",this.netaceaCaptchaPath=e.netaceaCaptchaPath,this.dynamicCaptchaContentType=e.dynamicCaptchaContentType??!1;const a=de(e.netaceaCookieAttributes??"",e.netaceaCaptchaCookieAttributes??"");var i,s;this.netaceaCookieAttributes=a.cookieAttributes??"",this.netaceaCaptchaCookieAttributes=a.captchaCookieAttributes??"",this.captchaHeader=e.captchaHeader,this.ipHeaderName=e.ipHeaderName?.toLowerCase()?.trim(),this.encryptedCookies=[this.netaceaCookieName,this.netaceaCaptchaCookieName],this.mitataCookieExpirySeconds=(i=this.mitigationType,void 0===(s=e.netaceaCookieExpirySeconds??e.mitataCookieExpirySeconds)?i===r.INGEST?3600:60:s),this.ingestEnabled=e.ingestEnabled??!0,this.cookieEncryptionKey=e.cookieEncryptionKey,this.requestAnalyser=new se({cookieEncryptionKey:this.cookieEncryptionKey,encryptedCookies:this.encryptedCookies,mitigationType:this.mitigationType,secretKey:this.secretKey,sessionCookieName:this.netaceaCookieName,captchaCookieName:this.netaceaCaptchaCookieName,ipHeaderName:this.ipHeaderName})}async run(e){let t;try{t=this.getRequestResponseFromEvent(e).request;const{uri:a,method:i}=t;if(function(e,t,a){return void 0!==a&&e.toLowerCase().includes(a.toLowerCase())&&"get"===t.toLowerCase()}(a,i,this.netaceaCaptchaPath)){const a=await async function({request:e,secretKey:t,mitigationCallFn:a,composeResultFn:i,cookieEncryptionKey:s,netaceaCookieName:o,netaceaCaptchaCookieName:n,ipHeaderName:r}){const{querystring:c}=e,h=j(e,r),u=e.headers["user-agent"]?.[0].value??"",d=e.headers.accept?.[0].value??"text/html",p=e.headers.host?.[0].value??"";if(void 0===t)throw new Error("Secret key needs to be defined to make mitigation calls.");const l=c.split("&").find((e=>e.includes("trackingId=")))?.replace("trackingId=",""),{headers:m}=e,y=await B(o,m,s),g=await B(n,m,s),{userId:k}=S(y)??{},C=await async function({userId:e,clientIp:t,userAgent:a,trackingId:i,accept:s,host:o,captchaCookie:n,mitigationCallFn:r,composeResultFn:c}){const h={match:0,mitigate:0,captcha:1},u=await r({userId:e,clientIP:t,userAgent:a,captchaCookie:n,accept:s,host:o,isCaptchaGet:!0,defaultMitataCodes:h,trackingId:i});return c(u.body,u.setCookie,u.status,u.match,u.mitigate,u.captcha,!0,u.latency??0)}({userId:k,clientIp:h,userAgent:u,captchaCookie:g,accept:d,host:p,trackingId:l,mitigationCallFn:a,composeResultFn:i});return G(e,C.apiCallStatus,C.apiCallLatency),{headers:z(C.setCookie),status:"403",body:C.body,statusDescription:"Forbidden"}}({request:t,secretKey:this.secretKey,mitigationCallFn:this.makeMitigateAPICall.bind(this),composeResultFn:this.composeResult.bind(this),cookieEncryptionKey:this.cookieEncryptionKey,netaceaCookieName:this.netaceaCookieName,netaceaCaptchaCookieName:this.netaceaCaptchaCookieName,ipHeaderName:this.ipHeaderName});return await this.ingest(e,a),{respondWith:a}}const s=await this.runMitigation(t);return this.addNetaceaCookiesToRequest(t,s),t.headers[me.NetaceaTrueUserAgentHeader]=[{key:me.NetaceaTrueUserAgentHeader,value:this.getValueFromHeaderOrDefault(t.headers,"user-agent","-")}],void 0!==s&&this.ingestType===o.KINESIS&&G(t,s.apiCallStatus,s.apiCallLatency),{respondWith:s?.response}}catch(e){return console.error("Netacea FailOpen - ",e.message),void 0!==t&&e instanceof ae&&U(t,e),{}}}async makeRequest({host:e,path:t,method:i,body:s,headers:o,timeout:n}){const r=`${e}${t}`,c=await a.request({url:r,data:s,headers:o,method:i,timeout:n,transformResponse:e=>e});return{headers:c.headers,status:c.status,body:c.data}}async mitigate(e){try{const{netaceaResult:a,request:i}=await this.getMitigationResponse(e);let s;if(a.mitigated){const e={"set-cookie":[]};for(const t of a.setCookie)e["set-cookie"]=e["set-cookie"]??[],e["set-cookie"].push({key:"set-cookie",value:t});"captcha"===a.mitigation&&void 0!==this.captchaHeader&&(e[this.captchaHeader.name]=[{key:this.captchaHeader.name,value:this.captchaHeader.value}]);s={headers:e,...J(i.uri,i.method)?{status:"200",statusDescription:"OK",body:""}:{status:"403",statusDescription:"Forbidden",body:"Forbidden"}};let n=0;if(void 0!==a.body&&a.body.length>0){n=a.body.length;const e=(t=a.body).includes("captchaRelativeURL")&&t.includes("captchaAbsoluteURL");s.status=e?"403":"200",s.statusDescription=e?"Forbidden":"OK",s.body=a.body,s.bodyEncoding="text"}const r={status:s.status,statusDescription:s.statusDescription??"",headers:{"content-length":[{key:"content-length",value:n.toString()}],"set-cookie":a.setCookie.map((e=>({key:"set-cookie",value:e})))}};this.ingestType===o.KINESIS&&G(i,a.apiCallStatus,a.apiCallLatency),await this.ingest(i,r)}return this.addNetaceaCookiesToRequest(i,a),{response:s,sessionStatus:a.sessionStatus,setCookie:a.setCookie,apiCallLatency:a.apiCallLatency,apiCallStatus:a.apiCallStatus}}catch(t){if(t instanceof ae&&U(e,t),J(e.uri,e.method)){const t={status:"500",statusDescription:"Internal Server Error",body:"",headers:{}},a={response:t,sessionStatus:"error_open"};return await this.ingest(e,t),a}return console.error("Netacea FailOpen Error: ",t),{sessionStatus:"error_open"}}var t}async inject(e){try{const{netaceaResult:t}=await this.getMitigationResponse(e);return{injectHeaders:t.injectHeaders,sessionStatus:t.sessionStatus,setCookie:t.setCookie,apiCallLatency:t.apiCallLatency,apiCallStatus:t.apiCallStatus}}catch(e){return console.error("Netacea FailOpen Error: ",e),{sessionStatus:"",injectHeaders:void 0,setCookie:void 0}}}async ingest(e,t=void 0){let a;if(Object.prototype.hasOwnProperty.call(e,"Records")){const i=this.getRequestResponseFromEvent(e);a=i.request,void 0===t&&(t=i.response)}else a=e;if(!this.ingestEnabled)return;if(null==t)throw new Error("Cloudfront response is required to ingest");const i=this.getMitataValueFromHeaderOrDefault(t.headers,"set-cookie"),s=""!==i?i:this.getMitataValueFromHeaderOrDefault(a.headers,"cookie");let o=await this.readCookie(this.netaceaCookieName,s)??"";if(void 0===o||""===o){const e=this.getMitataValueFromHeaderOrDefault(a.headers,"cookie");o=await this.readCookie(this.netaceaCookieName,e)??""}let n=0,r=0,c=0;const h=S(o);void 0!==h&&(n=h.match,r=h.mitigate,c=h.captcha);const{sessionStatus:d,mitigationLatency:p,mitigationStatus:l}=function(e){return{sessionStatus:X(e.headers,"x-netacea-session-status"),mitigationLatency:X(e.headers,"x-netacea-api-call-latency"),mitigationStatus:X(e.headers,"x-netacea-api-call-status")}}(a),m=this.shouldSetCaptchaPass(a,t),y=await this.requestAnalyser.getNetaceaRequestDetails(a),{sessionStatus:g}=te(this.mitigationType,n,r,c,m);await this.callIngest({bytesSent:this.getValueFromHeaderOrDefault(t.headers,"content-length","0"),ip:y.clientIp,method:y.method,path:y.url,protocol:null,referer:this.getValueFromHeaderOrDefault(a.headers,"referer"),requestTime:"0",status:t.status,userAgent:this.getValueFromHeaderOrDefault(a.headers,me.NetaceaTrueUserAgentHeader,y.userAgent),mitataCookie:o,sessionStatus:d??g,integrationType:"@netacea/cloudfront".replace("@netacea/",""),integrationVersion:"6.0.15",xForwardedFor:this.getValueFromHeaderOrDefault(a.headers,"x-forwarded-for"),integrationMode:this.mitigationType,requestHost:this.getValueFromHeaderOrDefault(a.headers,"host",void 0),mitigationLatency:void 0!==p?u(p):void 0,mitigationStatus:void 0!==l?u(l):void 0,netaceaCookieStatus:y.sessionDetails.sessionCookieStatus})}addNetaceaCookiesToResponse(e){const{response:t,request:a}=this.getRequestResponseFromEvent(e);if(void 0===t)throw new Error("Response required to add cookies to response");const i=a.headers[me.NetaceaCookieHeader];if(null!=i&&null!=t.headers){let e=!1;if(void 0===t.headers["set-cookie"]?t.headers["set-cookie"]=[]:e=void 0!==t.headers["set-cookie"].find((e=>e.value.includes(this.netaceaCookieName)||e.value.includes(this.netaceaCaptchaCookieName))),!e)for(const e of i)t.headers["set-cookie"].push({key:"set-cookie",value:e.value})}this.setInjectHeaders(e)}setInjectHeaders(e){const{response:t,request:a}=this.getRequestResponseFromEvent(e);void 0!==t&&(a.headers["x-netacea-captcha"]=this.shouldSetCaptchaPass(a,t)?[{key:"x-netacea-captcha",value:"2"}]:a.headers["x-netacea-captcha"])}getValueFromHeaderOrDefault(e,t,a=""){if(void 0!==e?.[t]){const a=e[t];if(void 0!==a)return a[0].value}return a}getMitataValueFromHeaderOrDefault(e,t,a=""){if(void 0!==e?.[t]){const a=e[t];if(void 0!==a){const e=a.find((e=>e.value.includes(this.netaceaCookieName)));if(void 0!==e)return e.value}}return a}getRequestResponseFromEvent(e){return e.Records[0].cf}async getMitigationResponse(e){const t=this.getMitataValueFromHeaderOrDefault(e.headers,"cookie"),a=await this.readCookie(this.netaceaCookieName,t),i=await this.readCookie(this.netaceaCaptchaCookieName,t),s=j(e,this.ipHeaderName),o=this.getValueFromHeaderOrDefault(e.headers,"user-agent"),n=this.getValueFromHeaderOrDefault(e.headers,"accept","text/html"),r=this.getValueFromHeaderOrDefault(e.headers,"host");return{netaceaResult:await this.processMitigateRequest({getBodyFn:async()=>await Promise.resolve(Buffer.from(e.body?.data??"","base64").toString()),clientIp:s,method:e.method,url:e.uri,userAgent:o,accept:n,host:r,mitata:a,mitataCaptcha:i}),request:e}}addNetaceaCookiesToRequest(e,t){if(void 0===t)return e;if(e.headers[me.NetaceaCookieHeader]=[],void 0!==t.setCookie)for(const a of t.setCookie){const t=e.headers[me.NetaceaCookieHeader]??[];t.push({key:me.NetaceaCookieHeader,value:a}),e.headers[me.NetaceaCookieHeader]=t}if(this.mitigationType===r.INJECT)for(const[a,i]of Object.entries(t.injectHeaders??{}))e.headers[a]=[{key:a,value:i}];return e}getCookieHeader(e){return this.getMitataValueFromHeaderOrDefault(e.headers,"cookie")}async encryptCookieValue(e){return void 0!==this.cookieEncryptionKey?await async function(e,t){const a=h.base64url.decode(t),i=(new TextEncoder).encode(e);return await new h.CompactEncrypt(i).setProtectedHeader({alg:"dir",enc:"A256GCM"}).encrypt(a)}(e,this.cookieEncryptionKey):e}async decryptCookieValue(e){return void 0!==this.cookieEncryptionKey?await L(e,this.cookieEncryptionKey):e}async runMitigation(e){try{switch(this.mitigationType){case r.MITIGATE:return await this.mitigate(e);case r.INJECT:return await this.inject(e);case r.INGEST:return await this.processIngest(e);default:throw new Error(`Netacea Error: Mitigation type ${this.mitigationType} not recognised`)}}catch(e){return console.error("Netacea FAILOPEN Error:",e),{injectHeaders:{"x-netacea-captcha":"0","x-netacea-match":"0","x-netacea-mitigate":"0"},sessionStatus:""}}}async readCookie(e,t){if(null==t)return;if("string"==typeof t)return await this.readCookie(e,t.split(";"));const a=`${e}=`;for(const i of t){const t=i.split(";")[0].trimStart();if(t.startsWith(a)){const i=t.slice(a.length);if(this.encryptedCookies.includes(e))try{return await this.decryptCookieValue(i)}catch(e){return}return i}}}async processMitigateRequest(e){const t=J(e.url,e.method);return await(t?this.processCaptcha(e.mitata,e.clientIp,e.userAgent,await e.getBodyFn()):this.check(e.mitata,e.clientIp,e.userAgent,e.accept,e.host,e.mitataCaptcha))}shouldSetCaptchaPass(e,t){if(J(e.uri,e.method))return!0;if(void 0===t)return!1;const a=null!=t.headers?t.headers["set-cookie"]:void 0,i=a?.find((e=>e.value.split("=")[0]===this.netaceaCaptchaCookieName)),s=void 0!==i;return this.mitigationType===r.INJECT&&s}async processCaptcha(e,t,a,i){const{status:s,match:o,mitigate:n,captcha:r,body:c,setCookie:h,latency:u}=await this.makeCaptchaAPICall(e,t,a,i);return this.composeResult(c,h,s,o,n,r,!0,u)}async makeCaptchaAPICall(e,t,a,i){const s={"X-Netacea-API-Key":this.apiKey,"X-Netacea-Client-IP":t,"user-agent":a,"Content-Type":"application/x-www-form-urlencoded; charset=UTF-8"},o=S(e);void 0!==o&&(s["X-Netacea-UserId"]=o.userId),void 0!==this.captchaSiteKey&&void 0!==this.captchaSecretKey&&(s["X-Netacea-Captcha-Site-Key"]=this.captchaSiteKey,s["X-Netacea-Captcha-Secret-Key"]=this.captchaSecretKey);const n=Date.now(),r=await this.makeRequest({host:this.mitigationServiceUrl,path:"/AtaVerifyCaptcha",headers:s,method:"POST",body:i,timeout:this.timeout}),c=Date.now()-n;return await this.getApiCallResponseFromResponse(r,o?.userId,t,c)}async getApiCallResponseFromResponse(e,t,a,i,s){if(200!==e.status)throw new ae(e,i);let o=Y(e.headers,le.match)??NaN,n=Y(e.headers,le.mitigate)??NaN,r=Y(e.headers,le.captcha)??NaN;isNaN(o)&&(o=s?.match??0),isNaN(n)&&(n=s?.mitigate??0),isNaN(r)&&(r=s?.captcha??0);let c=Y(e.headers,le.mitataExpiry)??NaN;isNaN(c)&&(c=86400);const h=[await this.createMitata(a,t,o,n,r),await this.createMitataCaptcha(e.headers)].filter((e=>void 0!==e)),u=W(e.headers,le.eventId);return{status:e.status,match:o,mitigate:n,captcha:r,setCookie:h,body:e.body,eventId:u,mitataMaxAge:c,latency:i}}APIError(e){let t="Unknown error";switch(e.status){case 403:t="Invalid credentials";break;case 500:t="Server error";break;case 502:t="Bad Gateway";break;case 503:t="Service Unavailable";break;case 400:t="Invalid request"}return new Error(`Error reaching Netacea API (${t}), status: ${e.status}`)}async createMitata(e,t,a,i,s,o=86400,n=void 0){const r=[1,3,5].includes(s)||3===i?-60:this.mitataCookieExpirySeconds,c=n??Math.floor(Date.now()/1e3)+r;if(void 0===this.secretKey)throw new Error("Cannot build cookie without secret key.");const h=[a,i,s].join(""),u=function(e,t,a,i,s="000"){void 0===t&&(t=v());const o=[a,t,N(e+"|"+String(a),i),s].join(p);return`${N(o,i)}${p}${o}`}(e,t,c,this.secretKey,h);let d,l,m=o;if(""!==this.netaceaCookieAttributes){const{extractedAttribute:e,cookieAttributes:t}=ce(this.netaceaCookieAttributes,"Max-Age");m=void 0!==e?Number(e):o;const{extractedAttribute:a,cookieAttributes:i}=ce(t,"Path");d=a??"/",l=i??void 0}return await this.buildCookieFromValues(this.netaceaCookieName,u,m,l,d)}async createMitataCaptcha(e){let t=e["set-cookie"]??[];t="string"==typeof t?[t]:t;const a=t.find((e=>e.startsWith("_mitatacaptcha=")));let i,s="86400";if(void 0!==a&&""!==a)try{const e=ue(a);i=e.value,s=re(e.attributes,"Max-Age")??"86400"}catch(e){return}if(""===i||void 0===i)return;const o=he([this.netaceaCaptchaCookieAttributes,"Path=/",`Max-Age=${s}`]);return i=this.encryptedCookies.includes(this.netaceaCaptchaCookieName)?await this.encryptCookieValue(i):i,`${this.netaceaCaptchaCookieName}=${i}; ${o}`}async buildCookieFromValues(e,t,a,i,s="/"){const o=`${e}=${this.encryptedCookies.includes(e)?await this.encryptCookieValue(t):t}; Max-Age=${a}; Path=${s}`;return void 0!==i&&""!==i?`${o}; ${i}`:o}async callIngest(e){const t=Q(this.logVersion,e);if(this.ingestType===o.KINESIS){if(void 0===this.kinesis)return void console.error("Netacea Error: Unable to log as Kinesis has not been defined.");try{await this.kinesis.ingest({...t,apiKey:this.apiKey},this.makeRequest.bind(this))}catch(e){console.error("NETACEA Error: ",e.message)}}else{const e={"X-Netacea-API-Key":this.apiKey,"content-type":"application/json"},a=await this.makeIngestApiCall(e,t);if(200!==a.status)throw this.APIError(a)}}async makeIngestApiCall(e,t){return await this.makeRequest({host:this.ingestServiceUrl,method:"POST",path:"/",headers:e,body:JSON.stringify(t),timeout:this.timeout})}async processIngest(e){if(void 0===this.secretKey)throw new Error("Secret key is required for ingest");const t=this.getCookieHeader(e),a=I(await this.readCookie(this.netaceaCookieName,t),k,this.secretKey);return a.isPrimaryHashValid?a.requiresReissue?await this.setIngestOnlyMitataCookie(a.mitata?.userId):{sessionStatus:"",setCookie:[]}:await this.setIngestOnlyMitataCookie(void 0)}async setIngestOnlyMitataCookie(e){return{sessionStatus:"",setCookie:[await this.createMitata(k,e,0,0,0,86400)]}}async check(e,t,a,i,s,o){let n,r,c,h,u,d,p,l;if(void 0===this.secretKey)throw new Error("Secret key is required to mitigate");const m=I(e,t,this.secretKey);if(!m.isPrimaryHashValid||m.requiresReissue){const e=await this.makeMitigateAPICall({userId:m.mitata?.userId,clientIP:t,userAgent:a,captchaCookie:o,accept:i,host:s});n=e.status,r=e.match,c=e.mitigate,h=e.captcha,u=e.body,l=e.latency,d=[await this.createMitata(t,m.mitata?.userId,r,c,h,e.mitataMaxAge)],p=e.eventId}else r=m.match,c=m.mitigate,h=m.captcha,u=void 0,d=[];return this.composeResult(u,d,n,r,c,h,!1,l,p)}async makeMitigateAPICall({userId:e,clientIP:t,userAgent:a,captchaCookie:i,accept:s,host:o,isCaptchaGet:n=!1,defaultMitataCodes:r,trackingId:c}){const h={"X-Netacea-API-Key":this.apiKey,"X-Netacea-Client-IP":t,"user-agent":a,cookie:this.buildCookieHeader({_mitatacaptcha:i})};void 0!==e&&(h["X-Netacea-UserId"]=e),void 0!==this.captchaSiteKey&&void 0!==this.captchaSecretKey&&(h["X-Netacea-Captcha-Site-Key"]=this.captchaSiteKey,h["X-Netacea-Captcha-Secret-Key"]=this.captchaSecretKey),this.dynamicCaptchaContentType&&void 0!==this.netaceaCaptchaPath&&(h["X-Netacea-Captcha-Content-Type"]=function(e){const t=e?.toLowerCase()??"text/html",a=t?.includes("text/html")||t?.includes("application/html"),i=t?.includes("application/json");return i&&!a?"application/json":"text/html"}(s));const u="application/json"===h["X-Netacea-Captcha-Content-Type"],d=void 0!==c?`?trackingId=${c}`:"",p=Date.now(),l=await this.makeRequest({host:this.mitigationServiceUrl,path:n?`/captcha${d}`:"/",headers:h,method:"GET",timeout:this.timeout}),m=Date.now()-p;return u&&void 0!==this.netaceaCaptchaPath&&(l.body=function(e,t,a){let i;if(void 0===e||""===e)return"";if("string"==typeof e&&(i=JSON.parse(e)),!function(e){if(null==e)return!1;const t=e;return void 0!==t?.captchaSiteKey&&void 0!==t?.trackingId&&void 0!==t?.captchaURL}(i))throw new Error("Body is not a Mitigation Service JSON response!");const s=`${a}?trackingId=${i.trackingId}`,o=`https://${t}${s}`;return JSON.stringify({captchaRelativeURL:s,captchaAbsoluteURL:o})}(l.body,o,this.netaceaCaptchaPath)),await this.getApiCallResponseFromResponse(l,e,t,m,r)}buildCookieHeader(e){let t="",a="";for(const i in e){const s=e[i];void 0!==s&&(t=`${t}${a}${i}=${s}`,a="; ")}return t}composeResult(e,t,a,i,s,o,n,c,h){const u=te(this.mitigationType,i,s,o,n),d={body:e,apiCallStatus:a,apiCallLatency:c,setCookie:t,sessionStatus:u.sessionStatus,mitigation:u.mitigation,mitigated:[pe.block,pe.captcha,pe.captchaPass].includes(u.mitigation)};if(this.mitigationType===r.INJECT){const e={"x-netacea-match":u.parts.match.toString(),"x-netacea-mitigate":u.parts.mitigate.toString(),"x-netacea-captcha":u.parts.captcha.toString()};void 0!==h&&(e["x-netacea-event-id"]=h),d.injectHeaders=e}return d}}exports.Cloudfront=me;
|
|
2
2
|
//# sourceMappingURL=index.js.map
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@netacea/cloudfront",
|
|
3
|
-
"version": "6.0.
|
|
3
|
+
"version": "6.0.15",
|
|
4
4
|
"description": "Netacea Cloudfront CDN integration",
|
|
5
5
|
"files": [
|
|
6
6
|
"dist/index.js",
|
|
@@ -23,5 +23,5 @@
|
|
|
23
23
|
"axios": "^0.21.0",
|
|
24
24
|
"jose": "^4.11.2"
|
|
25
25
|
},
|
|
26
|
-
"gitHead": "
|
|
26
|
+
"gitHead": "094acb64590a4031a7bf322858fd934ac5eb5512"
|
|
27
27
|
}
|