Combining koa-passport with koa-router (getting user data) - mongodb

I have created a login which is able to login a user and store the user if they are new in the database.
The user is then redirected to / and then is checked if they are authenticated or not, see below (app.js):
.get('/', function* () {
if (this.isAuthenticated()) {
yield this.render('homeSecure', {}); // <-- need user data here
} else {
yield this.render('homePublic', {});
}
As I commented in the code, I would like to send the user object of which is logged in. I have no idea how to get a hold of the id of the person logged in as the documentation for koa in general is not as complete as that of express.
I am using koa-generic-session-mongo to handle my sessions. Here is my GoogleStrategy (auth.js):
var user = null;
// ...
var GoogleStrategy = require('passport-google').Strategy;
passport.use(new GoogleStrategy({
returnURL: 'http://localhost:' + (process.env.PORT || 3000) + '/auth/google/callback',
realm: 'http://localhost:' + (process.env.PORT || 3000)
},
function (identifier, profile, done) {
var emails = new Array();
for (var i = 0; i < profile.emails.length; i++) {
emails.push(profile.emails[i].value);
}
co(function* () {
yield users.findOne({
emails: emails
});
});
if (user === null) { // first time signin, create account
co(function* () {
user = {
id: 1,
name: profile.displayName,
emails: emails
};
yield users.insert(user);
});
}
console.log(user);
done(null, user);
}));

publicRouter
.get('/', function* () {
if (this.isAuthenticated()) {
yield this.render('homeSecure', {
user: this.req.user
});
} else {
yield this.render('homePublic', {});
}
})...

Disclaimer: I've not used koa-passport, I've just looked at the code.
According to the source code of the koa-passport library, the property you're looking for is passport.user, and is used like so:
app.use( function*(){
var user = this.passport.user
})
Thus, your code sample would become
.get('/', function* () {
if (this.isAuthenticated()) {
yield this.render('homeSecure', this.passport.user );
} else {
yield this.render('homePublic', {});
}
If that does not work, this file leads me to suspect that koa-passport follows the standard passport interface and provides this.user to the request.

Related

Issue Connecting to MongoDB collections

I am using axios and express.js API to connect to my mongo DB. I have a .get() request that works for one collection and doesn't work for any other collection. This currently will connect to the database and can access one of the collections called users. I have another collection setup under the same database called tasks, I have both users and tasks setup the same way and being used the same way in the code. The users can connect to the DB (get, post) and the tasks fails to connect to the collection when calling the get or the post functions. When viewing the .get() API request in the browser it just hangs and never returns anything or finishes the request.
any help would be greatly appreciated!
The project is on GitHub under SCRUM-150.
API connection
MONGO_URI=mongodb://localhost:27017/mydb
Working
methods: {
//load all users from DB, we call this often to make sure the data is up to date
load() {
http
.get("users")
.then(response => {
this.users = response.data.users;
})
.catch(e => {
this.errors.push(e);
});
},
//opens delete dialog
setupDelete(user) {
this.userToDelete = user;
this.deleteDialog = true;
},
//opens edit dialog
setupEdit(user) {
Object.keys(user).forEach(key => {
this.userToEdit[key] = user[key];
});
this.editName = user.name;
this.editDialog = true;
},
//build the alert info for us
//Will emit an alert, followed by a boolean for success, the type of call made, and the name of the
//resource we are working on
alert(success, callName, resource) {
console.log('Page Alerting')
this.$emit('alert', success, callName, resource)
this.load()
}
},
//get those users
mounted() {
this.load();
}
};
Broken
methods: {
//load all tasks from DB, we call this often to make sure the data is up to date
load() {
http
.get("tasks")
.then(response => {
this.tasks = response.data.tasks
})
.catch(e => {
this.errors.push(e);
});
},
//opens delete dialog
setupDelete(tasks) {
this.taskToDelete = tasks;
this.deleteDialog = true;
},
//opens edit dialog
setupEdit(tasks) {
Object.keys(tasks).forEach(key => {
this.taskToEdit[key] = tasks[key];
});
this.editName = tasks.name;
this.editDialog = true;
},
//build the alert info for us
//Will emit an alert, followed by a boolean for success, the type of call made, and the name of the
//resource we are working on
alert(success, callName, resource) {
console.log('Page Alerting')
this.$emit('alert', success, callName, resource)
this.load()
}
},
//get those tasks
mounted() {
this.load();
}
};
Are you setting any access controls in the code?
Also refer to mongoDB's documentation here:
https://docs.mongodb.com/manual/core/collection-level-access-control/
Here is my solution:
In your app.js, have this:
let mongoose = require('mongoose');
mongoose.connect('Your/Database/Url', {
keepAlive : true,
reconnectTries: 2,
useMongoClient: true
});
In your route have this:
let mongoose = require('mongoose');
let db = mongoose.connection;
fetchAndSendDatabase('yourCollectionName', db);
function fetchAndSendDatabase(dbName, db) {
db.collection(dbName).find({}).toArray(function(err, result) {
if( err ) {
console.log("couldn't get database items. " + err);
}
else {
console.log('Database received successfully');
}
});
}

How to come out of method execution based on a condition in protractor?

I'm a Java developer and new to protractor. I'm trying to iterate through a dynamic web table in a web page and trying to find out a particular user name and open his profile. Once I open his profile, I want my test method to stop execution and return. But the return statement doesn't work and the for loop still runs. Could anyone please help me with this? Below is my method.
searchUser() {
// Iterate through the user listing table
browser.driver.findElement(by.css('.slds-max-medium-table--stacked-horizontal')).then(function (table) {
table.findElement(by.tagName('tbody')).then(function (tbody) {
tbody.findElements(by.tagName('tr')).then(function (rows) {
for (var i = 0; i < rows.length; i++) {
rows[i].findElements(by.tagName('td')).then(function (cols) {
cols[1].getText().then(function (user) {
if (user == "ADAM SMITH") {
// found user, open his profile
cols[1].click();
return;
}
});
});
}
// user not found in the current page. Click on next page and continue search
element(by.xpath("//*[#id='main']/div/app-users-profile/users-listing/form/div[2]/div/div/div/div[2]/div/button")).click();
browser.sleep(3000);
var currentPage = new LoginPage();
currentPage.searchUser();
});
});
});
}
I try to make as less differences as I can.
async function searchUser () {
let result = false;
while (!result) {
const table = browser.$('.slds-max-medium-table--stacked-horizontal');
const tbody = table.$('tbody');
const rows = tbody.$$('tr');
await rows.map(async (row) => {
const column = row.findElements(by.tagName('td')).get(1);
const name = await column.getText();
if (name === 'ADAM SMITH') {
await column.click();
result = true;
}
});
if (!result) {
await element(by.xpath("//*[#id='main']/div/app-users-profile/users-listing/form/div[2]/div/div/div/div[2]/div/button")).click();
await browser.sleep(3000);
const currentPage = new LoginPage();
await currentPage.searchUser();
}
}
}

Auth0 - get provider user id

at the moment I am relying on a junky method to get the provider user id (the string/number used in in user page urls of the social) based on splitting the profile "sub" field given from the /profile endpoint.
I saw that the old API had a field named "identities" where seems to be stored the provider user id, is there an equivalent for the new API?
Basically it should return:
facebook: the user number or url nickname http://www.facebook.com/mattiamanzati or http://www.facebook.com/100011120071734 if a nickname was'nt set
twitter: the twitter handle http://www.twitter.com/mattiamanzati
instagram: the instagram handle http://www.instagram.com/cenaacorte
This is the code I've been using now, and you can see how junky is the provider and provider_uid setting is.
var webAuth = new auth0.WebAuth({
domain: "himy.eu.auth0.com",
clientID: "0gz79WpxVxXNH5qeYRXXTxTQiWZZEV9S",
redirectUri: window.location.href,
audience: "https://himy.eu.auth0.com/userinfo",
responseType: "token id_token",
scope: "openid profile"
});
function handleAuthentication() {
webAuth.parseHash(function(err, authResult) {
if (authResult && authResult.accessToken && authResult.idToken) {
window.location.hash = "";
webAuth.client.userInfo(authResult.accessToken, function(err, profile) {
if (profile) {
if (window.postMessage) {
if (profile.sub.indexOf("facebook") === 0) {
profile.provider_uid = profile.sub.split("|")[1];
profile.provider = "facebook";
} else if (profile.sub.indexOf("instagram") === 0) {
profile.provider_uid = profile.nickname;
profile.provider = "instagram";
}
window.postMessage(JSON.stringify(profile));
}
console.log(profile);
}
});
} else if (err) {
console.log(err);
}
});
}
window.addEventListener("load", function(e) {
if (!window.location.hash) {
webAuth.authorize();
} else {
handleAuthentication();
}
});

Waterlocks authentication from server side form

I am having a problem with waterlock-local-auth. Basically I've been playing around with waterlock all day trying to figure out how to create a new user (with hashed password and all), and also how to authenticate the user from a form on a server side sails.js view. But have been completely unsuccessful. Below is the code in my LoginController that my login form is posting to. Any help will be greatly appreciated. Thanks!
module.exports = {
login: function(req, res) {
var isAuthenticated = function(){...} <-- Authenticated by waterlocks
if(isAuthenticated) {
res.view('home');
}
else {
res.view('login', {errorMessage: "Invalid username or password"});
}
}
};
Ok, so basically I went with the solution posted here (Sails.js Waterlock /auth/register causes error 500). ;0)
module.exports = require('waterlock').waterlocked({
// Endpoint for registering new users. Taken from: https://stackoverflow.com/questions/29944905/sails-js-waterlock-auth-register-causes-error-500/29949255#29949255
register: function (req, res) {
var params = req.params.all(),
def = waterlock.Auth.definition,
criteria = {},
scopeKey = def.email !== undefined ? 'email' : 'username'; // Determines if the credentials are using username or emailaddess.
var attr = { password: params.password }
attr[scopeKey] = params[scopeKey];
criteria[scopeKey] = attr[scopeKey];
waterlock.engine.findAuth(criteria, function (err, user) {
if (user)
return res.badRequest("User already exists");
else
waterlock.engine.findOrCreateAuth(criteria, attr, function (err, user) {
if (err)
return res.badRequest(err);
delete user.password;
return res.ok(user);
});
});
}
});

Add new data from restful api to angularjs scope

I'm trying to create a list with endless scroll in angularjs. For this I need to fetch new data from an api and then append it to the existing results of a scope in angularjs. I have tried several methods, but none of them worked so far.
Currently this is my controller:
userControllers.controller('userListCtrl', ['$scope', 'User',
function($scope, User) {
$scope.users = User.query();
$scope.$watch('users');
$scope.orderProp = 'name';
window.addEventListener('scroll', function(event) {
if (document.body.offsetHeight < window.scrollY +
document.documentElement.clientHeight + 300) {
var promise = user.query();
$scope.users = $scope.users.concat(promise);
}
}, false);
}
]);
And this is my service:
userServices.factory('User', ['$resource',
function($resource) {
return $resource('api/users', {}, {
query: {
method: 'GET',
isArray: true
}
});
}
]);
How do I append new results to the scope instead of replacing the old ones?
I think you may need to use $scope.apply()
When the promise returns, because it isnt
Part of the angular execution loop.
Try something like:
User.query().then(function(){
$scope.apply(function(result){
// concat new users
});
});
The following code did the trick:
$scope.fetch = function() {
// Use User.query().$promise.then(...) to parse the results
User.query().$promise.then(function(result) {
for(var i in result) {
// There is more data in the result than just the users, so check types.
if(result[i] instanceof User) {
// Never concat and set the results, just append them.
$scope.users.push(result[i]);
}
}
});
};
window.addEventListener('scroll', function(event) {
if (document.body.offsetHeight < window.scrollY +
document.documentElement.clientHeight + 300) {
$scope.fetch();
}
}, false);