Migrating Users From Facebook's "Raw" Authentication to Firebase Based Facebook Authentication - node.js

I am working on a project which needs User Authentication. The "Clients" are iOS (Swift) or Android (Kotlin) native applications. The original form of the API (NodeJS) used Facebook and Account Kit for OAuth and Phone authentication respectively. Since Account Kit shutdown, we moved to Firebase Phone Authentication for Phone but left Facebook in its original form. Now, we're wanting to consolidate our Authentication providers (to Firebase) but I can't seem to find a way to "convert" or "import" Facebook users to Firebase-based Facebook users.
So far, I've read through the Documentation, including the category about importing users, but it doesn't seem to indicate an ability to maintain backwards compatibility, while also moving forward to Firebase. What I mean is, it has an ability to set information, but it doesn't indicate that the same information will be used to authenticate that user as the same unique visitor.
What I am looking for is either transitory logic, which will handle this during login, or preferably, a "bulk-insert" type migration. Essentially, I want to have it setup so that the API only needs to keep a single authentication UID, and use only a single third party (even if they then use another subsequent third party) while maintaining user uniqueness (so that it doesn't create a new user for the same Facebook account).
Part of my problem in creating a temporary patch (not necessary if the main question is answered) is that I don't know of a way to differentiate between a Facebook UID and a Firebase UID to fork the logic. Again, this is only relevant if there isn't a solution for migration.
Feel free to request any more details that would be useful.
Update #1
I realized my question was open ended in what I was asking. I've been digging further and can better define my question:
I need a way to bulk insert users into Firebase's Authentication with a provider of Facebook. I know I can import them, via admin.auth().importUsers([...]) and that I can create accounts via admin.auth().createUser({...}) but when I do the former I can't seem to get back the user's UID, and the latter doesn't seem to allow specifying a provider. Am I missing something?

Related

How could I secure this API?

I'm building a full-stack application with Next-JS. I'm building an API that works with Firebase. I was wondering if there is a way to make this API secure.
Let me elaborate. There is an option to your account called Premium. This variable is stored in the Firestore and will determine if you have purchased a Premium membership. This will determine whether or not you have access to certain features. I will use an API to change this variable.
I had the following in mind:
Have a button on the page to upgrade account.
Button pressed? Call to the API with the following params: email, upgrade to. This is because the same function can also be used to downgrade an account, for example when the user doesn't pay for the upgrade.
That API function changes the variable in the Firestore. It returns a status and a message.
I want to make option 2 more secure because otherwise, it would allow anyone to change the premium variable. That is obviously not what I want. Is there anything I can do about that? For example, a token system, the thing with that is that I have been thinking about that and I don't really know how to implement that and how it would work exactly.
For anyone wondering why I am using an API: I will also be creating an app, probably with react-native. The user will also be able to change their account status and interact with the API to do other stuff in that app.
Thanks for reading and responding! I hope this is at least a bit clear. If you have any questions, please comment them.
I do similar things in my app. I use Cloud Functions (which operate in a secure environment) to both save settings in Security-Rules -protected tables, as well as setting Custom Claims in the users Auth profile. All authorizations are then verified in the Cloud Functions before any changes are made - You may need to "seed" some values in a protected collection/document from the Console to get the process started.

How to detect a returning user to Google Assistant on Android in Dialogflow fulfillments?

I have a running website, where users already have accounts. And I am trying to create a Google Assistant agent, accessible on Android, to help users access their information.
My issue is that I can't detect returning users on Android Smartphones, each time they have to sign in.
I tried Anonymous User Identity, but it is soon to be deprecated.
Is there an other way to keep track of users?Using some kind of userId that I can store, so I can make "my own Acount Linking" linking the person/Smartphone with already existing user accounts.
There are a few angles to your question.
Is there any way to keep track of users?
Yes... but...
You can store a userId that you generate in the user storage area. You do need to treat this like you would a cookie, so some jurisdictions might impose restrictions on this, but this is one approach to moving from the anonymous ID that is being turned off soon.
But...
How do I let them log into my service through the Action?
That is the problem. The General Policies states the following limitation for collecting user data:
Authentication Data
(including passwords, PINs, and answers to security questions)
Don't collect authentication data via the conversational interface (text or speech).
After a user's account has been linked, PINs or passwords may be used as part of a second verification process.
So you need to use Account Linking to connect to the existing account on your service.
How can I do Account Linking if I don't require Google Sign-In?
You can still use Google Sign-In for Assistant if it will (or may) provide the information as part of the profile that match what you have. So it doesn't need to use the same account - just have the same email (for example).
But that still may not be enough.
For other cases, you can look into setting things up to work with an OAuth server that you control.
So why use Google Sign-In if I setup an OAuth server that uses Google Sign-In?
Google Sign-In is good for a more streamlined flow, if you can use it. It can be done completely with voice, such as with a smart speaker, instead of requiring the user to go to a phone to complete the login. So if you have the user's email address in your account system, and you also get this from Google Sign In, then you can connect the two accounts.
In some cases, such as if the user is expected to have logged into the account on your website first, they won't even need to do that. If both the voice client and web client use the same Google project, then authentication will take place automatically.

Windows Store 8.1 App Azure ADAL offline client authetication

I'm building a Windows 8.1 store app and need to incorporate authentication. This is an enterprise app used in house. We load the app onto a tablet and a team may check that tablet out for weeks at a time, go out to the field to collect data and then we put in on a shelf until another team needs to use it. Now different teams may work for difference clients so when we authenticate users not only do they get access to the app but we also check what groups they are in to determine what clients they can work on or what previous records they can search for.
I've followed various ADAL tutorials and am able to setup everything in Azure and in my app I am able to authenticate a user successfully and get their groups. This relies on ADAL handling the username/password. What happens when the app shuts down and the user in a place where there is no internet (or even a reliable cell connection)? Specifically how can I have the user type a username/password to re-authenticate and get the same groups they were in when they can't access Azure services?
It appears they isn't available as the guidance always points to that is a risky proposition to have the app handle username/passwords. I understand that stance and can appreciate the caution behind it. However, in all of the ADAL documentation that I find that says this, none of them tell me how to handle an offline authentication scenario.
I have found links such as ADAL v3: How to authenticate using UserPasswordCredential? that tell me how to bypass the ADAL login page. I may have to move to that route and handle all of the username/passwords securely within the app, but first I would like to reach out and see how others tackle this scenario. Is it really as simple as avoiding best practices and just handle the username/password within the app?
If anyone has some guidance, ADAL (or other oauth providers) documentation, or other articles/advice I can follow up on to help achieve offline authentication I would greatly appreciate it!
Additional Information:
My scenario that I'm trying to cover is what happens when I have 1 device, 1 app, and many different users? These users will be in different groups that will determine how data fields get populated (filter data in combo boxes) and what previously submitted forms they can query for. All users would need to login when online to cache their information (say on Day 0) before they can ever use the app. On Day 1 user 1 uses the app and doesn't log out. I would expect the app to have a timeout timer to log that user out after 2 hours of no activity. On Day 2, user 2 just grabs the device off the shelf and takes it out into the field. He has no internet and needs to log in to determine who they are and what group they are in. I would expect since he has logged in once and verified his credentials already that we can enable this sort of scenario.
What I'm looking for is guidance if ADAL as a library can handle this or is it truly up to me the app developer to handle this sort of scenario. As I see it currently I need to store all user credentials, but at the same time it seems like everyone advises against that. I feel like I'm in a situation where I need to create a custom login screen and store the user data, SECURELY of course, even though its not recommended. It seems like all articles on how to use ADAL are written from a consumer app standpoint (or a BYOD) and don't take into account how a mobile app would be written for the enterprise.
That depends on your app design, if the first time(app online) , user login and app store all groups ,user information .After that user doesn't need to use token to get related information again(send request to server to acquire groups/user info). If app is offline , user doesn't need to re-authenticate(app controls the user session) , just get group/user information from cache . When using resource owner flow , you still need to send authenticate request to Azure AD server which need internet.

How do I access data for all of my students?

I'm making an app that authenticates a coach with KA's API, in order to present statistics and reports on the progress of each student.
How do I see "For whom am I a coach" (inverse of /api/v1/user.coaches)?
or otherwise request user and progress data for all my students?
You can request /api/v1/user/students to get a list of the currently authenticated users' students. Note that this is an undocumented endpoint, not sure if that's on purpose or not, but I suspect just an oversight because IIRC I've seen them reference it on github issues in the past.
I added that endpoint to the khan npm module in this PR: https://github.com/weo-edu/khan/pull/4
An important caveat to note is that as of this writing, you won't be able to request students on behalf of a user who has authenticated your application, only the user who created the app you're currently using.
Put another way: If I create an application called "hello" while logged in as "Jeffrey", I can get all of Jeffrey's students by authenticating with the "hello" app. However, If I log in as Lisa via the "hello" app (via oauth, e.g. passport-khan), I'll have an access token but the Khan API will refuse my request because Lisa did not create the "hello" app.
This behavior is documented (albeit a bit confusingly) in this wiki page, here's the relevant paragraph:
It is recommended that schools have one teacher/coach account that registers for an API key. This enables a situation where the logged-in user is the same as the third-party developer, who then can access their own students' data pursuant to Khan Academy's "coach" relationship. For example, suppose the principal of Riverdale High wished to export data for multiple students via the API. The principal would create a teacher/coach account, perhaps called "RiverdaleHighAPI," and register for an API key. The principal would then ask all students of Riverdale High to add "RiverdaleHighAPI" as a coach, either directly or via several class codes. When accessing the API with "RiverdaleHighAPI" as the logged in user, the principal would be able to access the data for all students that have added "RiverdaleHighAPI" as a coach. The app would not have access to any other coaches' student data, even if another coach logged in through the app. To protect student privacy, we do not allow indirect consent through the coach, and we require each student to explicitly grant permission to access their data. Please note that we are working to improve this functionality; for the time being, this "RiverdaleHighAPI" account should only be used by the school's API client, not by any actual teacher or coach.
Lastly, khan actually encourages public use of their internal API. They recommend opening up your developer console while logged in to khan and looking for the endpoints that return the data you want. (see this note on their authentication document).
This is obviously a fairly non-standard practice and I assume the endpoints would be subject to breaking changes without warning. Also you'll be flying documentation free. That said, this approach may be the most robust option for your purposes. Here's the quote from their wiki for posterity:
The API explorer documents our public API, which has URLs starting with /api/v1, but unfortunately it's not very well-maintained and lacking in a few areas.
If you're feeling adventurous, though, you're welcome to use any internal undocumented API endpoints. For example, if you load a Khan Academy video page and use your browser's developer tools to look at the ajax requests being sent, you'll see that it gets a URL like /api/internal/videos/aubZU0iWtgI/transcript, which contains a JSON response with the video subtitles. That "internal" in the name means that we don't provide documentation, and we may remove the endpoint or change the format in the future, but you're welcome to use any internal endpoints if you keep those caveats in mind.

Deployd: How to implement dpd-passport and securely authenticate

Let me start by saying I really like Deployd. I want to use it in production, but I want to incorporate OAuth and social logins, so I installed the dpd-passport module. It works great, except for two little (big) problems:
When a user signs in via an OAuth provider (e.g. Facebook, Twitter, Github) a new user record is created...but if the same user clears their cookies or uses a different browser to log in, a new user record is created.
If I do something clever (read: hacky) and assign users with social logins an ID based on the socialAccount and socialAccountId (something unique but constant for each social account), someone could use the standard method of user creation to spoof a user by making a POST request to the /users endpoint if they knew that user's socialAccount and socialAccountId.
My question is: How can I A) prevent #1 from occurring, or B) disable the standard method of user creation without also preventing OAuth user creation?
Has anyone ever successfully used Deployd and dpd-passport in production? If so, I want to speak with you...
Thanks in advance!
First of all, I think you haven't added the custom fields per the docs.
https://www.npmjs.com/package/dpd-passport#requirements
I hadn't either, and observed the new user feature (because it couldn't lookup the response from the auth service to find the user from before). Adding these fields fixed it.
Also, there is a google group here:
https://groups.google.com/forum/#!forum/deployd-users
Hope that helps.

Resources