How to access logged in user data in GAE? - node.js

I have a site dashboard on GAE standard node.js environment that uses login: admin option in handlers: element in my app.yaml file. This option makes google login window appear before accessing the site. Is it possible to get email and profile of user logged in?

Updates on Feb 2
Tested on my local server
I added login:required in app.yaml; it's a Python3 App but I did not use users api; I start the app with dev_appserver.py to make sure it uses the app.yaml file in the development environment; When I loaded the home page, it prompted me to sign in with test#example.com
I dumped the header output and it included the following
X-Appengine-User-Email: test#example.com
X-Appengine-User-Id: XXXXX
Original Answer
You can use the 'users' Api and call the function GetCurrentUser()
Example, if your code was in python, you'd have something like
from google.appengine.api import users
# Get information about the currently logged in user
users.GetCurrentUser()
# Extra - if you wanted to confirm this is an admin user
users.IsCurrentUserAdmin()
Since you're not using Python, see if the environment variable for USER_EMAIL exists. The source code for users api has the snippet below (so see if it works for you)
email = os.environ.get('USER_EMAIL', email)
_user_id = os.environ.get('USER_ID', _user_id)

Related

passport-apple inexplainable invalid_client on nodejs backend -- using clean example repository with fresh set of credentials

I've cloned https://github.com/ananay/passport-apple-example and replaced the config with this:
clientID: "com.myname.web",
teamID: "myteamid",
callbackURL: "https://myurldev.com/auth/apple/redirect",
keyID: "mykeyid",
privateKeyLocation: path.join(__dirname, "../apple-key.p8")
I've also added SSL certificate on my machine and starting the server with https, all works fine & is recognized by my browser. I'm also starting the app on port 443 and proxying using my hosts file myurl.dev.com -> 127.0.0.1.
I have the same auth setup for facebook, google & microsoft and everything works fine.
I have:
Created a new APP identifier and enabled Sign in with Apple for it, named it: com.myname.dev
Created a new SERVICE identifier and enabled Sign in with apple, called it: com.myname.web
Added "https://myurldev.com/auth/apple/redirect" to the "Reply URLS" on the service identifier com.myname.web
Set my app identifier com.myname.dev as the main app identifier my service to be grouped with.
Created a private key and enabled sign in with apple, interface confirmed the presence of grouped ID com.myname.web bundled with com.myname.dev for which the key was created.
I have confirmed using console.log that the private key is indeed at the path being passed as parameter.
converted the .p8 file to base64 & then back to UTF-8 in an attempt to use the string for privateKeyString
successfully implemented Apple Oauth several times in the past using passport-apple
This time around, for some reason, auth simply doesn't work.
If I set the clientID as the APP identifier, not the service, I'm getting
invalid_request
Invalid web redirect url.
instead of invalid_client
Any advice on debugging this is highly appreciated. Thank you.
EDIT #1:
I have dug a bit deeper into the passport-apple package to figure out if anything goes against apple's docs around token generation, but the flow never reaches that part, indicating things go wrong on the actual configuration in Apple's console & what I'm trying to use for my project.
EDIT #2
2 of the app Ids I have created always throw "wrong redirect uri" because they're not service IDs so I can't configure redirect_uri, this will change if to "required" if I pass undefined as a redirect_uri.
One of the app ids throws only invalid client_id instead, regardless if I pass undefined or good value for redirect_uri.
EDIT #3
Went full vanilla through the OAuth code flow process and just created a url & redirected the user it, failing with this method is consistent with what is happening when using the passport-apple module.
const url = new URL("https://appleid.apple.com/auth/authorize");
url.searchParams.append("state", "fdbd287b1f");
url.searchParams.append("response_type", "code");
url.searchParams.append("scope", "name email");
url.searchParams.append("response_mode", "form_post");
url.searchParams.append(
"redirect_uri",
"https://raiseitupdev.com/auth/apple/redirect",
);
url.searchParams.append("client_id", "com.myname.web");
return res.redirect(url.toString());
[Creator of the library here.]
Did it stop working in development too? I feel this is a configuration error because the actual thing is working live on my website:
https://passport-apple.ananay.dev
Please follow up on this Github issue. Thanks!
https://github.com/ananay/passport-apple/issues/23

How can I protect the loopback explorer by username and password?

I've just started using loopback4 and I would like to protect the /explorer from being public. The user would initially see a page where username and password must be entered. If successful, the user is redirected to /explorer where he can see all API methods (and execute them). If user is not authenticated, accessing the path /explorer would give a response of "Unauthorized". Is there a way to easily implement this?
There is issue talking about a GLOBAL default strategy is enabled for all routes including explorer in https://github.com/strongloop/loopback-next/issues/5758
The way is to specify a global metadata through the options:
this.configure(AuthenticationBindings.COMPONENT).to({
defaultMetadata: {
strategy: 'JWTStrategy'
}
})
this.component(AuthenticationComponent);
registerAuthenticationStrategy(this, JWTAuthenticationStrategy)
But in terms of enabling a single endpoint added by route.get(), it's not supported yet, see code of how explorer is registered. #loopback/authentication retrieves auth strategy name from a controller class or its members, but if the route is not defined in the controller, it can only fall back to the default options, see implementation

How to transfer data from page to another in node js

Hello there i am learning node.js and got stuck in a scenario.The flow is that in website user register himself and after successfully registering i will be sending him to route named create_profile which in is post request and also i want to send userId to create_profile route.In case if user close the website then if he agains open it and login then if profile is incomplete then i will be taking his userId and send to create_profile route.And after that to home page.What i was thinking to store session for user authentication in create profile page and login.This is because if login there can be tow cases : If user has successfully completed his profile then take him to home and store a global session there and second case it to take him to create profile as its incomplete then after successfully creating take him to home store global session for user authentication.But my confusion is to how to pass userId from login to create profile which is post request.Do i need to make temp session ? Please solve my issue i am confused how to solve this .
You can create a "profile_completed" coloumn in DB and set it as "false" (default), update it to "true" if user has completed the profile. While user login check if his profile is updated ,if yes send him to home else ask him to update.
You can pass user I'd to create_profile via request or get it from session storage you saved earlier

Nextcloud external login for users in another database

I have a Nextcloud installation, with users stored in an external database, and this works fine with this app : https://apps.nextcloud.com/apps/user_sql
With that in place, I can login on my Nextcloud instance via the login form provided by Nextcloud.
I need to autolog the users when they come from another app.
I've written a PHP script, placed at the root of my Nextcloud installation, and it gets called by other internal apps of my company.
This script receives a userId and a token in the URL. After a successful check (no need to get in the details here), this script should log the user in.
Which API should I call to get the user logged in?
I tried the following, without success:
OC_User::login(...)
OC_User::getUserSession()->login(...)
Is there a way to trigger a valid login, so that I can get the users logged in?
Thank you for your answers, guys!
$user = '';
$pass = '';
$s = \OC::$server->getUserSession();
if (!$s->isLoggedin()) $s->login($user, $pass);
else $s->logout();
Placing this at /index.php and before calling OC::handleRequest() does the trick. It doesn`t work as expected but you could try to continue from here.
PD: Nextcloud Server v14.0.0 Alpha

Opening a google drive file using the google drive api while I'm NOT signed in to google drive

This has really been bugging me for some time so any help to confirm or affirm this is much appreciated! This is also the first time I actually post a question despite being developing for a long time :)
So I have a nodejs app integrating with the Google Drive API and I want users to authorize multiple Google Drive accounts and be able to view and open (and in general just interact with) all files from the accounts that they add.
I authorize my app using the highest available scope: https://www.googleapis.com/auth/drive and because I don't want users to have to sign-in again when the access_token runs out so I also include the approval_prompt: "force" and ``access_type: "offline"` when I request my access tokens.
Everything is fine - I authorize nicely, I can delete files, I can open them, I can share them, I can download them. Except for one thing:
If I e.g. authorize horse#gmail.com and then beaver#gmail.com. Then I can still delete, share, download and preview files from both accounts. But I simply cannot open documents from horse#gmail.com in google docs for editing (because beaver#gmail.com is signed in on my local machine). The best I can do is getting to a point where it shows me the document, with the right account logged in in the top right corner of the screen, but asks me to sign-in with a button. When I click the button it just refreshes and give me the same message and the same screen.
What I've tried is:
Simply redirecting the user to the file resources alternateLink from the API
Taking the alternateLink and appending my access_token to it and then redirect the user to it.
(and a ton of other random things I found various places that didn't work).
In both cases I have also tried signing out from all google accounts.
Now I checked a couple of webservices like Jollicloud and Odrive that tries something similar. However, both of them appear to force the user to login to google to access a file.
Is it really true that you can do all kinds of crazy things with the users files like deleting and downloading, but you can't open them in Google Docs own apps?
Not completely sure what kind of code I should add to show you what I've got. But here's some. This is my open action (what happens when the user clicks on a file and wants to open the file in the Google Docs/Sheet/etc.) (the orientdb stuff is because we're using the OrientDB graph database - it just fetches an account where we store the tokens). The link is the link property of the file (see below):
open: function(req,res,next){
var link = req.param("link");
var uid = req.param("uid");
orientdb.select().from('Account').where({uid: uid}).one()
.then(function(account){
var URL = link + "&access_token=" + account.tokens.access_token;
res.redirect(URL);
});
}
Here's an example file document from our database (I've replaced all compromising data with a descriptive
ODocument - Class: File id: #13:20499 v.6
name : Hummer2
service : Gdrive
kind : Google Doc
created : Nov 17, 2014
changed : Nov 17, 2014
users : [MB]
uid : mrb#flowtale.com
childID : <FILE.ID>
exportLinks : {DOCX=https://docs.google.com/feeds/download/documents/export/Export?id=<FILE.ID>&exportFormat=docx, Open Office doc=https://docs.google.com/feeds/download/documents/export/Export?id=<FILE.ID>&exportFormat=odt, Rich text=https://docs.google.com/feeds/download/documents/export/Export?id=<FILE.ID>&exportFormat=rtf, HTML=https://docs.google.com/feeds/download/documents/export/Export?id=<FILE.ID>&exportFormat=html, Plain text=https://docs.google.com/feeds/download/documents/export/Export?id=<FILE.ID>&exportFormat=txt, PDF=https://docs.google.com/feeds/download/documents/export/Export?id=<FILE.ID>&exportFormat=pdf}
usernames : [<ARRAY OF USERNAMES ASSOCIATED WITH THIS FILE>]
in_hasFile : User#11:0{out_hasFile:[size=2237],out_hasAccount:[size=4],username:null,email:h#h.com,password:<SOME ENCRYPTED PASSWORD>} v2244
out_belongsTo : Account#12:3{in_belongsTo:[size=6],type:Gdrive,uid:<SOME UID>,tokens:{access_token=<OUR ACCOUNT ACCESS TOKEN>, token_type=Bearer, refresh_token=<OUR ACCOUNT REFRESH TOKEN>, expiry_date=1416258913290},rootFolderID:<ROOT FOLDER ID>,email:<THE ACCOUNT EMAIL>,filesCached:2,usersCached:2,job:4,in_hasAccount:#11:0} v15
in_folderContains : File#13:20495{out_folderContains:[size=2],name:Testhest,service:Gdrive,kind:folder,created:Oct 12, 2014,changed:Oct 12, 2014,users:[1],link:https://docs.google.com/a/flowtale.com/folderview?id=<FOLDER.ID>&usp=drivesdk,uid:mrb#flowtale.com,childID:<FOLDER.ID>,exportLinks:{},usernames:[1],parents:[1],in_hasFile:#11:0,out_belongsTo:#12:3,in_folderContains:#13:13891} v36
link : https://docs.google.com/a/flowtale.com/document/d/<FILE.ID>/edit?usp=drivesdk
Looking forward to hear if anybody can help me or have experienced this before.
Thanks!
The API will allow you to do several actions in your drive account. I haven't been able to reproduce the behavior you mention with files that I haven't granted permissions to another account.
When you authenticate through the OAuth process, you will grant access to your account only to the application which created the OAuth request. You can not edit the content of a file without manually opening it through GDocs. Therefore, when the browser opens the AlternateUrl, it will require you to login to the account, in order to access the file.

Resources