Access custom attributes for AWS Cognito User - ios

I'm trying to get a custom attribute for a user in Cognito. In the AWS console I can see the custom attribute is set but in iOS when I make the call to AWSCognitoIdentityUser.getDetails().continueOnSuccessWith(block:) the response does not contain the custom attributes. Why would this be and how can I get access to them?

Here is how we accessed all attributed for cognito user.
//var params = {
// AccessToken: 'STRING_VALUE'
//};
cognitoidentityserviceprovider.getUser(params, function(err, data) {
if (err) {
callback(null, err);
} else {
callback(null, data);
}
});
Hope it helps.
EDIT1:
Also you need to ensure the custom attributes are with read permissions.
If you don't have read permissions, it will not be returned in your request.

Related

Microsoft Graph API Unauthorized Error 401

I am new to MS graph api. I am learning this API and I followed this tutorial https://learn.microsoft.com/en-us/azure/active-directory/develop/tutorial-v2-nodejs-console and it works fine for me when retrieving the user. here is the code
async function main() {
try {
// here we get an access token
const authResponse = await auth.getToken(auth.tokenRequest);
console.log("get auth reespones ", authResponse)
const options = {
method: 'get',
headers: {
Authorization: `Bearer ${authResponse}`
}
};
// call the web API with the access token
const users = await fetch.callApi(auth.apiConfig.uri, options);
console.log("get users ", users)
} catch (error) {
console.log("error here",error);
}
};
But I am trying to call other API and I have a problem accessing the calendar API.
here is the new function I use to call the calendar api in ms graph.
async function getcalendar() {
try {
// here we get an access token
const authResponse = await auth.getToken(auth.tokenRequest);
const options = {
method: 'get',
headers: {
Authorization: `Bearer ${authResponse}`,
Prefer: `outlook.timezone="Pacific Standard Time"`
}
}
// call the web API with the access token
const users = await fetch.callApi('https://graph.microsoft.com/v1.0/me/calendar', options);
console.log("get users ", users)
} catch (error) {
console.log("error is here ",error);
}
};
in my application in azure I already set all the permissions
I have no idea why it keeps saying unauthorized.
Any help is appreciated. Thank you
Try to set Calendars.Read, Calendars.ReadWrite for Delegated permission type instead of Application type.
getSchedule api doesn't support personal Microsoft account.
You cannot use personal accounts to hit the me/calendar/getschedule because this is not supported.
The permissions works only for work or school accounts or with App token.
As you are using Application context you need to make the call something like below.
/users/{id|userPrincipalName}/calendar/getSchedule as there is no meaning for me if there is no user involved.

Getting email id value null as response during apple-authentication

I'm implementing apple-authentication in react native using expo-apple-authentication package.
Below is the code which I'm calling on button's onPress.
async handleSocialLogin() {
const { mutate, BB, onSuccess, navigation } = this.props;
try {
const result = await AppleAuthentication.signInAsync({
requestedScopes: [
AppleAuthentication.AppleAuthenticationScope.FULL_NAME,
AppleAuthentication.AppleAuthenticationScope.EMAIL,
],
});
Alert.alert(JSON.stringify(result))
// signed in
} catch (e) {
Alert.alert(e)
if (e.code === 'ERR_CANCELED') {
// handle that the user canceled the sign-in flow
} else {
// handle other errors
}
}
}
It should return me authentication-token, Full_Name and Email which I requested in scope but It is giving me null for Full_Name and Email.
As per the documentation:
requestedScopes (AppleAuthenticationScope[]) (optional) - Array of user information scopes to which your app is requesting access. Note that the user can choose to deny your app access to any scope at the time of logging in. You will still need to handle null values for any scopes you request. Additionally, note that the requested scopes will only be provided to you the first time each user signs into your app; in subsequent requests they will be null.
You have probably already logged in once and didn't catch the logs. Subsequent log in will result in this data being null

Actions on Google 'Get Sign In' Helper

I am using the following code in my Actions on Google application:
app.intent('Get Sign In', async (conv, params, signin) => {
if (signin.status !== 'OK') {
return conv.close(`Let's try again next time.`);
}
const color = conv.data[Fields.COLOR];
const {email} = conv.user;
if (!conv.data.uid && email) {
try {
conv.data.uid = (await auth.getUserByEmail(email)).uid;
} catch (e) {
if (e.code !== 'auth/user-not-found') {
throw e;
}
// If the user is not found, create a new Firebase auth user
// using the email obtained from the Google Assistant
conv.data.uid = (await auth.createUser({email})).uid;
}
}
if (conv.data.uid) {
conv.user.ref = db.collection('users').doc(conv.data.uid);
}
conv.close(`I saved ${color} as your favorite color for next time.`);
});
I've been looking through the docs, but can't find any explanation about the 'params' argument of the function? How do I pass values to it?
You can use the params object if you are using dialogflow. For example, if you use entities in Dialogflow you can retrieve them through params object in the intent handler.
If you are using Dialogflow, you can access the parameter values via the params variable.
Source
More info about the param object itself can be found here.

Custom authentication integration with parse-server and auth0

I would like to use auth0.com in conjunction with the open source-parse server.
My current approach is to obtain the token from auth0 by using their standard login through the Lock library for iOS. With that token I would like to call a custom authentication method on my parse-server, that checks whether the token is valid and if it is will log in the user.
My problem is that there is almost no documentation on writing custom oauth for parse-server.
So far, I have this code for my custom auth.
var Parse = require('parse/node').Parse;
function validateAuthData(authData, options) {
console.log('validateAuthData()');
return new Promise((resolve, reject) => {
try {
var decoded = jwt.verify(authData.access_token, opions.sharedSecret);
if (authData.id === decoded.sub) {
resolve({});
}
throw new Parse.Error(Parse.Error.OBJECT_NOT_FOUND, 'Unauthorized');
} catch(e) {
throw new Parse.Error(Parse.Error.OBJECT_NOT_FOUND, e.message);
}
});
}
function validateAppId(appIds, authData) {
console.log('validateAppId()');
return Promise.resolve();
}
module.exports = {
validateAppId: validateAppId,
validateAuthData: validateAuthData
};
However, it doesn't work and also I don't understand how this code can be used to authenticate a specific user. Does the parse-server do database look-ups to match the specific auth data to a specific user? Also, how can I register a new user with custom auth. What happens when a user tries to log in but he doesn't exist yet in my parse database?
An alternative seems to be this, using a rule an auth0.com. What are the differences and how would the rule work? I have very little experience with authentication and oauth and jwt's.
Lastly, I am using this to call my custom auth from my iOS client. However this doesn't work either, but I am not sure whether it is due to the iOS part or because my custom auth isn't working yet.
In conclusion, I am having trouble with something that seems rather easy. I want to use auth0 as my authentication provider and I want to integrate it was the parse-server, since I really appreciate the convenience around parse and the client sdk's. I am fairly certain that more people have a similar problem, however I have not found any definitive resource on how to properly do this.
Further Links
Parse user authenticated using Auth0
https://auth0.com/blog/2016/03/07/hapijs-authentication-secure-your-api-with-json-web-tokens/
https://github.com/ParsePlatform/parse-server/wiki/OAuth
https://jwt.io/introduction/
late answer but I was solving the same problem and came across this post:
Auth0 has rules you can apply that run when the login occurs. I've modified their example one from https://github.com/auth0/rules/blob/master/src/rules/parse.js, extracting the API endpoint into a constant.
function(user, context, callback) {
// run this only for the Parse application
// if (context.clientID !== 'PARSE CLIENT ID IN AUTH0') return callback(null, user, context);
const request = require('request');
const MY_API = 'https://subdomian.back4app.io';
const PARSE_APP_ID = '*********';
const PARSE_API_KEY = '**********';
const PARSE_USER_PASSWORD = 'REPLACE_WITH_RANDOM_STRING'; // you can use this to generate one http://www.random.org/strings/
const username = user.email || user.name || user.user_id; // this is the Auth0 user prop that will be mapped to the username in the db
request.get({
url: `${MY_API}/login`,
qs: {
username: username,
password: PARSE_USER_PASSWORD
},
headers: {
'X-Parse-Application-Id': PARSE_APP_ID,
'X-Parse-REST-API-Key': PARSE_API_KEY
}
},
function(err, response, body) {
if (err) return callback(err);
// user was found, add sessionToken to user profile
if (response.statusCode === 200) {
context.idToken[`${MY_API}/parse_session_token`] = JSON.parse(body).sessionToken;
return callback(null, user, context);
}
// Not found. Likely the user doesn't exist, we provision one
if (response.statusCode === 404) {
request.post({
url: `${MY_API}/users`,
json: {
username: username,
password: PARSE_USER_PASSWORD
},
headers: {
'X-Parse-Application-Id': PARSE_APP_ID,
'X-Parse-REST-API-Key': PARSE_API_KEY,
'Content-Type': 'application/json'
}
},
function(err, response, body) {
if (err) return callback(new Error('user already exists'));
// user created, add sessionToken to user profile
if (response.statusCode === 201) {
context.idToken[`${MY_API}/parse_session_token`] = body.sessionToken;
return callback(null, user, context);
}
return callback(new Error(username + ' The user provisioning returned an unknown error. Body: ' + JSON.stringify(body)));
});
} else {
return callback(new Error('The login returned an unknown error. Status: ' + response.statusCode + ' Body: ' + body));
}
});
}
I'm writing a SPA in JS, so I have some client side code that handles the Auth0 login, (replace 'https://subdomian.back4app.io' with your own parse server's API address - the same value as used in the above Auth0 rule). Note the Parse.User.become function, which assigns the session id created in the Auth0 rule to the current parse User:
handleAuthentication() {
this.auth0.parseHash((err, authResult) => {
if (authResult && authResult.accessToken && authResult.idToken) {
this.setSession(authResult);
Parse.User.become(authResult.idTokenPayload['https://subdomian.back4app.io/parse_session_token']);
history.replace('/');
} else if (err) {
history.replace('/home');
console.log(err);
}
});
}

Meteor acounts add info from Twitter accounts

I'm trying to figure out how I can add additional information from a user's Twitter account to the created account on a Meteor installation.
In particular I am trying to access the user's bio via Twitter Api v 1.1 and am not successful in doing so.
Therefore I am trying to extend Accounts.onCreateUser(function(options,user) {}); with the Twitter bio. How do I do that? And then access this data from a template?
Here's a perfect answer for returning data from Github, however I've had trouble porting this approach over to Twitter as the authenticating service: Meteor login with external service: how to get profile information?
You could do it on this way:
Accounts.onCreateUser(function (options, user){
user.profile = options.profile || {};
//Twitter returns some useful info as the username and the picture
if(user.services.twitter){
user.profile.picture= user.services.twitter.profile_image_url_https;
user.profile.username= user.services.twitter.screenName;
}
return user;
});
For getting the data from the Twitter API I´m using the node package oauth:
OAuth = Npm.require('oauth');
oauth = new OAuth.OAuth(
'https://api.twitter.com/oauth/request_token',
'https://api.twitter.com/oauth/access_token',
'consumerKey',
'secretKey',
'1.0A',
null,
'HMAC-SHA1'
);
getTwitterUserData: function (id) {
var accountUser = AccountsUserCollection.findOne({_id: id});
var url = "https://api.twitter.com/1.1/users/show.json?screen_name="+accountUser.screen_name;
oauth.get(url, 'accessToken', 'accessSecret', function (err, data, response) {
if(err){
console.log(err);
}
if(data){
Fiber(function () {
AccountsUserCollection.update({_id: accountUser._id}, {$set: {dataTwitter: JSON.parse(data)}});
}).run();
}
if(response){
Log.info(response);
}
});
}

Resources