unshared-clientjs-sdk 2.0.0-rc.23 → 2.0.0-rc.24
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.
|
@@ -1 +1 @@
|
|
|
1
|
-
import{isBot}from"../utils/is-bot";import{extractClientIp}from"../utils/client-ip";import{parseCookie}from"../utils/cookies";import{extractDeviceId}from"../utils/device-id";import{isSecureRequest}from"../utils/secure";import{isSentinelUserId}from"../utils/sentinel-user-id";import{sendJson}from"../utils/http-helpers";export function handleSubmitFingerprint(e){return async(i,s)=>{try{const t=i.body??{},n={full_hash:t.hash??"",fingerprint_id:t.stable_hash??"",timestamp:t.collected_at??(new Date).toISOString(),isIncognito:t.is_incognito??!1,components:t.components??{},version:t.version??"inline-1.0.0"};let o,r,d;try{const s=e.resolveUserId?e.resolveUserId(i):void 0;s&&!isSentinelUserId(s)&&(o=s)}catch{}if(!o){const e="string"==typeof t.user_id?t.user_id:void 0;e&&!isSentinelUserId(e)&&(o=e)}if(!o){const e=parseCookie(i,"__unshared_uid");e&&!isSentinelUserId(e)&&(o=e)}try{r=e.resolveEmailAddress?e.resolveEmailAddress(i):void 0}catch{}r=r??parseCookie(i,"__unshared_email")??t.email??void 0;try{d=e.resolveSessionId?e.resolveSessionId(i):void 0}catch{}d=d??t.session_id??parseCookie(i,"__unshared_sid");const a=extractClientIp(i),c=i.headers["user-agent"]??"";if(isBot(c))return void sendJson(s,200,{success:!0});const p=(n.fingerprint_id&&n.fingerprint_id.length>0?n.fingerprint_id:void 0)??extractDeviceId(i,e.resolveDeviceId),u=n.fingerprint_id||void 0,l=isSecureRequest(i)?"; Secure":"",
|
|
1
|
+
import{isBot}from"../utils/is-bot";import{extractClientIp}from"../utils/client-ip";import{parseCookie}from"../utils/cookies";import{extractDeviceId}from"../utils/device-id";import{isSecureRequest}from"../utils/secure";import{isSentinelUserId}from"../utils/sentinel-user-id";import{sendJson}from"../utils/http-helpers";export function handleSubmitFingerprint(e){return async(i,s)=>{try{const t=i.body??{},n={full_hash:t.hash??"",fingerprint_id:t.stable_hash??"",timestamp:t.collected_at??(new Date).toISOString(),isIncognito:t.is_incognito??!1,components:t.components??{},version:t.version??"inline-1.0.0"};let o,r,d;try{const s=e.resolveUserId?e.resolveUserId(i):void 0;s&&!isSentinelUserId(s)&&(o=s)}catch{}if(!o){const e="string"==typeof t.user_id?t.user_id:void 0;e&&!isSentinelUserId(e)&&(o=e)}if(!o){const e=parseCookie(i,"__unshared_uid");e&&!isSentinelUserId(e)&&(o=e)}try{r=e.resolveEmailAddress?e.resolveEmailAddress(i):void 0}catch{}r=r??parseCookie(i,"__unshared_email")??t.email??void 0;try{d=e.resolveSessionId?e.resolveSessionId(i):void 0}catch{}d=d??t.session_id??parseCookie(i,"__unshared_sid");const a=extractClientIp(i),c=i.headers["user-agent"]??"";if(isBot(c))return void sendJson(s,200,{success:!0});const p=(n.fingerprint_id&&n.fingerprint_id.length>0?n.fingerprint_id:void 0)??extractDeviceId(i,e.resolveDeviceId),u=n.fingerprint_id||void 0,l=n.full_hash||void 0,m=isSecureRequest(i)?"; Secure":"",_=[];if(l&&!parseCookie(i,"__unshared_fingerprint_id")&&_.push(`__unshared_fingerprint_id=${encodeURIComponent(l)}; HttpOnly; Path=/; SameSite=Lax${m}`),u){const e=parseCookie(i,"__unshared_fp_id");e&&e===u||_.push(`__unshared_fp_id=${encodeURIComponent(u)}; Path=/; SameSite=Lax; Max-Age=31536000${m}`)}if(r&&!parseCookie(i,"__unshared_email")&&_.push(`__unshared_email=${encodeURIComponent(r)}; HttpOnly; Path=/; SameSite=Lax${m}`),_.length>0){const e=s.getHeader("Set-Cookie");if(e){const i=Array.isArray(e)?[...e]:[String(e)];i.push(..._),s.setHeader("Set-Cookie",i)}else s.setHeader("Set-Cookie",_)}let f;if("string"==typeof t.event_type&&t.event_type)f=t.event_type;else{const e=i.headers.referer??i.headers.referrer;let s="unknown";if("string"==typeof e&&e.length>0)try{const i=new URL(e);s=(i.pathname||"/")+(i.search||"")}catch{}f=s}const h=i.headers["x-idempotency-key"],v=("string"==typeof h&&h.length>0?h:void 0)??(u&&o?`${u}|${o}|${f}`:void 0);if(o&&e.client.submitFingerprintEvent(n,{userId:o,emailAddress:r,sessionHash:d,eventType:f,ipAddress:a,userAgent:c,idempotencyKey:v}).catch(i=>{e.onError&&e.onError(i,{operation:"submitFingerprintEvent",userId:o,emailAddress:r})}),o&&r&&!e.rateLimitBackoff.isPaused()&&!e.dispatchDedupe.wasRecentlyDispatched(o,f)){e.dispatchDedupe.mark(o,f);try{const i=await e.client.processUserEvent({eventType:f,userId:o,emailAddress:r,ipAddress:a,deviceId:p,fingerprintId:u,sessionHash:d??"unknown",userAgent:c});i.success&&i.data?.analysis&&e.verdictCache.update(o,{isFlagged:i.data.analysis.is_user_flagged}),!i.success&&i.error?.retryAfter&&e.rateLimitBackoff.pause(1e3*i.error.retryAfter)}catch(i){e.onError&&e.onError(i,{operation:"processUserEvent",userId:o,emailAddress:r})}}sendJson(s,200,{success:!0})}catch{sendJson(s,200,{success:!0})}}}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{VerdictCache}from"../middleware/verdict-cache";import{RateLimitBackoff}from"../middleware/rate-limit-backoff";import{DispatchDedupe}from"../middleware/dispatch-dedupe";import{generateFingerprintScript}from"../middleware/injection/fingerprint-script";import{isHtmlContentType}from"../middleware/utils/content-type";import{shouldSkipPath}from"../middleware/utils/skip-paths";import{shouldIncludePath}from"../middleware/utils/include-path";import{isBot}from"../middleware/utils/is-bot";import{isSentinelUserId,SENTINEL_STICKINESS_TTL_MS}from"../middleware/utils/sentinel-user-id";import{parseCookieFromRequest,extractClientIpFromRequest,extractDeviceIdFromRequest,extractDeviceIdFromRequestOrUnknown,isSecureWebRequest,jsonResponse,emptyResponse,bodyResponse,mergeResponseHeaders}from"./web-helpers";const CHECK_USER_TIMEOUT_MS=500;export function createWebProtectionMiddleware(e,s){if(!s.userId)throw new Error("[Unshared] userId resolver is required");const{userId:t,emailAddress:r,routePrefix:n="/__unshared",corsOrigins:i,cacheTTL:o=6e4,skipPaths:a,includePathPrefix:d,sessionId:c,deviceId:u,fingerprintSdkBundle:l="",onFlagged:p,onError:m}=s,f=new VerdictCache(o),h=new RateLimitBackoff,_=new DispatchDedupe,R=Date.now().toString(36),I=generateFingerprintScript(n,R),g=`${n}/fp.js`,v=`${n}/submit-fp`,S=`${n}/verify-trigger`,y=`${n}/verify`,C=`${n}/status`,w=i?Array.isArray(i)?i:[i]:null;return async function(s,i){let o,R,A;try{const e=new URL(s.url);o=e.pathname,R=e.search}catch{return i(s)}if(o.startsWith(n+"/")){const n=function(e){if(!w)return{};const s=e.headers.get("origin")??"",t=w.includes("*");return t||w.includes(s)?{"Access-Control-Allow-Origin":t?"*":s,"Access-Control-Allow-Methods":"POST, OPTIONS","Access-Control-Allow-Headers":"Content-Type, X-Idempotency-Key, X-Session-Id, X-Device-Id","Access-Control-Allow-Credentials":"true"}:{}}(s);if("OPTIONS"===s.method)return emptyResponse(204,n);if("GET"===s.method&&o===g)return l?bodyResponse(200,l,{...n,"Content-Type":"application/javascript","Cache-Control":"public, max-age=3600"}):jsonResponse(404,{success:!1,error:{code:"NOT_FOUND",message:"Fingerprint SDK bundle not configured. Pass fingerprintSdkBundle in config."}},n);if("POST"===s.method&&(o===v||o===S||o===y)){let i;try{i=await s.json()}catch{return jsonResponse(400,{success:!1,error:{code:"BODY_PARSER_MISSING",message:"Request body is not valid JSON."}},n)}return o===v?handleSubmitFp(s,i,{client:e,verdictCache:f,rateLimitBackoff:h,dispatchDedupe:_,resolveUserId:t,resolveEmailAddress:r,resolveSessionId:c,resolveDeviceId:u,onError:m},n):o===S?handleVerifyTriggerWeb(s,i,{client:e,verdictCache:f,resolveEmailAddress:r,resolveDeviceId:u,onError:m},n):handleVerifyWeb(s,i,{client:e,verdictCache:f,resolveEmailAddress:r,resolveDeviceId:u,onError:m},n)}if("GET"===s.method&&o===C){let e;try{e=t(s)}catch{}if(!e)return jsonResponse(200,{status:"anonymous"},n);const i=resolveEmail(s,r),o=f.get(e);return o&&o.isFlagged&&!o.isVerified&&p&&i?jsonResponse(403,{error:"account_flagged",email:i},n):jsonResponse(200,{status:"ok"},n)}return jsonResponse(404,{success:!1,error:{code:"NOT_FOUND",message:"Unknown route"}},n)}if(shouldSkipPath(o,a))return i(s);if(!shouldIncludePath(o,d))return injectIntoHtmlResponse(await i(s),I);try{A=t(s)}catch{}if(isSentinelUserId(A)){const e=parseCookieFromRequest(s,"__unshared_uid"),t=parseCookieFromRequest(s,"__unshared_uid_at"),r=t?Number(t):NaN,n=Number.isFinite(r)&&Date.now()-r<=SENTINEL_STICKINESS_TTL_MS;A=e&&n?e:void 0}if(!A){const e=isSecureWebRequest(s)?"; Secure":"",t=[`__unshared_uid=; Path=/; SameSite=Lax; Max-Age=0${e}`,`__unshared_uid_at=; Path=/; SameSite=Lax; Max-Age=0${e}`,`__unshared_sid=; Path=/; SameSite=Lax; Max-Age=0${e}`,`__unshared_email=; Path=/; SameSite=Lax; Max-Age=0${e}`];return injectIntoHtmlResponse(await i(s),I,t)}const E=resolveEmail(s,r),F=[],T=isSecureWebRequest(s)?"; Secure":"";if(F.push(`__unshared_uid=${encodeURIComponent(A)}; Path=/; SameSite=Lax${T}`),F.push(`__unshared_uid_at=${Date.now()}; Path=/; SameSite=Lax${T}`),E&&F.push(`__unshared_email=${encodeURIComponent(E)}; HttpOnly; Path=/; SameSite=Lax${T}`),!E)return injectIntoHtmlResponse(await i(s),I,F);const k=extractSessionIdFromRequest(s,c),q=extractDeviceIdFromRequest(s,u),x=parseCookieFromRequest(s,"__unshared_fingerprint_id")||void 0,j=s.headers.get("user-agent")??"",O=extractClientIpFromRequest(s);if(isBot(j))return i(s);if("unknown"===k)return injectIntoHtmlResponse(await i(s),I,F);const L=q??x;if(!L)return injectIntoHtmlResponse(await i(s),I,F);h.isPaused()||dispatchUserEvent(e,f,h,_,{userId:A,emailAddress:E,sessionId:k,deviceId:L,fingerprintId:x,userAgent:j,ipAddress:O,eventType:o+R},m);let U=f.get(A);if(U)f.isStale(A)&&!f.isRefreshing(A)&&(f.markRefreshing(A),fetchAndCacheVerdict(e,f,A,E,L,x,k).finally(()=>f.clearRefreshing(A)));else try{U=await fetchAndCacheVerdict(e,f,A,E,L,x,k)}catch{return injectIntoHtmlResponse(await i(s),I,F)}if(U.isFlagged&&!U.isVerified&&p)try{const e=await p({userId:A,emailAddress:E,verdict:U,request:s});if(e)return injectIntoHtmlResponse(e,I,F)}catch(e){m&&m(e,{operation:"checkUser",userId:A,emailAddress:E})}return injectIntoHtmlResponse(await i(s),I,F)}}async function injectIntoHtmlResponse(e,s,t){const r=e.headers.get("content-type");if(!isHtmlContentType(r??void 0)){if(!t||0===t.length)return e;const s=mergeResponseHeaders(e.headers,void 0,t);return new Response(e.body,{status:e.status,statusText:e.statusText,headers:s})}const n=await e.text(),i=n.lastIndexOf("</body>"),o=-1===i?n+s:n.slice(0,i)+s+n.slice(i),a=mergeResponseHeaders(e.headers,{"Cache-Control":"no-store","Content-Length":String((new TextEncoder).encode(o).length)},t);return a.delete("ETag"),a.delete("Last-Modified"),a.delete("Content-Encoding"),new Response(o,{status:e.status,statusText:e.statusText,headers:a})}function resolveEmail(e,s){if(s)try{const t=s(e);if(t)return t}catch{}const t=parseCookieFromRequest(e,"__unshared_email");if(t)return t}function resolveEmailWithBody(e,s,t){const r=resolveEmail(e,t);if(r)return r;const n=s.email;return"string"==typeof n&&n?n:void 0}function extractSessionIdFromRequest(e,s){if(s)try{const t=s(e);if(t)return t}catch{}return parseCookieFromRequest(e,"__unshared_sid")??"unknown"}function dispatchUserEvent(e,s,t,r,n,i){r.mark(n.userId,n.eventType),e.processUserEvent({eventType:n.eventType,userId:n.userId,emailAddress:n.emailAddress,ipAddress:n.ipAddress,deviceId:n.deviceId,fingerprintId:n.fingerprintId,sessionHash:n.sessionId,userAgent:n.userAgent}).then(e=>{e.success&&e.data?.analysis&&s.update(n.userId,{isFlagged:e.data.analysis.is_user_flagged}),!e.success&&e.error?.retryAfter&&t.pause(1e3*e.error.retryAfter)}).catch(e=>{i&&i(e,{operation:"processUserEvent",userId:n.userId,emailAddress:n.emailAddress})})}async function fetchAndCacheVerdict(e,s,t,r,n,i,o){const a={};let d;n&&"unknown"!==n&&(a.deviceId=n),i&&(a.fingerprintId=i);const c=await Promise.race([e.checkUser(r,a),new Promise(e=>{d=setTimeout(()=>e(null),500)})]);if(clearTimeout(d),!c)return{isFlagged:!1,isVerified:!1,emailAddress:r,sessionId:o,cachedAt:0,ttl:0};const u=c.data?.is_user_flagged??!1;return s.set(t,{isFlagged:u,isVerified:!1,emailAddress:r,sessionId:o}),s.get(t)}async function handleSubmitFp(e,s,t,r){try{const n={full_hash:s.hash??"",fingerprint_id:s.stable_hash??"",timestamp:s.collected_at??(new Date).toISOString(),isIncognito:s.is_incognito??!1,components:s.components??{},version:s.version??"inline-1.0.0"};let i,o,a;try{const s=t.resolveUserId(e);s&&!isSentinelUserId(s)&&(i=s)}catch{}if(!i){const e="string"==typeof s.user_id?s.user_id:void 0;e&&!isSentinelUserId(e)&&(i=e)}if(!i){const s=parseCookieFromRequest(e,"__unshared_uid");s&&!isSentinelUserId(s)&&(i=s)}try{o=t.resolveEmailAddress?t.resolveEmailAddress(e):void 0}catch{}o=o??parseCookieFromRequest(e,"__unshared_email")??s.email??void 0;try{a=t.resolveSessionId?t.resolveSessionId(e):void 0}catch{}a=a??s.session_id??parseCookieFromRequest(e,"__unshared_sid");const d=extractClientIpFromRequest(e),c=e.headers.get("user-agent")??"";if(isBot(c))return jsonResponse(200,{success:!0},r);const u=(n.fingerprint_id&&n.fingerprint_id.length>0?n.fingerprint_id:void 0)??extractDeviceIdFromRequestOrUnknown(e,t.resolveDeviceId),l=n.fingerprint_id||void 0,p=isSecureWebRequest(e)?"; Secure":"",m=[];if(l&&!parseCookieFromRequest(e,"__unshared_fingerprint_id")&&m.push(`__unshared_fingerprint_id=${encodeURIComponent(l)}; HttpOnly; Path=/; SameSite=Lax${p}`),l){const s=parseCookieFromRequest(e,"__unshared_fp_id");s&&s===l||m.push(`__unshared_fp_id=${encodeURIComponent(l)}; Path=/; SameSite=Lax; Max-Age=31536000${p}`)}let f;if(o&&!parseCookieFromRequest(e,"__unshared_email")&&m.push(`__unshared_email=${encodeURIComponent(o)}; HttpOnly; Path=/; SameSite=Lax${p}`),"string"==typeof s.event_type&&s.event_type)f=s.event_type;else{const s=e.headers.get("referer")??e.headers.get("referrer");let t="unknown";if(s)try{const e=new URL(s);t=(e.pathname||"/")+(e.search||"")}catch{}f=t}const h=(e.headers.get("x-idempotency-key")||void 0)??(l&&i?`${l}|${i}|${f}`:void 0);i&&t.client.submitFingerprintEvent(n,{userId:i,emailAddress:o,sessionHash:a,eventType:f,ipAddress:d,userAgent:c,idempotencyKey:h}).catch(e=>{t.onError&&t.onError(e,{operation:"submitFingerprintEvent",userId:i,emailAddress:o})}),i&&o&&!t.rateLimitBackoff.isPaused()&&!t.dispatchDedupe.wasRecentlyDispatched(i,f)&&(t.dispatchDedupe.mark(i,f),t.client.processUserEvent({eventType:f,userId:i,emailAddress:o,ipAddress:d,deviceId:u,fingerprintId:l,sessionHash:a??"unknown",userAgent:c}).then(e=>{e.success&&e.data?.analysis&&t.verdictCache.update(i,{isFlagged:e.data.analysis.is_user_flagged}),!e.success&&e.error?.retryAfter&&t.rateLimitBackoff.pause(1e3*e.error.retryAfter)}).catch(e=>{t.onError&&t.onError(e,{operation:"processUserEvent",userId:i,emailAddress:o})}));const _={...r,"Content-Type":"application/json"},R=new Response(JSON.stringify({success:!0}),{status:200,headers:_});for(const e of m)R.headers.append("Set-Cookie",e);return R}catch{return jsonResponse(200,{success:!0},r)}}async function handleVerifyTriggerWeb(e,s,t,r){try{const n=resolveEmailWithBody(e,s??{},t.resolveEmailAddress);if(!n)return jsonResponse(400,{success:!1,error:{code:"VALIDATION_ERROR",message:"Email is required"}},r);const i=extractDeviceIdFromRequestOrUnknown(e,t.resolveDeviceId),o=parseCookieFromRequest(e,"__unshared_fingerprint_id")||void 0,a=await t.client.triggerEmailVerification(n,i,{fingerprintId:o});return a.success?jsonResponse(200,{success:!0,data:a.data},r):jsonResponse(200,{success:!1,error:a.error??{code:"TRIGGER_FAILED",message:"Failed to send verification email"}},r)}catch(e){return t.onError&&t.onError(e,{operation:"verifyTrigger"}),jsonResponse(200,{success:!1,error:{code:"INTERNAL_ERROR",message:"Failed to trigger verification"}},r)}}async function handleVerifyWeb(e,s,t,r){try{const n=resolveEmailWithBody(e,s??{},t.resolveEmailAddress),i=s?.code;if(!n||!i)return jsonResponse(400,{success:!1,error:{code:"VALIDATION_ERROR",message:"Email and code are required"}},r);const o=extractDeviceIdFromRequestOrUnknown(e,t.resolveDeviceId),a=parseCookieFromRequest(e,"__unshared_fingerprint_id")||void 0,d=await t.client.verify(n,o,i,{fingerprintId:a});if(d.success){const s=parseCookieFromRequest(e,"__unshared_uid");return s&&t.verdictCache.update(s,{isVerified:!0}),jsonResponse(200,{success:!0,data:{verified:!0}},r)}return jsonResponse(200,{success:!1,error:d.error??{code:"VERIFICATION_FAILED",message:"Verification failed"}},r)}catch(e){return t.onError&&t.onError(e,{operation:"verify"}),jsonResponse(200,{success:!1,error:{code:"INTERNAL_ERROR",message:"Verification failed"}},r)}}
|
|
1
|
+
import{VerdictCache}from"../middleware/verdict-cache";import{RateLimitBackoff}from"../middleware/rate-limit-backoff";import{DispatchDedupe}from"../middleware/dispatch-dedupe";import{generateFingerprintScript}from"../middleware/injection/fingerprint-script";import{isHtmlContentType}from"../middleware/utils/content-type";import{shouldSkipPath}from"../middleware/utils/skip-paths";import{shouldIncludePath}from"../middleware/utils/include-path";import{isBot}from"../middleware/utils/is-bot";import{isSentinelUserId,SENTINEL_STICKINESS_TTL_MS}from"../middleware/utils/sentinel-user-id";import{parseCookieFromRequest,extractClientIpFromRequest,extractDeviceIdFromRequest,extractDeviceIdFromRequestOrUnknown,isSecureWebRequest,jsonResponse,emptyResponse,bodyResponse,mergeResponseHeaders}from"./web-helpers";const CHECK_USER_TIMEOUT_MS=500;export function createWebProtectionMiddleware(e,s){if(!s.userId)throw new Error("[Unshared] userId resolver is required");const{userId:t,emailAddress:r,routePrefix:n="/__unshared",corsOrigins:i,cacheTTL:o=6e4,skipPaths:a,includePathPrefix:d,sessionId:c,deviceId:u,fingerprintSdkBundle:l="",onFlagged:p,onError:m}=s,f=new VerdictCache(o),h=new RateLimitBackoff,_=new DispatchDedupe,R=Date.now().toString(36),I=generateFingerprintScript(n,R),g=`${n}/fp.js`,v=`${n}/submit-fp`,S=`${n}/verify-trigger`,y=`${n}/verify`,C=`${n}/status`,w=i?Array.isArray(i)?i:[i]:null;return async function(s,i){let o,R,A;try{const e=new URL(s.url);o=e.pathname,R=e.search}catch{return i(s)}if(o.startsWith(n+"/")){const n=function(e){if(!w)return{};const s=e.headers.get("origin")??"",t=w.includes("*");return t||w.includes(s)?{"Access-Control-Allow-Origin":t?"*":s,"Access-Control-Allow-Methods":"POST, OPTIONS","Access-Control-Allow-Headers":"Content-Type, X-Idempotency-Key, X-Session-Id, X-Device-Id","Access-Control-Allow-Credentials":"true"}:{}}(s);if("OPTIONS"===s.method)return emptyResponse(204,n);if("GET"===s.method&&o===g)return l?bodyResponse(200,l,{...n,"Content-Type":"application/javascript","Cache-Control":"public, max-age=3600"}):jsonResponse(404,{success:!1,error:{code:"NOT_FOUND",message:"Fingerprint SDK bundle not configured. Pass fingerprintSdkBundle in config."}},n);if("POST"===s.method&&(o===v||o===S||o===y)){let i;try{i=await s.json()}catch{return jsonResponse(400,{success:!1,error:{code:"BODY_PARSER_MISSING",message:"Request body is not valid JSON."}},n)}return o===v?handleSubmitFp(s,i,{client:e,verdictCache:f,rateLimitBackoff:h,dispatchDedupe:_,resolveUserId:t,resolveEmailAddress:r,resolveSessionId:c,resolveDeviceId:u,onError:m},n):o===S?handleVerifyTriggerWeb(s,i,{client:e,verdictCache:f,resolveEmailAddress:r,resolveDeviceId:u,onError:m},n):handleVerifyWeb(s,i,{client:e,verdictCache:f,resolveEmailAddress:r,resolveDeviceId:u,onError:m},n)}if("GET"===s.method&&o===C){let e;try{e=t(s)}catch{}if(!e)return jsonResponse(200,{status:"anonymous"},n);const i=resolveEmail(s,r),o=f.get(e);return o&&o.isFlagged&&!o.isVerified&&p&&i?jsonResponse(403,{error:"account_flagged",email:i},n):jsonResponse(200,{status:"ok"},n)}return jsonResponse(404,{success:!1,error:{code:"NOT_FOUND",message:"Unknown route"}},n)}if(shouldSkipPath(o,a))return i(s);if(!shouldIncludePath(o,d))return injectIntoHtmlResponse(await i(s),I);try{A=t(s)}catch{}if(isSentinelUserId(A)){const e=parseCookieFromRequest(s,"__unshared_uid"),t=parseCookieFromRequest(s,"__unshared_uid_at"),r=t?Number(t):NaN,n=Number.isFinite(r)&&Date.now()-r<=SENTINEL_STICKINESS_TTL_MS;A=e&&n?e:void 0}if(!A){const e=isSecureWebRequest(s)?"; Secure":"",t=[`__unshared_uid=; Path=/; SameSite=Lax; Max-Age=0${e}`,`__unshared_uid_at=; Path=/; SameSite=Lax; Max-Age=0${e}`,`__unshared_sid=; Path=/; SameSite=Lax; Max-Age=0${e}`,`__unshared_email=; Path=/; SameSite=Lax; Max-Age=0${e}`];return injectIntoHtmlResponse(await i(s),I,t)}const E=resolveEmail(s,r),F=[],T=isSecureWebRequest(s)?"; Secure":"";if(F.push(`__unshared_uid=${encodeURIComponent(A)}; Path=/; SameSite=Lax${T}`),F.push(`__unshared_uid_at=${Date.now()}; Path=/; SameSite=Lax${T}`),E&&F.push(`__unshared_email=${encodeURIComponent(E)}; HttpOnly; Path=/; SameSite=Lax${T}`),!E)return injectIntoHtmlResponse(await i(s),I,F);const k=extractSessionIdFromRequest(s,c),q=extractDeviceIdFromRequest(s,u),x=parseCookieFromRequest(s,"__unshared_fingerprint_id")||void 0,j=s.headers.get("user-agent")??"",O=extractClientIpFromRequest(s);if(isBot(j))return i(s);if("unknown"===k)return injectIntoHtmlResponse(await i(s),I,F);const L=q??x;if(!L)return injectIntoHtmlResponse(await i(s),I,F);h.isPaused()||dispatchUserEvent(e,f,h,_,{userId:A,emailAddress:E,sessionId:k,deviceId:L,fingerprintId:x,userAgent:j,ipAddress:O,eventType:o+R},m);let U=f.get(A);if(U)f.isStale(A)&&!f.isRefreshing(A)&&(f.markRefreshing(A),fetchAndCacheVerdict(e,f,A,E,L,x,k).finally(()=>f.clearRefreshing(A)));else try{U=await fetchAndCacheVerdict(e,f,A,E,L,x,k)}catch{return injectIntoHtmlResponse(await i(s),I,F)}if(U.isFlagged&&!U.isVerified&&p)try{const e=await p({userId:A,emailAddress:E,verdict:U,request:s});if(e)return injectIntoHtmlResponse(e,I,F)}catch(e){m&&m(e,{operation:"checkUser",userId:A,emailAddress:E})}return injectIntoHtmlResponse(await i(s),I,F)}}async function injectIntoHtmlResponse(e,s,t){const r=e.headers.get("content-type");if(!isHtmlContentType(r??void 0)){if(!t||0===t.length)return e;const s=mergeResponseHeaders(e.headers,void 0,t);return new Response(e.body,{status:e.status,statusText:e.statusText,headers:s})}const n=await e.text(),i=n.lastIndexOf("</body>"),o=-1===i?n+s:n.slice(0,i)+s+n.slice(i),a=mergeResponseHeaders(e.headers,{"Cache-Control":"no-store","Content-Length":String((new TextEncoder).encode(o).length)},t);return a.delete("ETag"),a.delete("Last-Modified"),a.delete("Content-Encoding"),new Response(o,{status:e.status,statusText:e.statusText,headers:a})}function resolveEmail(e,s){if(s)try{const t=s(e);if(t)return t}catch{}const t=parseCookieFromRequest(e,"__unshared_email");if(t)return t}function resolveEmailWithBody(e,s,t){const r=resolveEmail(e,t);if(r)return r;const n=s.email;return"string"==typeof n&&n?n:void 0}function extractSessionIdFromRequest(e,s){if(s)try{const t=s(e);if(t)return t}catch{}return parseCookieFromRequest(e,"__unshared_sid")??"unknown"}function dispatchUserEvent(e,s,t,r,n,i){r.mark(n.userId,n.eventType),e.processUserEvent({eventType:n.eventType,userId:n.userId,emailAddress:n.emailAddress,ipAddress:n.ipAddress,deviceId:n.deviceId,fingerprintId:n.fingerprintId,sessionHash:n.sessionId,userAgent:n.userAgent}).then(e=>{e.success&&e.data?.analysis&&s.update(n.userId,{isFlagged:e.data.analysis.is_user_flagged}),!e.success&&e.error?.retryAfter&&t.pause(1e3*e.error.retryAfter)}).catch(e=>{i&&i(e,{operation:"processUserEvent",userId:n.userId,emailAddress:n.emailAddress})})}async function fetchAndCacheVerdict(e,s,t,r,n,i,o){const a={};let d;n&&"unknown"!==n&&(a.deviceId=n),i&&(a.fingerprintId=i);const c=await Promise.race([e.checkUser(r,a),new Promise(e=>{d=setTimeout(()=>e(null),500)})]);if(clearTimeout(d),!c)return{isFlagged:!1,isVerified:!1,emailAddress:r,sessionId:o,cachedAt:0,ttl:0};const u=c.data?.is_user_flagged??!1;return s.set(t,{isFlagged:u,isVerified:!1,emailAddress:r,sessionId:o}),s.get(t)}async function handleSubmitFp(e,s,t,r){try{const n={full_hash:s.hash??"",fingerprint_id:s.stable_hash??"",timestamp:s.collected_at??(new Date).toISOString(),isIncognito:s.is_incognito??!1,components:s.components??{},version:s.version??"inline-1.0.0"};let i,o,a;try{const s=t.resolveUserId(e);s&&!isSentinelUserId(s)&&(i=s)}catch{}if(!i){const e="string"==typeof s.user_id?s.user_id:void 0;e&&!isSentinelUserId(e)&&(i=e)}if(!i){const s=parseCookieFromRequest(e,"__unshared_uid");s&&!isSentinelUserId(s)&&(i=s)}try{o=t.resolveEmailAddress?t.resolveEmailAddress(e):void 0}catch{}o=o??parseCookieFromRequest(e,"__unshared_email")??s.email??void 0;try{a=t.resolveSessionId?t.resolveSessionId(e):void 0}catch{}a=a??s.session_id??parseCookieFromRequest(e,"__unshared_sid");const d=extractClientIpFromRequest(e),c=e.headers.get("user-agent")??"";if(isBot(c))return jsonResponse(200,{success:!0},r);const u=(n.fingerprint_id&&n.fingerprint_id.length>0?n.fingerprint_id:void 0)??extractDeviceIdFromRequestOrUnknown(e,t.resolveDeviceId),l=n.fingerprint_id||void 0,p=n.full_hash||void 0,m=isSecureWebRequest(e)?"; Secure":"",f=[];if(p&&!parseCookieFromRequest(e,"__unshared_fingerprint_id")&&f.push(`__unshared_fingerprint_id=${encodeURIComponent(p)}; HttpOnly; Path=/; SameSite=Lax${m}`),l){const s=parseCookieFromRequest(e,"__unshared_fp_id");s&&s===l||f.push(`__unshared_fp_id=${encodeURIComponent(l)}; Path=/; SameSite=Lax; Max-Age=31536000${m}`)}let h;if(o&&!parseCookieFromRequest(e,"__unshared_email")&&f.push(`__unshared_email=${encodeURIComponent(o)}; HttpOnly; Path=/; SameSite=Lax${m}`),"string"==typeof s.event_type&&s.event_type)h=s.event_type;else{const s=e.headers.get("referer")??e.headers.get("referrer");let t="unknown";if(s)try{const e=new URL(s);t=(e.pathname||"/")+(e.search||"")}catch{}h=t}const _=(e.headers.get("x-idempotency-key")||void 0)??(l&&i?`${l}|${i}|${h}`:void 0);i&&t.client.submitFingerprintEvent(n,{userId:i,emailAddress:o,sessionHash:a,eventType:h,ipAddress:d,userAgent:c,idempotencyKey:_}).catch(e=>{t.onError&&t.onError(e,{operation:"submitFingerprintEvent",userId:i,emailAddress:o})}),i&&o&&!t.rateLimitBackoff.isPaused()&&!t.dispatchDedupe.wasRecentlyDispatched(i,h)&&(t.dispatchDedupe.mark(i,h),t.client.processUserEvent({eventType:h,userId:i,emailAddress:o,ipAddress:d,deviceId:u,fingerprintId:l,sessionHash:a??"unknown",userAgent:c}).then(e=>{e.success&&e.data?.analysis&&t.verdictCache.update(i,{isFlagged:e.data.analysis.is_user_flagged}),!e.success&&e.error?.retryAfter&&t.rateLimitBackoff.pause(1e3*e.error.retryAfter)}).catch(e=>{t.onError&&t.onError(e,{operation:"processUserEvent",userId:i,emailAddress:o})}));const R={...r,"Content-Type":"application/json"},I=new Response(JSON.stringify({success:!0}),{status:200,headers:R});for(const e of f)I.headers.append("Set-Cookie",e);return I}catch{return jsonResponse(200,{success:!0},r)}}async function handleVerifyTriggerWeb(e,s,t,r){try{const n=resolveEmailWithBody(e,s??{},t.resolveEmailAddress);if(!n)return jsonResponse(400,{success:!1,error:{code:"VALIDATION_ERROR",message:"Email is required"}},r);const i=extractDeviceIdFromRequestOrUnknown(e,t.resolveDeviceId),o=parseCookieFromRequest(e,"__unshared_fingerprint_id")||void 0,a=await t.client.triggerEmailVerification(n,i,{fingerprintId:o});return a.success?jsonResponse(200,{success:!0,data:a.data},r):jsonResponse(200,{success:!1,error:a.error??{code:"TRIGGER_FAILED",message:"Failed to send verification email"}},r)}catch(e){return t.onError&&t.onError(e,{operation:"verifyTrigger"}),jsonResponse(200,{success:!1,error:{code:"INTERNAL_ERROR",message:"Failed to trigger verification"}},r)}}async function handleVerifyWeb(e,s,t,r){try{const n=resolveEmailWithBody(e,s??{},t.resolveEmailAddress),i=s?.code;if(!n||!i)return jsonResponse(400,{success:!1,error:{code:"VALIDATION_ERROR",message:"Email and code are required"}},r);const o=extractDeviceIdFromRequestOrUnknown(e,t.resolveDeviceId),a=parseCookieFromRequest(e,"__unshared_fingerprint_id")||void 0,d=await t.client.verify(n,o,i,{fingerprintId:a});if(d.success){const s=parseCookieFromRequest(e,"__unshared_uid");return s&&t.verdictCache.update(s,{isVerified:!0}),jsonResponse(200,{success:!0,data:{verified:!0}},r)}return jsonResponse(200,{success:!1,error:d.error??{code:"VERIFICATION_FAILED",message:"Verification failed"}},r)}catch(e){return t.onError&&t.onError(e,{operation:"verify"}),jsonResponse(200,{success:!1,error:{code:"INTERNAL_ERROR",message:"Verification failed"}},r)}}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
"use strict";Object.defineProperty(exports,"i",{value:!0}),exports.handleSubmitFingerprint=handleSubmitFingerprint;const is_bot_1=require("../utils/is-bot"),client_ip_1=require("../utils/client-ip"),cookies_1=require("../utils/cookies"),device_id_1=require("../utils/device-id"),secure_1=require("../utils/secure"),sentinel_user_id_1=require("../utils/sentinel-user-id"),http_helpers_1=require("../utils/http-helpers");function handleSubmitFingerprint(e){return async(i,s)=>{try{const t=i.body??{},n={full_hash:t.hash??"",fingerprint_id:t.stable_hash??"",timestamp:t.collected_at??(new Date).toISOString(),isIncognito:t.is_incognito??!1,components:t.components??{},version:t.version??"inline-1.0.0"};let r,o,_;try{const s=e.resolveUserId?e.resolveUserId(i):void 0;s&&!(0,sentinel_user_id_1.isSentinelUserId)(s)&&(r=s)}catch{}if(!r){const e="string"==typeof t.user_id?t.user_id:void 0;e&&!(0,sentinel_user_id_1.isSentinelUserId)(e)&&(r=e)}if(!r){const e=(0,cookies_1.parseCookie)(i,"__unshared_uid");e&&!(0,sentinel_user_id_1.isSentinelUserId)(e)&&(r=e)}try{o=e.resolveEmailAddress?e.resolveEmailAddress(i):void 0}catch{}o=o??(0,cookies_1.parseCookie)(i,"__unshared_email")??t.email??void 0;try{_=e.resolveSessionId?e.resolveSessionId(i):void 0}catch{}_=_??t.session_id??(0,cookies_1.parseCookie)(i,"__unshared_sid");const d=(0,client_ip_1.extractClientIp)(i),c=i.headers["user-agent"]??"";if((0,is_bot_1.isBot)(c))return void(0,http_helpers_1.sendJson)(s,200,{success:!0});const u=(n.fingerprint_id&&n.fingerprint_id.length>0?n.fingerprint_id:void 0)??(0,device_id_1.extractDeviceId)(i,e.resolveDeviceId),a=n.fingerprint_id||void 0,p=(0,secure_1.isSecureRequest)(i)?"; Secure":"",
|
|
1
|
+
"use strict";Object.defineProperty(exports,"i",{value:!0}),exports.handleSubmitFingerprint=handleSubmitFingerprint;const is_bot_1=require("../utils/is-bot"),client_ip_1=require("../utils/client-ip"),cookies_1=require("../utils/cookies"),device_id_1=require("../utils/device-id"),secure_1=require("../utils/secure"),sentinel_user_id_1=require("../utils/sentinel-user-id"),http_helpers_1=require("../utils/http-helpers");function handleSubmitFingerprint(e){return async(i,s)=>{try{const t=i.body??{},n={full_hash:t.hash??"",fingerprint_id:t.stable_hash??"",timestamp:t.collected_at??(new Date).toISOString(),isIncognito:t.is_incognito??!1,components:t.components??{},version:t.version??"inline-1.0.0"};let r,o,_;try{const s=e.resolveUserId?e.resolveUserId(i):void 0;s&&!(0,sentinel_user_id_1.isSentinelUserId)(s)&&(r=s)}catch{}if(!r){const e="string"==typeof t.user_id?t.user_id:void 0;e&&!(0,sentinel_user_id_1.isSentinelUserId)(e)&&(r=e)}if(!r){const e=(0,cookies_1.parseCookie)(i,"__unshared_uid");e&&!(0,sentinel_user_id_1.isSentinelUserId)(e)&&(r=e)}try{o=e.resolveEmailAddress?e.resolveEmailAddress(i):void 0}catch{}o=o??(0,cookies_1.parseCookie)(i,"__unshared_email")??t.email??void 0;try{_=e.resolveSessionId?e.resolveSessionId(i):void 0}catch{}_=_??t.session_id??(0,cookies_1.parseCookie)(i,"__unshared_sid");const d=(0,client_ip_1.extractClientIp)(i),c=i.headers["user-agent"]??"";if((0,is_bot_1.isBot)(c))return void(0,http_helpers_1.sendJson)(s,200,{success:!0});const u=(n.fingerprint_id&&n.fingerprint_id.length>0?n.fingerprint_id:void 0)??(0,device_id_1.extractDeviceId)(i,e.resolveDeviceId),a=n.fingerprint_id||void 0,p=n.full_hash||void 0,l=(0,secure_1.isSecureRequest)(i)?"; Secure":"",h=[];if(p&&!(0,cookies_1.parseCookie)(i,"__unshared_fingerprint_id")&&h.push(`__unshared_fingerprint_id=${encodeURIComponent(p)}; HttpOnly; Path=/; SameSite=Lax${l}`),a){const e=(0,cookies_1.parseCookie)(i,"__unshared_fp_id");e&&e===a||h.push(`__unshared_fp_id=${encodeURIComponent(a)}; Path=/; SameSite=Lax; Max-Age=31536000${l}`)}if(o&&!(0,cookies_1.parseCookie)(i,"__unshared_email")&&h.push(`__unshared_email=${encodeURIComponent(o)}; HttpOnly; Path=/; SameSite=Lax${l}`),h.length>0){const e=s.getHeader("Set-Cookie");if(e){const i=Array.isArray(e)?[...e]:[String(e)];i.push(...h),s.setHeader("Set-Cookie",i)}else s.setHeader("Set-Cookie",h)}let f;if("string"==typeof t.event_type&&t.event_type)f=t.event_type;else{const e=i.headers.referer??i.headers.referrer;let s="unknown";if("string"==typeof e&&e.length>0)try{const i=new URL(e);s=(i.pathname||"/")+(i.search||"")}catch{}f=s}const v=i.headers["x-idempotency-key"],m=("string"==typeof v&&v.length>0?v:void 0)??(a&&r?`${a}|${r}|${f}`:void 0);if(r&&e.client.submitFingerprintEvent(n,{userId:r,emailAddress:o,sessionHash:_,eventType:f,ipAddress:d,userAgent:c,idempotencyKey:m}).catch(i=>{e.onError&&e.onError(i,{operation:"submitFingerprintEvent",userId:r,emailAddress:o})}),r&&o&&!e.rateLimitBackoff.isPaused()&&!e.dispatchDedupe.wasRecentlyDispatched(r,f)){e.dispatchDedupe.mark(r,f);try{const i=await e.client.processUserEvent({eventType:f,userId:r,emailAddress:o,ipAddress:d,deviceId:u,fingerprintId:a,sessionHash:_??"unknown",userAgent:c});i.success&&i.data?.analysis&&e.verdictCache.update(r,{isFlagged:i.data.analysis.is_user_flagged}),!i.success&&i.error?.retryAfter&&e.rateLimitBackoff.pause(1e3*i.error.retryAfter)}catch(i){e.onError&&e.onError(i,{operation:"processUserEvent",userId:r,emailAddress:o})}}(0,http_helpers_1.sendJson)(s,200,{success:!0})}catch{(0,http_helpers_1.sendJson)(s,200,{success:!0})}}}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
"use strict";Object.defineProperty(exports,"t",{value:!0}),exports.createWebProtectionMiddleware=createWebProtectionMiddleware;const verdict_cache_1=require("../middleware/verdict-cache"),rate_limit_backoff_1=require("../middleware/rate-limit-backoff"),dispatch_dedupe_1=require("../middleware/dispatch-dedupe"),fingerprint_script_1=require("../middleware/injection/fingerprint-script"),content_type_1=require("../middleware/utils/content-type"),skip_paths_1=require("../middleware/utils/skip-paths"),include_path_1=require("../middleware/utils/include-path"),is_bot_1=require("../middleware/utils/is-bot"),sentinel_user_id_1=require("../middleware/utils/sentinel-user-id"),web_helpers_1=require("./web-helpers"),CHECK_USER_TIMEOUT_MS=500;function createWebProtectionMiddleware(e,r){if(!r.userId)throw new Error("[Unshared] userId resolver is required");const{userId:s,emailAddress:t,routePrefix:i="/__unshared",corsOrigins:n,cacheTTL:a=6e4,skipPaths:o,includePathPrefix:d,sessionId:c,deviceId:_,fingerprintSdkBundle:l="",onFlagged:u,onError:p}=r,h=new verdict_cache_1.VerdictCache(a),f=new rate_limit_backoff_1.RateLimitBackoff,m=new dispatch_dedupe_1.DispatchDedupe,w=Date.now().toString(36),g=(0,fingerprint_script_1.generateFingerprintScript)(i,w),b=`${i}/fp.js`,v=`${i}/submit-fp`,I=`${i}/verify-trigger`,y=`${i}/verify`,A=`${i}/status`,S=n?Array.isArray(n)?n:[n]:null;return async function(r,n){let a,w,R;try{const e=new URL(r.url);a=e.pathname,w=e.search}catch{return n(r)}if(a.startsWith(i+"/")){const i=function(e){if(!S)return{};const r=e.headers.get("origin")??"",s=S.includes("*");return s||S.includes(r)?{"Access-Control-Allow-Origin":s?"*":r,"Access-Control-Allow-Methods":"POST, OPTIONS","Access-Control-Allow-Headers":"Content-Type, X-Idempotency-Key, X-Session-Id, X-Device-Id","Access-Control-Allow-Credentials":"true"}:{}}(r);if("OPTIONS"===r.method)return(0,web_helpers_1.emptyResponse)(204,i);if("GET"===r.method&&a===b)return l?(0,web_helpers_1.bodyResponse)(200,l,{...i,"Content-Type":"application/javascript","Cache-Control":"public, max-age=3600"}):(0,web_helpers_1.jsonResponse)(404,{success:!1,error:{code:"NOT_FOUND",message:"Fingerprint SDK bundle not configured. Pass fingerprintSdkBundle in config."}},i);if("POST"===r.method&&(a===v||a===I||a===y)){let n;try{n=await r.json()}catch{return(0,web_helpers_1.jsonResponse)(400,{success:!1,error:{code:"BODY_PARSER_MISSING",message:"Request body is not valid JSON."}},i)}return a===v?handleSubmitFp(r,n,{client:e,verdictCache:h,rateLimitBackoff:f,dispatchDedupe:m,resolveUserId:s,resolveEmailAddress:t,resolveSessionId:c,resolveDeviceId:_,onError:p},i):a===I?handleVerifyTriggerWeb(r,n,{client:e,verdictCache:h,resolveEmailAddress:t,resolveDeviceId:_,onError:p},i):handleVerifyWeb(r,n,{client:e,verdictCache:h,resolveEmailAddress:t,resolveDeviceId:_,onError:p},i)}if("GET"===r.method&&a===A){let e;try{e=s(r)}catch{}if(!e)return(0,web_helpers_1.jsonResponse)(200,{status:"anonymous"},i);const n=resolveEmail(r,t),a=h.get(e);return a&&a.isFlagged&&!a.isVerified&&u&&n?(0,web_helpers_1.jsonResponse)(403,{error:"account_flagged",email:n},i):(0,web_helpers_1.jsonResponse)(200,{status:"ok"},i)}return(0,web_helpers_1.jsonResponse)(404,{success:!1,error:{code:"NOT_FOUND",message:"Unknown route"}},i)}if((0,skip_paths_1.shouldSkipPath)(a,o))return n(r);if(!(0,include_path_1.shouldIncludePath)(a,d))return injectIntoHtmlResponse(await n(r),g);try{R=s(r)}catch{}if((0,sentinel_user_id_1.isSentinelUserId)(R)){const e=(0,web_helpers_1.parseCookieFromRequest)(r,"__unshared_uid"),s=(0,web_helpers_1.parseCookieFromRequest)(r,"__unshared_uid_at"),t=s?Number(s):NaN,i=Number.isFinite(t)&&Date.now()-t<=sentinel_user_id_1.SENTINEL_STICKINESS_TTL_MS;R=e&&i?e:void 0}if(!R){const e=(0,web_helpers_1.isSecureWebRequest)(r)?"; Secure":"",s=[`__unshared_uid=; Path=/; SameSite=Lax; Max-Age=0${e}`,`__unshared_uid_at=; Path=/; SameSite=Lax; Max-Age=0${e}`,`__unshared_sid=; Path=/; SameSite=Lax; Max-Age=0${e}`,`__unshared_email=; Path=/; SameSite=Lax; Max-Age=0${e}`];return injectIntoHtmlResponse(await n(r),g,s)}const E=resolveEmail(r,t),T=[],C=(0,web_helpers_1.isSecureWebRequest)(r)?"; Secure":"";if(T.push(`__unshared_uid=${encodeURIComponent(R)}; Path=/; SameSite=Lax${C}`),T.push(`__unshared_uid_at=${Date.now()}; Path=/; SameSite=Lax${C}`),E&&T.push(`__unshared_email=${encodeURIComponent(E)}; HttpOnly; Path=/; SameSite=Lax${C}`),!E)return injectIntoHtmlResponse(await n(r),g,T);const O=extractSessionIdFromRequest(r,c),x=(0,web_helpers_1.extractDeviceIdFromRequest)(r,_),P=(0,web_helpers_1.parseCookieFromRequest)(r,"__unshared_fingerprint_id")||void 0,$=r.headers.get("user-agent")??"",L=(0,web_helpers_1.extractClientIpFromRequest)(r);if((0,is_bot_1.isBot)($))return n(r);if("unknown"===O)return injectIntoHtmlResponse(await n(r),g,T);const k=x??P;if(!k)return injectIntoHtmlResponse(await n(r),g,T);f.isPaused()||dispatchUserEvent(e,h,f,m,{userId:R,emailAddress:E,sessionId:O,deviceId:k,fingerprintId:P,userAgent:$,ipAddress:L,eventType:a+w},p);let N=h.get(R);if(N)h.isStale(R)&&!h.isRefreshing(R)&&(h.markRefreshing(R),fetchAndCacheVerdict(e,h,R,E,k,P,O).finally(()=>h.clearRefreshing(R)));else try{N=await fetchAndCacheVerdict(e,h,R,E,k,P,O)}catch{return injectIntoHtmlResponse(await n(r),g,T)}if(N.isFlagged&&!N.isVerified&&u)try{const e=await u({userId:R,emailAddress:E,verdict:N,request:r});if(e)return injectIntoHtmlResponse(e,g,T)}catch(e){p&&p(e,{operation:"checkUser",userId:R,emailAddress:E})}return injectIntoHtmlResponse(await n(r),g,T)}}async function injectIntoHtmlResponse(e,r,s){const t=e.headers.get("content-type");if(!(0,content_type_1.isHtmlContentType)(t??void 0)){if(!s||0===s.length)return e;const r=(0,web_helpers_1.mergeResponseHeaders)(e.headers,void 0,s);return new Response(e.body,{status:e.status,statusText:e.statusText,headers:r})}const i=await e.text(),n=i.lastIndexOf("</body>"),a=-1===n?i+r:i.slice(0,n)+r+i.slice(n),o=(0,web_helpers_1.mergeResponseHeaders)(e.headers,{"Cache-Control":"no-store","Content-Length":String((new TextEncoder).encode(a).length)},s);return o.delete("ETag"),o.delete("Last-Modified"),o.delete("Content-Encoding"),new Response(a,{status:e.status,statusText:e.statusText,headers:o})}function resolveEmail(e,r){if(r)try{const s=r(e);if(s)return s}catch{}const s=(0,web_helpers_1.parseCookieFromRequest)(e,"__unshared_email");if(s)return s}function resolveEmailWithBody(e,r,s){const t=resolveEmail(e,s);if(t)return t;const i=r.email;return"string"==typeof i&&i?i:void 0}function extractSessionIdFromRequest(e,r){if(r)try{const s=r(e);if(s)return s}catch{}return(0,web_helpers_1.parseCookieFromRequest)(e,"__unshared_sid")??"unknown"}function dispatchUserEvent(e,r,s,t,i,n){t.mark(i.userId,i.eventType),e.processUserEvent({eventType:i.eventType,userId:i.userId,emailAddress:i.emailAddress,ipAddress:i.ipAddress,deviceId:i.deviceId,fingerprintId:i.fingerprintId,sessionHash:i.sessionId,userAgent:i.userAgent}).then(e=>{e.success&&e.data?.analysis&&r.update(i.userId,{isFlagged:e.data.analysis.is_user_flagged}),!e.success&&e.error?.retryAfter&&s.pause(1e3*e.error.retryAfter)}).catch(e=>{n&&n(e,{operation:"processUserEvent",userId:i.userId,emailAddress:i.emailAddress})})}async function fetchAndCacheVerdict(e,r,s,t,i,n,a){const o={};let d;i&&"unknown"!==i&&(o.deviceId=i),n&&(o.fingerprintId=n);const c=await Promise.race([e.checkUser(t,o),new Promise(e=>{d=setTimeout(()=>e(null),500)})]);if(clearTimeout(d),!c)return{isFlagged:!1,isVerified:!1,emailAddress:t,sessionId:a,cachedAt:0,ttl:0};const _=c.data?.is_user_flagged??!1;return r.set(s,{isFlagged:_,isVerified:!1,emailAddress:t,sessionId:a}),r.get(s)}async function handleSubmitFp(e,r,s,t){try{const i={full_hash:r.hash??"",fingerprint_id:r.stable_hash??"",timestamp:r.collected_at??(new Date).toISOString(),isIncognito:r.is_incognito??!1,components:r.components??{},version:r.version??"inline-1.0.0"};let n,a,o;try{const r=s.resolveUserId(e);r&&!(0,sentinel_user_id_1.isSentinelUserId)(r)&&(n=r)}catch{}if(!n){const e="string"==typeof r.user_id?r.user_id:void 0;e&&!(0,sentinel_user_id_1.isSentinelUserId)(e)&&(n=e)}if(!n){const r=(0,web_helpers_1.parseCookieFromRequest)(e,"__unshared_uid");r&&!(0,sentinel_user_id_1.isSentinelUserId)(r)&&(n=r)}try{a=s.resolveEmailAddress?s.resolveEmailAddress(e):void 0}catch{}a=a??(0,web_helpers_1.parseCookieFromRequest)(e,"__unshared_email")??r.email??void 0;try{o=s.resolveSessionId?s.resolveSessionId(e):void 0}catch{}o=o??r.session_id??(0,web_helpers_1.parseCookieFromRequest)(e,"__unshared_sid");const d=(0,web_helpers_1.extractClientIpFromRequest)(e),c=e.headers.get("user-agent")??"";if((0,is_bot_1.isBot)(c))return(0,web_helpers_1.jsonResponse)(200,{success:!0},t);const _=(i.fingerprint_id&&i.fingerprint_id.length>0?i.fingerprint_id:void 0)??(0,web_helpers_1.extractDeviceIdFromRequestOrUnknown)(e,s.resolveDeviceId),l=i.fingerprint_id||void 0,u=(0,web_helpers_1.isSecureWebRequest)(e)?"; Secure":"",p=[];if(l&&!(0,web_helpers_1.parseCookieFromRequest)(e,"__unshared_fingerprint_id")&&p.push(`__unshared_fingerprint_id=${encodeURIComponent(l)}; HttpOnly; Path=/; SameSite=Lax${u}`),l){const r=(0,web_helpers_1.parseCookieFromRequest)(e,"__unshared_fp_id");r&&r===l||p.push(`__unshared_fp_id=${encodeURIComponent(l)}; Path=/; SameSite=Lax; Max-Age=31536000${u}`)}let h;if(a&&!(0,web_helpers_1.parseCookieFromRequest)(e,"__unshared_email")&&p.push(`__unshared_email=${encodeURIComponent(a)}; HttpOnly; Path=/; SameSite=Lax${u}`),"string"==typeof r.event_type&&r.event_type)h=r.event_type;else{const r=e.headers.get("referer")??e.headers.get("referrer");let s="unknown";if(r)try{const e=new URL(r);s=(e.pathname||"/")+(e.search||"")}catch{}h=s}const f=(e.headers.get("x-idempotency-key")||void 0)??(l&&n?`${l}|${n}|${h}`:void 0);n&&s.client.submitFingerprintEvent(i,{userId:n,emailAddress:a,sessionHash:o,eventType:h,ipAddress:d,userAgent:c,idempotencyKey:f}).catch(e=>{s.onError&&s.onError(e,{operation:"submitFingerprintEvent",userId:n,emailAddress:a})}),n&&a&&!s.rateLimitBackoff.isPaused()&&!s.dispatchDedupe.wasRecentlyDispatched(n,h)&&(s.dispatchDedupe.mark(n,h),s.client.processUserEvent({eventType:h,userId:n,emailAddress:a,ipAddress:d,deviceId:_,fingerprintId:l,sessionHash:o??"unknown",userAgent:c}).then(e=>{e.success&&e.data?.analysis&&s.verdictCache.update(n,{isFlagged:e.data.analysis.is_user_flagged}),!e.success&&e.error?.retryAfter&&s.rateLimitBackoff.pause(1e3*e.error.retryAfter)}).catch(e=>{s.onError&&s.onError(e,{operation:"processUserEvent",userId:n,emailAddress:a})}));const m={...t,"Content-Type":"application/json"},w=new Response(JSON.stringify({success:!0}),{status:200,headers:m});for(const e of p)w.headers.append("Set-Cookie",e);return w}catch{return(0,web_helpers_1.jsonResponse)(200,{success:!0},t)}}async function handleVerifyTriggerWeb(e,r,s,t){try{const i=resolveEmailWithBody(e,r??{},s.resolveEmailAddress);if(!i)return(0,web_helpers_1.jsonResponse)(400,{success:!1,error:{code:"VALIDATION_ERROR",message:"Email is required"}},t);const n=(0,web_helpers_1.extractDeviceIdFromRequestOrUnknown)(e,s.resolveDeviceId),a=(0,web_helpers_1.parseCookieFromRequest)(e,"__unshared_fingerprint_id")||void 0,o=await s.client.triggerEmailVerification(i,n,{fingerprintId:a});return o.success?(0,web_helpers_1.jsonResponse)(200,{success:!0,data:o.data},t):(0,web_helpers_1.jsonResponse)(200,{success:!1,error:o.error??{code:"TRIGGER_FAILED",message:"Failed to send verification email"}},t)}catch(e){return s.onError&&s.onError(e,{operation:"verifyTrigger"}),(0,web_helpers_1.jsonResponse)(200,{success:!1,error:{code:"INTERNAL_ERROR",message:"Failed to trigger verification"}},t)}}async function handleVerifyWeb(e,r,s,t){try{const i=resolveEmailWithBody(e,r??{},s.resolveEmailAddress),n=r?.code;if(!i||!n)return(0,web_helpers_1.jsonResponse)(400,{success:!1,error:{code:"VALIDATION_ERROR",message:"Email and code are required"}},t);const a=(0,web_helpers_1.extractDeviceIdFromRequestOrUnknown)(e,s.resolveDeviceId),o=(0,web_helpers_1.parseCookieFromRequest)(e,"__unshared_fingerprint_id")||void 0,d=await s.client.verify(i,a,n,{fingerprintId:o});if(d.success){const r=(0,web_helpers_1.parseCookieFromRequest)(e,"__unshared_uid");return r&&s.verdictCache.update(r,{isVerified:!0}),(0,web_helpers_1.jsonResponse)(200,{success:!0,data:{verified:!0}},t)}return(0,web_helpers_1.jsonResponse)(200,{success:!1,error:d.error??{code:"VERIFICATION_FAILED",message:"Verification failed"}},t)}catch(e){return s.onError&&s.onError(e,{operation:"verify"}),(0,web_helpers_1.jsonResponse)(200,{success:!1,error:{code:"INTERNAL_ERROR",message:"Verification failed"}},t)}}
|
|
1
|
+
"use strict";Object.defineProperty(exports,"t",{value:!0}),exports.createWebProtectionMiddleware=createWebProtectionMiddleware;const verdict_cache_1=require("../middleware/verdict-cache"),rate_limit_backoff_1=require("../middleware/rate-limit-backoff"),dispatch_dedupe_1=require("../middleware/dispatch-dedupe"),fingerprint_script_1=require("../middleware/injection/fingerprint-script"),content_type_1=require("../middleware/utils/content-type"),skip_paths_1=require("../middleware/utils/skip-paths"),include_path_1=require("../middleware/utils/include-path"),is_bot_1=require("../middleware/utils/is-bot"),sentinel_user_id_1=require("../middleware/utils/sentinel-user-id"),web_helpers_1=require("./web-helpers"),CHECK_USER_TIMEOUT_MS=500;function createWebProtectionMiddleware(e,r){if(!r.userId)throw new Error("[Unshared] userId resolver is required");const{userId:s,emailAddress:t,routePrefix:i="/__unshared",corsOrigins:n,cacheTTL:a=6e4,skipPaths:o,includePathPrefix:d,sessionId:c,deviceId:_,fingerprintSdkBundle:l="",onFlagged:u,onError:p}=r,h=new verdict_cache_1.VerdictCache(a),f=new rate_limit_backoff_1.RateLimitBackoff,m=new dispatch_dedupe_1.DispatchDedupe,w=Date.now().toString(36),g=(0,fingerprint_script_1.generateFingerprintScript)(i,w),b=`${i}/fp.js`,v=`${i}/submit-fp`,I=`${i}/verify-trigger`,y=`${i}/verify`,A=`${i}/status`,S=n?Array.isArray(n)?n:[n]:null;return async function(r,n){let a,w,R;try{const e=new URL(r.url);a=e.pathname,w=e.search}catch{return n(r)}if(a.startsWith(i+"/")){const i=function(e){if(!S)return{};const r=e.headers.get("origin")??"",s=S.includes("*");return s||S.includes(r)?{"Access-Control-Allow-Origin":s?"*":r,"Access-Control-Allow-Methods":"POST, OPTIONS","Access-Control-Allow-Headers":"Content-Type, X-Idempotency-Key, X-Session-Id, X-Device-Id","Access-Control-Allow-Credentials":"true"}:{}}(r);if("OPTIONS"===r.method)return(0,web_helpers_1.emptyResponse)(204,i);if("GET"===r.method&&a===b)return l?(0,web_helpers_1.bodyResponse)(200,l,{...i,"Content-Type":"application/javascript","Cache-Control":"public, max-age=3600"}):(0,web_helpers_1.jsonResponse)(404,{success:!1,error:{code:"NOT_FOUND",message:"Fingerprint SDK bundle not configured. Pass fingerprintSdkBundle in config."}},i);if("POST"===r.method&&(a===v||a===I||a===y)){let n;try{n=await r.json()}catch{return(0,web_helpers_1.jsonResponse)(400,{success:!1,error:{code:"BODY_PARSER_MISSING",message:"Request body is not valid JSON."}},i)}return a===v?handleSubmitFp(r,n,{client:e,verdictCache:h,rateLimitBackoff:f,dispatchDedupe:m,resolveUserId:s,resolveEmailAddress:t,resolveSessionId:c,resolveDeviceId:_,onError:p},i):a===I?handleVerifyTriggerWeb(r,n,{client:e,verdictCache:h,resolveEmailAddress:t,resolveDeviceId:_,onError:p},i):handleVerifyWeb(r,n,{client:e,verdictCache:h,resolveEmailAddress:t,resolveDeviceId:_,onError:p},i)}if("GET"===r.method&&a===A){let e;try{e=s(r)}catch{}if(!e)return(0,web_helpers_1.jsonResponse)(200,{status:"anonymous"},i);const n=resolveEmail(r,t),a=h.get(e);return a&&a.isFlagged&&!a.isVerified&&u&&n?(0,web_helpers_1.jsonResponse)(403,{error:"account_flagged",email:n},i):(0,web_helpers_1.jsonResponse)(200,{status:"ok"},i)}return(0,web_helpers_1.jsonResponse)(404,{success:!1,error:{code:"NOT_FOUND",message:"Unknown route"}},i)}if((0,skip_paths_1.shouldSkipPath)(a,o))return n(r);if(!(0,include_path_1.shouldIncludePath)(a,d))return injectIntoHtmlResponse(await n(r),g);try{R=s(r)}catch{}if((0,sentinel_user_id_1.isSentinelUserId)(R)){const e=(0,web_helpers_1.parseCookieFromRequest)(r,"__unshared_uid"),s=(0,web_helpers_1.parseCookieFromRequest)(r,"__unshared_uid_at"),t=s?Number(s):NaN,i=Number.isFinite(t)&&Date.now()-t<=sentinel_user_id_1.SENTINEL_STICKINESS_TTL_MS;R=e&&i?e:void 0}if(!R){const e=(0,web_helpers_1.isSecureWebRequest)(r)?"; Secure":"",s=[`__unshared_uid=; Path=/; SameSite=Lax; Max-Age=0${e}`,`__unshared_uid_at=; Path=/; SameSite=Lax; Max-Age=0${e}`,`__unshared_sid=; Path=/; SameSite=Lax; Max-Age=0${e}`,`__unshared_email=; Path=/; SameSite=Lax; Max-Age=0${e}`];return injectIntoHtmlResponse(await n(r),g,s)}const E=resolveEmail(r,t),T=[],C=(0,web_helpers_1.isSecureWebRequest)(r)?"; Secure":"";if(T.push(`__unshared_uid=${encodeURIComponent(R)}; Path=/; SameSite=Lax${C}`),T.push(`__unshared_uid_at=${Date.now()}; Path=/; SameSite=Lax${C}`),E&&T.push(`__unshared_email=${encodeURIComponent(E)}; HttpOnly; Path=/; SameSite=Lax${C}`),!E)return injectIntoHtmlResponse(await n(r),g,T);const O=extractSessionIdFromRequest(r,c),x=(0,web_helpers_1.extractDeviceIdFromRequest)(r,_),P=(0,web_helpers_1.parseCookieFromRequest)(r,"__unshared_fingerprint_id")||void 0,$=r.headers.get("user-agent")??"",L=(0,web_helpers_1.extractClientIpFromRequest)(r);if((0,is_bot_1.isBot)($))return n(r);if("unknown"===O)return injectIntoHtmlResponse(await n(r),g,T);const k=x??P;if(!k)return injectIntoHtmlResponse(await n(r),g,T);f.isPaused()||dispatchUserEvent(e,h,f,m,{userId:R,emailAddress:E,sessionId:O,deviceId:k,fingerprintId:P,userAgent:$,ipAddress:L,eventType:a+w},p);let N=h.get(R);if(N)h.isStale(R)&&!h.isRefreshing(R)&&(h.markRefreshing(R),fetchAndCacheVerdict(e,h,R,E,k,P,O).finally(()=>h.clearRefreshing(R)));else try{N=await fetchAndCacheVerdict(e,h,R,E,k,P,O)}catch{return injectIntoHtmlResponse(await n(r),g,T)}if(N.isFlagged&&!N.isVerified&&u)try{const e=await u({userId:R,emailAddress:E,verdict:N,request:r});if(e)return injectIntoHtmlResponse(e,g,T)}catch(e){p&&p(e,{operation:"checkUser",userId:R,emailAddress:E})}return injectIntoHtmlResponse(await n(r),g,T)}}async function injectIntoHtmlResponse(e,r,s){const t=e.headers.get("content-type");if(!(0,content_type_1.isHtmlContentType)(t??void 0)){if(!s||0===s.length)return e;const r=(0,web_helpers_1.mergeResponseHeaders)(e.headers,void 0,s);return new Response(e.body,{status:e.status,statusText:e.statusText,headers:r})}const i=await e.text(),n=i.lastIndexOf("</body>"),a=-1===n?i+r:i.slice(0,n)+r+i.slice(n),o=(0,web_helpers_1.mergeResponseHeaders)(e.headers,{"Cache-Control":"no-store","Content-Length":String((new TextEncoder).encode(a).length)},s);return o.delete("ETag"),o.delete("Last-Modified"),o.delete("Content-Encoding"),new Response(a,{status:e.status,statusText:e.statusText,headers:o})}function resolveEmail(e,r){if(r)try{const s=r(e);if(s)return s}catch{}const s=(0,web_helpers_1.parseCookieFromRequest)(e,"__unshared_email");if(s)return s}function resolveEmailWithBody(e,r,s){const t=resolveEmail(e,s);if(t)return t;const i=r.email;return"string"==typeof i&&i?i:void 0}function extractSessionIdFromRequest(e,r){if(r)try{const s=r(e);if(s)return s}catch{}return(0,web_helpers_1.parseCookieFromRequest)(e,"__unshared_sid")??"unknown"}function dispatchUserEvent(e,r,s,t,i,n){t.mark(i.userId,i.eventType),e.processUserEvent({eventType:i.eventType,userId:i.userId,emailAddress:i.emailAddress,ipAddress:i.ipAddress,deviceId:i.deviceId,fingerprintId:i.fingerprintId,sessionHash:i.sessionId,userAgent:i.userAgent}).then(e=>{e.success&&e.data?.analysis&&r.update(i.userId,{isFlagged:e.data.analysis.is_user_flagged}),!e.success&&e.error?.retryAfter&&s.pause(1e3*e.error.retryAfter)}).catch(e=>{n&&n(e,{operation:"processUserEvent",userId:i.userId,emailAddress:i.emailAddress})})}async function fetchAndCacheVerdict(e,r,s,t,i,n,a){const o={};let d;i&&"unknown"!==i&&(o.deviceId=i),n&&(o.fingerprintId=n);const c=await Promise.race([e.checkUser(t,o),new Promise(e=>{d=setTimeout(()=>e(null),500)})]);if(clearTimeout(d),!c)return{isFlagged:!1,isVerified:!1,emailAddress:t,sessionId:a,cachedAt:0,ttl:0};const _=c.data?.is_user_flagged??!1;return r.set(s,{isFlagged:_,isVerified:!1,emailAddress:t,sessionId:a}),r.get(s)}async function handleSubmitFp(e,r,s,t){try{const i={full_hash:r.hash??"",fingerprint_id:r.stable_hash??"",timestamp:r.collected_at??(new Date).toISOString(),isIncognito:r.is_incognito??!1,components:r.components??{},version:r.version??"inline-1.0.0"};let n,a,o;try{const r=s.resolveUserId(e);r&&!(0,sentinel_user_id_1.isSentinelUserId)(r)&&(n=r)}catch{}if(!n){const e="string"==typeof r.user_id?r.user_id:void 0;e&&!(0,sentinel_user_id_1.isSentinelUserId)(e)&&(n=e)}if(!n){const r=(0,web_helpers_1.parseCookieFromRequest)(e,"__unshared_uid");r&&!(0,sentinel_user_id_1.isSentinelUserId)(r)&&(n=r)}try{a=s.resolveEmailAddress?s.resolveEmailAddress(e):void 0}catch{}a=a??(0,web_helpers_1.parseCookieFromRequest)(e,"__unshared_email")??r.email??void 0;try{o=s.resolveSessionId?s.resolveSessionId(e):void 0}catch{}o=o??r.session_id??(0,web_helpers_1.parseCookieFromRequest)(e,"__unshared_sid");const d=(0,web_helpers_1.extractClientIpFromRequest)(e),c=e.headers.get("user-agent")??"";if((0,is_bot_1.isBot)(c))return(0,web_helpers_1.jsonResponse)(200,{success:!0},t);const _=(i.fingerprint_id&&i.fingerprint_id.length>0?i.fingerprint_id:void 0)??(0,web_helpers_1.extractDeviceIdFromRequestOrUnknown)(e,s.resolveDeviceId),l=i.fingerprint_id||void 0,u=i.full_hash||void 0,p=(0,web_helpers_1.isSecureWebRequest)(e)?"; Secure":"",h=[];if(u&&!(0,web_helpers_1.parseCookieFromRequest)(e,"__unshared_fingerprint_id")&&h.push(`__unshared_fingerprint_id=${encodeURIComponent(u)}; HttpOnly; Path=/; SameSite=Lax${p}`),l){const r=(0,web_helpers_1.parseCookieFromRequest)(e,"__unshared_fp_id");r&&r===l||h.push(`__unshared_fp_id=${encodeURIComponent(l)}; Path=/; SameSite=Lax; Max-Age=31536000${p}`)}let f;if(a&&!(0,web_helpers_1.parseCookieFromRequest)(e,"__unshared_email")&&h.push(`__unshared_email=${encodeURIComponent(a)}; HttpOnly; Path=/; SameSite=Lax${p}`),"string"==typeof r.event_type&&r.event_type)f=r.event_type;else{const r=e.headers.get("referer")??e.headers.get("referrer");let s="unknown";if(r)try{const e=new URL(r);s=(e.pathname||"/")+(e.search||"")}catch{}f=s}const m=(e.headers.get("x-idempotency-key")||void 0)??(l&&n?`${l}|${n}|${f}`:void 0);n&&s.client.submitFingerprintEvent(i,{userId:n,emailAddress:a,sessionHash:o,eventType:f,ipAddress:d,userAgent:c,idempotencyKey:m}).catch(e=>{s.onError&&s.onError(e,{operation:"submitFingerprintEvent",userId:n,emailAddress:a})}),n&&a&&!s.rateLimitBackoff.isPaused()&&!s.dispatchDedupe.wasRecentlyDispatched(n,f)&&(s.dispatchDedupe.mark(n,f),s.client.processUserEvent({eventType:f,userId:n,emailAddress:a,ipAddress:d,deviceId:_,fingerprintId:l,sessionHash:o??"unknown",userAgent:c}).then(e=>{e.success&&e.data?.analysis&&s.verdictCache.update(n,{isFlagged:e.data.analysis.is_user_flagged}),!e.success&&e.error?.retryAfter&&s.rateLimitBackoff.pause(1e3*e.error.retryAfter)}).catch(e=>{s.onError&&s.onError(e,{operation:"processUserEvent",userId:n,emailAddress:a})}));const w={...t,"Content-Type":"application/json"},g=new Response(JSON.stringify({success:!0}),{status:200,headers:w});for(const e of h)g.headers.append("Set-Cookie",e);return g}catch{return(0,web_helpers_1.jsonResponse)(200,{success:!0},t)}}async function handleVerifyTriggerWeb(e,r,s,t){try{const i=resolveEmailWithBody(e,r??{},s.resolveEmailAddress);if(!i)return(0,web_helpers_1.jsonResponse)(400,{success:!1,error:{code:"VALIDATION_ERROR",message:"Email is required"}},t);const n=(0,web_helpers_1.extractDeviceIdFromRequestOrUnknown)(e,s.resolveDeviceId),a=(0,web_helpers_1.parseCookieFromRequest)(e,"__unshared_fingerprint_id")||void 0,o=await s.client.triggerEmailVerification(i,n,{fingerprintId:a});return o.success?(0,web_helpers_1.jsonResponse)(200,{success:!0,data:o.data},t):(0,web_helpers_1.jsonResponse)(200,{success:!1,error:o.error??{code:"TRIGGER_FAILED",message:"Failed to send verification email"}},t)}catch(e){return s.onError&&s.onError(e,{operation:"verifyTrigger"}),(0,web_helpers_1.jsonResponse)(200,{success:!1,error:{code:"INTERNAL_ERROR",message:"Failed to trigger verification"}},t)}}async function handleVerifyWeb(e,r,s,t){try{const i=resolveEmailWithBody(e,r??{},s.resolveEmailAddress),n=r?.code;if(!i||!n)return(0,web_helpers_1.jsonResponse)(400,{success:!1,error:{code:"VALIDATION_ERROR",message:"Email and code are required"}},t);const a=(0,web_helpers_1.extractDeviceIdFromRequestOrUnknown)(e,s.resolveDeviceId),o=(0,web_helpers_1.parseCookieFromRequest)(e,"__unshared_fingerprint_id")||void 0,d=await s.client.verify(i,a,n,{fingerprintId:o});if(d.success){const r=(0,web_helpers_1.parseCookieFromRequest)(e,"__unshared_uid");return r&&s.verdictCache.update(r,{isVerified:!0}),(0,web_helpers_1.jsonResponse)(200,{success:!0,data:{verified:!0}},t)}return(0,web_helpers_1.jsonResponse)(200,{success:!1,error:d.error??{code:"VERIFICATION_FAILED",message:"Verification failed"}},t)}catch(e){return s.onError&&s.onError(e,{operation:"verify"}),(0,web_helpers_1.jsonResponse)(200,{success:!1,error:{code:"INTERNAL_ERROR",message:"Verification failed"}},t)}}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "unshared-clientjs-sdk",
|
|
3
|
-
"version": "2.0.0-rc.
|
|
3
|
+
"version": "2.0.0-rc.24",
|
|
4
4
|
"description": "Server-side Node.js SDK for the Unshared Labs V2 API",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"module": "dist/esm/index.mjs",
|
|
@@ -52,7 +52,7 @@
|
|
|
52
52
|
"author": "",
|
|
53
53
|
"license": "MIT",
|
|
54
54
|
"dependencies": {
|
|
55
|
-
"unshared-frontend-sdk": "2.0.0-rc.
|
|
55
|
+
"unshared-frontend-sdk": "2.0.0-rc.24"
|
|
56
56
|
},
|
|
57
57
|
"devDependencies": {
|
|
58
58
|
"@types/express": "^4.17.21",
|