Skip to main content
malware code on a laptop monitor

Cybersecurity

Improve the security of your products and systems with our cybersecurity solutions. We'll help you understand and manage your risks, secure your products and protect your brand’s integrity.

Contact us

Building cybersecurity into connected products is a critical component needed to unlock the vast potential of IoT and OT innovation. If done well, it empowers companies to successfully implement their business strategy, mitigate risks, protect their brand reputation, create product differentiation and establish market leadership.      

Even with the advancement of connected product innovation across industries, most products today are still built to functional, cost and time-to-market objectives. Security may not be a primary consideration and the regulatory environment may often be fragmented and not required. This can unfortunately lead to compromised data and subsequent loss of stakeholder trust. To mitigate organizational risk, security needs to be a consistent and thorough consideration throughout product development and lifecycle management processes.

Cybersecurity Solutions infographic

Many organizations are looking to advance their IoT and OT cybersecurity capabilities and asking:

  • How can we best incorporate security as part of our connected products or systems? 
  • How can we help educate our development and security teams so they incorporate security by design principles into product design and development? 
  • How can we evaluate the maturity of our security and development processes? 
  • How can we ensure secure product lifecycle management (managing security throughout device lifecycle)?   
  • How can we demonstrate our cybersecurity posture to the marketplace?
X

Get in touch

Have questions, need specifics? Let's get this conversation started.

Please wait…
'; let submitButton = $('form.mktoForm .mktoButtonWrap .mktoButton'); submitButton.prop("disabled", true); submitButton.append(loadingHTML); // Ocp-Apim-Subscription-Key: '***'. var $ocpKey = drupalSettings.ul_marketo_validate_key; var $ocpUrl = drupalSettings.ul_marketo_validate_url; var $ocpEnv = drupalSettings.ul_marketo_validate_env; if (submitCount > 1 || isResponseSuccess == true) { isResponseHandled = true; form.submittable(true); if (paramsDebug.debug == 1) { console.log("NO.10 submitCount > 1: form.submit() "); } submitButton.click(); } else { var email = form.vals().Email; var phone = (form.vals().Phone) ? (form.vals().Phone) : '18472728800'; var country = (form.vals().Country) ? (form.vals().Country) : 'United States'; var countryCode = (phone == '18472728800') ? 'US' : getCountryCode(country); var $emailMsg = drupalSettings.ul_marketo_validate.email; var $phoneMsg = drupalSettings.ul_marketo_validate.phone; if (paramsDebug.debug == 1) { console.log("paramsDebug:"); console.log(paramsDebug); } sendingData = JSON.stringify({ 'Input_Email': email, 'Input_Phone': phone, 'Input_ISO2_Country_Code': countryCode }); if (paramsDebug.debug == 1) { console.log('URL, debug missing button:'); console.log($ocpUrl); console.log("Sending Data to API service (ajax):"); console.log(sendingData); } // API call for validate email/phone/country. var sendDate = (new Date()).getTime(); var responseTimeMs = sendDate; // Start a timer to handle a 3-second response timeout setTimeout(function() { if (!isResponseHandled) { isResponseHandled = true; // Handle the assumed "success" due to timeout here if (paramsDebug.debug == 1) { console.log('No response within timeout, proceeding with default validation success.'); } $('#ValidMsgEmail').remove(); $('#ValidMsgPhone').remove(); // set form to be submittable here $('#valSpinner').remove(); submitButton.prop("disabled", false); // Setup status as Timeout instead of Unknown. emailAddressStatus = "Timeout"; phoneNumberStatus = "Timeout"; phoneNumberValidated = "Timeout"; form.vals({ "emailAddressStatus": emailAddressStatus, "phoneNumberStatus": phoneNumberStatus, "phoneNumberValidated": phoneNumberValidated, }); form.submittable(true); isResponseSuccess = true; if (paramsDebug.debug == 1) { let receiveDate = (new Date()).getTime(); responseTimeMs = (receiveDate - sendDate) / 1000; console.log("setTimeout: " + responseTimeMs + " seconds."); } submitButton.click(); } }, paramsDebug.timeout * 1000); //END setTimeout $.ajax({ url: $ocpUrl, type: 'POST', data: sendingData, headers: { 'Content-Type': 'application/json', 'Ocp-Apim-Subscription-Key': $ocpKey, }, success: function (response) { $('#valSpinner').remove(); submitButton.prop("disabled", false); phoneNumberValidated = response.Validated_Phone_Number; if (!isResponseHandled) { isResponseHandled = true; // **** Handle the validation response if (paramsDebug.debug == 1) { console.log("API Response Data: "); console.log(response); } var emailCode = response.Email_Validation_Status_Number; var phoneCode = response.Phone_Validation_Status_Number; // Add values into two status fields. if (emailValidCode.hasOwnProperty(emailCode)) { emailAddressStatus = emailValidCode[emailCode]; } else { // API error code doesn't exist, set defaul. emailAddressStatus = emailValidCode['300']; } if (phoneValidCode.hasOwnProperty(phoneCode)) { phoneNumberStatus = phoneValidCode[phoneCode]; } else { // API error code doesn't exist, set defaul. phoneNumberStatus = phoneValidCode['301']; } if (emailAddressStatus.indexOf("email_not") != -1) { emailAddressStatus = 'Invalid'; } else if(emailAddressStatus == 'valid') { emailAddressStatus = 'Valid'; } if (phoneNumberStatus.indexOf('invalid_') != -1) { phoneNumberStatus = 'Invalid'; } else if(phoneNumberStatus == 'valid') { phoneNumberStatus = 'Valid'; } if (paramsDebug.debug == 1) { console.log('form.emailAddressStatus ' + emailAddressStatus); console.log('form.phoneNumberStatus ' + phoneNumberStatus); console.log('form.phoneNumberValidated ' + phoneNumberValidated); } if (validEmailCode.includes(emailCode) && validPhoneCode.includes(phoneCode)) { // Remove the loading spinner. $('#ValidMsgEmail').remove(); $('#ValidMsgPhone').remove(); $('#valSpinner').remove(); submitButton.prop("disabled", false); if (paramsDebug.debug == 1) { console.log("NO.1.1 VALID OK submitCount = " + submitCount); } isResponseSuccess = true; form.vals({ "emailAddressStatus": emailAddressStatus, "phoneNumberStatus": phoneNumberStatus, "phoneNumberValidated": phoneNumberValidated, }); form.submittable(true); submitButton.click(); } // API valid code is not "valid". else { form.submittable(false); if (paramsDebug.debug == 1) { console.log("NO.1.2 Submittable false : count= " + submitCount + " validateOrigin " + validateOrigin + " isResponseSuccess " + isResponseSuccess ); } // Set the invalid message in language translation. var msgEmailStatus = ""; if (!validEmailCode.includes(emailCode)) { if (emailCode == '300' || emailCode == '400') { msgEmailStatus = $emailMsg.email_not_valid; } else if (emailCode == '310' || emailCode == '500' ) { msgEmailStatus = $emailMsg.email_not_accept; } else { msgEmailStatus = "Unknown"; } if (paramsDebug.debug == 1) { console.log("NOT validEmailCode: " + msgEmailStatus); } errEmail = ''; $('#Email').after(errEmail); form.submittable(false); } // Set the invalid message in language translation. var msgPhoneStatus = "" if (!validPhoneCode.includes(phoneCode)) { msgPhoneStatus = $phoneMsg[phoneValidCode[phoneCode]]; if (paramsDebug.debug == 1) { console.log("NOT validPhoneCode: " + msgPhoneStatus); } errPhone = ''; $('#Phone').after(errPhone); form.submittable(false); } if (paramsDebug.debug == 1) { console.log(msgEmailStatus); console.log(msgPhoneStatus); } // Remove the loading spinner. $('#valSpinner').remove(); submitButton.prop("disabled", false); if (paramsDebug.debug == 1) { console.log("NO.1.6 Submittable false, count= " + submitCount); } form.vals({ "emailAddressStatus": emailAddressStatus, "phoneNumberStatus": phoneNumberStatus, "phoneNumberValidated": phoneNumberValidated, }); // 2nd API call and subit form. if (submitCount >= 1) { $('#ValidMsgEmail').remove(); $('#ValidMsgPhone').remove(); isResponseSuccess = true; form.submittable(true); if (paramsDebug.debug == 1) { console.log("NO.1.8 : 2nd Submit:: submittable=true && count=1 : " + submitCount); } if (submitCount==1) { submitButton.click(); } } } //END if{} else{}. }//END if (!isResponseHandled) // Calculate the time comsumed for the API call. if (paramsDebug.debug == 1) { let receiveDate = (new Date()).getTime(); responseTimeMs = (receiveDate - sendDate) / 1000; console.log("NO.1.9 : AJAX success: Time for API call: " + responseTimeMs + " seconds."); } submitCount++; }, //END success: function(); // API call error response. error: function (error) { $('#valSpinner').remove(); submitButton.prop("disabled", false); if (!isResponseHandled) { isResponseHandled = true; $('#valSpinner').remove(); submitButton.prop("disabled", false); // 2nd API call and subit form. if ( submitCount >= 1 ) { $('#ValidMsgEmail').remove(); $('#ValidMsgPhone').remove(); form.submittable(true); isResponseSuccess = true; if ( submitCount == 1 ) { form.submittable(true); } } // Handle AJAX error if (paramsDebug.debug == 1) { console.log('**** 2 ajax error. submitCount = ' + submitCount); console.log(error); } // Calculate the time comsumed for the API call. if (paramsDebug.debug == 1) { let receiveDate = (new Date()).getTime(); responseTimeMs = (receiveDate - sendDate) / 1000; console.log("NO.2.3 AJAX error: Time for API call: " + responseTimeMs + " seconds."); } } submitCount++; // Error status 500, then submit the form. submitButton.click(); } //END error: function(); }); //END $.ajax; if (isResponseSuccess) { if (paramsDebug.debug == 1) { console.log("NO.8.0 submittable(true)"); } form.submittable(true); } } //END: if (submitCount > 1) else // Setup the form.vals and form.submittable; form.vals({ "emailAddressStatus": emailAddressStatus, "phoneNumberStatus": phoneNumberStatus, "phoneNumberValidated": phoneNumberValidated, }); } //END: if (validateOrigin && (marketoBundle)) else { // For Event form and Newsletter form. if (validateOrigin === true){ form.submittable(true); } } }); //END form.onValidate() // Success callback() form.onSuccess(function(values, followUpUrl){ // Debug Phone/Email validation. if (paramsDebug.debug == 1) { console.log("NO.9.1 onSuccess: submittable = " + form.submittable()); console.log(form.getValues()); } // Track analytics. if (typeof dataLayer !== 'undefined'){ dataLayer.push({ event: drplMkto.dataLayerEvent, mktoFormId: form.getId(), 'FormValues': cleanFormVals(form.getValues()), 'FormFields': form.allFieldsFilled(), 'Submittable': form.submittable() }); } // If function exists, delete UTM cookie: if(typeof _deleteUtmCookie === "function"){ _deleteUtmCookie(); } // Marketo Modal "Thank You" message: if(use_post_submit_mssg){ $('html, body').animate({ scrollTop: 0 }, 'slow'); $('.mkto-presubmit').addClass('hidden'); $('.mktoModalContent').addClass('mkto_thnx_center'); $('.mktoModalMask').addClass('not_clicable'); $('.mkto-postsubmit').removeClass('hidden'); $('.mktoButton').removeAttr('disabled').text(drupalSettings.marketo.button_text); $('.mktoForm')[0].reset(); grecaptcha.reset(); } // Else, redirect user: else { window.location.href = drplMkto.success_url; } // IMPORTANT: Return false to prevent further code execution. return false; }); //END form.onSuccess. }); })(jQuery, drupalSettings.marketo);