@netacea/cloudfront 6.0.15 → 6.0.17

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 CHANGED
@@ -118,6 +118,10 @@ interface MakeRequestArgs {
118
118
  * Request timeout value in ms
119
119
  */
120
120
  timeout?: number;
121
+ /**
122
+ * Request URL parameters
123
+ */
124
+ params?: Record<string, string> | URLSearchParams;
121
125
  }
122
126
  interface NetaceaBaseArgs {
123
127
  /**
@@ -384,6 +388,13 @@ interface MakeRequestResponse {
384
388
  declare class Cloudfront {
385
389
  static NetaceaCookieHeader: string;
386
390
  static NetaceaTrueUserAgentHeader: string;
391
+ /**
392
+ * CloudFront special header names to grab header names in original order
393
+ * The get these headers in edge function, they need to be activated through origin request policy
394
+ * https://docs.aws.amazon.com/AmazonCloudFront/latest/DeveloperGuide/adding-cloudfront-headers.html#cloudfront-headers-viewer-headers
395
+ */
396
+ static HeadersInOriginalOrderHeader: string;
397
+ static NetaceaHeaderFingerPrintHeader: string;
387
398
  private readonly cookieEncryptionKey;
388
399
  ingestEnabled: boolean;
389
400
  private readonly netaceaCaptchaPath?;
@@ -391,6 +402,7 @@ declare class Cloudfront {
391
402
  private readonly dynamicCaptchaContentType;
392
403
  private readonly ipHeaderName?;
393
404
  private readonly requestAnalyser;
405
+ private readonly hashGenerator;
394
406
  protected mitataCookieExpirySeconds: number;
395
407
  protected apiKey: string;
396
408
  protected secretKey?: string;
@@ -412,7 +424,10 @@ declare class Cloudfront {
412
424
  run(cloudfrontEvent: CloudFrontRequestEvent): Promise<{
413
425
  respondWith?: CloudFrontResultResponse;
414
426
  }>;
415
- protected makeRequest({ host, path, method, body, headers, timeout }: MakeRequestArgs): Promise<MakeRequestResponse>;
427
+ protected makeRequest({ host, path, method, body, headers, timeout, params }: MakeRequestArgs): Promise<MakeRequestResponse>;
428
+ protected getFingerprints(cfRequest: CloudFrontRequest): Promise<{
429
+ headerFingerprint: string;
430
+ }>;
416
431
  protected mitigate(cfRequest: CloudFrontRequest): Promise<MitigateResponse<CloudFrontResultResponse>>;
417
432
  protected inject(request: CloudFrontRequest): Promise<InjectResponse>;
418
433
  ingest(requestOrEvent: CloudFrontRequestEvent | CloudFrontResponseEvent | CloudFrontRequest, response?: CloudFrontResultResponse | CloudFrontResponse | undefined): Promise<any>;
@@ -443,6 +458,7 @@ declare class Cloudfront {
443
458
  protected processMitigateRequest(args: ProcessMitigateRequestArgs & {
444
459
  accept: string;
445
460
  host: string;
461
+ headerFingerprint: string;
446
462
  }): Promise<ComposeResultResponse>;
447
463
  protected shouldSetCaptchaPass(request: CloudFrontRequest, response: CloudFrontResponse | CloudFrontResultResponse): boolean;
448
464
  private processCaptcha;
@@ -456,7 +472,7 @@ declare class Cloudfront {
456
472
  private makeIngestApiCall;
457
473
  protected processIngest(request: CloudFrontRequest): Promise<NetaceaResponseBase>;
458
474
  protected setIngestOnlyMitataCookie(userId: string | undefined): Promise<NetaceaResponseBase>;
459
- protected check(netaceaCookie: string | undefined, clientIP: string, userAgent: string, accept: string, host: string, captchaCookie?: string): Promise<ComposeResultResponse>;
475
+ protected check(netaceaCookie: string | undefined, clientIP: string, userAgent: string, accept: string, host: string, captchaCookie?: string, headerFingerprint?: string): Promise<ComposeResultResponse>;
460
476
  private makeMitigateAPICall;
461
477
  private buildCookieHeader;
462
478
  private composeResult;
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,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;
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_",11:"headerFP_"},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|[a-z])(\d)(\d))$/i;function S(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,36),mitigate:parseInt(n),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,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,userId:s.userId}}return i}function w(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 E(e,t=!1){return"string"!=typeof e&&(e=e.join("; ")),""===e?"":A(e.split(";"),t).join("; ")}function A(e,t=!1){if(t)return A(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=E(e??"",!0),i=t=E(t??"",!0);if(void 0!==e&&void 0!==t){const s=w(e,"Domain"),o=w(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=w(e,"Domain");void 0!==t&&(i=`Domain=${t}`)}else if(void 0===e&&void 0!==t){const e=w(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=w(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:w,removeDuplicateAttrs:E});function T(e){const t=E([e.otherAttributes??"",`Max-Age=${e.maxAgeAttribute??86400}`,"Path=/"].join("; "));return`${e.cookieName}=${e.cookieValue}; ${t}`}var H=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 K=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 x={cookie:{parse:K,attributes:b,netaceaSession:H}};class R{constructor(e){this.crypto=e}async hashString(e,t,a=!1){const i=a?[...t].sort():[...t],s=(new TextEncoder).encode(i.join(",")),o=await this.crypto.subtle.digest(e,s),r=Array.from(new Uint8Array(o)).map((e=>e.toString(16).padStart(2,"0"))).join("").substring(0,12);return"h"+(a?"s":"")+`_${t.length}_${r}`}static filterHeaderNames(e){return e.filter((e=>{const t=e.toLowerCase();return!["","cookie","referer"].includes(t)&&null===t.match(/^(x-netacea-|cloudfront-)/i)}))}async hashHeaders(e,t=!1){const a=R.filterHeaderNames(e);if(0===a.length)return"";try{return await this.hashString("SHA-256",a,t)}catch(e){return console.error(e),""}}}var _={},P={},O={},F={};Object.defineProperty(F,"__esModule",{value:!0}),F.API_VERSION=F.REGION=F.PAYLOAD_TYPE=F.STATE=void 0,F.STATE={ACTIVE:"ACTIVE",UPDATING:"UPDATING",CREATING:"CREATING",DELETING:"DELETING"},F.PAYLOAD_TYPE="string",F.REGION="eu-west-1",F.API_VERSION="2013-12-02",Object.defineProperty(O,"__esModule",{value:!0}),O.signRequest=void 0;const M=i,D=F;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 V=P;var L=_.default=V.default;async function j(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 G(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){X(e,t.protectorApiResponse.status,t.latencyMs),e.headers["x-netacea-session-status"]=[{key:"x-netacea-session-status",value:"error_open"}]}function X(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 z(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 j(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 W(e,t){return e.includes("/AtaVerifyCaptcha")&&"post"===t.toLowerCase()}function Y(e,t){const a=e[t];return"string"==typeof a?a:a?.[0]}function Z(e,t){const a=Y(e,t);if(void 0!==a)return parseInt(a,36)}function Q(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 ee(e,t){return t.bytesSent=""===t.bytesSent?"0":t.bytesSent,e===r.V2?function({ip:e,userAgent:t,status:a,method:i,path:s,protocol:o,referer:r,bytesSent:n,requestTime:c,mitataCookie:h,sessionStatus:d,integrationType:p,integrationVersion:l,xForwardedFor:m,integrationMode:g,requestHost:y,mitigationLatency:k,mitigationStatus:C}){const f=new Date,{path:v,query:N,request:I}=Q(i,s,o),w=S(h)?.userId;return{status:a,method:i,bytes_sent:u(n),referrer:""===r?void 0:r,request:I,request_time:u(c),integration_type:p,integration_version:l,protection_mode:g,protector_latency_ms:k,protector_status:C,request_host:y,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:w,x_forwarded_for:m}}(t):function({ip:e,userAgent:t,status:a,method:i,path:s,protocol:o,referer:r,bytesSent:n,requestTime:c,mitataCookie:h,sessionStatus:u,integrationType:d,integrationVersion:p,xForwardedFor:l,integrationMode:m,requestHost:g,mitigationLatency:y,mitigationStatus:k,netaceaCookieStatus:C,headerFingerprint:f}){const S=(new Date).toUTCString(),{request:v}=Q(i,s,o);return{Request:v,TimeLocal:S,RealIp:e,UserAgent:t,Status:a,RequestTime:c?.toString(),BytesSent:n?.toString(),Referer:""===r?"-":r,NetaceaUserIdCookie:h??"",NetaceaMitigationApplied:u??"",IntegrationType:d??"",IntegrationVersion:p??"",ProtectionMode:m,ProtectorLatencyMs:y,ProtectorStatus:k,RequestHost:g,XForwardedFor:l,NetaceaUserIdCookieStatus:C,HeaderHash:f}}(t)}const te="unknown";function ae(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=y.matchMap[t]??te+"_";o+=y.mitigateMap[a]??te;let r=y.bestMitigationMap[a];if(0!==i){o+=","+(y.captchaMap[i]??te);const e=y.bestMitigationCaptchaMap[i];void 0!==e&&(r=e)}return e===n.INJECT&&(r=y.mitigationTypes.none),{sessionStatus:o,mitigation:r,parts:{match:t,mitigate:a,captcha:i}}}class ie 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 se;!function(e){e[e.NEW_SESSION=1]="NEW_SESSION",e[e.EXISTING_SESSION=2]="EXISTING_SESSION",e[e.RENEW_SESSION=3]="RENEW_SESSION"}(se||(se={}));class oe{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=G(e,this.config.ipHeaderName),{sessionCookieDetails:r,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:r,isSameIP:c}=o,h=s||r||!c&&e.mitigationType!==n.INGEST?se.RENEW_SESSION:se.EXISTING_SESSION,{sessionStatus:u}=ae(e.mitigationType,o.match,o.mitigate,o.captcha,W(t,a));return{userId:i,sessionCookieStatus:h,sessionStatus:u,sessionCookieDetails:o}}return{sessionStatus:"",userId:v(),sessionCookieStatus:se.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:r,sessionCookieStatus:c,userId:u},fingerprints:{headerFingerprint:ne(e.headers,this.config.headerFingerprintHeaderName)}}}async readCookie(e,t){const a=re(e.headers,t,"set-cookie"),i=""!==a?a:re(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 j(a,this.config.cookieEncryptionKey)}catch(e){return}return a}}}function re(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:ce,extractAndRemoveCookieAttr:he,removeDuplicateAttrs:ue}=x.cookie.attributes,de=x.cookie.parse.parseSetCookie,{configureCookiesDomain:pe}=x.cookie.attributes,{mitigationTypes:le,netaceaHeaders:me}=y;class ge{static NetaceaCookieHeader="x-netacea-cloudfront-mitata-cookie";static NetaceaTrueUserAgentHeader="x-netacea-true-useragent-header";static HeadersInOriginalOrderHeader="cloudfront-viewer-header-order";static NetaceaHeaderFingerPrintHeader="x-netacea-header-fingerprint";cookieEncryptionKey;ingestEnabled=!0;netaceaCaptchaPath;captchaHeader;dynamicCaptchaContentType;ipHeaderName;requestAnalyser;hashGenerator;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??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 L({...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=pe(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,this.requestAnalyser=new oe({cookieEncryptionKey:this.cookieEncryptionKey,encryptedCookies:this.encryptedCookies,mitigationType:this.mitigationType,secretKey:this.secretKey,sessionCookieName:this.netaceaCookieName,captchaCookieName:this.netaceaCaptchaCookieName,ipHeaderName:this.ipHeaderName,headerFingerprintHeaderName:ge.NetaceaHeaderFingerPrintHeader}),this.hashGenerator=new R(globalThis.crypto)}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:r,ipHeaderName:n}){const{querystring:c}=e,h=G(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 z(o,m,s),y=await z(r,m,s),{userId:k}=S(g)??{},C=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:k,clientIp:h,userAgent:u,captchaCookie:y,accept:d,host:p,trackingId:l,mitigationCallFn:a,composeResultFn:i});return X(e,C.apiCallStatus,C.apiCallLatency),{headers:J(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[ge.NetaceaTrueUserAgentHeader]=[{key:ge.NetaceaTrueUserAgentHeader,value:this.getValueFromHeaderOrDefault(t.headers,"user-agent","-")}],void 0!==s&&this.ingestType===o.KINESIS&&X(t,s.apiCallStatus,s.apiCallLatency),{respondWith:s?.response}}catch(e){return console.error("Netacea FailOpen - ",e.message),void 0!==t&&e instanceof ie&&U(t,e),{}}}async makeRequest({host:e,path:t,method:i,body:s,headers:o,timeout:r,params:n}){const c=`${e}${t}`,h=await a.request({url:c,data:s,headers:o,method:i,timeout:r,params:n,transformResponse:e=>e});return{headers:h.headers,status:h.status,body:h.data}}async getFingerprints(e){const t=this.getValueFromHeaderOrDefault(e.headers,ge.HeadersInOriginalOrderHeader,"");let a="";if(""!==t)a=await this.hashGenerator.hashHeaders(t.split(":"));else{const t=Object.entries(e.headers).flatMap((([e,t])=>t.map((({key:t})=>t??e))));a=await this.hashGenerator.hashHeaders(t,!0)}return{headerFingerprint:a}}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,...W(i.uri,i.method)?{status:"200",statusDescription:"OK",body:""}:{status:"403",statusDescription:"Forbidden",body:"Forbidden"}};let r=0;if(void 0!==a.body&&a.body.length>0){r=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 n={status:s.status,statusDescription:s.statusDescription??"",headers:{"content-length":[{key:"content-length",value:r.toString()}],"set-cookie":a.setCookie.map((e=>({key:"set-cookie",value:e})))}};this.ingestType===o.KINESIS&&X(i,a.apiCallStatus,a.apiCallLatency),await this.ingest(i,n)}return this.addNetaceaCookiesToRequest(i,a),{response:s,sessionStatus:a.sessionStatus,setCookie:a.setCookie,apiCallLatency:a.apiCallLatency,apiCallStatus:a.apiCallStatus}}catch(t){if(t instanceof ie&&U(e,t),W(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 r=0,n=0,c=0;const h=S(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),g=await this.requestAnalyser.getNetaceaRequestDetails(a),{sessionStatus:y}=ae(this.mitigationType,r,n,c,m);await this.callIngest({bytesSent:this.getValueFromHeaderOrDefault(t.headers,"content-length","0"),ip:g.clientIp,method:g.method,path:g.url,protocol:null,referer:this.getValueFromHeaderOrDefault(a.headers,"referer"),requestTime:"0",status:t.status,userAgent:this.getValueFromHeaderOrDefault(a.headers,ge.NetaceaTrueUserAgentHeader,g.userAgent),mitataCookie:o,sessionStatus:d??y,integrationType:"@netacea/cloudfront".replace("@netacea/",""),integrationVersion:"6.0.17",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:g.sessionDetails.sessionCookieStatus,headerFingerprint:g.fingerprints.headerFingerprint})}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[ge.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=G(e,this.ipHeaderName),o=this.getValueFromHeaderOrDefault(e.headers,"user-agent"),r=this.getValueFromHeaderOrDefault(e.headers,"accept","text/html"),n=this.getValueFromHeaderOrDefault(e.headers,"host"),{headerFingerprint:c}=await this.getFingerprints(e);return e.headers[ge.NetaceaHeaderFingerPrintHeader]=[{key:ge.NetaceaHeaderFingerPrintHeader,value:""===c?"-":c}],{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,headerFingerprint:c}),request:e}}addNetaceaCookiesToRequest(e,t){if(void 0===t)return e;if(e.headers[ge.NetaceaCookieHeader]=[],void 0!==t.setCookie)for(const a of t.setCookie){const t=e.headers[ge.NetaceaCookieHeader]??[];t.push({key:ge.NetaceaCookieHeader,value:a}),e.headers[ge.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 j(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=W(e.url,e.method);return await(t?this.processCaptcha({...e,netaceaCookie:e.mitata,captchaData:await e.getBodyFn()}):this.check(e.mitata,e.clientIp,e.userAgent,e.accept,e.host,e.mitataCaptcha,e.headerFingerprint))}shouldSetCaptchaPass(e,t){if(W(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){const{status:t,match:a,mitigate:i,captcha:s,body:o,setCookie:r,latency:n}=await this.makeCaptchaAPICall(e);return this.composeResult(o,r,t,a,i,s,!0,n)}async makeCaptchaAPICall(e){const{netaceaCookie:t,clientIp:a,userAgent:i,headerFingerprint:s,captchaData:o}=e,r={"X-Netacea-API-Key":this.apiKey,"X-Netacea-Client-IP":a,"user-agent":i,"Content-Type":"application/x-www-form-urlencoded; charset=UTF-8"},n=S(t);void 0!==n&&(r["X-Netacea-UserId"]=n.userId),void 0!==this.captchaSiteKey&&void 0!==this.captchaSecretKey&&(r["X-Netacea-Captcha-Site-Key"]=this.captchaSiteKey,r["X-Netacea-Captcha-Secret-Key"]=this.captchaSecretKey);const c=new URLSearchParams;""!==s&&c.append("headerFP",s);const h=Date.now(),u=await this.makeRequest({host:this.mitigationServiceUrl,path:"/AtaVerifyCaptcha",headers:r,method:"POST",body:o,timeout:this.timeout,params:c}),d=Date.now()-h;return await this.getApiCallResponseFromResponse(u,n?.userId,a,d)}async getApiCallResponseFromResponse(e,t,a,i,s){if(200!==e.status)throw new ie(e,i);let o=Z(e.headers,me.match)??NaN,r=Z(e.headers,me.mitigate)??NaN,n=Z(e.headers,me.captcha)??NaN;isNaN(o)&&(o=s?.match??0),isNaN(r)&&(r=s?.mitigate??0),isNaN(n)&&(n=s?.captcha??0);let c=Z(e.headers,me.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=Y(e.headers,me.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.toString(36),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}=he(this.netaceaCookieAttributes,"Max-Age");m=void 0!==e?Number(e):o;const{extractedAttribute:a,cookieAttributes:i}=he(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=de(a);i=e.value,s=ce(e.attributes,"Max-Age")??"86400"}catch(e){return}if(""===i||void 0===i)return;const o=ue([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=ee(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,r){let n,c,h,u,d,p,l,m;if(void 0===this.secretKey)throw new Error("Secret key is required to mitigate");const g=I(e,t,this.secretKey);if(!g.isPrimaryHashValid||g.requiresReissue){const e=await this.makeMitigateAPICall({userId:g.mitata?.userId,clientIP:t,userAgent:a,captchaCookie:o,accept:i,host:s,headerFingerprint:r});n=e.status,c=e.match,h=e.mitigate,u=e.captcha,d=e.body,m=e.latency,p=[await this.createMitata(t,g.mitata?.userId,c,h,u,e.mitataMaxAge)],l=e.eventId}else c=g.match,h=g.mitigate,u=g.captcha,d=void 0,p=[];return this.composeResult(d,p,n,c,h,u,!1,m,l)}async makeMitigateAPICall({userId:e,clientIP:t,userAgent:a,captchaCookie:i,accept:s,host:o,isCaptchaGet:r=!1,defaultMitataCodes:n,trackingId:c,headerFingerprint:h}){const u={"X-Netacea-API-Key":this.apiKey,"X-Netacea-Client-IP":t,"user-agent":a,cookie:this.buildCookieHeader({_mitatacaptcha:i})};void 0!==e&&(u["X-Netacea-UserId"]=e),void 0!==this.captchaSiteKey&&void 0!==this.captchaSecretKey&&(u["X-Netacea-Captcha-Site-Key"]=this.captchaSiteKey,u["X-Netacea-Captcha-Secret-Key"]=this.captchaSecretKey),this.dynamicCaptchaContentType&&void 0!==this.netaceaCaptchaPath&&(u["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 d="application/json"===u["X-Netacea-Captcha-Content-Type"],p=void 0!==c?`?trackingId=${c}`:"",l=new URLSearchParams;"string"==typeof h&&l.set("headerFP",h);const m=Date.now(),g=await this.makeRequest({host:this.mitigationServiceUrl,path:r?`/captcha${p}`:"/",headers:u,method:"GET",timeout:this.timeout,params:l}),y=Date.now()-m;return d&&void 0!==this.netaceaCaptchaPath&&(g.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})}(g.body,o,this.netaceaCaptchaPath)),await this.getApiCallResponseFromResponse(g,e,t,y,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=ae(this.mitigationType,i,s,o,r),d={body:e,apiCallStatus:a,apiCallLatency:c,setCookie:t,sessionStatus:u.sessionStatus,mitigation:u.mitigation,mitigated:[le.block,le.captcha,le.captchaPass].includes(u.mitigation)};if(this.mitigationType===n.INJECT){const e={"x-netacea-match":u.parts.match.toString(36),"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=ge;
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.15",
3
+ "version": "6.0.17",
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": "094acb64590a4031a7bf322858fd934ac5eb5512"
26
+ "gitHead": "1739319709fac76e0ecdf122b24adcfd47db6a85"
27
27
  }