@netacea/cloudfront 6.0.52 → 6.0.53
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.js +1 -1
- package/package.json +2 -2
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"),s=require("jose"),o=require("uuid");function n(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 r,c,h,d=n(s),u=n(o);!function(e){e.ORIGIN="ORIGIN",e.HTTP="HTTP",e.KINESIS="KINESIS",e.NATIVE="NATIVE"}(r||(r={})),function(e){e.MITIGATE="MITIGATE",e.INJECT="INJECT",e.INGEST="INGEST"}(c||(c={})),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"}(h||(h={}));function p(e,t=0){return isNaN(e)?t:parseInt(e)}const l=3e3;const g="_/@#/",m={none:"",block:"block",captcha:"captcha",allow:"allow",captchaPass:"captchapass"},f={0:m.none,1:m.block,2:m.none,3:m.block,4:m.block},y={1:m.captcha,2:m.captchaPass,3:m.captcha,4:m.allow,5:m.captcha};var k=Object.freeze({__proto__:null,COOKIEDELIMITER:g,bestMitigationCaptchaMap:y,bestMitigationMap:f,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_",b:"headerFP_"},mitigateMap:{0:"",1:"blocked",2:"allow",3:"hardblocked",4:"block"},mitigationTypes:m,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",S="1234567890abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ".split(""),v=/^(.*)_\/@#\/(.*)_\/@#\/(.*)_\/@#\/(.*)_\/@#\/((\d|[a-z])(\d)(\d))$/i;function I(e){if(void 0===e)return;const t=e.match(v);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:n,mitigate:r,captcha:c}}}function N(t=16,a=S){const i=e.randomBytes(t-1);return`c${Array.from(i).map((e=>a[e%a.length])).join("")}`}function w(a,i){const s=e.createHmac("sha256",i);return s.update(a),t.Buffer.from(s.digest("hex")).toString("base64")}function A(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=I(e);if(void 0!==s){const e=[s.expiry,s.userId,s.ipHash,s.mitigationType].join(g),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=w(t+"|"+s.expiry,a),d=s.ipHash===h;return{mitata:s,requiresReissue:o||!d,isExpired:o,shouldExpire:c,isSameIP:d,isPrimaryHashValid:s.signature===w(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 T(e,t=!1){return"string"!=typeof e&&(e=e.join("; ")),""===e?"":b(e.split(";"),t).join("; ")}function b(e,t=!1){if(t)return b(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 R=Object.freeze({__proto__:null,configureCookiesDomain:function(e,t){let a=e=T(e??"",!0),i=t=T(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: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 K={cookie:{parse:x,attributes:R}};class P{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),n=Array.from(new Uint8Array(o)).map((e=>e.toString(16).padStart(2,"0"))).join("").substring(0,12);return"h"+(a?"s":"")+`_${t.length}_${n}`}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=P.filterHeaderNames(e);if(0===a.length)return"";try{return await this.hashString("SHA-256",a,t)}catch(e){return console.error(e),""}}}var H={},O={},M={},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(M,"__esModule",{value:!0}),M.signRequest=void 0;const _=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}M.signRequest=function(e,t,a){const{accessKeyId:i,secretAccessKey:s}=e,o={Records:q(t,a),PartitionKey:Date.now().toString(),StreamName:e.streamName};return _.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(O,"__esModule",{value:!0});const L=M;async function $(e){await new Promise((t=>{setTimeout(t,e)}))}O.default=class{constructor({kinesisStreamName:e,kinesisAccessKey:t,kinesisSecretKey:a,maxLogAgeSeconds:i,logBatchSize:s,rampUpBatchSize:o,maxAwaitTimePerIngestCallMs:n}){this.maxLogBatchSize=20,this.maxLogAgeSeconds=10,this.logBatchSize=20,this.logCache=[],this.intervalSet=!1,this.kinesisStreamName=e,this.kinesisAccessKey=t,this.kinesisSecretKey=a,this.maxAwaitTimePerIngestCallMs=n,void 0!==i&&i<this.maxLogAgeSeconds&&i>0&&(this.maxLogAgeSeconds=i),void 0!==s&&(this.maxLogBatchSize=s),this.logBatchSize=!0===o?1:this.maxLogBatchSize}async putToKinesis(e){if(0===this.logCache.length)return;const t=[...this.logCache];this.logCache=[];try{const a=(0,L.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}),this.logBatchSize!==this.maxLogBatchSize&&(this.logBatchSize=Math.min(this.maxLogBatchSize,2*this.logBatchSize))}catch(e){this.logCache.push(...t),console.error(e)}}async ingest(e,t){if(this.logCache.push(e),this.logCache.length>=this.logBatchSize){const e=[];e.push(this.putToKinesis(t)),void 0!==this.maxAwaitTimePerIngestCallMs&&e.push($(this.maxAwaitTimePerIngestCallMs)),await Promise.race(e)}else if(!this.intervalSet){this.intervalSet=!0;const e=$(1e3*this.maxLogAgeSeconds).then((async()=>{await this.putToKinesis(t),this.intervalSet=!1})).catch((()=>{}));void 0===this.maxAwaitTimePerIngestCallMs&&await e}}},Object.defineProperty(H,"__esModule",{value:!0});const U=O;var V=H.default=U.default;async function j(e,t){const a=d.base64url.decode(t),{plaintext:i}=await d.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 B(e,t){z(e,t.protectorApiResponse.status,t.latencyMs),e.headers["x-netacea-session-status"]=[{key:"x-netacea-session-status",value:"error_open"}]}function z(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 W(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 Y(e,t){return e.includes("/AtaVerifyCaptcha")&&"post"===t.toLowerCase()}function Q(e,t){const a=e[t];return"string"==typeof a?a:a?.[0]}function Z(e){return e.bytesSent=""===e.bytesSent?"0":e.bytesSent,function({bytesSent:e,headerFingerprint:t,integrationMode:a,integrationType:i,integrationVersion:s,ip:o,method:n,mitataCookie:r,mitigationLatency:c,mitigationStatus:h,netaceaCookieStatus:d,path:u,protocol:p,referer:l,requestHost:g,requestTime:m,sessionStatus:f,status:y,timeUnixMsUTC:k,userAgent:C,workerInstanceId:S,xForwardedFor:v}){const{request:I}=function(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}`:""}`}}(n,u,p);return{BytesSent:e?.toString(),HeaderHash:t,IntegrationType:i??"",IntegrationVersion:s??"",NetaceaMitigationApplied:f??"",NetaceaUserIdCookie:r??"",NetaceaUserIdCookieStatus:d,ProtectionMode:a,ProtectorLatencyMs:c,ProtectorStatus:h,RealIp:o,Referer:""===l?"-":l,Request:I,RequestHost:g,RequestTime:m?.toString(),Status:y,TimeLocal:new Date(k??Date.now()).toUTCString(),TimeUnixMsUTC:k??Date.now(),UserAgent:C,WorkerInstanceId:S,XForwardedFor:v}}(e)}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=k.matchMap[t]??ee+"_";o+=k.mitigateMap[a]??ee;let n=k.bestMitigationMap[a];if("0"!==i){o+=","+(k.captchaMap[i]??ee);const e=k.bestMitigationCaptchaMap[i];void 0!==e&&(n=e)}return e===c.INJECT&&(n=k.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=G(e,this.config.ipHeaderName),{sessionCookieDetails:n,sessionCookieStatus:r,sessionStatus:h,userId:d}=function(e,t,a,i,s){const o=A(i,s,e.secretKey);if(void 0!==o.userId&&o.isPrimaryHashValid){const i=o.userId,{isExpired:s,shouldExpire:n,isSameIP:r}=o,h=s||n||!r&&e.mitigationType!==c.INGEST?ie.RENEW_SESSION:ie.EXISTING_SESSION,{sessionStatus:d}=te(e.mitigationType,o.match,o.mitigate,o.captcha,Y(t,a));return{userId:i,sessionCookieStatus:h,sessionStatus:d,sessionCookieDetails:o}}return{sessionStatus:"",userId:N(),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:r,userId:d},fingerprints:{headerFingerprint:ne(e.headers,this.config.headerFingerprintHeaderName)}}}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 j(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{configureCookiesDomain:re}=K.cookie.attributes;class ce{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;mitataCookieExpirySeconds;apiKey;secretKey;mitigationServiceUrl="https://mitigations.netacea.net";ingestServiceUrl;timeout;captchaSiteKey;captchaSecretKey;ingestType;mitigationType;kinesisConfigArgs;encryptedCookies=[];netaceaCookieName;netaceaCaptchaCookieName;netaceaCookieAttributes;netaceaCaptchaCookieAttributes;netaceaBlockedResponseRedirectLocation;constructor(e){if(e.ingestType=r.KINESIS,this.kinesisConfigArgs=e.kinesis,void 0===e.kinesis&&(console.warn(['NETACEA :: Please move kinesis params to "kinesis" object in config.',"Backwards compatibility will soon be removed."].join(" ")),this.kinesisConfigArgs={kinesisStreamName:e.kinesisStreamName,kinesisAccessKey:e.kinesisAccessKey,kinesisSecretKey:e.kinesisSecretKey,maxLogAgeSeconds:1},void 0!==e.logBatchSize&&(this.kinesisConfigArgs.logBatchSize=e.logBatchSize)),null===e.apiKey||void 0===e.apiKey)throw new Error("apiKey is a required parameter");if(this.apiKey=e.apiKey,this.secretKey=e.secretKey,void 0!==e.mitigationServiceUrl){const t=e.mitigationServiceUrl;this.mitigationServiceUrl=t.endsWith("/")?t.slice(0,-1):t}var t;this.ingestServiceUrl=e.ingestServiceUrl??"https://ingest.netacea.net",this.mitigationType=e.mitigationType??c.INGEST,this.ingestType=e.ingestType??r.HTTP,void 0===e.captchaSiteKey&&void 0===e.captchaSecretKey||(this.captchaSiteKey=e.captchaSiteKey,this.captchaSecretKey=e.captchaSecretKey),this.timeout=(t=e.timeout??3e3)<=0?l:t,this.netaceaCookieName=e.netaceaCookieName??"_mitata",this.netaceaCaptchaCookieName=e.netaceaCaptchaCookieName??"_mitatacaptcha",this.netaceaCaptchaPath=e.netaceaCaptchaPath,this.dynamicCaptchaContentType=e.dynamicCaptchaContentType??!1;const a=re(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===c.INGEST?3600:60:s),this.ingestEnabled=e.ingestEnabled??!0,this.cookieEncryptionKey=e.cookieEncryptionKey,this.netaceaBlockedResponseRedirectLocation=e.netaceaBlockedResponseRedirectLocation}}const{extractCookieAttr:he,extractAndRemoveCookieAttr:de,removeDuplicateAttrs:ue}=K.cookie.attributes,pe=K.cookie.parse.parseSetCookie,{mitigationTypes:le,netaceaHeaders:ge}=k;exports.Cloudfront=class{config;kinesis;requestAnalyser;workerInstanceId;hashGenerator;constructor(t){this.config=new ce(t),this.config.ingestType===r.KINESIS&&(void 0===this.config.kinesisConfigArgs?console.warn(`NETACEA WARN: no kinesis args provided, when ingestType is ${this.config.ingestType}`):this.kinesis=new V({...this.config.kinesisConfigArgs,apiKey:this.config.apiKey,rampUpBatchSize:!0,maxAwaitTimePerIngestCallMs:0})),this.requestAnalyser=new se({cookieEncryptionKey:this.config.cookieEncryptionKey,encryptedCookies:this.config.encryptedCookies,mitigationType:this.config.mitigationType,secretKey:this.config.secretKey,sessionCookieName:this.config.netaceaCookieName,captchaCookieName:this.config.netaceaCaptchaCookieName,ipHeaderName:this.config.ipHeaderName,headerFingerprintHeaderName:ce.NetaceaHeaderFingerPrintHeader}),this.workerInstanceId=u.v4(),this.hashGenerator=new P(e)}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.config.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=G(e,r),d=e.headers["user-agent"]?.[0].value??"",u=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:g}=e,m=await W(o,g,s),f=await W(n,g,s),{userId:y}=I(m)??{},k=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"},d=await r({userId:e,clientIP:t,userAgent:a,captchaCookie:n,accept:s,host:o,isCaptchaGet:!0,defaultMitataCodes:h,trackingId:i});return c(d.body,d.setCookie,d.status,d.match,d.mitigate,d.captcha,!0,d.latency??0)}({userId:y,clientIp:h,userAgent:d,captchaCookie:f,accept:u,host:p,trackingId:l,mitigationCallFn:a,composeResultFn:i});return z(e,k.apiCallStatus,k.apiCallLatency),{headers:J(k.setCookie),status:"403",body:k.body,statusDescription:"Forbidden"}}({request:t,secretKey:this.config.secretKey,mitigationCallFn:this.makeMitigateAPICall.bind(this),composeResultFn:this.composeResult.bind(this),cookieEncryptionKey:this.config.cookieEncryptionKey,netaceaCookieName:this.config.netaceaCookieName,netaceaCaptchaCookieName:this.config.netaceaCaptchaCookieName,ipHeaderName:this.config.ipHeaderName});return await this.ingest(e,a),{respondWith:a}}const s=await this.runMitigation(t);return this.addNetaceaCookiesToRequest(t,s),t.headers[ce.NetaceaTrueUserAgentHeader]=[{key:ce.NetaceaTrueUserAgentHeader,value:this.getValueFromHeaderOrDefault(t.headers,"user-agent","-")}],void 0!==s&&this.config.ingestType===r.KINESIS&&z(t,s.apiCallStatus,s.apiCallLatency),{respondWith:s?.response}}catch(e){return console.error("Netacea FailOpen - ",e.message),void 0!==t&&e instanceof ae&&B(t,e),{}}}async makeRequest({host:e,path:t,method:i,body:s,headers:o,timeout:n,params:r}){const c=`${e}${t}`,h=await a.request({url:c,data:s,headers:o,method:i,timeout:n,params:r,transformResponse:e=>e});return{headers:h.headers,status:h.status,body:h.data}}async getFingerprints(e){const t=this.getValueFromHeaderOrDefault(e.headers,ce.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 o={"set-cookie":[]};for(const e of a.setCookie)o["set-cookie"]=o["set-cookie"]??[],o["set-cookie"].push({key:"set-cookie",value:e});const n="captcha"===a.mitigation;n&&void 0!==this.config.captchaHeader&&(o[this.config.captchaHeader.name]=[{key:this.config.captchaHeader.name,value:this.config.captchaHeader.value}]);s={headers:o,...Y(i.uri,i.method)?{status:"200",statusDescription:"OK",body:""}:{status:"403",statusDescription:"Forbidden",body:"Forbidden"}},void 0!==this.config.netaceaBlockedResponseRedirectLocation&&!n&&function(e){if("GET"!==e.method?.toUpperCase())return!1;const t=(e.headers["sec-fetch-mode"]??[]).map((e=>e.value));return!(t.length>0&&!t.includes("navigate"))&&(e.headers.accept??[]).map((e=>e.value.split(/, ?/))).flat().includes("text/html")}(e)&&(s.status="303",o.Location=[{key:"Location",value:this.config.netaceaBlockedResponseRedirectLocation}]);let c=0;if(n&&void 0!==a.body&&a.body.length>0){c=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 h={status:s.status,statusDescription:s.statusDescription??"",headers:{"content-length":[{key:"content-length",value:c.toString()}],"set-cookie":a.setCookie.map((e=>({key:"set-cookie",value:e})))}};this.config.ingestType===r.KINESIS&&z(i,a.apiCallStatus,a.apiCallLatency),await this.ingest(i,h)}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&&B(e,t),Y(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.config.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.config.netaceaCookieName,s)??"";if(void 0===o||""===o){const e=this.getMitataValueFromHeaderOrDefault(a.headers,"cookie");o=await this.readCookie(this.config.netaceaCookieName,e)??""}let n="0",r="0",c="0";const h=I(o);void 0!==h&&(n=h.match,r=h.mitigate,c=h.captcha);const{sessionStatus:d,mitigationLatency:u,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),g=this.shouldSetCaptchaPass(a,t),m=await this.requestAnalyser.getNetaceaRequestDetails(a),{sessionStatus:f}=te(this.config.mitigationType,n,r,c,g),y=this.getValueFromHeaderOrDefault(a.headers,ce.NetaceaTrueUserAgentHeader,m.userAgent);await this.callIngest({bytesSent:this.getValueFromHeaderOrDefault(t.headers,"content-length","0"),headerFingerprint:m.fingerprints.headerFingerprint,integrationMode:this.config.mitigationType,integrationType:"@netacea/cloudfront".replace("@netacea/",""),integrationVersion:"6.0.52",ip:m.clientIp,method:m.method,mitataCookie:o,mitigationLatency:void 0!==u?p(u):void 0,mitigationStatus:void 0!==l?p(l):void 0,netaceaCookieStatus:m.sessionDetails.sessionCookieStatus,path:m.url,protocol:null,referer:this.getValueFromHeaderOrDefault(a.headers,"referer"),requestHost:this.getValueFromHeaderOrDefault(a.headers,"host",void 0),requestTime:"0",sessionStatus:d??f,status:t.status,userAgent:y,workerInstanceId:this.workerInstanceId,xForwardedFor:this.getValueFromHeaderOrDefault(a.headers,"x-forwarded-for")})}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[ce.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.config.netaceaCookieName)||e.value.includes(this.config.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.config.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.config.netaceaCookieName,t),i=await this.readCookie(this.config.netaceaCaptchaCookieName,t),s=G(e,this.config.ipHeaderName),o=this.getValueFromHeaderOrDefault(e.headers,"user-agent"),n=this.getValueFromHeaderOrDefault(e.headers,"accept","text/html"),r=this.getValueFromHeaderOrDefault(e.headers,"host"),{headerFingerprint:c}=await this.getFingerprints(e);return e.headers[ce.NetaceaHeaderFingerPrintHeader]=[{key:ce.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:n,host:r,mitata:a,mitataCaptcha:i,headerFingerprint:c}),request:e}}addNetaceaCookiesToRequest(e,t){if(void 0===t)return e;if(e.headers[ce.NetaceaCookieHeader]=[],void 0!==t.setCookie)for(const a of t.setCookie){const t=e.headers[ce.NetaceaCookieHeader]??[];t.push({key:ce.NetaceaCookieHeader,value:a}),e.headers[ce.NetaceaCookieHeader]=t}if(this.config.mitigationType===c.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.config.cookieEncryptionKey?await async function(e,t){const a=d.base64url.decode(t),i=(new TextEncoder).encode(e);return await new d.CompactEncrypt(i).setProtectedHeader({alg:"dir",enc:"A256GCM"}).encrypt(a)}(e,this.config.cookieEncryptionKey):e}async decryptCookieValue(e){return void 0!==this.config.cookieEncryptionKey?await j(e,this.config.cookieEncryptionKey):e}async runMitigation(e){const t={"x-netacea-captcha":"0","x-netacea-match":"0","x-netacea-mitigate":"0"};try{if(function(e,t){if(void 0===t)return!1;const a=e.uri;if(t.startsWith("/"))return t===a;try{const i=e.headers.host?.[0]?.value,s=new URL(t);return s.host===i&&s.pathname===a}catch{return!1}}(e,this.config.netaceaBlockedResponseRedirectLocation))return{injectHeaders:t,sessionStatus:""};switch(this.config.mitigationType){case c.MITIGATE:return await this.mitigate(e);case c.INJECT:return await this.inject(e);case c.INGEST:return await this.processIngest(e);default:throw new Error(`Netacea Error: Mitigation type ${this.config.mitigationType} not recognised`)}}catch(e){return console.error("Netacea FAILOPEN Error:",e),{injectHeaders:t,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.config.encryptedCookies.includes(e))try{return await this.decryptCookieValue(i)}catch(e){return}return i}}}async processMitigateRequest(e){const t=Y(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(Y(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.config.netaceaCaptchaCookieName)),s=void 0!==i;return this.config.mitigationType===c.INJECT&&s}async processCaptcha(e){const{status:t,match:a,mitigate:i,captcha:s,body:o,setCookie:n,latency:r}=await this.makeCaptchaAPICall(e);return this.composeResult(o,n,t,a,i,s,!0,r)}async makeCaptchaAPICall(e){const{netaceaCookie:t,clientIp:a,userAgent:i,headerFingerprint:s,captchaData:o}=e,n={"X-Netacea-API-Key":this.config.apiKey,"X-Netacea-Client-IP":a,"user-agent":i,"Content-Type":"application/x-www-form-urlencoded; charset=UTF-8"},r=I(t);void 0!==r&&(n["X-Netacea-UserId"]=r.userId),void 0!==this.config.captchaSiteKey&&void 0!==this.config.captchaSecretKey&&(n["X-Netacea-Captcha-Site-Key"]=this.config.captchaSiteKey,n["X-Netacea-Captcha-Secret-Key"]=this.config.captchaSecretKey);const c=new URLSearchParams;""!==s&&c.append("headerFP",s);const h=Date.now(),d=await this.makeRequest({host:this.config.mitigationServiceUrl,path:"/AtaVerifyCaptcha",headers:n,method:"POST",body:o,timeout:this.config.timeout,params:c}),u=Date.now()-h;return await this.getApiCallResponseFromResponse(d,r?.userId,a,u)}async getApiCallResponseFromResponse(e,t,a,i,s){if(200!==e.status)throw new ae(e,i);const o=Q(e.headers,ge.match)??s?.match??"0",n=Q(e.headers,ge.mitigate)??s?.mitigate??"0",r=Q(e.headers,ge.captcha)??s?.captcha??"0";let c=function(e,t){const a=Q(e,t);if(void 0!==a)return parseInt(a,36)}(e.headers,ge.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)),d=Q(e.headers,ge.eventId);return{status:e.status,match:o,mitigate:n,captcha:r,setCookie:h,body:e.body,eventId:d,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.config.mitataCookieExpirySeconds,c=n??Math.floor(Date.now()/1e3)+r;if(void 0===this.config.secretKey)throw new Error("Cannot build cookie without secret key.");const h=[a,i,s].join(""),d=function(e,t,a,i,s="000"){void 0===t&&(t=N());const o=[a,t,w(e+"|"+String(a),i),s].join(g);return`${w(o,i)}${g}${o}`}(e,t,c,this.config.secretKey,h);let u,p,l=o;if(""!==this.config.netaceaCookieAttributes){const{extractedAttribute:e,cookieAttributes:t}=de(this.config.netaceaCookieAttributes,"Max-Age");l=void 0!==e?Number(e):o;const{extractedAttribute:a,cookieAttributes:i}=de(t,"Path");u=a??"/",p=i??void 0}return await this.buildCookieFromValues(this.config.netaceaCookieName,d,l,p,u)}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=pe(a);i=e.value,s=he(e.attributes,"Max-Age")??"86400"}catch(e){return}if(""===i||void 0===i)return;const o=ue([this.config.netaceaCaptchaCookieAttributes,"Path=/",`Max-Age=${s}`]);return i=this.config.encryptedCookies.includes(this.config.netaceaCaptchaCookieName)?await this.encryptCookieValue(i):i,`${this.config.netaceaCaptchaCookieName}=${i}; ${o}`}async buildCookieFromValues(e,t,a,i,s="/"){const o=`${e}=${this.config.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=Z(e);if(this.config.ingestType===r.KINESIS){if(void 0===this.kinesis)return void console.error("Netacea Error: Unable to log as Kinesis has not been defined.");if(void 0!==this.config.kinesisConfigArgs){const{kinesisStreamName:e,kinesisAccessKey:t,kinesisSecretKey:a}=this.config.kinesisConfigArgs;if(void 0===e||void 0===t||void 0===a)return void console.error("Netacea Error: Unable to log as Kinesis configuration misses credentials.")}try{await this.kinesis.ingest({...t,apiKey:this.config.apiKey},this.makeRequest.bind(this))}catch(e){console.error("NETACEA Error: ",e.message)}}else{const e={"X-Netacea-API-Key":this.config.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.config.ingestServiceUrl,method:"POST",path:"/",headers:e,body:JSON.stringify(t),timeout:this.config.timeout})}async processIngest(e){if(void 0===this.config.secretKey)throw new Error("Secret key is required for ingest");const t=this.getCookieHeader(e),a=A(await this.readCookie(this.config.netaceaCookieName,t),C,this.config.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)]}}async check(e,t,a,i,s,o,n){let r,c,h,d,u,p,l,g;if(void 0===this.config.secretKey)throw new Error("Secret key is required to mitigate");const m=A(e,t,this.config.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,headerFingerprint:n});r=e.status,c=e.match,h=e.mitigate,d=e.captcha,u=e.body,g=e.latency,p=[await this.createMitata(t,m.mitata?.userId,c,h,d,e.mitataMaxAge)],l=e.eventId}else c=m.match,h=m.mitigate,d=m.captcha,u=void 0,p=[];return this.composeResult(u,p,r,c,h,d,!1,g,l)}async makeMitigateAPICall({userId:e,clientIP:t,userAgent:a,captchaCookie:i,accept:s,host:o,isCaptchaGet:n=!1,defaultMitataCodes:r,trackingId:c,headerFingerprint:h}){const d={"X-Netacea-API-Key":this.config.apiKey,"X-Netacea-Client-IP":t,"user-agent":a,cookie:this.buildCookieHeader({_mitatacaptcha:i})};void 0!==e&&(d["X-Netacea-UserId"]=e),void 0!==this.config.captchaSiteKey&&void 0!==this.config.captchaSecretKey&&(d["X-Netacea-Captcha-Site-Key"]=this.config.captchaSiteKey,d["X-Netacea-Captcha-Secret-Key"]=this.config.captchaSecretKey),this.config.dynamicCaptchaContentType&&void 0!==this.config.netaceaCaptchaPath&&(d["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"===d["X-Netacea-Captcha-Content-Type"],p=void 0!==c?`?trackingId=${c}`:"",l=new URLSearchParams;"string"==typeof h&&l.set("headerFP",h);const g=Date.now(),m=await this.makeRequest({host:this.config.mitigationServiceUrl,path:n?`/captcha${p}`:"/",headers:d,method:"GET",timeout:this.config.timeout,params:l}),f=Date.now()-g;return u&&void 0!==this.config.netaceaCaptchaPath&&(m.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})}(m.body,o,this.config.netaceaCaptchaPath)),await this.getApiCallResponseFromResponse(m,e,t,f,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,r,h){const d=te(this.config.mitigationType,i,s,o,n),u={body:e,apiCallStatus:a,apiCallLatency:r,setCookie:t,sessionStatus:d.sessionStatus,mitigation:d.mitigation,mitigated:[le.block,le.captcha,le.captchaPass].includes(d.mitigation)};if(this.config.mitigationType===c.INJECT){const e={"x-netacea-match":d.parts.match,"x-netacea-mitigate":d.parts.mitigate,"x-netacea-captcha":d.parts.captcha};void 0!==h&&(e["x-netacea-event-id"]=h),u.injectHeaders=e}return u}};
|
|
1
|
+
"use strict";var e=require("node:crypto"),t=require("node:buffer"),a=require("axios"),i=require("aws4"),s=require("jose"),o=require("uuid");function n(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 r,c,h,d=n(s),u=n(o);!function(e){e.ORIGIN="ORIGIN",e.HTTP="HTTP",e.KINESIS="KINESIS",e.NATIVE="NATIVE"}(r||(r={})),function(e){e.MITIGATE="MITIGATE",e.INJECT="INJECT",e.INGEST="INGEST"}(c||(c={})),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"}(h||(h={}));function p(e,t=0){return isNaN(e)?t:parseInt(e)}const l=3e3;const g="_/@#/",m={none:"",block:"block",captcha:"captcha",allow:"allow",captchaPass:"captchapass"},f={0:m.none,1:m.block,2:m.none,3:m.block,4:m.block},y={1:m.captcha,2:m.captchaPass,3:m.captcha,4:m.allow,5:m.captcha};var k=Object.freeze({__proto__:null,COOKIEDELIMITER:g,bestMitigationCaptchaMap:y,bestMitigationMap:f,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_",b:"headerFP_"},mitigateMap:{0:"",1:"blocked",2:"allow",3:"hardblocked",4:"block"},mitigationTypes:m,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",S="1234567890abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ".split(""),v=/^(.*)_\/@#\/(.*)_\/@#\/(.*)_\/@#\/(.*)_\/@#\/((\d|[a-z])(\d)(\d))$/i;function I(e){if(void 0===e)return;const t=e.match(v);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:n,mitigate:r,captcha:c}}}function N(t=16,a=S){const i=e.randomBytes(t-1);return`c${Array.from(i).map((e=>a[e%a.length])).join("")}`}function w(a,i){const s=e.createHmac("sha256",i);return s.update(a),t.Buffer.from(s.digest("hex")).toString("base64")}function A(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=I(e);if(void 0!==s){const e=[s.expiry,s.userId,s.ipHash,s.mitigationType].join(g),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=w(t+"|"+s.expiry,a),d=s.ipHash===h;return{mitata:s,requiresReissue:o||!d,isExpired:o,shouldExpire:c,isSameIP:d,isPrimaryHashValid:s.signature===w(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 T(e,t=!1){return"string"!=typeof e&&(e=e.join("; ")),""===e?"":b(e.split(";"),t).join("; ")}function b(e,t=!1){if(t)return b(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 R=Object.freeze({__proto__:null,configureCookiesDomain:function(e,t){let a=e=T(e??"",!0),i=t=T(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: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 K={cookie:{parse:x,attributes:R}};class P{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),n=Array.from(new Uint8Array(o)).map((e=>e.toString(16).padStart(2,"0"))).join("").substring(0,12);return"h"+(a?"s":"")+`_${t.length}_${n}`}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=P.filterHeaderNames(e);if(0===a.length)return"";try{return await this.hashString("SHA-256",a,t)}catch(e){return console.error(e),""}}}var H={},O={},M={},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(M,"__esModule",{value:!0}),M.signRequest=void 0;const _=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}M.signRequest=function(e,t,a){const{accessKeyId:i,secretAccessKey:s}=e,o={Records:q(t,a),PartitionKey:Date.now().toString(),StreamName:e.streamName};return _.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(O,"__esModule",{value:!0});const L=M;async function $(e){await new Promise((t=>{setTimeout(t,e)}))}O.default=class{constructor({kinesisStreamName:e,kinesisAccessKey:t,kinesisSecretKey:a,maxLogAgeSeconds:i,logBatchSize:s,rampUpBatchSize:o,maxAwaitTimePerIngestCallMs:n}){this.maxLogBatchSize=20,this.maxLogAgeSeconds=10,this.logBatchSize=20,this.logCache=[],this.intervalSet=!1,this.kinesisStreamName=e,this.kinesisAccessKey=t,this.kinesisSecretKey=a,this.maxAwaitTimePerIngestCallMs=n,void 0!==i&&i<this.maxLogAgeSeconds&&i>0&&(this.maxLogAgeSeconds=i),void 0!==s&&(this.maxLogBatchSize=s),this.logBatchSize=!0===o?1:this.maxLogBatchSize}async putToKinesis(e){if(0===this.logCache.length)return;const t=[...this.logCache];this.logCache=[];try{const a=(0,L.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}),this.logBatchSize!==this.maxLogBatchSize&&(this.logBatchSize=Math.min(this.maxLogBatchSize,2*this.logBatchSize))}catch(e){this.logCache.push(...t),console.error(e)}}async ingest(e,t){if(this.logCache.push(e),this.logCache.length>=this.logBatchSize){const e=[];e.push(this.putToKinesis(t)),void 0!==this.maxAwaitTimePerIngestCallMs&&e.push($(this.maxAwaitTimePerIngestCallMs)),await Promise.race(e)}else if(!this.intervalSet){this.intervalSet=!0;const e=$(1e3*this.maxLogAgeSeconds).then((async()=>{await this.putToKinesis(t),this.intervalSet=!1})).catch((()=>{}));void 0===this.maxAwaitTimePerIngestCallMs&&await e}}},Object.defineProperty(H,"__esModule",{value:!0});const U=O;var V=H.default=U.default;async function j(e,t){const a=d.base64url.decode(t),{plaintext:i}=await d.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 B(e,t){z(e,t.protectorApiResponse.status,t.latencyMs),e.headers["x-netacea-session-status"]=[{key:"x-netacea-session-status",value:"error_open"}]}function z(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 W(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 Y(e,t){return e.includes("/AtaVerifyCaptcha")&&"post"===t.toLowerCase()}function Q(e,t){const a=e[t];return"string"==typeof a?a:a?.[0]}function Z(e){return e.bytesSent=""===e.bytesSent?"0":e.bytesSent,function({bytesSent:e,headerFingerprint:t,integrationMode:a,integrationType:i,integrationVersion:s,ip:o,method:n,mitataCookie:r,mitigationLatency:c,mitigationStatus:h,netaceaCookieStatus:d,path:u,protocol:p,referer:l,requestHost:g,requestTime:m,sessionStatus:f,status:y,timeUnixMsUTC:k,userAgent:C,workerInstanceId:S,xForwardedFor:v}){const{request:I}=function(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}`:""}`}}(n,u,p);return{BytesSent:e?.toString(),HeaderHash:t,IntegrationType:i??"",IntegrationVersion:s??"",NetaceaMitigationApplied:f??"",NetaceaUserIdCookie:r??"",NetaceaUserIdCookieStatus:d,ProtectionMode:a,ProtectorLatencyMs:c,ProtectorStatus:h,RealIp:o,Referer:""===l?"-":l,Request:I,RequestHost:g,RequestTime:m?.toString(),Status:y,TimeLocal:new Date(k??Date.now()).toUTCString(),TimeUnixMsUTC:k??Date.now(),UserAgent:C,WorkerInstanceId:S,XForwardedFor:v}}(e)}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=k.matchMap[t]??ee+"_";o+=k.mitigateMap[a]??ee;let n=k.bestMitigationMap[a];if("0"!==i){o+=","+(k.captchaMap[i]??ee);const e=k.bestMitigationCaptchaMap[i];void 0!==e&&(n=e)}return e===c.INJECT&&(n=k.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=G(e,this.config.ipHeaderName),{sessionCookieDetails:n,sessionCookieStatus:r,sessionStatus:h,userId:d}=function(e,t,a,i,s){const o=A(i,s,e.secretKey);if(void 0!==o.userId&&o.isPrimaryHashValid){const i=o.userId,{isExpired:s,shouldExpire:n,isSameIP:r}=o,h=s||n||!r&&e.mitigationType!==c.INGEST?ie.RENEW_SESSION:ie.EXISTING_SESSION,{sessionStatus:d}=te(e.mitigationType,o.match,o.mitigate,o.captcha,Y(t,a));return{userId:i,sessionCookieStatus:h,sessionStatus:d,sessionCookieDetails:o}}return{sessionStatus:"",userId:N(),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:r,userId:d},fingerprints:{headerFingerprint:ne(e.headers,this.config.headerFingerprintHeaderName)}}}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 j(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{configureCookiesDomain:re}=K.cookie.attributes;class ce{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;mitataCookieExpirySeconds;apiKey;secretKey;mitigationServiceUrl="https://mitigations.netacea.net";ingestServiceUrl;timeout;captchaSiteKey;captchaSecretKey;ingestType;mitigationType;kinesisConfigArgs;encryptedCookies=[];netaceaCookieName;netaceaCaptchaCookieName;netaceaCookieAttributes;netaceaCaptchaCookieAttributes;netaceaBlockedResponseRedirectLocation;constructor(e){if(e.ingestType=r.KINESIS,this.kinesisConfigArgs=e.kinesis,void 0===e.kinesis&&(console.warn(['NETACEA :: Please move kinesis params to "kinesis" object in config.',"Backwards compatibility will soon be removed."].join(" ")),this.kinesisConfigArgs={kinesisStreamName:e.kinesisStreamName,kinesisAccessKey:e.kinesisAccessKey,kinesisSecretKey:e.kinesisSecretKey,maxLogAgeSeconds:1},void 0!==e.logBatchSize&&(this.kinesisConfigArgs.logBatchSize=e.logBatchSize)),null===e.apiKey||void 0===e.apiKey)throw new Error("apiKey is a required parameter");if(this.apiKey=e.apiKey,this.secretKey=e.secretKey,void 0!==e.mitigationServiceUrl){const t=e.mitigationServiceUrl;this.mitigationServiceUrl=t.endsWith("/")?t.slice(0,-1):t}var t;this.ingestServiceUrl=e.ingestServiceUrl??"https://ingest.netacea.net",this.mitigationType=e.mitigationType??c.INGEST,this.ingestType=e.ingestType??r.HTTP,void 0===e.captchaSiteKey&&void 0===e.captchaSecretKey||(this.captchaSiteKey=e.captchaSiteKey,this.captchaSecretKey=e.captchaSecretKey),this.timeout=(t=e.timeout??3e3)<=0?l:t,this.netaceaCookieName=e.netaceaCookieName??"_mitata",this.netaceaCaptchaCookieName=e.netaceaCaptchaCookieName??"_mitatacaptcha",this.netaceaCaptchaPath=e.netaceaCaptchaPath,this.dynamicCaptchaContentType=e.dynamicCaptchaContentType??!1;const a=re(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===c.INGEST?3600:60:s),this.ingestEnabled=e.ingestEnabled??!0,this.cookieEncryptionKey=e.cookieEncryptionKey,this.netaceaBlockedResponseRedirectLocation=e.netaceaBlockedResponseRedirectLocation}}const{extractCookieAttr:he,extractAndRemoveCookieAttr:de,removeDuplicateAttrs:ue}=K.cookie.attributes,pe=K.cookie.parse.parseSetCookie,{mitigationTypes:le,netaceaHeaders:ge}=k;exports.Cloudfront=class{config;kinesis;requestAnalyser;workerInstanceId;hashGenerator;constructor(t){this.config=new ce(t),this.config.ingestType===r.KINESIS&&(void 0===this.config.kinesisConfigArgs?console.warn(`NETACEA WARN: no kinesis args provided, when ingestType is ${this.config.ingestType}`):this.kinesis=new V({...this.config.kinesisConfigArgs,apiKey:this.config.apiKey,rampUpBatchSize:!0,maxAwaitTimePerIngestCallMs:0})),this.requestAnalyser=new se({cookieEncryptionKey:this.config.cookieEncryptionKey,encryptedCookies:this.config.encryptedCookies,mitigationType:this.config.mitigationType,secretKey:this.config.secretKey,sessionCookieName:this.config.netaceaCookieName,captchaCookieName:this.config.netaceaCaptchaCookieName,ipHeaderName:this.config.ipHeaderName,headerFingerprintHeaderName:ce.NetaceaHeaderFingerPrintHeader}),this.workerInstanceId=u.v4(),this.hashGenerator=new P(e)}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.config.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=G(e,r),d=e.headers["user-agent"]?.[0].value??"",u=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:g}=e,m=await W(o,g,s),f=await W(n,g,s),{userId:y}=I(m)??{},k=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"},d=await r({userId:e,clientIP:t,userAgent:a,captchaCookie:n,accept:s,host:o,isCaptchaGet:!0,defaultMitataCodes:h,trackingId:i});return c(d.body,d.setCookie,d.status,d.match,d.mitigate,d.captcha,!0,d.latency??0)}({userId:y,clientIp:h,userAgent:d,captchaCookie:f,accept:u,host:p,trackingId:l,mitigationCallFn:a,composeResultFn:i});return z(e,k.apiCallStatus,k.apiCallLatency),{headers:J(k.setCookie),status:"403",body:k.body,statusDescription:"Forbidden"}}({request:t,secretKey:this.config.secretKey,mitigationCallFn:this.makeMitigateAPICall.bind(this),composeResultFn:this.composeResult.bind(this),cookieEncryptionKey:this.config.cookieEncryptionKey,netaceaCookieName:this.config.netaceaCookieName,netaceaCaptchaCookieName:this.config.netaceaCaptchaCookieName,ipHeaderName:this.config.ipHeaderName});return await this.ingest(e,a),{respondWith:a}}const s=await this.runMitigation(t);return this.addNetaceaCookiesToRequest(t,s),t.headers[ce.NetaceaTrueUserAgentHeader]=[{key:ce.NetaceaTrueUserAgentHeader,value:this.getValueFromHeaderOrDefault(t.headers,"user-agent","-")}],void 0!==s&&this.config.ingestType===r.KINESIS&&z(t,s.apiCallStatus,s.apiCallLatency),{respondWith:s?.response}}catch(e){return console.error("Netacea FailOpen - ",e.message),void 0!==t&&e instanceof ae&&B(t,e),{}}}async makeRequest({host:e,path:t,method:i,body:s,headers:o,timeout:n,params:r}){const c=`${e}${t}`,h=await a.request({url:c,data:s,headers:o,method:i,timeout:n,params:r,transformResponse:e=>e});return{headers:h.headers,status:h.status,body:h.data}}async getFingerprints(e){const t=this.getValueFromHeaderOrDefault(e.headers,ce.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 o={"set-cookie":[]};for(const e of a.setCookie)o["set-cookie"]=o["set-cookie"]??[],o["set-cookie"].push({key:"set-cookie",value:e});const n="captcha"===a.mitigation;n&&void 0!==this.config.captchaHeader&&(o[this.config.captchaHeader.name]=[{key:this.config.captchaHeader.name,value:this.config.captchaHeader.value}]);s={headers:o,...Y(i.uri,i.method)?{status:"200",statusDescription:"OK",body:""}:{status:"403",statusDescription:"Forbidden",body:"Forbidden"}},void 0!==this.config.netaceaBlockedResponseRedirectLocation&&!n&&function(e){if("GET"!==e.method?.toUpperCase())return!1;const t=(e.headers["sec-fetch-mode"]??[]).map((e=>e.value));return!(t.length>0&&!t.includes("navigate"))&&(e.headers.accept??[]).map((e=>e.value.split(/, ?/))).flat().includes("text/html")}(e)&&(s.status="303",o.Location=[{key:"Location",value:this.config.netaceaBlockedResponseRedirectLocation}]);let c=0;if(n&&void 0!==a.body&&a.body.length>0){c=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 h={status:s.status,statusDescription:s.statusDescription??"",headers:{"content-length":[{key:"content-length",value:c.toString()}],"set-cookie":a.setCookie.map((e=>({key:"set-cookie",value:e})))}};this.config.ingestType===r.KINESIS&&z(i,a.apiCallStatus,a.apiCallLatency),await this.ingest(i,h)}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&&B(e,t),Y(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.config.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.config.netaceaCookieName,s)??"";if(void 0===o||""===o){const e=this.getMitataValueFromHeaderOrDefault(a.headers,"cookie");o=await this.readCookie(this.config.netaceaCookieName,e)??""}let n="0",r="0",c="0";const h=I(o);void 0!==h&&(n=h.match,r=h.mitigate,c=h.captcha);const{sessionStatus:d,mitigationLatency:u,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),g=this.shouldSetCaptchaPass(a,t),m=await this.requestAnalyser.getNetaceaRequestDetails(a),{sessionStatus:f}=te(this.config.mitigationType,n,r,c,g),y=this.getValueFromHeaderOrDefault(a.headers,ce.NetaceaTrueUserAgentHeader,m.userAgent);await this.callIngest({bytesSent:this.getValueFromHeaderOrDefault(t.headers,"content-length","0"),headerFingerprint:m.fingerprints.headerFingerprint,integrationMode:this.config.mitigationType,integrationType:"@netacea/cloudfront".replace("@netacea/",""),integrationVersion:"6.0.53",ip:m.clientIp,method:m.method,mitataCookie:o,mitigationLatency:void 0!==u?p(u):void 0,mitigationStatus:void 0!==l?p(l):void 0,netaceaCookieStatus:m.sessionDetails.sessionCookieStatus,path:m.url,protocol:null,referer:this.getValueFromHeaderOrDefault(a.headers,"referer"),requestHost:this.getValueFromHeaderOrDefault(a.headers,"host",void 0),requestTime:"0",sessionStatus:d??f,status:t.status,userAgent:y,workerInstanceId:this.workerInstanceId,xForwardedFor:this.getValueFromHeaderOrDefault(a.headers,"x-forwarded-for")})}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[ce.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.config.netaceaCookieName)||e.value.includes(this.config.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.config.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.config.netaceaCookieName,t),i=await this.readCookie(this.config.netaceaCaptchaCookieName,t),s=G(e,this.config.ipHeaderName),o=this.getValueFromHeaderOrDefault(e.headers,"user-agent"),n=this.getValueFromHeaderOrDefault(e.headers,"accept","text/html"),r=this.getValueFromHeaderOrDefault(e.headers,"host"),{headerFingerprint:c}=await this.getFingerprints(e);return e.headers[ce.NetaceaHeaderFingerPrintHeader]=[{key:ce.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:n,host:r,mitata:a,mitataCaptcha:i,headerFingerprint:c}),request:e}}addNetaceaCookiesToRequest(e,t){if(void 0===t)return e;if(e.headers[ce.NetaceaCookieHeader]=[],void 0!==t.setCookie)for(const a of t.setCookie){const t=e.headers[ce.NetaceaCookieHeader]??[];t.push({key:ce.NetaceaCookieHeader,value:a}),e.headers[ce.NetaceaCookieHeader]=t}if(this.config.mitigationType===c.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.config.cookieEncryptionKey?await async function(e,t){const a=d.base64url.decode(t),i=(new TextEncoder).encode(e);return await new d.CompactEncrypt(i).setProtectedHeader({alg:"dir",enc:"A256GCM"}).encrypt(a)}(e,this.config.cookieEncryptionKey):e}async decryptCookieValue(e){return void 0!==this.config.cookieEncryptionKey?await j(e,this.config.cookieEncryptionKey):e}async runMitigation(e){const t={"x-netacea-captcha":"0","x-netacea-match":"0","x-netacea-mitigate":"0"};try{if(function(e,t){if(void 0===t)return!1;const a=e.uri;if(t.startsWith("/"))return t===a;try{const i=e.headers.host?.[0]?.value,s=new URL(t);return s.host===i&&s.pathname===a}catch{return!1}}(e,this.config.netaceaBlockedResponseRedirectLocation))return{injectHeaders:t,sessionStatus:""};switch(this.config.mitigationType){case c.MITIGATE:return await this.mitigate(e);case c.INJECT:return await this.inject(e);case c.INGEST:return await this.processIngest(e);default:throw new Error(`Netacea Error: Mitigation type ${this.config.mitigationType} not recognised`)}}catch(e){return console.error("Netacea FAILOPEN Error:",e),{injectHeaders:t,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.config.encryptedCookies.includes(e))try{return await this.decryptCookieValue(i)}catch(e){return}return i}}}async processMitigateRequest(e){const t=Y(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(Y(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.config.netaceaCaptchaCookieName)),s=void 0!==i;return this.config.mitigationType===c.INJECT&&s}async processCaptcha(e){const{status:t,match:a,mitigate:i,captcha:s,body:o,setCookie:n,latency:r}=await this.makeCaptchaAPICall(e);return this.composeResult(o,n,t,a,i,s,!0,r)}async makeCaptchaAPICall(e){const{netaceaCookie:t,clientIp:a,userAgent:i,headerFingerprint:s,captchaData:o}=e,n={"X-Netacea-API-Key":this.config.apiKey,"X-Netacea-Client-IP":a,"user-agent":i,"Content-Type":"application/x-www-form-urlencoded; charset=UTF-8"},r=I(t);void 0!==r&&(n["X-Netacea-UserId"]=r.userId),void 0!==this.config.captchaSiteKey&&void 0!==this.config.captchaSecretKey&&(n["X-Netacea-Captcha-Site-Key"]=this.config.captchaSiteKey,n["X-Netacea-Captcha-Secret-Key"]=this.config.captchaSecretKey);const c=new URLSearchParams;""!==s&&c.append("headerFP",s);const h=Date.now(),d=await this.makeRequest({host:this.config.mitigationServiceUrl,path:"/AtaVerifyCaptcha",headers:n,method:"POST",body:o,timeout:this.config.timeout,params:c}),u=Date.now()-h;return await this.getApiCallResponseFromResponse(d,r?.userId,a,u)}async getApiCallResponseFromResponse(e,t,a,i,s){if(200!==e.status)throw new ae(e,i);const o=Q(e.headers,ge.match)??s?.match??"0",n=Q(e.headers,ge.mitigate)??s?.mitigate??"0",r=Q(e.headers,ge.captcha)??s?.captcha??"0";let c=function(e,t){const a=Q(e,t);if(void 0!==a)return parseInt(a,36)}(e.headers,ge.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)),d=Q(e.headers,ge.eventId);return{status:e.status,match:o,mitigate:n,captcha:r,setCookie:h,body:e.body,eventId:d,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.config.mitataCookieExpirySeconds,c=n??Math.floor(Date.now()/1e3)+r;if(void 0===this.config.secretKey)throw new Error("Cannot build cookie without secret key.");const h=[a,i,s].join(""),d=function(e,t,a,i,s="000"){void 0===t&&(t=N());const o=[a,t,w(e+"|"+String(a),i),s].join(g);return`${w(o,i)}${g}${o}`}(e,t,c,this.config.secretKey,h);let u,p,l=o;if(""!==this.config.netaceaCookieAttributes){const{extractedAttribute:e,cookieAttributes:t}=de(this.config.netaceaCookieAttributes,"Max-Age");l=void 0!==e?Number(e):o;const{extractedAttribute:a,cookieAttributes:i}=de(t,"Path");u=a??"/",p=i??void 0}return await this.buildCookieFromValues(this.config.netaceaCookieName,d,l,p,u)}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=pe(a);i=e.value,s=he(e.attributes,"Max-Age")??"86400"}catch(e){return}if(""===i||void 0===i)return;const o=ue([this.config.netaceaCaptchaCookieAttributes,"Path=/",`Max-Age=${s}`]);return i=this.config.encryptedCookies.includes(this.config.netaceaCaptchaCookieName)?await this.encryptCookieValue(i):i,`${this.config.netaceaCaptchaCookieName}=${i}; ${o}`}async buildCookieFromValues(e,t,a,i,s="/"){const o=`${e}=${this.config.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=Z(e);if(this.config.ingestType===r.KINESIS){if(void 0===this.kinesis)return void console.error("Netacea Error: Unable to log as Kinesis has not been defined.");if(void 0!==this.config.kinesisConfigArgs){const{kinesisStreamName:e,kinesisAccessKey:t,kinesisSecretKey:a}=this.config.kinesisConfigArgs;if(void 0===e||void 0===t||void 0===a)return void console.error("Netacea Error: Unable to log as Kinesis configuration misses credentials.")}try{await this.kinesis.ingest({...t,apiKey:this.config.apiKey},this.makeRequest.bind(this))}catch(e){console.error("NETACEA Error: ",e.message)}}else{const e={"X-Netacea-API-Key":this.config.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.config.ingestServiceUrl,method:"POST",path:"/",headers:e,body:JSON.stringify(t),timeout:this.config.timeout})}async processIngest(e){if(void 0===this.config.secretKey)throw new Error("Secret key is required for ingest");const t=this.getCookieHeader(e),a=A(await this.readCookie(this.config.netaceaCookieName,t),C,this.config.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)]}}async check(e,t,a,i,s,o,n){let r,c,h,d,u,p,l,g;if(void 0===this.config.secretKey)throw new Error("Secret key is required to mitigate");const m=A(e,t,this.config.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,headerFingerprint:n});r=e.status,c=e.match,h=e.mitigate,d=e.captcha,u=e.body,g=e.latency,p=[await this.createMitata(t,m.mitata?.userId,c,h,d,e.mitataMaxAge)],l=e.eventId}else c=m.match,h=m.mitigate,d=m.captcha,u=void 0,p=[];return this.composeResult(u,p,r,c,h,d,!1,g,l)}async makeMitigateAPICall({userId:e,clientIP:t,userAgent:a,captchaCookie:i,accept:s,host:o,isCaptchaGet:n=!1,defaultMitataCodes:r,trackingId:c,headerFingerprint:h}){const d={"X-Netacea-API-Key":this.config.apiKey,"X-Netacea-Client-IP":t,"user-agent":a,cookie:this.buildCookieHeader({_mitatacaptcha:i})};void 0!==e&&(d["X-Netacea-UserId"]=e),void 0!==this.config.captchaSiteKey&&void 0!==this.config.captchaSecretKey&&(d["X-Netacea-Captcha-Site-Key"]=this.config.captchaSiteKey,d["X-Netacea-Captcha-Secret-Key"]=this.config.captchaSecretKey),this.config.dynamicCaptchaContentType&&void 0!==this.config.netaceaCaptchaPath&&(d["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"===d["X-Netacea-Captcha-Content-Type"],p=void 0!==c?`?trackingId=${c}`:"",l=new URLSearchParams;"string"==typeof h&&l.set("headerFP",h);const g=Date.now(),m=await this.makeRequest({host:this.config.mitigationServiceUrl,path:n?`/captcha${p}`:"/",headers:d,method:"GET",timeout:this.config.timeout,params:l}),f=Date.now()-g;return u&&void 0!==this.config.netaceaCaptchaPath&&(m.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})}(m.body,o,this.config.netaceaCaptchaPath)),await this.getApiCallResponseFromResponse(m,e,t,f,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,r,h){const d=te(this.config.mitigationType,i,s,o,n),u={body:e,apiCallStatus:a,apiCallLatency:r,setCookie:t,sessionStatus:d.sessionStatus,mitigation:d.mitigation,mitigated:[le.block,le.captcha,le.captchaPass].includes(d.mitigation)};if(this.config.mitigationType===c.INJECT){const e={"x-netacea-match":d.parts.match,"x-netacea-mitigate":d.parts.mitigate,"x-netacea-captcha":d.parts.captcha};void 0!==h&&(e["x-netacea-event-id"]=h),u.injectHeaders=e}return u}};
|
|
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.53",
|
|
4
4
|
"description": "Netacea Cloudfront CDN integration",
|
|
5
5
|
"files": [
|
|
6
6
|
"dist/index.js",
|
|
@@ -24,5 +24,5 @@
|
|
|
24
24
|
"jose": "^4.11.2",
|
|
25
25
|
"uuid": "^10.0.0"
|
|
26
26
|
},
|
|
27
|
-
"gitHead": "
|
|
27
|
+
"gitHead": "cc38a62fa00d0e70ee0a08d15bf5ca93ce678ef7"
|
|
28
28
|
}
|