unshared-clientjs-sdk 2.0.0-rc.26 → 2.0.0-rc.27
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,
|
|
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,t)=>{try{const s=i.body??{},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 o,r,d;try{const t=e.resolveUserId?e.resolveUserId(i):void 0;t&&!isSentinelUserId(t)&&(o=t)}catch{}if(!o){const e="string"==typeof s.user_id?s.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")??s.email??void 0;try{d=e.resolveSessionId?e.resolveSessionId(i):void 0}catch{}d=d??s.session_id??parseCookie(i,"__unshared_sid");const a=extractClientIp(i),c=i.headers["user-agent"]??"";if(isBot(c))return void sendJson(t,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=t.getHeader("Set-Cookie");if(e){const i=Array.isArray(e)?[...e]:[String(e)];i.push(..._),t.setHeader("Set-Cookie",i)}else t.setHeader("Set-Cookie",_)}let f;if("string"==typeof s.event_type&&s.event_type)f=s.event_type;else{const e=i.headers.referer??i.headers.referrer;let t="unknown";if("string"==typeof e&&e.length>0)try{const i=new URL(e);t=(i.pathname||"/")+(i.search||"")}catch{}f=t}const h=i.headers["x-idempotency-key"],v="string"==typeof h&&h.length>0?h:void 0,y=Date.now(),I=v?`${v}|${y}`:u&&o?`${u}|${o}|${f}|${y}`:void 0;if(o&&e.client.submitFingerprintEvent(n,{userId:o,emailAddress:r,sessionHash:d,eventType:f,ipAddress:a,userAgent:c,idempotencyKey:I}).catch(i=>{e.onError&&e.onError(i,{operation:"submitFingerprintEvent",userId:o,emailAddress:r})}),o&&r&&!e.rateLimitBackoff.isPaused()&&!e.dispatchDedupe.wasRecentlyDispatched(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(t,200,{success:!0})}catch{sendJson(t,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:r,emailAddress:t,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")??"",r=w.includes("*");return r||w.includes(s)?{"Access-Control-Allow-Origin":r?"*":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:r,resolveEmailAddress:t,resolveSessionId:c,resolveDeviceId:u,onError:m},n):o===S?handleVerifyTriggerWeb(s,i,{client:e,verdictCache:f,resolveEmailAddress:t,resolveDeviceId:u,onError:m},n):handleVerifyWeb(s,i,{client:e,verdictCache:f,resolveEmailAddress:t,resolveDeviceId:u,onError:m},n)}if("GET"===s.method&&o===C){let e;try{e=r(s)}catch{}if(!e)return jsonResponse(200,{status:"anonymous"},n);const i=resolveEmail(s,t),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=r(s)}catch{}if(isSentinelUserId(A)){const e=parseCookieFromRequest(s,"__unshared_uid"),r=parseCookieFromRequest(s,"__unshared_uid_at"),t=r?Number(r):NaN,n=Number.isFinite(t)&&Date.now()-t<=SENTINEL_STICKINESS_TTL_MS;A=e&&n?e:void 0}if(!A){const e=isSecureWebRequest(s)?"; Secure":"",r=[`__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,r)}const E=resolveEmail(s,t),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,O=s.headers.get("user-agent")??"",j=extractClientIpFromRequest(s),L=q??x;if(isBot(O))return i(s);let U=f.get(A);if(U)f.isStale(A)&&!f.isRefreshing(A)&&(f.markRefreshing(A),fetchAndCacheVerdict(e,f,A,E,L??"unknown",x,k).finally(()=>f.clearRefreshing(A)));else try{U=await fetchAndCacheVerdict(e,f,A,E,L??"unknown",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 U.isFlagged||"unknown"===k||!L||h.isPaused()||dispatchUserEvent(e,f,h,_,{userId:A,emailAddress:E,sessionId:k,deviceId:L,fingerprintId:x,userAgent:O,ipAddress:j,eventType:o+R},m),injectIntoHtmlResponse(await i(s),I,F)}}async function injectIntoHtmlResponse(e,s,r){const t=e.headers.get("content-type");if(!isHtmlContentType(t??void 0)){if(!r||0===r.length)return e;const s=mergeResponseHeaders(e.headers,void 0,r);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)},r);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 r=s(e);if(r)return r}catch{}const r=parseCookieFromRequest(e,"__unshared_email");if(r)return r}function resolveEmailWithBody(e,s,r){const t=resolveEmail(e,r);if(t)return t;const n=s.email;return"string"==typeof n&&n?n:void 0}function extractSessionIdFromRequest(e,s){if(s)try{const r=s(e);if(r)return r}catch{}return parseCookieFromRequest(e,"__unshared_sid")??"unknown"}function dispatchUserEvent(e,s,r,t,n,i){t.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&&r.pause(1e3*e.error.retryAfter)}).catch(e=>{i&&i(e,{operation:"processUserEvent",userId:n.userId,emailAddress:n.emailAddress})})}async function fetchAndCacheVerdict(e,s,r,t,n,i,o){const a={};let d;n&&"unknown"!==n&&(a.deviceId=n),i&&(a.fingerprintId=i);const c=await Promise.race([e.checkUser(t,a),new Promise(e=>{d=setTimeout(()=>e(null),500)})]);if(clearTimeout(d),!c)return{isFlagged:!1,isVerified:!1,emailAddress:t,sessionId:o,cachedAt:0,ttl:0};const u=c.data?.is_user_flagged??!1;return s.set(r,{isFlagged:u,isVerified:!1,emailAddress:t,sessionId:o}),s.get(r)}async function handleSubmitFp(e,s,r,t){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=r.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=r.resolveEmailAddress?r.resolveEmailAddress(e):void 0}catch{}o=o??parseCookieFromRequest(e,"__unshared_email")??s.email??void 0;try{a=r.resolveSessionId?r.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},t);const u=(n.fingerprint_id&&n.fingerprint_id.length>0?n.fingerprint_id:void 0)??extractDeviceIdFromRequestOrUnknown(e,r.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 r="unknown";if(s)try{const e=new URL(s);r=(e.pathname||"/")+(e.search||"")}catch{}h=r}const _=(e.headers.get("x-idempotency-key")||void 0)??(l&&i?`${l}|${i}|${h}`:void 0);i&&r.client.submitFingerprintEvent(n,{userId:i,emailAddress:o,sessionHash:a,eventType:h,ipAddress:d,userAgent:c,idempotencyKey:_}).catch(e=>{r.onError&&r.onError(e,{operation:"submitFingerprintEvent",userId:i,emailAddress:o})}),i&&o&&!r.rateLimitBackoff.isPaused()&&!r.dispatchDedupe.wasRecentlyDispatched(i,h)&&r.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&&r.verdictCache.update(i,{isFlagged:e.data.analysis.is_user_flagged}),!e.success&&e.error?.retryAfter&&r.rateLimitBackoff.pause(1e3*e.error.retryAfter)}).catch(e=>{r.onError&&r.onError(e,{operation:"processUserEvent",userId:i,emailAddress:o})});const R={...t,"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},t)}}async function handleVerifyTriggerWeb(e,s,r,t){try{const n=resolveEmailWithBody(e,s??{},r.resolveEmailAddress);if(!n)return jsonResponse(400,{success:!1,error:{code:"VALIDATION_ERROR",message:"Email is required"}},t);const i=extractDeviceIdFromRequestOrUnknown(e,r.resolveDeviceId),o=parseCookieFromRequest(e,"__unshared_fingerprint_id")||void 0,a=await r.client.triggerEmailVerification(n,i,{fingerprintId:o});return a.success?jsonResponse(200,{success:!0,data:a.data},t):jsonResponse(200,{success:!1,error:a.error??{code:"TRIGGER_FAILED",message:"Failed to send verification email"}},t)}catch(e){return r.onError&&r.onError(e,{operation:"verifyTrigger"}),jsonResponse(200,{success:!1,error:{code:"INTERNAL_ERROR",message:"Failed to trigger verification"}},t)}}async function handleVerifyWeb(e,s,r,t){try{const n=resolveEmailWithBody(e,s??{},r.resolveEmailAddress),i=s?.code;if(!n||!i)return jsonResponse(400,{success:!1,error:{code:"VALIDATION_ERROR",message:"Email and code are required"}},t);const o=extractDeviceIdFromRequestOrUnknown(e,r.resolveDeviceId),a=parseCookieFromRequest(e,"__unshared_fingerprint_id")||void 0,d=await r.client.verify(n,o,i,{fingerprintId:a});if(d.success){const s=parseCookieFromRequest(e,"__unshared_uid");return s&&r.verdictCache.update(s,{isVerified:!0}),jsonResponse(200,{success:!0,data:{verified:!0}},t)}return jsonResponse(200,{success:!1,error:d.error??{code:"VERIFICATION_FAILED",message:"Verification failed"}},t)}catch(e){return r.onError&&r.onError(e,{operation:"verify"}),jsonResponse(200,{success:!1,error:{code:"INTERNAL_ERROR",message:"Verification failed"}},t)}}
|
|
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:r,emailAddress:t,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")??"",r=w.includes("*");return r||w.includes(s)?{"Access-Control-Allow-Origin":r?"*":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:r,resolveEmailAddress:t,resolveSessionId:c,resolveDeviceId:u,onError:m},n):o===S?handleVerifyTriggerWeb(s,i,{client:e,verdictCache:f,resolveEmailAddress:t,resolveDeviceId:u,onError:m},n):handleVerifyWeb(s,i,{client:e,verdictCache:f,resolveEmailAddress:t,resolveDeviceId:u,onError:m},n)}if("GET"===s.method&&o===C){let e;try{e=r(s)}catch{}if(!e)return jsonResponse(200,{status:"anonymous"},n);const i=resolveEmail(s,t),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=r(s)}catch{}if(isSentinelUserId(A)){const e=parseCookieFromRequest(s,"__unshared_uid"),r=parseCookieFromRequest(s,"__unshared_uid_at"),t=r?Number(r):NaN,n=Number.isFinite(t)&&Date.now()-t<=SENTINEL_STICKINESS_TTL_MS;A=e&&n?e:void 0}if(!A){const e=isSecureWebRequest(s)?"; Secure":"",r=[`__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,r)}const E=resolveEmail(s,t),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,O=s.headers.get("user-agent")??"",j=extractClientIpFromRequest(s),D=q??x;if(isBot(O))return i(s);let L=f.get(A);if(L)f.isStale(A)&&!f.isRefreshing(A)&&(f.markRefreshing(A),fetchAndCacheVerdict(e,f,A,E,D??"unknown",x,k).finally(()=>f.clearRefreshing(A)));else try{L=await fetchAndCacheVerdict(e,f,A,E,D??"unknown",x,k)}catch{return injectIntoHtmlResponse(await i(s),I,F)}if(L.isFlagged&&!L.isVerified&&p)try{const e=await p({userId:A,emailAddress:E,verdict:L,request:s});if(e)return injectIntoHtmlResponse(e,I,F)}catch(e){m&&m(e,{operation:"checkUser",userId:A,emailAddress:E})}return L.isFlagged||"unknown"===k||!D||h.isPaused()||dispatchUserEvent(e,f,h,_,{userId:A,emailAddress:E,sessionId:k,deviceId:D,fingerprintId:x,userAgent:O,ipAddress:j,eventType:o+R},m),injectIntoHtmlResponse(await i(s),I,F)}}async function injectIntoHtmlResponse(e,s,r){const t=e.headers.get("content-type");if(!isHtmlContentType(t??void 0)){if(!r||0===r.length)return e;const s=mergeResponseHeaders(e.headers,void 0,r);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)},r);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 r=s(e);if(r)return r}catch{}const r=parseCookieFromRequest(e,"__unshared_email");if(r)return r}function resolveEmailWithBody(e,s,r){const t=resolveEmail(e,r);if(t)return t;const n=s.email;return"string"==typeof n&&n?n:void 0}function extractSessionIdFromRequest(e,s){if(s)try{const r=s(e);if(r)return r}catch{}return parseCookieFromRequest(e,"__unshared_sid")??"unknown"}function dispatchUserEvent(e,s,r,t,n,i){t.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&&r.pause(1e3*e.error.retryAfter)}).catch(e=>{i&&i(e,{operation:"processUserEvent",userId:n.userId,emailAddress:n.emailAddress})})}async function fetchAndCacheVerdict(e,s,r,t,n,i,o){const a={};let d;n&&"unknown"!==n&&(a.deviceId=n),i&&(a.fingerprintId=i);const c=await Promise.race([e.checkUser(t,a),new Promise(e=>{d=setTimeout(()=>e(null),500)})]);if(clearTimeout(d),!c)return{isFlagged:!1,isVerified:!1,emailAddress:t,sessionId:o,cachedAt:0,ttl:0};const u=c.data?.is_user_flagged??!1;return s.set(r,{isFlagged:u,isVerified:!1,emailAddress:t,sessionId:o}),s.get(r)}async function handleSubmitFp(e,s,r,t){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=r.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=r.resolveEmailAddress?r.resolveEmailAddress(e):void 0}catch{}o=o??parseCookieFromRequest(e,"__unshared_email")??s.email??void 0;try{a=r.resolveSessionId?r.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},t);const u=(n.fingerprint_id&&n.fingerprint_id.length>0?n.fingerprint_id:void 0)??extractDeviceIdFromRequestOrUnknown(e,r.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 r="unknown";if(s)try{const e=new URL(s);r=(e.pathname||"/")+(e.search||"")}catch{}h=r}const _=e.headers.get("x-idempotency-key")||void 0,R=Date.now(),I=_?`${_}|${R}`:l&&i?`${l}|${i}|${h}|${R}`:void 0;i&&r.client.submitFingerprintEvent(n,{userId:i,emailAddress:o,sessionHash:a,eventType:h,ipAddress:d,userAgent:c,idempotencyKey:I}).catch(e=>{r.onError&&r.onError(e,{operation:"submitFingerprintEvent",userId:i,emailAddress:o})}),i&&o&&!r.rateLimitBackoff.isPaused()&&!r.dispatchDedupe.wasRecentlyDispatched(i,h)&&r.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&&r.verdictCache.update(i,{isFlagged:e.data.analysis.is_user_flagged}),!e.success&&e.error?.retryAfter&&r.rateLimitBackoff.pause(1e3*e.error.retryAfter)}).catch(e=>{r.onError&&r.onError(e,{operation:"processUserEvent",userId:i,emailAddress:o})});const g={...t,"Content-Type":"application/json"},v=new Response(JSON.stringify({success:!0}),{status:200,headers:g});for(const e of f)v.headers.append("Set-Cookie",e);return v}catch{return jsonResponse(200,{success:!0},t)}}async function handleVerifyTriggerWeb(e,s,r,t){try{const n=resolveEmailWithBody(e,s??{},r.resolveEmailAddress);if(!n)return jsonResponse(400,{success:!1,error:{code:"VALIDATION_ERROR",message:"Email is required"}},t);const i=extractDeviceIdFromRequestOrUnknown(e,r.resolveDeviceId),o=parseCookieFromRequest(e,"__unshared_fingerprint_id")||void 0,a=await r.client.triggerEmailVerification(n,i,{fingerprintId:o});return a.success?jsonResponse(200,{success:!0,data:a.data},t):jsonResponse(200,{success:!1,error:a.error??{code:"TRIGGER_FAILED",message:"Failed to send verification email"}},t)}catch(e){return r.onError&&r.onError(e,{operation:"verifyTrigger"}),jsonResponse(200,{success:!1,error:{code:"INTERNAL_ERROR",message:"Failed to trigger verification"}},t)}}async function handleVerifyWeb(e,s,r,t){try{const n=resolveEmailWithBody(e,s??{},r.resolveEmailAddress),i=s?.code;if(!n||!i)return jsonResponse(400,{success:!1,error:{code:"VALIDATION_ERROR",message:"Email and code are required"}},t);const o=extractDeviceIdFromRequestOrUnknown(e,r.resolveDeviceId),a=parseCookieFromRequest(e,"__unshared_fingerprint_id")||void 0,d=await r.client.verify(n,o,i,{fingerprintId:a});if(d.success){const s=parseCookieFromRequest(e,"__unshared_uid");return s&&r.verdictCache.update(s,{isVerified:!0}),jsonResponse(200,{success:!0,data:{verified:!0}},t)}return jsonResponse(200,{success:!1,error:d.error??{code:"VERIFICATION_FAILED",message:"Verification failed"}},t)}catch(e){return r.onError&&r.onError(e,{operation:"verify"}),jsonResponse(200,{success:!1,error:{code:"INTERNAL_ERROR",message:"Verification failed"}},t)}}
|
|
@@ -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=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=
|
|
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,g=Date.now(),y=m?`${m}|${g}`:a&&r?`${a}|${r}|${f}|${g}`:void 0;if(r&&e.client.submitFingerprintEvent(n,{userId:r,emailAddress:o,sessionHash:_,eventType:f,ipAddress:d,userAgent:c,idempotencyKey:y}).catch(i=>{e.onError&&e.onError(i,{operation:"submitFingerprintEvent",userId:r,emailAddress:o})}),r&&o&&!e.rateLimitBackoff.isPaused()&&!e.dispatchDedupe.wasRecentlyDispatched(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,E;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{E=s(r)}catch{}if((0,sentinel_user_id_1.isSentinelUserId)(E)){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;E=e&&i?e:void 0}if(!E){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 R=resolveEmail(r,t),T=[],C=(0,web_helpers_1.isSecureWebRequest)(r)?"; Secure":"";if(T.push(`__unshared_uid=${encodeURIComponent(E)}; Path=/; SameSite=Lax${C}`),T.push(`__unshared_uid_at=${Date.now()}; Path=/; SameSite=Lax${C}`),R&&T.push(`__unshared_email=${encodeURIComponent(R)}; HttpOnly; Path=/; SameSite=Lax${C}`),!R)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")??"",k=(0,web_helpers_1.extractClientIpFromRequest)(r),L=x??P;if((0,is_bot_1.isBot)($))return n(r);let N=h.get(E);if(N)h.isStale(E)&&!h.isRefreshing(E)&&(h.markRefreshing(E),fetchAndCacheVerdict(e,h,E,R,L??"unknown",P,O).finally(()=>h.clearRefreshing(E)));else try{N=await fetchAndCacheVerdict(e,h,E,R,L??"unknown",P,O)}catch{return injectIntoHtmlResponse(await n(r),g,T)}if(N.isFlagged&&!N.isVerified&&u)try{const e=await u({userId:E,emailAddress:R,verdict:N,request:r});if(e)return injectIntoHtmlResponse(e,g,T)}catch(e){p&&p(e,{operation:"checkUser",userId:E,emailAddress:R})}return N.isFlagged||"unknown"===O||!L||f.isPaused()||dispatchUserEvent(e,h,f,m,{userId:E,emailAddress:R,sessionId:O,deviceId:L,fingerprintId:P,userAgent:$,ipAddress:k,eventType:a+w},p),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.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)}}
|
|
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,E;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{E=s(r)}catch{}if((0,sentinel_user_id_1.isSentinelUserId)(E)){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;E=e&&i?e:void 0}if(!E){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 R=resolveEmail(r,t),T=[],C=(0,web_helpers_1.isSecureWebRequest)(r)?"; Secure":"";if(T.push(`__unshared_uid=${encodeURIComponent(E)}; Path=/; SameSite=Lax${C}`),T.push(`__unshared_uid_at=${Date.now()}; Path=/; SameSite=Lax${C}`),R&&T.push(`__unshared_email=${encodeURIComponent(R)}; HttpOnly; Path=/; SameSite=Lax${C}`),!R)return injectIntoHtmlResponse(await n(r),g,T);const O=extractSessionIdFromRequest(r,c),$=(0,web_helpers_1.extractDeviceIdFromRequest)(r,_),x=(0,web_helpers_1.parseCookieFromRequest)(r,"__unshared_fingerprint_id")||void 0,P=r.headers.get("user-agent")??"",k=(0,web_helpers_1.extractClientIpFromRequest)(r),L=$??x;if((0,is_bot_1.isBot)(P))return n(r);let N=h.get(E);if(N)h.isStale(E)&&!h.isRefreshing(E)&&(h.markRefreshing(E),fetchAndCacheVerdict(e,h,E,R,L??"unknown",x,O).finally(()=>h.clearRefreshing(E)));else try{N=await fetchAndCacheVerdict(e,h,E,R,L??"unknown",x,O)}catch{return injectIntoHtmlResponse(await n(r),g,T)}if(N.isFlagged&&!N.isVerified&&u)try{const e=await u({userId:E,emailAddress:R,verdict:N,request:r});if(e)return injectIntoHtmlResponse(e,g,T)}catch(e){p&&p(e,{operation:"checkUser",userId:E,emailAddress:R})}return N.isFlagged||"unknown"===O||!L||f.isPaused()||dispatchUserEvent(e,h,f,m,{userId:E,emailAddress:R,sessionId:O,deviceId:L,fingerprintId:x,userAgent:P,ipAddress:k,eventType:a+w},p),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,w=Date.now(),g=m?`${m}|${w}`:l&&n?`${l}|${n}|${f}|${w}`:void 0;n&&s.client.submitFingerprintEvent(i,{userId:n,emailAddress:a,sessionHash:o,eventType:f,ipAddress:d,userAgent:c,idempotencyKey:g}).catch(e=>{s.onError&&s.onError(e,{operation:"submitFingerprintEvent",userId:n,emailAddress:a})}),n&&a&&!s.rateLimitBackoff.isPaused()&&!s.dispatchDedupe.wasRecentlyDispatched(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 b={...t,"Content-Type":"application/json"},v=new Response(JSON.stringify({success:!0}),{status:200,headers:b});for(const e of h)v.headers.append("Set-Cookie",e);return v}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.27",
|
|
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.27"
|
|
56
56
|
},
|
|
57
57
|
"devDependencies": {
|
|
58
58
|
"@types/express": "^4.17.21",
|