NEVPNManager - Connect on-demand blocks internet access - ios

I'm creating a VPN profile through my app and I have the following rules and set up:
let newIPSec = NEVPNProtocolIPSec()
newIPSec.serverAddress = AppConfiguration.getVPNEndPoint()
newIPSec.authenticationMethod = NEVPNIKEAuthenticationMethod.sharedSecret
newIPSec.username = VPNCredentialsModel.instance.vpnUserName()
newIPSec.passwordReference = VPNCredentialsModel.instance.vpnPasswordReference() as Data?
newIPSec.sharedSecretReference = VPNCredentialsModel.instance.vpnPresharedKeyReference() as Data?
newIPSec.useExtendedAuthentication = true
newIPSec.disconnectOnSleep = false
self.manager.protocolConfiguration = newIPSec
let connectRule = NEOnDemandRuleConnect()
connectRule.interfaceTypeMatch = .any
let ignoreRule = NEOnDemandRuleIgnore()
ignoreRule.interfaceTypeMatch = .any
ignoreRule.probeURL = URL(string:probeURL)
self.manager.onDemandRules = [ignoreRule,connectRule]
self.manager.isOnDemandEnabled = true
self.manager.isEnabled = true
Update
My probeURL is a rest API call which updates the backend and returns 200 or 500 based on the user status. There is some latency since there are some sql querying being carried out. The probeURL expects a 200 OK else invalidates the ignore rule. The ignore rule becomes invalid and it tries to connect to the VPN but the user can't connect anymore since the VPN blocked the user. The iOS device keeps trying in an infinite loops and blocks the internet access from other applications pushing the device to a brick state. Is there a better way to handle this case?
Suggestion
I can update the DB with a file endpoint that points the user status like a flag - (each user has a file endpoint). If the file is available it returns a 200 OK and if its removed returns 404. This way probe url can receive a 200 OK with no latency when needed. However this might be an extra layer of implementation and file management. Whats your view on this? Can someone recommend a better way to handle this test case?
Testing
I was testing a successful scenario with the following probe URL:
httpstat.us/200 for ignoreRule to be valid and not connect
httpstat.us/500 for ignoreRUle to be invalid and continue connecting to the VPN

Related

Graph Lifecycle Notifications Not registering correct endpoint

I am trying to us the Lifecycle events within the Graph Beta API using code like this:
var subscription = new Subscription
{
Resource = $"users/{userObjectId}/mailFolders('{resource}')/messages",
ChangeType = "created,updated",
NotificationUrl = notificationWebHookUrl,
LifecycleNotificationUrl = lifecycleNotificationWebHookUrl,
ClientState = clientState,
ExpirationDateTime = DateTime.UtcNow + new TimeSpan(0, 0, 4200, 0),
};
However, even though I have supplied a different LifecycleNotificationUrl to the NotificationUrl, the initial requests to perform the validate request only go to the NotificationUrl endpoint not the LifecycleNotificationUrl endpoint. I have checked and I am definitely supplying different endpoint urls.
I am using 2 separate Azure Functions with Http triggers as the endpoints.
Also to note is that I am using ngrok for exposing my localhost Azure functions.
I understand that if you do not supply a LifecycleNotificationUrl that this is the behaviour that you should expect, but I am.
We currently have an open issue where the validation code is sending two validation requests to the notificationUrl and none to the lifecycleNotificationUrl. This is something we're trying to address, hopefully shortly. I suggest you follow this issue to get notified of any update on the matter.
Besides that, once the validation is passed, lifecycle notifications will get delivered to your lifecycleNotificationUrl and not your notificationUrl.

Twilio WhatsApp messages are in 'queued' status

Okay so I got approval from WhatsApp and Twilio (after Facebook Business verification) to use the WhatsApp API for sending out appointment reminders to my clients. I configured the message templates and they got approved too. Check the image below:
I have written a code in Python where I pick my data from a PostgreSQL server hosted on cloud (using psycopg2) and then it sends out messages to the phone numbers fetched using a query. Here is the code:
from twilio.rest import Client
import psycopg2
import time
account_sid = 'AC54xxxxxxxxxxxxxxxxxxxxxxxxxxx'
auth_token = 'f1384yyyyyyyyyyyyyyyyyyyyyyyyyyy'
connection_string = ""
conn = psycopg2.connect(user = "xxxx",
password = "yyyyyy",
host = "zzzzzzzzzzzzzzz.zzzzzzzzzzzz",
port = "ABCD",
database = "some_db")
cur = conn.cursor()
cur.execute("""query to pick data""")
rows = cur.fetchall()
client_phone_list = []
phone_list_not_received = []
session_date_list = []
session_time_list = []
client_first_name_list = []
for row in rows:
session_date_list.append(row[0])
session_time_list.append(row[1])
client_first_name_list.append(row[2])
client_phone_list.append(row[3])
cur.close()
conn.close()
client = Client(account_sid, auth_token)
message_reminder_template = """Hello {},
This is a reminder about your session today at {}. Please be on time to utilize the full length of
the session and avoid distress :)
We look forward to taking care of you!"""
for i in range(len(client_phone_list)):
first_name = client_first_name_list[i]
appointment_time = session_time_list[i]
message_body = message_reminder_template.format(first_name, appointment_time)
print(message_body)
message = client.messages.create(body = str(message_body),
from_ = 'whatsapp:+1(mytwilionumber)',
to = 'whatsapp:+91'+client_phone_list[i])
time.sleep(10)
text_status = message.status
print(text_status)
Whenever I run this code the message status returned is always 'queued'. I have checked that I am not using the 'Test Credentials' but the 'Live Credentials'.
I have also checked the error_code and error_message which returns as NULL. So there is no error but the messages are not getting sent. How can I change that?
Any help would be hugely appreciated.
Also note that the message body used in the code above is approved as a template from WhatsApp.
Twilio developer evangelist here.
At the point that you make the API request to send the message the status will be returned to code as "queued". That's this point in your code here:
message = client.messages.create(body = str(message_body),
from_ = 'whatsapp:+1(mytwilionumber)',
to = 'whatsapp:+91'+client_phone_list[i])
What you do next will not work though:
time.sleep(10)
text_status = message.status
print(text_status)
Waiting 10 seconds and then reading the status from the message object that was returned when you created the message will still return "queued".
If you want to fetch the message status after 10 seconds to see if it has been sent then you will need to make a second call to the messages API, like so:
time.sleep(10)
latest_message = client.messages(message.sid).fetch()
print(latest_message.status)
For a more efficient method of keeping track of the status of your messages, check out this tutorial on receiving webhooks for message status updates.
Let me know if that helped at all.

How can I add Amount using Cyber source SDK iOS?

I downloaded Cyber Source SDK iOS from Github. It is also working fine. But I need to set total amount and I can not find any parameter in SDK. How to set amount in Cyber source using SDK?
I don't know it is set by SDK or Backend(API). Please check my code below:
//Card data
let cardData = InAppSDKCardData.init()
cardData.accountNumber = txtCardNumber.text
cardData.expirationMonth = txtMonth.text
cardData.expirationYear = txtYear.text
cardData.cvNumber = txtCVV.text
//Create Transaction object
let transactionObj = InAppSDKTransactionObject.init()
transactionObj.billTo = getBillToData()
transactionObj.cardData = cardData
//Get the Merchant data and credentials and assign.
transactionObj.merchant = getMerchantData()
//Set the End point / Environment. Test or Live
InAppSDKSettings.sharedInstance()?.inAppSDKEnvironment = INAPPSDK_ENV_TEST
//Enable log for debugging
InAppSDKSettings.sharedInstance()?.enableLog = true
//Obtain the gateway sharted instance.
let gatWay = InAppSDKGateway.sharedInstance()
result = (gatWay?.performPaymentDataEncryption(transactionObj, with: self))!
if (result) {
NSLog("InAppSDK: Request Accepted. Expect the response in the delegate method.");
}
else {
NSLog("InAppSDK: Request NOT Accepted. Verify the input values if any one is invalid.");
}
And I got a response like this
<?xml version="1.0" encoding="utf-8"?><soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
<soap:Header>
<wsse:Security xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd"><wsu:Timestamp xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd" wsu:Id="Timestamp-1623853623"><wsu:Created>2019-08-01T10:25:43.747Z</wsu:Created></wsu:Timestamp></wsse:Security></soap:Header><soap:Body><c:replyMessage xmlns:c="urn:schemas-cybersource-com:transaction-data-1.120"><c:merchantReferenceCode>Cyber_iOS</c:merchantReferenceCode><c:requestID>5646551432976553503004</c:requestID><c:decision>ACCEPT</c:decision><c:reasonCode>100</c:reasonCode><c:requestToken>AhizbwSTMhmkg5ScYGkcEQFRp++q/94CP9hk0ky9GK+AnABMoAny</c:requestToken><c:encryptedPayment><c:data>eyJkYXRhIjoiK1ZrdmNpTDhpcStyeEt2RytTMDl3R05MbTFGZzlRcXZpQUE3K3FWOFNvckJqYnp1b0lcL3VzRUs0RWpDZkpxZ1pJejJRbWd3cjBNdGxpVXltS2k0bERNS3lFZmdHZmlOS1wvOWRIMWpMXC9WaCszbk5nOXV6NVp2eG54OVpJbmExNkpBbmtvMmt0OSs0S2lDdW1TYkVBVlVtSkdrRm12ZFhqYlBRUXFzVXNcL0xjS2tlVEkzb1RrSkhFXC9jWVBkRXRHZUs1bVErOW8zbDUySWtUb0xPWkJJcUxmeEtcLzNiNUVRY3FcL2ZZOXZJT3l1aFVnZEc2OXVwXC9oQTJJakpORmY1bm1ZcmQ1bkRkVEdEa1EyeGY3RnNGTDdKRjYxdlNUbHljcHIweHFvS09adDNpQVplM1wvR3htT2p1Unp6XC9oTFhsOTZNRFFaUUc1eXZHZHBXaUNydEhRPT0iLCJoZWFkZXIiOnsiYXBwbGljYXRpb25EYXRhIjoiNDc3NTY5NjQzRDMwMzYzMzYxNjI2MTYzMzYyRDYxMzEzMDMzMkQzNDY2NjY2NTJEMzgzOTYzMzAyRDM4MzczNDY2MzMzNTM1NjI2NTMxNjM2MzNCNDQ2MTc0NjU1NDY5NkQ2NTNEMzIzMDMxMzkyRDMwMzgyRDMwMzE1NDMxMzAzQTMyMzUzQTM0MzMyRTM2MzAzOTM1MzAzNTM4NUEiLCJlcGhlbWVyYWxQdWJsaWNLZXkiOiJNRmt3RXdZSEtvWkl6ajBDQVFZSUtvWkl6ajBEQVFjRFFnQUVaRE41dU8rb1R0eXNzdlwvb1V2SjZhQnE1bkVrWVBXZEdDT01sb1YyYkJpaHVROTlHSnBobEk2elwvOHg2M1dmUGpjbGFTcG04ODBJZGNaU0czUkRnNVpRPT0iLCJwdWJsaWNLZXlIYXNoIjoieXRLSjgwc3JjWXppQnVwNzRcL0R5K3RTV1FQSENwXC9ZbkFabGhcL3lXOFk3ND0iLCJ0cmFuc2FjdGlvbklkIjoiNTY0NjU1MTQzMjk3NjU1MzUwMzAwNCJ9LCJzaWduYXR1cmVBbGdJbmZvIjoiU0hBMjU2Iiwic2lnbmF0dXJlIjoiNXdya1BuTEtJZWoxV0ZEVjVZNUJEc0orTUg2QkJSN2Zoa2FVM1ZsQzE2OD0iLCJ2ZXJzaW9uIjoiMS4xLjEuMiJ9</c:data></c:encryptedPayment><c:encryptPaymentDataReply><c:reasonCode>100</c:reasonCode><c:requestDateTime>2019-08-01T10:25:43Z</c:requestDateTime></c:encryptPaymentDataReply><c:reserved><ics_message xmlns="urn:schemas-cybersource-com:transaction-data:ics"><encrypt_payment_data_rcode>1</encrypt_payment_data_rcode><ics_return_code>1000000</ics_return_code><encrypt_payment_data_rmsg>Request was processed successfully.</encrypt_payment_data_rmsg><ics_rcode>1</ics_rcode><encrypt_payment_data_return_code>1001000</encrypt_payment_data_return_code><ics_rmsg>Request was processed successfully.</ics_rmsg><request_id>5646551432976553503004</request_id><encrypt_payment_data.reason_code>100</encrypt_payment_data.reason_code><encrypt_payment_data_rflag>SOK</encrypt_payment_data_rflag><request_token>AhizbwSTMhmkg5ScYGkcEQFRp++q/94CP9hk0ky9GK+AnABMoAny</request_token><ics_decision_reason_code>100</ics_decision_reason_code><encrypt_payment_data_request_date_time>2019-08-01T102543Z</encrypt_payment_data_request_date_time><ics_rflag>SOK</ics_rflag><merchant_ref_number>Cyber_iOS</merchant_ref_number><encrypted_payment_data>eyJkYXRhIjoiK1ZrdmNpTDhpcStyeEt2RytTMDl3R05MbTFGZzlRcXZpQUE3K3FWOFNvckJqYnp1b0lcL3VzRUs0RWpDZkpxZ1pJejJRbWd3cjBNdGxpVXltS2k0bERNS3lFZmdHZmlOS1wvOWRIMWpMXC9WaCszbk5nOXV6NVp2eG54OVpJbmExNkpBbmtvMmt0OSs0S2lDdW1TYkVBVlVtSkdrRm12ZFhqYlBRUXFzVXNcL0xjS2tlVEkzb1RrSkhFXC9jWVBkRXRHZUs1bVErOW8zbDUySWtUb0xPWkJJcUxmeEtcLzNiNUVRY3FcL2ZZOXZJT3l1aFVnZEc2OXVwXC9oQTJJakpORmY1bm1ZcmQ1bkRkVEdEa1EyeGY3RnNGTDdKRjYxdlNUbHljcHIweHFvS09adDNpQVplM1wvR3htT2p1Unp6XC9oTFhsOTZNRFFaUUc1eXZHZHBXaUNydEhRPT0iLCJoZWFkZXIiOnsiYXBwbGljYXRpb25EYXRhIjoiNDc3NTY5NjQzRDMwMzYzMzYxNjI2MTYzMzYyRDYxMzEzMDMzMkQzNDY2NjY2NTJEMzgzOTYzMzAyRDM4MzczNDY2MzMzNTM1NjI2NTMxNjM2MzNCNDQ2MTc0NjU1NDY5NkQ2NTNEMzIzMDMxMzkyRDMwMzgyRDMwMzE1NDMxMzAzQTMyMzUzQTM0MzMyRTM2MzAzOTM1MzAzNTM4NUEiLCJlcGhlbWVyYWxQdWJsaWNLZXkiOiJNRmt3RXdZSEtvWkl6ajBDQVFZSUtvWkl6ajBEQVFjRFFnQUVaRE41dU8rb1R0eXNzdlwvb1V2SjZhQnE1bkVrWVBXZEdDT01sb1YyYkJpaHVROTlHSnBobEk2elwvOHg2M1dmUGpjbGFTcG04ODBJZGNaU0czUkRnNVpRPT0iLCJwdWJsaWNLZXlIYXNoIjoieXRLSjgwc3JjWXppQnVwNzRcL0R5K3RTV1FQSENwXC9ZbkFabGhcL3lXOFk3ND0iLCJ0cmFuc2FjdGlvbklkIjoiNTY0NjU1MTQzMjk3NjU1MzUwMzAwNCJ9LCJzaWduYXR1cmVBbGdJbmZvIjoiU0hBMjU2Iiwic2lnbmF0dXJlIjoiNXdya1BuTEtJZWoxV0ZEVjVZNUJEc0orTUg2QkJSN2Zoa2FVM1ZsQzE2OD0iLCJ2ZXJzaW9uIjoiMS4xLjEuMiJ9</encrypted_payment_data></ics_message></c:reserved></c:replyMessage></soap:Body></soap:Envelope>
Thanks in advance.
This SDK is intended for one purpose - to reduce PCI scope by encrypting the card data which can then be passed to your server. Since it is only encrypting the card data there is no need for an amount.
Once you have the encrypted data you pass that to your server and can then use it to authorize the card. See "Using the Payment Blob" on this page https://github.com/CyberSource/cybersource-ios-sdk. This is the point where you will need the amount. You will also have to pass the amount to your server if it is coming from your iOS App.

reporting success events in omniture

Trying to track how many visistors who don't log in see the popup box that prompts them to create an account, and then each subsequent page of that popup box (java lightbox).
I have these tags in the box coding (the vendor implemented it):
s.prop4=Login Success
event19 = Already Registered
s.eVar20=Non-registered
Conversion flow ->
event20 = Welcome
event22 = Stop
event23 = Login
event24 = Plan Options
event25 = Create Account
event26 = Confirm Print Address
event27 = Enter Payment
event28,purchase=Transaction Complete
and then in Omniture I have put everything in its respective place, but I feel like i am missing something. I get a custom conversion report that shows how many got the login success vs the non-registered but none of the events past that.
What am I missing?

How SignalR manages connection between Postbacks

1> Just want to understand how SignalR 1.x functions in a particular scenario
Lets say we have a 10 clients connected to Hub and one of the connected clients say client-1 performs a postback so OnDisconnected is called than OnConnected is called right ?
What happens if during this phase if client-2 try's to send message to client-1 exactly between the said scenario ie (msg is sent after client-1 is disconnected and before connected again )will client-1 miss the message or there's internal mechanism which makes sure client-1 does not miss the message sent by client-2
2> Second query I have is that I'm trying to pass a querystring using following code
var chat = $.connection.myHub;
$.connection.myHub.qs = { "token": "hello" };
but not able to retrieve it on the server side from the Context object
using
Context.QueryString.AllKeys
I even tried
var chat = $.connection.myHub;
$.connection.myHub.qs = "token=hello" ;
But it does not work ie when I check the keys, token is not present in AllKeys
Will appreciate if someone just help me out.
1: If a postback occurs a client will disconnect and then connect. However, when the client performs a connect again it will have a different Connection Id than it had prior to the postback. Therefore, any message sent to the old connection id will be missed because when the users browser connects again it will be known as a different client.
2: You're trying to set the query string on the hub proxy, not the connection. What you should be doing is:
$.connection.hub.qs = { foo: "bar" };

Resources