Identify Request return of (id)result - ios

I am retrieving some user date out of my iOS app (me/friens, me/events, ...) I want to forward this JSON to a server where I do some additional data processing.
The thing is that I get an answer for my me/events object without any kind of identifier:
(
{
data = (
The only thing I get is this 'data' string: But how is it possible to manipulate the JSON in the way that I get an identifier like:
(
{
events = (
Thank you very much for any kind of help!

I was wrong. Of couse this is not JSON. It is the output of a NSDictionary object. If you want to enable Facebook SSO in your Application and handle open graph data after the User logged in you just send the Facebook Id and the access_token to the server to perform additional tasks.

Related

How to create a "challenge" for my Cloud Functions server

I'm trying use Apple's new DeviceCheck API to verify that network calls in my app are actually coming from an uncompromised version of my app.
Documentation
After successfully verifying a key’s attestation, your server can
require the app to assert its legitimacy for any or all future server
requests. The app does this by signing the request. In the app, first
obtain a unique, one-time challenge from the server. You use a
challenge here, like for attestation, to avoid replay attacks. Then
combine the challenge with the server request to create a hash:
let challenge = <# A string from your server #>
let request = [ "action": "getGameLevel",
"levelId": "1234",
"challenge": challenge ]
guard let clientData = try? JSONEncoder().encode(request) else { return }
let clientDataHash = Data(SHA256.hash(data: clientData))
Use this hash and the key identifier that you generated earlier to
create an assertion object by calling the
generateAssertion(_:clientDataHash:completionHandler:) method:
service.generateAssertion(keyId, clientDataHash: clientDataHash) { assertion, error in
guard error == nil else { /* Handle the error. */ }
// Send the assertion and request to your server.
}
I'm trying to add this assertion functionality to my Swift function, which is a helper function that calls a Firebase Cloud Function.
I want the assertion object to be passed as data to the Cloud Function, to verify that the Cloud Function is being called from an uncompromised version of my app:
func callFunction(name: String, data: [String:Any?], completion: #escaping (HTTPSCallableResult?, Error?)->()){
var functions = Functions.functions()
functions.httpsCallable(name).call(data){ (result, error) in
completion(result, error)
}
}
(Example of callFunction() being used below):
let data: [String:Any?] = [
"gameId": self.game?.id,
"answer": answer,
"answeredAt": Date().millisecondsSince1970
]
callFunction(name: "answerQuestion", data: data){ res, err in
print("Submitted answer: \(res.debugDescription) | Error: \(err)")
if let err = err {
self.game?.question?.state = .initial
}
}
To generate the assertion object to send to my server (cloud function), it requires me to generate a challenge as stated above. However I'm not sure how to generate this challenge.
Apple says it should be "A string from your server". But I'm not sure what the string should be. Is it meant to be a dynamic string based on the user's UID? A Base64-encoded string of the user ID and a static secret string? And when I try to retrieve this string from the server, the user will just be able to read it as they can see incoming network JSON (I presume I would retrieve the string with a Cloud Function call) - so it seems pointless as it's not a secret string anymore?
Any idea how I can make the challenge work securely?
The point of the challenge is to avoid replay attacks, so it can be any randomised string. A UUID would be fine. It doesn't need to be a secret.
The challenge string is combined with the transaction data and a hash is generated. You send the hash to and you send that to generateAssertion and receive the assertion object. You then send this to your server along with the request data.
Now your server can combine the received request data with the challenge (which it knows, since it sent it to the client initially), generate the same hash and validate the attestation.
The server-side attestation article provides detail on the challenge data:
Provide a Challenge
Every time your app needs to communicate attestation data to your server, the app first asks the server for a unique, one-time challenge. App Attest integrates this challenge into the objects that it provides, and that your app sends back to your server for validation. This makes it harder for an attacker to implement a replay attack.
When asked for a challenge, provide your app with a randomized data value, and remember the value for use when verifying the corresponding attestation or assertion objects sent by the client. How you use the challenge data depends on the kind of object that you need to validate.

How to access data field in Dialogflow?

As the Dialogflow documentations states, the data field represents
Additional data required for performing the action on the client side.
The data is sent to the client in the original form and is not
processed by Dialogflow.
How should one access it in the iOS framework?
request?.setMappedCompletionBlockSuccess({ (request, response) in
...
}
I couldn't find it in the response object and can't find any documentation for iOS.
Thanks.
Your question is a bit vague (can you edit and narrow it down?), but i think you got it the other way round, what that snippet of documentation that you pasted means is that you are supposed to send that payload to DialogFlow and it will forward it to a connected Client (e.g Messenger, Slack etc) un-touched. It simply means that DialogFlow assumes that you know what you are doing.
Here is a sample Fulfilment response to DialogFlow in JS
module.exports.sendGenericMessageWithText = function(message) {
return {
data: {
facebook: [
{
text: message
]
}
}
}

handling byte array of image in node js server

I am following this below library for my applications where user have to chat with other user.
SocketChat
There I can chat with other users. Now my prime concern is to send images to server and then that image is going to reflect in the chat of the other user's window. Its like Group chat.
I am done with image sending from iOS app
I don't know what to write to handle byte array which is of the image I sent from one of the client.
clientSocket.on('images', function(clientNickname, message){
var currentDateTime = new Date().toLocaleString();
var dataType = "imageType"
delete typingUsers[clientNickname];
io.emit("userTypingUpdate", typingUsers);
io.emit('newChatMessage', clientNickname, message, currentDateTime,dataType);
});
I think its not working. Its good for the string type data. Can you please let me know what to write there in order to receive image and send that back.

How to get key/value data from PushNotification in PhoneGap Build

I'm using the Push plugin in PhoneGap Build. I am able to send as well as receive push notifications to my device. I'm sending the notification + additional data (specifically which page to load) using the node-gcm library to registered devices. Here's the code on my node.js server:
var gcm = require('node-gcm');
var message = new gcm.Message();
//API Server Key
var sender = new gcm.Sender('GCM API SERVER/BROWSER KEY');
var registrationIds = [];
// Value the payload data to send...
message.addData('message','Hello from Portland, OR!');
message.addData('title','My Push Notification');
message.addData('msgcnt','3');
message.addData('soundname','beep.wav');
message.addDataWithKeyValue('pageid','1234566788'); //THIS IS THE ADDITIONAL DATA I'D
// ... ID LIKE TO SEND TO MY PHONEGAP BUILD APP AND INTERPRET
message.timeToLive = 3;// Duration in seconds to hold and retry to deliver the message in GCM before timing out. Default 4 weeks if not specified
// At least one reg id required
registrationIds.push('REGISTRATION ID');
/**
* Parameters: message-literal, registrationIds-array, No. of retries, callback-function
*/
sender.send(message, registrationIds, 4, function (result) {
console.log("hello" + result);
});
Now that I believe I have sent the additional page data, I'd like to know how I can GET the data from the notification itself inside of my PhoneGap build application.
I'm also using jquery mobile to manage the different html pages (which basically makes each page a separate div inside of one html document) and could use feedback on how to load the notified page with this in mind.
Any help would be greatly appreciated, thanks so much!
-- 24x7
You can get the value of key/pairs of notification in phonegap as follows:
The message text can be retrieved with: e.message
All other key/value pairs can be retrieved with: e.payload.key
For example if you want get the title of the notification(in above) then you will get it in "e.payload.title".
After getting the value you can put conditional statemnets depending upon the value to go to different pages/divs.

Restore Access Token in hybridauth

I saved the Access Token (using this method: getAccessToken ()) in my database, but now I would like to restore this value to an object.
How can I do this?
This is explained in hybridauth user manual with below code :
// get the stored hybridauth data from your storage system
$hybridauth_session_data = get_sorted_hybridauth_session( $current_user_id );
Get_sorted_hybridauth_session is your internal function to get the stored data.
It doesnt matter whether you store the data in a table in a field named 'external_token' or something, get it through a normal sql query, and then just feed it to below function :
// then call Hybrid_Auth::restoreSessionData() to get stored data
$hybridauth->restoreSessionData( $hybridauth_session_data );
// call back an instance of Twitter adapter
$twitter = $hybridauth->getAdapter( "Twitter" );
// regrab te user profile
$user_profile = $twitter->getUserProfile();
$hybridauth->restoreSessionData( $hybridauth_session_data ); will restore the serialized session object, and then it will get an adapter for whichever provider it was saved for. Its best that you also save the provider name (Twitter in this case) in the same database table with something like external_provider , and then you can get it through a sql auery and feed it to getAdapter function. That should do what you need to do.
The manual example is below :
http://hybridauth.sourceforge.net/userguide/HybridAuth_Sessions.html
=============
As an added info - what i saw in my tests was, saving session in this way does not prevent hybridauth from logging the user in, even if the user has revoked access from the app in the meantime. Ie, if user is already logged in and authorized, but, went to the app separately and revoked the access (google for example), hybridauth will still log in the user to your system. Im currently trying to find a way to make sure the user is logged to the remote system too.
Late, but I thought this would help:
The following code verifies and removes those providers from HybridAuth that the user is not truly logged into:
$providers = $this->hybridauthlib->getConnectedProviders();
foreach( $providers as $connectedWith ){
$p = $this->hybridauthlib->getAdapter( $connectedWith );
try {
$p->getUserProfile();
} catch (Exception $e) {
$p->logout();
}
}

Resources