AWS amplify validating authorization code - node.js

I am a compete beginner to AWS and amplify, but what I am trying to do seems it should be fairly simple.
I have managed to set up front-end react access to read/write to amplify GraphQL database. What I want however, is only people with an access code to be able to read/write from the database.
In short, I want a form on a page to be filled out only if the person knows/has an access code. I don't want to go through the hassle of creating accounts and setting up authentication, because security does not need to be person specific and high. I imagine the validation of the access code is similar to validating a promotion code (a list of possible promotion codes is available on the database and it only gets validated if it matches one of them).
This should be done on the server-side. If anyone knows what is needed and if they know of any resources on how to do it please let me know.
Any advice on how to approach this? Many thanks.
I've tried researching if I should use nodejs or lambda but don't really see how this would work. Ideally somehow just adding a layer of validation ontop of the front end react reading/writing to the database.

Related

How should I set up the auth flow when handling drive files of a user server side?

The gist of it all is that I'm trying to fetch audio metadata from a user's google drive files to store them into firebase.
At first I intended to do this locally, entirely client-sided, because my front-facing web/iOS/Android app is in flutter;
but as it turns out, there's almost no library handling audio metadata properly, and after dabbling with it, I realized I could probably get some formats (say, .wav & most RIFF-type audio files) to work, but doing an entire library to handle all kinds of audio metadata was a task significantly bigger than my original plans. Another option would be to create interfaces between C++ code and/or JS code into my Flutter application, but I'd have almost no control over that, it's not the easiest of process, and there would be possible inconsistencies between platforms.
I might make that library eventually, but in order to facilitate my work, I decided to use a server as a middleman that'd run with node and handle the file requests and metadata treatment, & also facilitate the interactions with firebase for me by making them handled by a service account.
Now, this makes me run into one issue : how to handle the google Auth.
When my user logs into my app, I get all the required auth scopes (google drive files access and write, contacts, email, etc) for my app; it goes through the consent screen and I get authenticated.
I'm still a little confused with the recommendations from google and best practices in this case, since my app, in itself, did not require an auth system outside of getting access to the google drive files through google identification, and I therefore do not have Firebase/Firestore users; I can simply store them in my (firestore) database for identification purposes (or maybe tie in the frontend flow to my firestore app to also create a user when logging in through google if that is possible. I'm currently using the google sign in
flutter package.)
To come back to my actual problem now that the situation is laid out :
Should I just transfer the auth tokens (and maybe reverify them in some ways to avoid impersonation) from my frontend app to the server through a HTTPS post request or through headers, and use them to directly query the Google Drive API (I wouldn't even need to store them outside of memory, which would be relatively safe against any attacks on the server itself), handle the files and the possibly expired token ?
Should I modify my frontend workflow so it directly grants access to my server who would handle the session rather than getting the tokens locally ?
In the first case, I would most likely simply use the users UID as identifiers for the firestore data (none of it is sensitive anyway, it would simply be playlists and some metadata). In the second case, I could probably implement a stronger security on firestore using the firestore rules,but it'd require a significant amount of refactoring and logic changes in my frontend.
In case that wasn't clear, I wish my server to make all the Drive related requests (after getting the proper authorizations from the user of course) and handle these without having to request the files locally in frontend. Both solutions (and others if available) should work, but I'm wondering what the best practice would be in the context of the Oauth2 system used by google and the fact that the authorization is transitioning between client and server and could be subject to security issues.
I'll add code/visual representations if this isn't clear enough. It is to me, but I obviously designed the mess.

LDAP Authentication Node.js

Help! I have no clue what I am doing here. I am reworking old C# code and I need to use LDAP for integrated authentication on an intranet. The user should be completely unaware of this process but what I need is to have the React page contact the express server passing in the users domain id. From there I need to perform basic authentication then return all the groups that this user is a member of for validation.
I have read numerous tutorials on passport-activediretory and passport-ldap and so on but I am still confused.
What I am looking for is a single function that will run on every call to the API and will return either validation or, if requested, validation and group names the user belongs to.
What is available to make this process very simple. I looked at passport but to be honest authentication is not my milieu so I am at best uncertain as to how any of it works.
I am hoping that it will be as simple as app.all("*", functionHere());
Being very new to node (first project) I really need extensive help, hopefully in small words.
Thanks
For now I have switched to a .Net back end which support for LDAP integration without the need to a lot of excess code.
Will move back to Node once the application is finished then port it over.

NodeJS Performance question - Single Threaded

Need some suggestions about how to handle operations in NodeJs. I have tried to search things but couldn’t find it anywhere, so I thought I will post it here to get the experts feedback.
We have built an E commerce platform using NextJS and NodeJS.
I still have to go test and do a load test confirming how do we perform, but I’m a little worried about all the statements and declarations about how nodejs is not a multi threading language and it is a show stopper and bla bla bla. So I am here to get your suggestion/feedback on what we are doing is okayish or not. This is what I have:
Authentication Microservice: for authenticating requests and finding if the user has access to a particular module
payment microservice: for accepting payments and refunds.
Shopping Service
MySQL and Sequelize
I will try to explain my question with an example of "order processing". So when I get a request to confirm an order, this is what I am doing to authenticate the request and confirm if details are full proof.
Confirm the request is authenticated through jwt token
Make a request to user auth and confirm user is a valid user and has access to order module.
Verify the price of items through database (because I’m assuming a payload can be hacked and wrong prices can be sent)
Verify if the discount is validated correctly from the database
Verify if the coupon is valid and the discount applied is correct or not
Check if the reward points sent are correct or not - a request to user service is sent
Our payment gateway is Razor Pay, here, we confirm if the payment id sent is a valid payment id, and the amount received from the user matches the total amount to be charged.
So this is a long list of validations we do at NodeJS right now.
It’s super fast on a single request. I will definitely tune things around when we go deep into load testing.... but my current dilemma right now is whether we have opted the right approach or not. Is NodeJS good enough to do this kind of execution. I am expecting no more than 200+ concurrent users in 6-7 months down the line so I am not toooooo worried about performance. I can do clustering and dockering to boost up performance. I want to know if I have made the right choice to do this in NodeJS. It’s not a very high cpu intensive algorithm, just some ‘for loops’ and some Database requests.
Should I keep this in Node, or should I move this code of algorithm in another service written in a different language like C++ or may be python.
Big time confused right now. Any help will be greatly appreciated.
Node.js may be single-threaded, but it should be fine with what you are doing. It is well suited for horizontally scaling/clustering and there are plenty of node modules already there to help you out with that.
https://medium.com/iquii/good-practices-for-high-performance-and-scalable-node-js-applications-part-1-3-bb06b6204197
Additionally, Node.js is asynchronous and can handle concurrent requests.
I have also included an older link on how to scale node.js that lists how many users each scaling method can help support. Long story short you can use vertical scaling, horizontal scaling, microservices(which it sounds like you already looking at) and automation to easily scale up your application. Node.js should work fine.
https://adrianmejia.com/how-to-scale-a-nodejs-app-based-on-number-of-users/

Actionlogging with Node

I am quite sure that I am not the first person on the planet trying to implement the following, but I am sure that I am not able to find a good guide how to do it.
Our node backend is setup quite like a MVC to say so.
View = Express Server offering our api
Controller = Library, a set of controller functions to manage our data
Model = Our mysql database, it's Javascript DAO respectively (since our usecase is quite unique we need to write own DAO's and can not go let's say for js-data.
The challenge we face now, is:
As a developer, I want to keep our library clean from overhead for developers.
On the other side, as a database administrator I clearly want to know who did what modification and so on
Until now I tried to keep the 'user' object out of the library, since I do not want all controller functions to look like
function ctrl(param1, param2, param..., user)
Going for this would mean, we have to pass around User objects all the time, which would make it a pain to code inside the libraries.
On the other hand, I can not find any other approach in node/express to somehow get knowledge about the user without passing it (since we do not really have sessions, at least not yet in our code).
TL:DR; I do want to action log all database modifications, but do not want to pass around a User object all the time.
Is there any known approach for that challenge which does scale and is 'best practice'?
Thanks in advance

parse.com security

Recently I discovered how useful and easy parse.com is.
It really speeds up the development and gives you an off-the-shelf database to store all the data coming from your web/mobile app.
But how secure is it? From what I understand, you have to embed your app private key in the code, thus granting access to the data.
But what if someone is able to recover the key from your app? I tried it myself. It took me 5 minutes to find the private key from a standard APK, and there is also the possibility to build a web app with the private key hard-coded in your javascript source where pretty much anyone can see it.
The only way to secure the data I've found are ACLs (https://www.parse.com/docs/data), but this still means that anyone may be able to tamper with writable data.
Can anyone enlighten me, please?
As with any backend server, you have to guard against potentially malicious clients.
Parse has several levels of security to help you with that.
The first step is ACLs, as you said. You can also change permissions in the Data Browser to disable unauthorized clients from making new classes or adding rows or columns to existing classes.
If that level of security doesn't satisfy you, you can proxy your data access through Cloud Functions. This is like creating a virtual application server to provide a layer of access control between your clients and your backend data store.
I've taken the following approach in the case where I just needed to expose a small view of the user data to a web app.
a. Create a secondary object which contains a subset of the secure objects fields.
b. Using ACLs, make the secure object only accessible from an appropriate login
c. Make the secondary object public read
d. Write a trigger to keep the secondary object synchronised with updates to the primary.
I also use cloud functions most of the time but this technique is useful when you need some flexibility and may be simpler than cloud functions if the secondary object is a view over multiple secure objects.
What I did was the following.
Restrict read/write for public for all classes. The only way to access the class data would be through the cloud code.
Verify that the user is a logged in user using the parameter request.user ,and if the user session is null and if the object id is legit.
When the user is verified then I would allow the data to be retrieved using the master key.
Just keep a tight control on your Global Level Security options (client class creation, etc...), Class Level Security options (you can for instance, disable clients deleting _Installation entries. It's also common to disable user field creation for all classes.), and most important of all, look out for the ACLs.
Usually I use beforeSave triggers to make sure the ACLs are always correct. So, for instance, _User objects are where the recovery email is located. We don't want other users to be able to see each other's recovery emails, so all objects in the _User class must have read and write set to the user only (with public read false and public write false).
This way only the user itself can tamper with their own row. Other users won't even notice this row exists in your database.
One way to limit this further in some situations, is to use cloud functions. Let's say one user can send a message to another user. You may implement this as a new class Message, with the content of the message, and pointers to the user who sent the message and to the user who will receive the message.
Since the user who sent the message must be able to cancel it, and since the user who received the message must be able to receive it, both need to be able to read this row (so the ACL must have read permissions for both of them). However, we don't want either of them to tamper with the contents of the message.
So you have two alternatives: either you create a beforeSave trigger that checks if the modifications the users are trying to make to this row are valid before committing them, or you set the ACL of the message so that nobody has write permissions, and you create cloud functions that validates the user, and then modifies the message using the master key.
Point is, you have to make these considerations for every part of your application. As far as I know, there's no way around this.

Resources