Help
RSS
API
Feed
Maltego
Contact
Domain > connect.sunlightapi.com
×
More information on this domain is in
AlienVault OTX
Is this malicious?
Yes
No
DNS Resolutions
Date
IP Address
2024-06-10
65.8.178.95
(
ClassC
)
2024-08-14
54.230.202.64
(
ClassC
)
2025-10-09
3.169.173.77
(
ClassC
)
Port 80
HTTP/1.1 301 Moved PermanentlyServer: CloudFrontDate: Thu, 09 Oct 2025 00:59:06 GMTContent-Type: text/htmlContent-Length: 167Connection: keep-aliveLocation: https://connect.sunlightapi.com/X-Cache: Redirect from cloudfrontVia: 1.1 7d14d4fc1c149f1d429681a4c414c21a.cloudfront.net (CloudFront)X-Amz-Cf-Pop: HIO52-P4X-Amz-Cf-Id: TFCuBukA9oOYFDmHmgYYL2fYC5xmLQif6jZMOq_UMc_eQBNsUSGH0w html>head>title>301 Moved Permanently/title>/head>body>center>h1>301 Moved Permanently/h1>/center>hr>center>CloudFront/center>/body>/html>
Port 443
HTTP/1.1 200 OKContent-Type: text/htmlContent-Length: 45601Connection: keep-aliveDate: Wed, 08 Oct 2025 19:29:51 GMTLast-Modified: Thu, 11 Sep 2025 09:48:32 GMTETag: 1db5cd669a0f1d7d2ec979801f1e0a20x-amz-server-side-encryption: AES256x-amz-version-id: TOf.GWzDdUQAaAPaqOWBgm0fGedG8R5uAccept-Ranges: bytesServer: AmazonS3X-Cache: Hit from cloudfrontVia: 1.1 743dabf2fdbfd64c0bd7adf3cea9dbec.cloudfront.net (CloudFront)X-Amz-Cf-Pop: HIO52-P4X-Amz-Cf-Id: g2Z5K3vVvAayfWh8Vnd5wRa0a1zDoMG6o4FNiIapIYOSSm9ZwzpLCQAge: 19756 !--This is a generated file (2025/09/11 09:44:51). check out scripts folder for more details -->!doctype html>html langen>head> meta charsetUTF-8> meta contentwidthdevice-width, initial-scale1 nameviewport> style> :root { --primary-color: #6366f1; --primary-hover: #4f46e5; --primary-light: #e0e7ff; --secondary-color: #f1f5f9; --text-primary: #0f172a; --text-secondary: #64748b; --text-muted: #94a3b8; --border-color: #e2e8f0; --border-hover: #cbd5e1; --success-color: #10b981; --error-color: #ef4444; --warning-color: #f59e0b; --bg-primary: #ffffff; --bg-secondary: #f8fafc; --shadow-sm: 0 1px 2px 0 rgb(0 0 0 / 0.05); --shadow-md: 0 4px 6px -1px rgb(0 0 0 / 0.1), 0 2px 4px -2px rgb(0 0 0 / 0.1); --shadow-lg: 0 10px 15px -3px rgb(0 0 0 / 0.1), 0 4px 6px -4px rgb(0 0 0 / 0.1); --shadow-xl: 0 20px 25px -5px rgb(0 0 0 / 0.1), 0 8px 10px -6px rgb(0 0 0 / 0.1); --radius-sm: 0.375rem; --radius-md: 0.5rem; --radius-lg: 0.75rem; --radius-xl: 1rem; } * { box-sizing: border-box; } html { font-family: -apple-system, BlinkMacSystemFont, Segoe UI, Roboto, Oxygen, Ubuntu, Cantarell, sans-serif; line-height: 1.6; scroll-behavior: smooth; } body { background: linear-gradient(135deg, #667eea 0%, #764ba2 100%); margin: 0; padding: 0; min-height: 100vh; color: var(--text-primary); } .container { max-width: 1200px; margin: 2rem auto; padding: 0 1rem; display: flex; flex-direction: column; gap: 2rem; } .container-inner { display: grid; grid-template-columns: 1fr; gap: 2rem; } @media (min-width: 1024px) { .container-inner { grid-template-columns: 1fr 400px; gap: 3rem; } } .left-section { background: var(--bg-primary); border-radius: var(--radius-xl); padding: 2rem; box-shadow: var(--shadow-xl); backdrop-filter: blur(10px); border: 1px solid rgba(255, 255, 255, 0.1); } .right-section { background: var(--bg-primary); border-radius: var(--radius-xl); padding: 2rem; box-shadow: var(--shadow-xl); backdrop-filter: blur(10px); border: 1px solid rgba(255, 255, 255, 0.1); display: flex; flex-direction: column; align-items: center; gap: 1.5rem; } .header { background: var(--bg-primary); border-radius: var(--radius-xl); padding: 1.5rem 2rem; box-shadow: var(--shadow-xl); backdrop-filter: blur(10px); border: 1px solid rgba(255, 255, 255, 0.1); display: flex; justify-content: space-between; align-items: center; margin-bottom: 0; } .header img { height: 48px; filter: drop-shadow(0 2px 4px rgba(0, 0, 0, 0.1)); } .header .env-info { font-size: 0.875rem; color: var(--text-muted); font-weight: 500; background: var(--secondary-color); padding: 0.5rem 1rem; border-radius: var(--radius-md); border: 1px solid var(--border-color); } .collapsible { background: linear-gradient(135deg, var(--primary-color), var(--primary-hover)); color: white; font-weight: 600; cursor: pointer; padding: 1.25rem 1.5rem; width: 100%; border: none; text-align: left; outline: none; font-size: 1.125rem; transition: all 0.2s cubic-bezier(0.4, 0, 0.2, 1); border-radius: var(--radius-lg); margin-bottom: 0.5rem; position: relative; overflow: hidden; } .collapsible::before { content: ; position: absolute; top: 0; left: 0; right: 0; bottom: 0; background: linear-gradient(135deg, rgba(255, 255, 255, 0.1), transparent); opacity: 0; transition: opacity 0.2s; } .collapsible:hover::before { opacity: 1; } .collapsible:hover { transform: translateY(-1px); box-shadow: var(--shadow-lg); } .collapsible:after { content: +; color: rgba(255, 255, 255, 0.8); font-weight: 300; font-size: 1.5rem; float: right; transition: transform 0.2s; } .collapsible.active:after { transform: rotate(45deg); } .content { padding: 0; max-height: 0; overflow: hidden; transition: max-height 0.3s cubic-bezier(0.4, 0, 0.2, 1), padding 0.3s; background: var(--bg-secondary); border-radius: 0 0 var(--radius-lg) var(--radius-lg); margin-bottom: 1rem; } .content.active { padding: 1.5rem; } .form-group { margin-bottom: 1.5rem; } .form-group label { display: block; font-size: 0.875rem; font-weight: 600; margin-bottom: 0.5rem; color: var(--text-primary); } .form-group inputtypetext, .form-group inputtypenumber, .form-group select { width: 100%; padding: 0.875rem 1rem; font-size: 1rem; border: 2px solid var(--border-color); border-radius: var(--radius-md); background: var(--bg-primary); color: var(--text-primary); transition: all 0.2s; } .form-group input:focus, .form-group select:focus { outline: none; border-color: var(--primary-color); box-shadow: 0 0 0 3px rgba(99, 102, 241, 0.1); } .form-group input:hover, .form-group select:hover { border-color: var(--border-hover); } .button-group { display: flex; flex-direction: column; gap: 1rem; width: 100%; } .button-group button { background: linear-gradient(135deg, var(--primary-color), var(--primary-hover)); color: white; border: none; padding: 1rem 1.5rem; font-size: 1rem; font-weight: 600; cursor: pointer; border-radius: var(--radius-lg); transition: all 0.2s cubic-bezier(0.4, 0, 0.2, 1); position: relative; overflow: hidden; min-height: 3.5rem; display: flex; align-items: center; justify-content: center; gap: 0.5rem; } .button-group button::before { content: ; position: absolute; top: 0; left: 0; right: 0; bottom: 0; background: linear-gradient(135deg, rgba(255, 255, 255, 0.1), transparent); opacity: 0; transition: opacity 0.2s; } .button-group button:hover::before { opacity: 1; } .button-group button:hover { transform: translateY(-2px); box-shadow: var(--shadow-xl); } .button-group button:active { transform: translateY(0); } .progress-bar { width: 100%; height: 0.75rem; background-color: var(--secondary-color); border-radius: var(--radius-md); overflow: hidden; box-shadow: inset 0 1px 3px rgba(0, 0, 0, 0.1); } .progress { width: 0; height: 100%; background: linear-gradient(90deg, var(--primary-color), var(--primary-hover)); transition: width 0.5s cubic-bezier(0.4, 0, 0.2, 1); border-radius: var(--radius-md); position: relative; } .progress::after { content: ; position: absolute; top: 0; left: 0; right: 0; bottom: 0; background: linear-gradient(90deg, transparent, rgba(255, 255, 255, 0.2), transparent); animation: shimmer 2s infinite; } @keyframes shimmer { 0% { transform: translateX(-100%); } 100% { transform: translateX(100%); } } .progress-text { margin-top: 1rem; text-align: center; font-size: 0.875rem; font-weight: 500; color: var(--text-secondary); } .render-mode-toggle { display: flex; align-items: center; gap: 0.75rem; margin-bottom: 1.5rem; } .render-mode-toggle label { font-size: 0.875rem; font-weight: 600; color: var(--text-primary); margin: 0; } .render-mode-toggle select { min-width: 120px; } #render-container { width: 375px; height: 608px; margin: 0 auto; position: relative; box-sizing: border-box; display: none; border: 2px dashed var(--border-color); border-radius: var(--radius-lg); background: var(--bg-secondary); } .section-wrapper { margin-bottom: 1rem; } #progress-body { width: 100%; display: flex; flex-direction: column; align-items: center; margin-bottom: 2rem; padding: 1.5rem; background: var(--bg-secondary); border-radius: var(--radius-lg); border: 1px solid var(--border-color); } .platform-card-pair { display: flex; gap: 0.5rem; align-items: center; margin-bottom: 0.75rem; } .platform-card-pair input { flex: 1; } .platform-card-pair button { background: var(--error-color); color: white; border: none; padding: 0.5rem; border-radius: var(--radius-sm); cursor: pointer; font-size: 1.125rem; width: 2.5rem; height: 2.5rem; display: flex; align-items: center; justify-content: center; transition: all 0.2s; } .platform-card-pair button:hover { background: #dc2626; transform: scale(1.1); } .add-platform-button { background: var(--success-color) !important; color: white !important; border: none !important; padding: 0.75rem 1rem !important; margin-top: 0.75rem !important; border-radius: var(--radius-md) !important; cursor: pointer !important; font-weight: 500 !important; transition: all 0.2s !important; width: 100% !important; } .add-platform-button:hover { background: #059669 !important; transform: translateY(-1px) !important; } @media (max-width: 640px) { .container { margin: 1rem; padding: 0; } .header { padding: 1rem; flex-direction: column; gap: 1rem; text-align: center; } .left-section, .right-section { padding: 1.5rem; } #render-container { width: 100%; max-width: 375px; } } @media only screen and (-webkit-min-device-pixel-ratio: 2) and (orientation: portrait) and (pointer: coarse) { #render-container { width: 375px; height: 100%; min-height: 608px; } } /style> title>Sunlight Connect PROD/title> link hrefhttps://images.sunlightapi.com/connect-app/images/favicon.ico relicon typeimage/x-icon>/head>body>div classcontainer> div classheader>img altSunlight Logo srchttps://images.sunlightapi.com/connect-app/images/logo.png> span classenv-info>Running on PROD (1.11.6)/span> /div> div classcontainer-inner> div classleft-section> div classsection-wrapper> button classcollapsible typebutton>Connect/button> div classcontent> div classform-group> label forapikey>API Key/label> input idapikey nameapikey typetext value> /div> div classform-group> label forsecret>Secret Key/label> input idsecret namesecret typetext value> /div> div classform-group> label foruserId>External User ID/label> input iduserId nameuserId typetext value> /div> div classform-group> label foraccessToken>Access Token (Optional for Setting Card Details via API)/label> input idaccessToken nameaccessToken typetext value> /div> div classform-group> label forcustomizationValue>Customization ID/label> input idcustomizationValue namecustomizationId typetext value> /div> /div> /div> div classsection-wrapper> button classcollapsible typebutton>Card/button> div classcontent> div classform-group> label forcardIdentifier>Card Identifier (Legacy)/label> input idcardIdentifier namecardIdentifierId typetext value> /div> div classform-group> label>Platform Card Identifiers/label> div idplatformCardIdentifiers> div classplatform-card-pair> input typetext placeholderPlatform Key classplatform-key> input typetext placeholderCard Identifier classcard-identifier> button typebutton onclickremovePlatformCardPair(this)>×/button> /div> /div> button typebutton onclickaddPlatformCardPair() classadd-platform-button>+ Add Platform Card/button> /div> div classform-group> label forcardPan>Card PAN/label> input idcardPan namecardPan typetext value> /div> div classform-group> label forcardExp>Card Expiration/label> input idcardExp namecardExp typetext value> /div> div classform-group> label forcardCvv>Card CVV/label> input idcardCvv namecardCvv typetext value> /div> /div> /div> div classsection-wrapper> button classcollapsible typebutton>CHD/button> div classcontent> div classform-group> label forcardFirstName>First Name/label> input idcardFirstName namecardFirstName typetext value> /div> div classform-group> label forcardLastName>Last Name/label> input idcardLastName namecardLastName typetext value> /div> div classform-group> label forcardMiddleName>Middle Name/label> input idcardMiddleName namecardMiddleName typetext value> /div> div classform-group> label forcardAddress1>Address 1/label> input idcardAddress1 namecardAddress1 typetext value> /div> div classform-group> label forcardAddress2>Address 2/label> input idcardAddress2 namecardAddress2 typetext value> /div> div classform-group> label forcardCity>City/label> input idcardCity namecardCity typetext value> /div> div classform-group> label forcardState>State/label> input idcardState namecardState typetext value> /div> div classform-group> label forcardCountry>Country/label> input idcardCountry namecardCountry typetext value> /div> div classform-group> label forcardPostalCode>Postal Code/label> input idcardPostalCode namecardPostalCode typetext value> /div> div classform-group> label forcardEmail>Email/label> input idcardEmail namecardEmail typetext value> /div> div classform-group> label forcardPhone>Phone/label> input idcardPhone namecardPhone typetext value> /div> div classform-group> label forcardGovernmentId>Government ID/label> input idcardGovernmentId namecardGovernmentId typetext value> /div> div classform-group> label forcardPassport>Passport/label> input idcardPassport namecardPassport typetext value> /div> /div> /div> div classsection-wrapper> button classcollapsible typebutton>Delegation/button> div classcontent> div classform-group> label fortokenTTL>Token TTL in hours/label> input idtokenTTL nametokenTTL typenumber value3> /div> /div> /div> div classsection-wrapper> button classcollapsible typebutton>Branding/button> div classcontent> div classform-group> label forcustomerName>Customer Name/label> input idcustomerName namecustomerName typetext value> /div> div classform-group> label forcustomerLogo>Customer Logo/label> input idcustomerLogo namecustomerLogo typetext value> /div> /div> /div> div classsection-wrapper> button classcollapsible typebutton>Invoice/button> div classcontent> div classform-group> label forinvoiceId>Invoice ID/label> input idinvoiceId nameinvoiceId typetext value> /div> /div> /div> /div> div idprogress-body> div classprogress-bar> div classprogress idprogressBar>/div> /div> div classprogress-text idprogressText>Step 1: Initializing.../div> /div> div classright-section> div classrender-mode-toggle> label forrender-mode>Render Mode:/label> select idrender-mode> option valuemodal>Modal/option> option valuecontainer>Container/option> /select> /div> div classbutton-group> button onclickstartConnect()>Connect 🚀/button> button onclickstartThinDelegationTask()>Thin Delegation Task 🔑/button> button onclickstartDelegationTask()>Delegation Task 🔒/button> /div> div idrender-container>/div> /div> /div>/div>/body>script srcsunlight-connect-1.11.6.js>/script>script> var coll document.getElementsByClassName(collapsible); var i; for (i 0; i coll.length; i++) { colli.addEventListener(click, function () { this.classList.toggle(active); var content this.nextElementSibling; if (content.style.maxHeight) { content.style.maxHeight null; content.classList.remove(active); } else { content.style.maxHeight content.scrollHeight + px; content.classList.add(active); } }); } coll0.click()/script>script> addEventListener(load, () > { setProgressVisibility(false); }) console.log(!!!! Sunlight PROD Server !!!!) let sunlightConnect null; async function startThinDelegationTask() { await _startDelegationTask(initThinDelegatedTask) } async function startDelegationTask() { await _startDelegationTask(iniDelegatedTask) } async function _startDelegationTask(func) { setButtonState(true); setProgressVisibility(true); const inputApiKey document.getElementById(apikey).value; const inputSecret document.getElementById(secret).value; const renderMode document.getElementById(render-mode).value; if (inputApiKey ) { alert(missing API Key) return } if (inputSecret ) { alert(missing Secret Key) return } // Prepare the container if needed let renderContainer document.getElementById(render-container); // If container exists but might have a shadow root, replace it if (renderContainer) { const parent renderContainer.parentNode; renderContainer.remove(); // Create new container with proper styling renderContainer document.createElement(div); renderContainer.id render-container; renderContainer.style.width 375px; renderContainer.style.height 608px; renderContainer.style.margin 20px auto; renderContainer.style.position relative; renderContainer.style.boxSizing border-box; renderContainer.style.border 1px dashed #ccc; // Check if were on mobile if (window.matchMedia((-webkit-min-device-pixel-ratio: 2) and (orientation: portrait) and (pointer: coarse)).matches) { renderContainer.style.height 100%; renderContainer.style.minHeight 608px; } parent.appendChild(renderContainer); } if (renderMode container) { // Show the container renderContainer.style.display block; } else { // Hide the container renderContainer.style.display none; } await func() } async function startConnect() { setButtonState(true); setProgressVisibility(true); const inputApiKey document.getElementById(apikey).value; const inputSecret document.getElementById(secret).value; const inputUserId document.getElementById(userId).value; const accessToken document.getElementById(accessToken).value; const renderMode document.getElementById(render-mode).value; if (inputApiKey ) { alert(missing API Key) return } if (inputSecret ) { alert(missing Secret Key) return } if (inputUserId ) { alert(missing User ID) return } // Prepare the container if needed let renderContainer document.getElementById(render-container); // If container exists but might have a shadow root, replace it if (renderContainer) { const parent renderContainer.parentNode; renderContainer.remove(); // Create new container with proper styling renderContainer document.createElement(div); renderContainer.id render-container; renderContainer.style.width 375px; renderContainer.style.height 608px; renderContainer.style.margin 20px auto; renderContainer.style.position relative; renderContainer.style.boxSizing border-box; renderContainer.style.border 1px dashed #ccc; // Check if were on mobile if (window.matchMedia((-webkit-min-device-pixel-ratio: 2) and (orientation: portrait) and (pointer: coarse)).matches) { renderContainer.style.height 100%; renderContainer.style.minHeight 608px; } parent.appendChild(renderContainer); } if (renderMode container) { // Show the container renderContainer.style.display block; } else { // Hide the container renderContainer.style.display none; } const userId inputUserId try { nextStep(50, Step 1: Generating Access Token...) const token accessToken.length > 0 ? accessToken : await generateAccessToken(userId); nextStep(100, Done) initSunlightConnect({userId: userId, token: token}) } catch (e) { failStep(e.message) console.error(e) } } function openSunlight(sunlight) { sunlightConnect sunlight const renderMode document.getElementById(render-mode).value; const containerId renderMode container ? render-container : null; sunlightConnect.open(containerId, { styleNonce: 7010309194 }); sunlightConnect.on(app-closed, (obj) > { console.log(\u001b34mHTML app-closed hook, obj); setProgressVisibility(false); setButtonState(false); // Clear the container when SDK is closed const renderContainer document.getElementById(render-container); if (renderContainer) { // Remove the container and recreate it to avoid shadow DOM issues const parent renderContainer.parentNode; renderContainer.remove(); // Create new container with proper styling const newContainer document.createElement(div); newContainer.id render-container; newContainer.style.width 375px; newContainer.style.height 608px; newContainer.style.margin 20px auto; newContainer.style.position relative; newContainer.style.boxSizing border-box; newContainer.style.border 1px dashed #ccc; newContainer.style.display none; // Check if were on mobile if (window.matchMedia((-webkit-min-device-pixel-ratio: 2) and (orientation: portrait) and (pointer: coarse)).matches) { newContainer.style.height 100%; newContainer.style.minHeight 608px; } parent.appendChild(newContainer); } }); sunlightConnect.on(app-opened, () > { console.log(\u001b34mHTML app-opened event - UI is stable and rendered); }); sunlightConnect.on(analytics, (event) > { console.log(\u001b34mHTML analytics event + JSON.stringify(event)); }); sunlightConnect.on(delegation-link-generated, (event) > { const platformId eventplatform_id const platformName eventplatform_name const delegationURL eventdelegation_url console.log(\u001b34mHTML delegation link generated + JSON.stringify(event)) }); sunlightConnect.on(card-switch-requested, (event) > { const platformId eventplatform_id const platformName eventplatform_name console.log(\u001b34mHTML card switch requested for: + JSON.stringify(event)) }); sunlightConnect.on(card-switch-completed, (event) > { const operationId eventoperation_id const platformId eventplatform_id const platformName eventplatform_name const status eventstatus const errorReason eventerror_reason console.log(\u001b34mHTML card switch completed for: + JSON.stringify(event)) }); } function initSunlightConnect(input) { const config { userId: input.userId, token: input.token, debug: true }; if (getStringValueFromInput(customerName)) { config.branding { customerName: getStringValueFromInput(customerName), customerLogo: getStringValueFromInput(customerLogo), } } if (getStringValueFromInput(invoiceId)) { config.invoicePayload { invoiceIdentifier: getStringValueFromInput(invoiceId) } } if (getStringValueFromInput(customizationValue)) config.customizationId getStringValueFromInput(customizationValue) const cardPayload {} const cardIdentifier getStringValueFromInput(cardIdentifier) if (cardIdentifier) cardPayload.cardIdentifier cardIdentifier const platformCardIdentifiers getPlatformCardIdentifiers() if (platformCardIdentifiers) cardPayload.platformCardIdentifiers platformCardIdentifiers const cardDetails { pan: getStringValueFromInput(cardPan), cvv: getStringValueFromInput(cardCvv), expDate: getStringValueFromInput(cardExp), } if (removeNullKeys(cardDetails)) cardPayload.cardDetails removeNullKeys(cardDetails) const cardExtraFields { firstName: getStringValueFromInput(cardFirstName), lastName: getStringValueFromInput(cardLastName), middleName: getStringValueFromInput(cardMiddleName), country: getStringValueFromInput(cardCountry), postalCode: getStringValueFromInput(cardPostalCode), state: getStringValueFromInput(cardState), city: getStringValueFromInput(cardCity), address1: getStringValueFromInput(cardAddress1), address2: getStringValueFromInput(cardAddress2), email: getStringValueFromInput(cardEmail), phone: getStringValueFromInput(cardPhone), governmentId: getStringValueFromInput(cardGovernmentId), passport: getStringValueFromInput(cardPassport), } if (removeNullKeys(cardPayload)) config.cardPayload removeNullKeys(cardPayload) if (removeNullKeys(cardExtraFields)) config.cardExtraFields removeNullKeys(cardExtraFields) console.log(HTML, config) openSunlight(SunlightConnect.initialize(removeNullKeys(config))); } async function initThinDelegatedTask() { let customizationId getStringValueFromInput(customizationValue) try { nextStep(10, Step 1: Create User...) const users await Promise.all( await generateUser(), ) nextStep(30, Step 2: Create Access Token...) const tokens await Promise.all( await generateAccessToken(users0), ) let cardId `external-card-${Math.floor(Math.random() * 100)}`; nextStep(60, Step 3: Set Card Details...) await setCardDetails(users0, tokens0, cardId) nextStep(100, Done) let config { userId: users0, token: tokens0, customizationId, cardPayload: { cardIdentifier: cardId } }; // Also add platform card identifiers if they exist in the UI const platformCardIdentifiers getPlatformCardIdentifiers() if (platformCardIdentifiers) { config.cardPayload.platformCardIdentifiers platformCardIdentifiers } console.log(HTML, config) openSunlight(SunlightConnect.initialize(config)); } catch (e) { failStep(e.message) console.error(e) } } async function iniDelegatedTask() { let customizationId getStringValueFromInput(customizationValue) try { nextStep(10, Step 1: Create Users...) const users await Promise.all( await generateUser(), await generateUser() ) nextStep(30, Step 2: Create Access Tokens...) const tokens await Promise.all( await generateAccessToken(users0), await generateAccessToken(users1), ) let cardId `external-card-${Math.floor(Math.random() * 100)}`; nextStep(60, Step 3: Set Card Details...) await setCardDetails(users0, tokens0, cardId) nextStep(70, Step 4: Set Assignee Token Duration...) await extendAccessToken(users1, tokens1) nextStep(80, Step 5: Create Delegation Task...) const delegationTaskId await createDelegationTask(users0, tokens0, users1, tokens1, cardId, customizationId) nextStep(100, Done) openSunlight(SunlightConnect.Auth.initialize({delegationId: delegationTaskId, debug: true})); } catch (e) { failStep(e.message) console.error(e) } } async function generateAccessToken(userId) { const inputApiKey document.getElementById(apikey).value; const inputSecret document.getElementById(secret).value; const headers new Headers(); headers.append(x-api-key, inputApiKey); headers.append(x-secret-key, inputSecret); headers.append(x-version, 1); headers.append(Content-Type, application/json); headers.append(Accept, application/json); const response await fetch(https://api.sunlightapi.com/api/generate_token, { method: POST, headers: headers, body: JSON.stringify({ user_external_id: userId }), redirect: follow }) const data await response.json(); if (dataerror_code) { throw Error(dataerror_message) } if (data.token null) { throw Error(`token is null`) } return data.token } async function extendAccessToken(userId, accessToken) { const inputApiKey document.getElementById(apikey).value; const inputSecret document.getElementById(secret).value; const tokenTTL document.getElementById(tokenTTL).value; if (tokenTTL 3) return const headers new Headers(); headers.append(x-api-key, inputApiKey); headers.append(x-secret-key, inputSecret); headers.append(x-version, 1); headers.append(Content-Type, application/json); headers.append(Accept, application/json); const response await fetch(https://api.sunlightapi.com/api/extend_token_expiration, { method: POST, headers: headers, body: JSON.stringify({ user_external_id: userId, access_token: accessToken, duration_in_hours: tokenTTL }), redirect: follow }) const data await response.json(); if (dataerror_code) { throw Error(dataerror_message) } if (data.token null) { throw Error(token is null) } console.log(access token, accessToken, duration, tokenTTL) return data.token } async function generateUser() { const inputApiKey document.getElementById(apikey).value; const inputSecret document.getElementById(secret).value; const headers new Headers(); headers.append(x-api-key, inputApiKey); headers.append(x-secret-key, inputSecret); headers.append(x-version, 1); headers.append(Content-Type, application/json); headers.append(Accept, application/json); const response await fetch(https://api.sunlightapi.com/api/create_user, { method: POST, headers: headers, redirect: follow }) const data await response.json(); if (dataerror_code) { throw Error(dataerror_message) } if (data.user_external_id null) { throw Error(user_external_id is null) } return data.user_external_id } async function setCardDetails(userId, token, cardId) { const inputApiKey document.getElementById(apikey).value; const inputSecret document.getElementById(secret).value; const headers new Headers(); headers.append(x-api-key, inputApiKey); headers.append(x-secret-key, inputSecret); headers.append(x-version, 1); headers.append(Content-Type, application/json); headers.append(Accept, application/json); await fetch(https://api.sunlightapi.com/api/set_card_details, { method: POST, headers: headers, redirect: follow, body: JSON.stringify({ user_external_id: userId, access_token: token, pan: 4111111111111111, cvv: 123, exp_date: 12/31, card_id: cardId }) }) } async function createDelegationTask(userId1, token1, userId2, token2, cardId, customizationId) { const inputApiKey document.getElementById(apikey).value; const inputSecret document.getElementById(secret).value; const headers new Headers(); headers.append(x-api-key, inputApiKey); headers.append(x-secret-key, inputSecret); headers.append(x-version, 1); headers.append(Content-Type, application/json); headers.append(Accept, application/json); const response await fetch(https://api.sunlightapi.com/api/delegation-tasks, { method: POST, headers: headers, body: JSON.stringify({ requester: { user_external_id: userId1, access_token: token1 }, assignee: { user_external_id: userId2, access_token: token2, email_address: jmiller@sunlightapi.com }, card_id: cardId, customization_id: customizationId }) }) const data await response.json(); if (dataerror_code) { throw Error(dataerror_message) } if (datadelegation_task_id null) { throw Error(delegation_task_id is null) } return datadelegation_task_id } function removeNullKeys(obj) { const newObj Object.fromEntries( Object.entries(obj).filter((_, value) > value ! null) ); return Object.keys(newObj).length 0 ? null : newObj; } function getStringValueFromInput(name) { let value document.getElementById(name)?.value; return value ? null : value; } function nextStep(progress, text) { const progressBar document.getElementById(progressBar); const progressText document.getElementById(progressText); progressBar.style.width `${progress}%`; progressText.innerText text; progressText.style.color black; } function failStep(text) { const progressBar document.getElementById(progressBar); const progressText document.getElementById(progressText); progressBar.style.width `0%`; progressText.innerText text; progressText.style.color red; setButtonState(false) } function setButtonState(disabled) { const submitButtons document.getElementsByClassName(submit-button); for (let i 0; i submitButtons.length; i++) { submitButtonsi.disabled disabled; } } function setProgressVisibility(visible) { document.getElementById(progress-body).style.display visible ? flex : none } function addPlatformCardPair() { const container document.getElementById(platformCardIdentifiers); const pairDiv document.createElement(div); pairDiv.className platform-card-pair; pairDiv.style.marginTop 0.5rem; pairDiv.innerHTML ` input typetext placeholderPlatform Key classplatform-key> input typetext placeholderCard Identifier classcard-identifier> button typebutton onclickremovePlatformCardPair(this)>×/button> `; container.appendChild(pairDiv); } function removePlatformCardPair(button) { const container document.getElementById(platformCardIdentifiers); const pairDiv button.parentNode; // Keep at least one pair if (container.children.length > 1) { container.removeChild(pairDiv); } else { // Clear the values of the last remaining pair pairDiv.querySelector(.platform-key).value ; pairDiv.querySelector(.card-identifier).value ; } } function getPlatformCardIdentifiers() { const pairs document.querySelectorAll(.platform-card-pair); const platformCardIdentifiers {}; pairs.forEach(pair > { const platformKey pair.querySelector(.platform-key).value.trim(); const cardId pair.querySelector(.card-identifier).value.trim(); if (platformKey && cardId) { platformCardIdentifiersplatformKey cardId; } }); return Object.keys(platformCardIdentifiers).length > 0 ? platformCardIdentifiers : null; }/script>/html>
View on OTX
|
View on ThreatMiner
Please enable JavaScript to view the
comments powered by Disqus.
Data with thanks to
AlienVault OTX
,
VirusTotal
,
Malwr
and
others
. [
Sitemap
]