Mongodb Realm, registerUser is undefined, Node.js - node.js

I followed the docs,
https://docs.mongodb.com/realm/node/manage-email-password-users/#node-manage-email-password-users
app.emailPasswordAuth.registerUser(email, password);
It complains registerUser is undefined.
By following the type interface, I tried realmApp.auth.emailPassword.registerUser, it complains registerUser is not a function.
I have checked email/password user authentication, which is on.
Can anyone tell me what could possibly go wrong here?
I couldn't find any example that is using Node.js to register a user with email and password.

Figured it out.
The docs should be updated to realmApp.auth.emailPassword.registerEmail(email, password);

Related

Xero Api NodeJS - invalid grant issue

I am using the xero-node module to create an app for Xero with NodeJS.
For some reason every single request for a refresh token is coming back as invalid grant
i have been taken the code and made the callback attempt to grab the refresh straight after i do the auth so I can ensure thats its the latest token and still does the same thing.
Code is below this method is called when Xero passes back to the app (callbackURL)
The error i get is "invalid_grant" it does not give any other errors and there is no errors logs in Xero so very unhelful.
exports.callback = async function (req, res) {
const tokenSet = await xero.apiCallback(req.url);
try {
const newTokenSet2 = await xero.refreshWithRefreshToken('ClientID, 'ClientSecret', tokenSet.refresh_token);
}
catch(error){
console.log(`ERROR refresh: \n ${JSON.stringify(error.response.body, null, 2)}`);
};
///console.log(tokenSet);
};
Any ideas ?
Without seeing more of your code for context it's bit tough to tell. I'm assuming you're not actually sending 'ClientID' and 'ClientSecret' as strings.
I would refer you here for refreshing with a fully initialized client leveraging openid-client:
https://github.com/XeroAPI/xero-node-oauth2-app/blob/f1fbd3a08e840e54e8ce57f7050ddde6686208d8/src/app.ts#L233
Or here, to initialize an empty client and refresh by passing the client, secret, and refresh_token:
https://github.com/XeroAPI/xero-node-oauth2-app/blob/f1fbd3a08e840e54e8ce57f7050ddde6686208d8/src/app.ts#L236
I think what's happening is that you're using the second method but with an already initialized client. Again, tough to tell with limited context. If this doesn't resolve it please post more detail.

Cant access property of req.user

I'm writing in Node using passport.js to authenticate.
console.log(req.user);
returns
{ group: 'CuManager',
password: 'password',
username: 'administrator',
cu_id: 2,
_id: 569fd3f4328ef124be533caf }
but
console.log(req.user.cu_id);
returns
undefined
I was thinking that cu_id property maybe is not available due to serialization/deserialization, but it's there. I just can't access it.
How can I do that?
I need it for
find({cu_id : req.user.cu_id})
BTW I can't help thinking passport.js is little overcomplicated (maybe we just don't get along). What else can I use to authenticate users in Node (I use express)?
If req.user is a Mongoose document, you should probably add cu_id to the proper schema.
Otherwise you can use something like req.user.toObject().cu_id to access the property, or make sure that somehow the result of doc.toObject() is assigned to req.user.
As for a Passport-replacement: this depends on how exactly you want to authenticate your users. If you're POST'ing a login form to an Express route, you can perform the password validation and session setup yourself.
try parsing it in JSON.
JSON.parse(req.user)['cu_id']

NodeJS - Not being able to access the route I want

I'm having some troubles getting to a route I got. The route works on http://localhost:3000/me and shows info but on http://localhost:3000/!#/me it doenst show anything. The purpose of said route is to show the logged persons' profile.
On my server routes I got:
app.get('/me', users.me);
The users.me function is as follows:
exports.me = function(req, res) {
res.jsonp(req.user);
};
The console states it expected a object and got an array, I can understand that since I'm getting a json, but how can I send the own user back to the front-end so it shows his/her profile?
Edit: I managed to solve my problem, since I use passportjs I can get the user id from the session. Since I already had a route for a user by id, I simply had to redirect to said route. Like this: req.redirect('users/'+ req.session.passport.user);. Since I already had a /users/:userId route working it completely solved my issue.
Edit2: Apparently there are several ways to get the user id. Try to console.log the request and you will see what I mean :)
/me and /!#/me are not the same route . The later won't match get('
/me',..)
the hash fragment #/me will not send to the server, you cannot capture that by server side routers(without force the page refresh by client code). But you can manage that by client-code.

NodeJS - Passport password appears as plain text in DB

Probably I am missing something here.
Got an Express server with MongoDB and i'm using passport to authenticate.
I'm using one of the standard code example to signup and it seems ok, but I can see the password I type in the password field (plain text) in my DB.
I expected it to be encrypted...
Am i doing something wrong?
You have to hash the password yourself. Here is how to do it using brcypt:
function hashPassword (password) {
return bcrypt.hashSync(password, bcrypt.genSaltSync());
}
So before you save your user to the DB simply invoke that function like so:
user.password = hashPassword(thepassword);

Re-validating expired AccessToken (or get new one) when logging into app via Facebook Strategy using Passport

Under a variety of circumstances, Facebook's internal AccessToken (used for various features in the Facebook API and other cases) may become invalid. For example, if a user changes her password between sessions of using an application that relies on Facebook Login. There are a few other cases as well.
What happens, however, is that your application essentially crashes, with an error like this: data={"error":{"message":"Error validating access token: Session does not match current stored session. This may be because the user changed the password since the time the session was created or Facebook has changed the session for security reasons.", "type":"OAuthException", "code":190, "error_subcode":460}}.
Passport's Facebook Strategy uses the AccessToken, and it's available to an app as soon as a user is logged in / authenticated via Passport. The problem, however, is what to do when the above error is encountered. Facebook gives a convoluted re-auth flow as an example in PHP, but the general sense is that you need to re-authorize your app with Facebook.
The question is, even when removing the Facebook app from your Facebook page, and forcing the application relying on Facebook Login to re-authorize itself, it seems that Passport + Facebook Strategy is still picking up the last existing AccessToken from the browser's session storage. (At least that's what I'm seeing with Mozilla/Fx 26). I have re-authorized my app several times, but when debugging and looking at what Passport returns, I always get back the same invalid AccessToken. Seems like if an AccessToken exists in session-storage, Passport picks that up instead of getting a new one from Facebook.
So is there a way - within Passport + Facebook Strategy - to essentially ignore or override any stored AccessToken and always request a new one from Facebook, in the event of this kind of error? Not at all clear how to make that happen. Thanks for the help.
Update: The sample code for invoking the strategy has refreshToken as a parameter; what does this do? Is there a possible solution with this parameter?
passport.use(new FacebookStrategy(
{
...
},
function(accessToken, refreshToken, profile, done)
{
I found the answer to my question, and will leave it up in case anyone else encounters the same issue.
Passport, in its VerifyCallback function, passes the AccessToken to the application. The recommendation (tacit or otherwise) is to of course save this AccessToken as part of the user's persisted record (say, a MongoDB document). It'll be needed when making subsequent calls to the Facebook API, and though it can probably be safely retrieved from the request.user object passed around through the Express middleware, having your own local copy probably makes sense.
Now, when you're done authenticating the user via Passport, you still will pull up your user's persisted record to get other user data. Passport documentation features a generic function called Users.findOrCreate() to serve as a model/prototype of this function for you to implement. And here's where the issue lies: If you find a user (one already exists) via this function, you'll be using that record throughout your app. And if that record also holds an AccessToken, and that AccessToken has changed, then of course you'll be in trouble: Passport/Facebook is passing you a new AccessToken, but you're using an outdated one.
So the simple fix is this: If you've implemented a Users.findOrCreate() function to persist a user and rely on this to retrieve a user's set of data - and that record also stores the AccessToken - then make sure you check the current (old) AccessToken to the one Passport/Facebook is passing you in the VerifyCallback when a user has just been authenticated; if the two are different, update the user's persisted record and use this new Token.

Resources