Auth0 - enriching data with user information - node.js

I need my API to return objects that contain some user info. For example:
api/comment/123 needs to return:
{
id: 123,
author: {
id: 'googleblahblah|123456789',
name: 'James Bond'
}
}
Normally I would just join the user and the comment table, though in this case I can't. My app's database stores the user id, though the name (and other user stuff) is stored in Auth0.
Obviously making an API call to Auth0 to 'enrich' objects on every API call is not plausible.
Do I cache all / some some user info on my app server? Have only the user ID in the API result and let the client enrich the data?
How do people handle this?

I do not think there is an ultimate solution for this problem.
What I did was creating a user table with user id and user name in my own database. Whenever somebody logs via Auth0 in I would create or update the logged-in user information in that table with the OAuth token information.
After that you could join the tables as you stated.

Related

How can I validate a user exists in the kuzzle database given only <kuid> and a <jwt> of that user?

I am using kuzzle (2.6) as a backend to my app. I'd like to encrypt data stored to Kuzzle by the users of the app, and organize encryption keys separate from the database. The key holding entity (keyStore for short) should give keys only to users that are truly registered in the database, without becoming able to access the user data itself.
So I'm trying to pass, from the app, when the user is logged in, a <kuid> together with a corresponding <jwt> obtained e.g. via kuzzle.auth.login('local', {username: <username>, password: <password>}) to the keyStore via https. The keyStore should send the information to the Kuzzle database, where a Kuzzle plugin can verify the user exists. If Kuzzle confirms the identity of the user to the keyStore, the keyStore will hand out a key to the user such that the user can encrypt/decrypt its data.
In short:
Is there any way I can let a plugin validate that a given <jwt> and a given <kuid> belong to the same user? <username> and <password> would both not be available to the plugin.
Kuzzle core developer here.
Right now we don't have a public API to get the user linked to an authentication token.
Still, you can use the auth:checkToken API action to verify the token validity and the jsonwebtoken package used by Kuzzle to retrieve the user kuid from the token.
const { valid } = await app.sdk.auth.checkToken(token);
if (valid) {
const kuid = require('jsonwebtoken').decode(token)._id;
}
Anyway, that's an interesting feature and we will discuss it in our next product workshop.
I will update this answer accordingly.

Apple sign in, authorize method returns name only first time

Implementing Apple sign in in a web app (old fashion ASP.NET, but it doesn't matter - the question can be treated as simple HTML/JS POC), calling method authorize on Apple endpoint:
https://appleid.apple.com/auth/authorize?client_id=...&redirect_uri=...&response_type=code%20id_token&state=...&response_mode=form_post&scope=name%20email
I want to get the user's first and last name.
Method returns something like this:
{
"state": "xxx",
"code": "yyy",
"id_token": "zzz",
"user": {
"name": {
"firstName":"John",
"lastName":"Doe"
},
"email":"example#privaterelay.appleid.com"
}
}
id_token is JWT which consists of user's apple ID and email, there is no data regarding name or surname.
As you can see, I can get name and surname from the user property. That's the only way known to me.
The problem is, Apple returns this data only the first time I request it. It's not a bug, it's a feature: https://developer.apple.com/documentation/sign_in_with_apple/sign_in_with_apple_js/configuring_your_webpage_for_sign_in_with_apple :
Important
Apple only returns the user object the first time the user authorizes
the app. Persist this information from your app; subsequent
authorization requests won’t contain the user object.
So I store this data for later in the workflow, I will store it in database.
Now my problem/question:
When user deletes their account, I delete all their data from db (I have to, because of the contract, law etc).
When the user registers again through Apple sign in, I ping Apple endpoint, and I don't get user data (including name and surname) any more (because of the Apple policy quoted above)!
What should I do to get it?
I'm doing apple sign-in back-end part, faced the similar issue.
For IOS 13+
SDK provides apple user uuid, email and name for the first authorize request.
We are mapping this unique apple_user_uuid with the profile details in DB.
(In case of request failures, you can ask back-end to put this in queue and app should keep this in cache until back-end call is successful).
For ANDROID/WEB Flow/IOS Below 13
For the first time in apple callback, it sends us the name with a one time code (5 minute expiry).
Using this code when we call token API, it provides us id_token JWT.
In token the subject is apple_user_uuid.
Persist it in the same table.
So now in back-end you will always have email,firstName, lastName tagged with apple_user_uuid, which remains constant for an apple id.
And don't delete this mapping if the user deletes your account. Until apple provides a fix.

How to map storage.userId and idToken in Google Assistant actionSdk

Hi, We have created a bot where user interact with the bot. so our
bot has two type of queries static and dynamic queries. if user asks
static query we don't ask for SIGN IN but if user ask for dynamic
query than we ask user to SIGN IN and redirect to SIGN IN page than
we ask mobile no and dob and send OTP to user and than verify the
user and send back a token in response which we get in further
request. The problem is let use suppose user came on our our bot and
asked static query so i store the chat of user to my db initially I
create a userId for user like this conv.user.storage.userId =
'unique_id' and store this unique_id in my db to identify the user
next time and send back. Next time same bot get same userId and keep
updating my chat in db for this userId. Now the problem comes when
users asks a dynamic query than I have to redirect user to our
account linking page. user is redirectd to account linking page and
user fill his mobile no. and DOb and we send a otp to usermobile.
When our SendOtp api is called I create a userId and store in
databse but I want the userId which I set before for static queries
(conv.user.storeage.userId) this one. How can I get this Id. Can we
pass this userId as params to when to ask for SIGN In (conv.ask(new
SignIn('To get your account details'))) and get this static query
userId in my SendOtp API. I need same ID to send further to update
chat.
When you create a SignIn request, you cannot provide any additional data in that request. However, you are able to provide this behavior when your Action gets a callback. You will get a Sign In event that can be set to when the user signs in. At that point you can add your additional logic to connect the user's account on your backend with the account ID in userStorage.
Here's an example of what it may look like.
app.handle('linkAccount', async conv => {
let payload = conv.headers.authorization;
if (payload) {
// Perform account merge
await performAccountMerge(payload.email, conv.user.storage.userId)
}
});
async function performAccountMerge(authorizedEmail, savedUserId) {
await saveInDatabaseForEmail(authorizedEmail, savedUserId)
}

Dialogflow - Fulfillment request pay load - How to register the user with user id received in request payload

What are the google/Microsoft(Skype) APIs available in order to register user in my application with the same user id as received in fulfillment request payload to my web hook?
I receive following for skype:
{
"originalDetectIntentRequest":{
"source":"skype",
"payload":{
"user":{
"name":"Sana Zehra",
"id":"29:1I3o3Np8sTLU7YSuhHO-IDuc1SgqMwg-83YwGryAZceE"
}
}
}
}
For Google I receive this:
{
"originalDetectIntentRequest":{
"payload":{
"user":{
"lastSeen":"2019-01-02T07:57:02Z",
"locale":"en-US",
"userId":"ABwppHHxPEyGWY1R26WqV3o5i1w8YNGbAIn5TXd28cre8Eu3iWtPlJEMuSzPWIW1b5u8e94djCv1xvmszegO1Q"
}
}
}
}
I need to register my users with this id as I authenticate if an incoming request is a registered user or not.
You would need to build a flow for registration something that allows you to gather all the required information and register the user at your end, you can then verify if the user is registered by validating them against their id.
A sample article that handles the user registration via chatbot scenario:
https://medium.com/#sage.mcenery/building-a-registration-chatbot-on-aws-with-lex-and-twilio-4a14c15b8725
You can use google helpers in case of assistant which can give you the following additional info about the user:
Display name,
Given name,
Family name,
Coarse device location (zip code and city),
Precise device location (coordinates and street address)
Documentation on the same:
https://developers.google.com/actions/assistant/helpers#built-in_helper_intents
I've never tried this myself though so I'm not too sure about this.
I do not think Skype and Google will give you much info about the user if that's what your looking for but a unique id against the user should do the trick in most cases.
Neither ID has any direct relation to the user's account on that platform.
Furthermore, the userId provided on the Actions on Google platform has been deprecated, and is scheduled to be removed in May 2019.
The suggested way to associate the user's Google account with their session with you is to use Google Sign In for Assistant. With the user's one-time permission, you can then get their Google profile ID and other profile information.

How to pass user information back to server side with ADAL for angular

I am trying to integrate azure Active Directory Authentication Library for js to my site. I downloaded the SPA sample and made it work with my app detail.
However, how can I pass user information back to server?
For example, this is the example code on server side to retrive the logged in user:
string owner = ClaimsPrincipal.Current.FindFirst(ClaimTypes.NameIdentifier).Value;
IEnumerable<Todo> currentUserToDos = db.Todoes.Where(a => a.Owner == owner);
The owner string turned out to be a guid like token other than a readable username or email address.
Is there a way to retrieve username or email address by using this library directly or I have to send it to server side myself?
ClaimTypes.NameIdentifier is a guid unique to each user. If you want readable username or email address, try ClaimTypes.Email or ClaimTypes.Name.
Yes, we are able to get the user info from client directly via adal-angular.js. It already store the user information to the $rootScope. userInfo, we can retrieve the user information from it instead of from web server.
Here is the code that retrieve the name and email address:
console.log($rootScope.userInfo.userName);
console.log($rootScope.userInfo.profile.name);
console.log($rootScope.userInfo.profile.upn);
And below is a figure for the struct of userInfo object for your reference:

Resources