When I use login function
User.login({email: 'foo#bar.com', password: 'bar'}, function(err, accessToken) {
console.log(err);
console.log(accessToken);
})
the error is
TypeError: Object [Model session] has no method 'create'
It looks like you are using an old version of LoopBack. Try upgrading and making sure the user model is attached to a data source. Below are the steps to do this.
// # Verify version
// Ω slc version
// slc v2.1.1 (node v0.10.9)
// # upgrade with `npm install strong-cli -g`
// # create a simple project
// Ω slc lb project hello-user
// Ω cd hello-user
// # create hello-user/models/user.js
var user = require('app').models.user;
var credentials = {
email: 'foo#bar.com',
password: 'password'
};
user.create(credentials, function(err) {
user.login(credentials, function(err, accessToken) {
console.log(accessToken);
// { userId: 1,
// ttl: 1209600,
// id: 'nt2KN4N5p3QbxByypRiHlduavxCRJUPbcStWPfxgrWYU8JllryjUp028hlJAFx4D',
// created: Tue Jan 14 2014 08:26:22 GMT-0800 (PST) }
});
});
Related
In tedious config, using process.env.(database details) fails. However if I put the same values by hand, the connect is successful.
I would like to use process.env instead of hard coding my database details.
Database is being hosted on azure.
Here's my code:
const { Connection, Request } = require("tedious");
const dotenv = require("dotenv");
dotenv.config();
// Create connection to database
const config = {
authentication: {
options: {
userName: "process.env.databaseUser",
password: "process.env.databasePassword",
},
type: "default",
},
server: "process.env.databaseUrl",
options: {
database: "process.env.databaseName",
encrypt: true,
},
};
const connection = new Connection(config);
// Attempt to connect and execute queries if connection goes through
connection.on("connect", (err) => {
if (err) {
console.error(err.message);
} else {
queryDatabase();
}
});
async function queryDatabase(query) {
const request = new Request(query, (err, rowCount) => {
if (err) {
console.error(err.message);
} else {
console.log(`${rowCount} row(s) returned`);
}
});
request.on("row", (columns) => {
columns.forEach((column) => {
console.log("%s\t%s", column.metadata.colName, column.value);
});
});
connection.execSql(request);
}
module.exports = {
queryDatabase,
};
terminal output:
Worker 09d76af8-01c2-4cdb-a2c1-d84de5ccfb89 connecting on 127.0.0.1:41165
[5/2/20 7:12:06 AM] Sat, 02 May 2020 07:12:06 GMT tedious deprecated The default value for `config.options.trustServerCertificate` will change from `true` to `false` in the next major version of `tedious`. Set the value to `true` or `false` explicitly to silence this message. at shared/my-db-helper.js:22:20
[5/2/20 7:12:06 AM] Sat, 02 May 2020 07:12:06 GMT tedious deprecated In the next major version of `tedious`, creating a new `Connection` instance will no longer establish a connection to the server automatically. Please use the new `connect` helper function or call the `.connect` method on the newly created `Connection` object to silence this message. at internal/process/next_tick.js:131:7
[5/2/20 7:12:06 AM] Failed to connect to process.env.databaseUrl:1433 - getaddrinfo ENOTFOUND process.env.databaseUrl
[5/2/20 7:12:07 AM] (node:21327) [DEP0064] DeprecationWarning: tls.createSecurePair() is deprecated. Please use tls.Socket instead.
.env file:
NODE_ENV=development
databaseUser=dataReader
databasePassword=***
databaseUrl=***.database.windows.net
databaseName=website
WRITE_FAILED_QUERY_TO_FILE=true
Replacing process.env variables with hard coded strings containing the same info is successful and returns the intended output.
I was putting process.env.(databasedata) in quotes!
process.env is an object.
removed the quotes and everything works.
#MaazSyedAdeeb. ty. Such a blind mistake. It works.
I've installed Realm Object Server using the docker container method on a VM on the google cloud platform. The container is running and I am able to connect in a browser and see the ROS page. I am able to connect to it using Realm Studio and add a user.
I have a nodeJS app running locally on a Mac and I'm trying to use that to sign in and write to realm on the server. When I run the app I get an error and the user returned is an empty object. Not sure what I'm doing wrong.
I'm new to NodeJS.
Code:
var theRealm;
const serverUrl = "http://xx.xx.xx.xx:9080";
const username = "xxxx";
const password = "xxxx";
var token = "long-token-for-enterprise-trial";
Realm.Sync.setFeatureToken(token);
console.log("Will log in user");
Realm.Sync.User.login(serverUrl, username, password)
.then(user => {
``
// user is logged in
console.log("user is logged in " + util.inspect(user));
// do stuff ...
console.log("Will create config");
const config = {
schema:[
schema.interventionSchema,
schema.reportSchema
],
sync: {
user: user,
url: serverUrl
}
};
console.log("Will open realm with config: " + config);
const realm = Realm.open(config)
.then(realm => {
// use the realm instance here
console.log("Realm is active " + realm);
console.log("Will create Realm");
theRealm = new Realm({
path:'model/realm_db/theRealm.realm',
schema:[
schema.interventionSchema,
schema.reportSchema
]
});
console.log("Did create Realm: " + theRealm);
})
.catch(error => {
// Handle the error here if something went wrong
console.log("Error when opening Realm: " + error);
});
})
.catch(error => {
// an auth error has occurred
console.log("Error when logging in user: " + error);
});
Output:
Will log in user
Server is running...
user is logged in {}
Will create config
Will open realm with config: [object Object]
TypeError: Cannot read property 'token_data' of undefined
at performFetch.then.then (/pathToProject/node_modules/realm/lib/user-methods.js:203:49)
at <anonymous>
at process._tickCallback (internal/process/next_tick.js:188:7)
TypeError: Cannot read property 'token_data' of undefined
at performFetch.then.then (/pathToProject/node_modules/realm/lib/user-methods.js:203:49)
at <anonymous>
at process._tickCallback (internal/process/next_tick.js:188:7)
Error # user-methods.js:203:49
const tokenData = json.access_token.token_data;
json is:
{ user_token:
{ token: 'xxxxxxxx',
token_data:
{ app_id: 'io.realm.Auth',
identity: 'xxxxxxx',
salt: 'xxxxxxxx',
expires: 1522930743,
is_admin: false } } };
So json.access_token.token_data is undefined but json. user_token.token_data would not be.
I would suggest you to try the ROS connection with realm studio in that u can check logs as well which will help you to fix the error. If your still not able to fix then you can contact Realm support team even they helped me to fix the issue of ROS connection in Xamarin Forms using Docker.
I have the following route for the password reset form, the form has a password and password confirmation field.
router.post('/users/reset/:token', (req, res, next) => {
if(req.body.password === req.body['password-confirm']) {
req.flash('error', 'Passwords do not match!');
res.redirect('/users/forgot');
}
User.findOne({
resetPasswordToken: req.params.token,
resetPasswordExpires: { $gt: Date.now() }
}, function(err, user) {
if(!user) {
req.flash('error', ' Password reset is invalid or has expired');
res.redirect(302, '/login');
}
const setPassword = promisify(user.setPassword, user);
setPassword(req.body.password);
user.resetPasswordToken = undefined;
user.resetPasswordExpires = undefined;
const updatedUser = user.save();
user.save((saveError, updatedUser) => {
// Check if saveError is present here and handle appropriately
req.login(updatedUser, loginError => {
req.flash('success_msg', 'Your password has been reset successfully! You are now logged in!');
res.redirect('/dashboard' + req.user);
})
});
});
});
When I fill out the form I get the following error
Fri Jan 26 2018 11:28:55 GMT+0000 (GMT): GET /users/reset/6e2574bfa532e0d13af7fae61114308f9a683767
Mongoose: users.findOne({ resetPasswordExpires: { '$gt': new Date("Fri, 26 Jan 2018 11:28:55 GMT") }, resetPasswordToken: '6e2574bfa532e0d13af7fae61114308f
9a683767' }, { fields: {} })
Fri Jan 26 2018 11:28:55 GMT+0000 (GMT): GET /favicon.ico
Fri Jan 26 2018 11:29:02 GMT+0000 (GMT): POST /users/reset/6e2574bfa532e0d13af7fae61114308f9a683767
Mongoose: users.findOne({ resetPasswordExpires: { '$gt': new Date("Fri, 26 Jan 2018 11:29:02 GMT") }, resetPasswordToken: '6e2574bfa532e0d13af7fae61114308f
9a683767' }, { fields: {} })
Mongoose: users.update({ _id: ObjectId("5a5c6740b9e210087e098fd6") }, { '$unset': { resetPasswordExpires: 1, resetPasswordToken: 1 } })
Mongoose: users.update({ _id: ObjectId("5a5c6740b9e210087e098fd6") }, { '$unset': { resetPasswordExpires: 1, resetPasswordToken: 1 } })
(node:1451) UnhandledPromiseRejectionWarning: TypeError: Cannot read property 'apply' of undefined
at /Users/benbagley/Code/poetry-out-loud/node_modules/es6-promisify/dist/promisify.js:75:41
at new Promise (<anonymous>)
at /Users/benbagley/Code/poetry-out-loud/node_modules/es6-promisify/dist/promisify.js:54:20
at /Users/benbagley/Code/poetry-out-loud/routes/users.js:321:5
at model.Query.<anonymous> (/Users/benbagley/Code/poetry-out-loud/node_modules/mongoose/lib/model.js:4056:16)
at /Users/benbagley/Code/poetry-out-loud/node_modules/kareem/index.js:273:21
at /Users/benbagley/Code/poetry-out-loud/node_modules/kareem/index.js:131:16
at process._tickCallback (internal/process/next_tick.js:150:11)
(node:1451) UnhandledPromiseRejectionWarning: Unhandled promise rejection. This error originated either by throwing inside of an async function without a c
atch block, or by rejecting a promise which was not handled with .catch(). (rejection id: 1)
(node:1451) [DEP0018] DeprecationWarning: Unhandled promise rejections are deprecated. In the future, promise rejections that are not handled will terminat
e the Node.js process with a non-zero exit code.
Fri Jan 26 2018 11:29:02 GMT+0000 (GMT): GET /users/forgot
events.js:136
throw er; // Unhandled 'error' event
^
Error [ERR_HTTP_HEADERS_SENT]: Cannot set headers after they are sent to the client
at validateHeader (_http_outgoing.js:503:11)
at ServerResponse.setHeader (_http_outgoing.js:510:3)
at ServerResponse.header (/Users/benbagley/Code/poetry-out-loud/node_modules/express/lib/response.js:767:10)
at ServerResponse.location (/Users/benbagley/Code/poetry-out-loud/node_modules/express/lib/response.js:884:15)
at ServerResponse.redirect (/Users/benbagley/Code/poetry-out-loud/node_modules/express/lib/response.js:922:18)
at req.login.loginError (/Users/benbagley/Code/poetry-out-loud/routes/users.js:332:13)
at /Users/benbagley/Code/poetry-out-loud/node_modules/passport/lib/http/request.js:51:48
at /Users/benbagley/Code/poetry-out-loud/node_modules/passport/lib/sessionmanager.js:16:14
at pass (/Users/benbagley/Code/poetry-out-loud/node_modules/passport/lib/authenticator.js:297:14)
at Authenticator.serializeUser (/Users/benbagley/Code/poetry-out-loud/node_modules/passport/lib/authenticator.js:299:5)
at SessionManager.logIn (/Users/benbagley/Code/poetry-out-loud/node_modules/passport/lib/sessionmanager.js:14:8)
at IncomingMessage.req.login.req.logIn (/Users/benbagley/Code/poetry-out-loud/node_modules/passport/lib/http/request.js:50:33)
at user.save (/Users/benbagley/Code/poetry-out-loud/routes/users.js:330:11)
at /Users/benbagley/Code/poetry-out-loud/node_modules/mongoose/lib/model.js:4056:16
at /Users/benbagley/Code/poetry-out-loud/node_modules/mongoose/lib/services/model/applyHooks.js:170:20
at process._tickCallback (internal/process/next_tick.js:150:11)
I'm still new to node so any refactoring tips, or fixes for this would be most appreciated, been stuck on this issue for a few days, not sure what I'm doing wrong.
Thank you.
First thing is that this error occur when node sent response of API call more than one time. Secondly, it is best practice to use return when sending response for example return res.json(<OBJECT>);
In your code you are checking the password like
req.body.password === req.body['password-confirm']
it should be like
req.body.password !== req.body['password-confirm']
that may the case that causing node to sent multiple response
You are sending response to client multiple time, that's why facing Cannot set headers after they are sent to the client error.
In your case, your are not returning (exiting) from the function execution when you should have. E.g. when password doesn't match, you are trying to redirect user to /users/forgot, but you are not returning the function there. Hence, code below if condition executes and try to send response back again.
Solution:
router.post('/users/reset/:token', (req, res, next) => {
if // some condition {
// some code
return res.redirect('/users/forgot');
}
User.findOne({
// some code
}, function(err, user) {
if(!user) {
// some code
return res.redirect(302, '/login');
}
// some code
user.save((saveError, updatedUser) => {
req.login(updatedUser, loginError => {
// some code
return res.redirect('/dashboard' + req.user);
})
});
});
});
Duplicate key E11000 is the expected behavior but crashing the server is not. The duplicate key error comes from my unique index on email.
controller method:
exports.saveOAuthUserProfile = function(req, profile, done) {
User.findOne({
provider: profile.provider,
providerId: profile.providerId
}, function(err, user) {
if (err) {
return done(err);
} else {
if (!user) {
var possibleUsername = profile.username || ((profile.email) ? profile.email.split('#')[0] : '');
User.findUniqueUsername(possibleUsername, null, function(availableUsername) {
profile.username = availableUsername;
user = new User(profile);
user.save(function(err) {
if (err) {
var message = getErrorMessage(err);
console.log(message);
//req.flash('error', message);
return res.redirect('/signup');
}
return done(err, user);
});
});
} else {
return done(err, user);
}
}
});
};
getErrorMessage method:
var getErrorMessage = function(err) {
var message = '';
// If an internal MongoDB error occurs get the error message
if (err.code) {
switch (err.code) {
// If a unique index error occurs set the message error
case 11000:
message = 'Duplicate Key';
break;
case 11001:
message = 'Username already exists';
break;
// If a general error occurs set the message error
default:
message = 'Something went wrong';
}
} else {
// Grab the first error message from a list of possible errors
for (var errName in err.errors) {
if (err.errors[errName].message) message = err.errors[errName].message;
}
}
return message;
};
email in UserSchema:
email: {
type: String,
unique: 'That email is already taken',
match: [/.+\#.+\..+/, 'Please use a valid e-mail address']
},
cli output:
λ node server
Server running at http://localhost:3000/
GET / 200 26.879 ms - 1347
GET /lib/angular-route/angular-route.min.js 200 12.790 ms - 4408
GET /lib/angular-resource/angular-resource.min.js 200 13.863 ms - 3598
GET /modules/example/example.client.module.js 200 14.557 ms - 30
GET /modules/example/controllers/example.client.controller.js 200 12.595 ms - 240
GET /modules/example/config/example.client.routes.js 200 12.024 ms - 547
GET /lib/angular/angular.min.js 200 77.183 ms - 145234
GET /modules/users/users.client.module.js 200 24.306 ms - 28
GET /modules/users/services/authentication.client.service.js 200 25.467 ms - 168
GET /application.js 200 23.834 ms - 536
GET /modules/articles/articles.client.module.js 200 27.471 ms - 31
GET /modules/articles/services/articles.client.service.js 200 28.066 ms - 234
GET /modules/example/views/example.client.view.html 200 1.968 ms - 83
GET /lib/angular/angular.min.js.map 304 10.579 ms - -
GET /lib/angular-route/angular-route.min.js.map 304 17.932 ms - -
GET /lib/angular-resource/angular-resource.min.js.map 304 31.510 ms - -
GET /signin 200 5.881 ms - 606
GET /oauth/google 302 2.573 ms - 0
Duplicate Key
C:\Users\lotus\Desktop\mastering_mean\application\node_modules\mongoose\node_modules\mpromise\lib\promise.js:108
if (this.ended && !this.hasRejectListeners()) throw reason;
^
ReferenceError: res is not defined
at EventEmitter.<anonymous> (C:\Users\lotus\Desktop\mastering_mean\application\app\controllers\users.server.controller.js:107:22)
at EventEmitter.<anonymous> (C:\Users\lotus\Desktop\mastering_mean\application\node_modules\mongoose\node_modules\mpromise\lib\promise.js:174:48)
at EventEmitter.emit (events.js:107:17)
at Promise.safeEmit (C:\Users\lotus\Desktop\mastering_mean\application\node_modules\mongoose\node_modules\mpromise\lib\promise.js:81:21)
at Promise.reject (C:\Users\lotus\Desktop\mastering_mean\application\node_modules\mongoose\node_modules\mpromise\lib\promise.js:109:15)
at Promise.error (C:\Users\lotus\Desktop\mastering_mean\application\node_modules\mongoose\lib\promise.js:94:15)
at Promise.resolve (C:\Users\lotus\Desktop\mastering_mean\application\node_modules\mongoose\lib\promise.js:112:24)
at C:\Users\lotus\Desktop\mastering_mean\application\node_modules\mongoose\lib\document.js:1578:39
at handleError (C:\Users\lotus\Desktop\mastering_mean\application\node_modules\mongoose\node_modules\hooks-fixed\hooks.js:40:22)
at next_ (C:\Users\lotus\Desktop\mastering_mean\application\node_modules\mongoose\node_modules\hooks-fixed\hooks.js:75:26)
at EventEmitter.fnWrapper (C:\Users\lotus\Desktop\mastering_mean\application\node_modules\mongoose\node_modules\hooks-fixed\hooks.js:171:15)
at EventEmitter.<anonymous> (C:\Users\lotus\Desktop\mastering_mean\application\node_modules\mongoose\node_modules\mpromise\lib\promise.js:174:48)
at EventEmitter.emit (events.js:107:17)
at Promise.safeEmit (C:\Users\lotus\Desktop\mastering_mean\application\node_modules\mongoose\node_modules\mpromise\lib\promise.js:81:21)
at Promise.reject (C:\Users\lotus\Desktop\mastering_mean\application\node_modules\mongoose\node_modules\mpromise\lib\promise.js:109:15)
at C:\Users\lotus\Desktop\mastering_mean\application\node_modules\mongoose\lib\model.js:263:20
As you can see in the cli output my getErrorMessage function is correctly retrieving the error and I can console.log(message) but at this point node server crashes resulting in the error message that res is not defined.
node version: 0.12.4
MongoDB shell version: 3.0.3
express 4.12.4
mongoose 4.0.5
Win 7 Pro x64
Any more information I can provide?
UPDATE:
Adding the passport strategy that calls the controller method
module.exports = function() {
passport.use(new GoogleStrategy({
clientID: config.google.clientID,
clientSecret: config.google.clientSecret,
callbackURL: config.google.callbackURL,
passReqToCallback: true
},
function(req, accessToken, refreshToken, profile, done) {
var providerData = profile._json;
providerData.accessToken = accessToken;
providerData.refreshToken = refreshToken;
var providerUserProfile = {
firstName: profile.name.givenName,
lastName: profile.name.familyName,
fullName: profile.displayName,
email: profile.emails[0].value,
username: profile.emails[0].value.replace(/#.*$/,""),
provider: 'google',
providerId: profile.id,
providerData: providerData
};
users.saveOAuthUserProfile(req, providerUserProfile, done);
}));
Passport strategy handlers have an option to get passed req (by setting passReqToCallback), but not res. So if you need the response object in the strategy handler, or any functions called from it (like your users.saveOAuthUserProfile), you need to use the fact that Express adds the response object to the request object, which you can access through req.res.
So this:
return res.redirect('/signup');
Needs to be this:
return req.res.redirect('/signup');
There's not many examples out there for hapi and its auth-cookie plugin but here's what I have so far in an attempt to secure a route. Note, most of the examples I've seen are using an older version of hapi which doesn't seem to quite apply to this situation and im hoping im just missing something simple:
var Hapi = require('hapi');
var Mongoose = require('mongoose');
Mongoose.connect('mongodb://localhost/rfmproducetogo');
var server = new Hapi.Server(8080, "localhost");
server.pack.register([{
plugin: require("lout")
}, {
plugin: require('hapi-auth-cookie')
}, {
plugin: require("./plugins/togo")
}, {
plugin: require("./plugins/auth")
}], function(err) {
if (err) throw err;
server.auth.strategy('session', 'cookie', {
password: 'shhasecret',
cookie: 'wtfisthisfor',
isSecure: false,
redirectTo: false
});
server.start(function() {
console.log("hapi server started # " + server.info.uri);
});
});
And in my togo plugin I have this route setup to use the session
exports.create = function(plugin) {
plugin.route({
method: 'POST',
path: '/togo/add',
handler: function(request, reply) {
produce = new Produce();
produce.label = request.payload.label;
produce.price = request.payload.price;
produce.uom = request.payload.uom;
produce.category = request.payload.category;
produce.save(function(err) {
if (!err) {
reply(produce).created('/togo/' + produce._id);
} else {
reply(err);
}
});
},
config: {
auth: 'session'
}
});
};
The error im seeing is this:
/home/adam/Projects/bushhog/node_modules/hapi/node_modules/hoek/lib/index.js:421
throw new Error(msgs.join(' ') || 'Unknown error');
^
Error: Unknown authentication strategy: session in path: /togo/add
at Object.exports.assert (/home/adam/Projects/bushhog/node_modules/hapi/node_modules/hoek/lib/index.js:421:11)
at /home/adam/Projects/bushhog/node_modules/hapi/lib/auth.js:123:14
at Array.forEach (native)
at internals.Auth._setupRoute (/home/adam/Projects/bushhog/node_modules/hapi/lib/auth.js:121:24)
at new module.exports.internals.Route (/home/adam/Projects/bushhog/node_modules/hapi/lib/route.js:118:43)
at /home/adam/Projects/bushhog/node_modules/hapi/lib/router.js:110:25
at Array.forEach (native)
at /home/adam/Projects/bushhog/node_modules/hapi/lib/router.js:107:17
at Array.forEach (native)
at internals.Router.add (/home/adam/Projects/bushhog/node_modules/hapi/lib/router.js:104:13)
Running node 0.10.28, hapijs 6.x, hapi-auth-cookie 1.02
this issue occurs when you try to use an authentication strategy before it's actually available.
You're already following a good application setup by splitting the functionality into individual, small plugins with a given scope.
UPDATE: here's a dedicated tutorial for that problem, how to fix „unknown authentication strategy“
A good way to set up authentication and your plugins that rely on authentication is to create an extra "auth plugin" that adds your desired strategies and can be used as a dependency in your other plugins.
hapi auth plugin example
exports.register = function (server, options, next) {
// declare/register dependencies
server.register(require('hapi-auth-cookie'), err => {
/**
* Register authentication strategies to hapi server
*
* We’re using hapi-auth-cookie plugin to store user information on
* client side to remember user data on every website visit
*
* For sure, we could and will add more authentication strategies.
* What’s next: JWT (we highly welcome pull requests to add JWT functionality!)
*/
server.auth.strategy('session', 'cookie', {
password: 'ThisIsASecretPasswordThisIsASecretPassword',
cookie: 'hapi-rethink-dash',
redirectTo: '/login',
isSecure: false
});
server.log('info', 'Plugin registered: cookie authentication with strategy »session«')
next()
})
}
exports.register.attributes = {
name: 'authentication',
version: '1.0.0'
}
In your /plugins/togo you set the authentication plugin as a dependency (with server.dependency([array-of-deps])) which means hapi registers the auth plugin first and the depending ones afterwards.
You register your plugins like this:
server.register([{
plugin: require('./plugins/authentication')
}, {
plugin: require("./plugins/togo")
}], function(err) {
// handle callback
})
Check hapi-rethinkdb-dash for a detailed example.
Hope that helps!
keep in mind if you use server.dependency inside a plugin like Marcus Poehls did, you also need to register that dependency
server.register([{
plugin: require('hapi-auth-cookie')
},{
plugin: require('./plugins/authentication')
}, {
plugin: require("./plugins/togo")
}], function(err) {
// handle callback
})