How to delete users from account-ui meteor - meteor

I'm making a meteor app and using accounts ui and bootstrap and all that stuff but I'm wondering if there is a way I can be like an admin and delete users because recently people have been making inappropriate usernames and such..

Well you can delete users pretty easy like. having a template protected just to admin accounts and on that template have a list with the users, based on that create an event like this.
Template.example.events({
'click #deleteAccount':function(){
meteor.users.remove({_id:this._id})
}
})
and use an allow method like this.
Meteor.allow({
remove:function(){
//if is admin return true;
}
})
But thats not a good practice, why? check this David Weldon -common-mistakes
if there is a way I can be like an admin?
For accomplish this on a better way use the meteor-roles package,
With this you can can protect templates with
{{if isInRole 'Admin'}}
<!--show admin stuff-->
{{else}}
<!--sorry just admin stuff here -->
{{/else}}
and create basic admin accounts.
if(Meteor.users.find().count() === 0){
var users = [
{name:"Admin Example",email:"supersecretaccount#gmail.com",roles:['Admin']}
];
_.each(users, function (user) {
var id;
id = Accounts.createUser({
email: user.email,
password: "amore251327",
profile: { name: user.name }
});
if (user.roles.length > 0) {
Roles.addUsersToRoles(id, user.roles);
}
});
}
Try it

Related

Meteor: Restricting an admin route only to admin roles

Im trying to restrict a route to only users whose roles are admin
Router.route('/admin', {
if(Roles.userIsInRole(Meteor.user(), ['admin'])) {
template: 'admin' };
else
template: 'restricted'
});
returned with unexpected token
The template Iron Router option is for the simple case when you just need to route to a constant template, that will never change nor need any specific parameter.
If your route is more complex (as in your case when you return a different template based on the current user's role), you have to use the action router option instead.
Note that if you are using Iron Router, the new syntax is Router.route('/path', actionFunction)
Managed to get it working thanks to ghybs's suggestion. Ive updated it to
Router.route('/admin', {
action: function() {
if(Roles.userIsInRole(Meteor.user(), ['admin'])) {
this.render('admin') }
else
this.render('denied')
}
});
If someone can provide a more tight & secure code please do input :D Thanks

How do I login a user with Meteor

I've added accounts-password and useraccounts:unstyled
I've included the signin template in my footer.html -
{{#if showSignIn}}
{{> atForm state="signIn"}}
{{/if}}
I'm hard coding the creation of users as the app starts up -
import { Accounts } from 'meteor/accounts-base'
if (!Acounts.findUserByEmail('aidan#gmail.com')) {
Accounts.createUser({
username: 'Aidan',
email: 'aidan#gmail.com',
password: 'securePassword'
});
}
It's just that I can't work out how to actually log my user in. I've tried simply entering the password and email address into the form. That doesn't work (the form error says 'Login Forbidden').
I've tried adding the following line (to the same file as my account creation code) -
accountsServer.validateLoginAttempt(()=>{return true;});
Unsurprisingly that doesn't do anything.
I've tried add a submit event into my footer.js file -
Template.footer.events({
'submit form'(event) {
console.log('submitted');
const email = document.getElementById('at-field-email').value;
const password = document.getElementById('at-field-password').value;
Meteor.loginWithPassword(email, password);
},
});
I can see that the event is firing, but when I try Meteor.user() in the console I still get null.
There's typo in if (!Acounts.findUserByEmail('aidan#gmail.com')) (it should have been Accounts). The user isn't being created.
To get a super simple functional login with a single hard coded user -
Add the accounts-password package and the ui user accounts package.
> meteor add accounts-password
> meteor add useraccouts:unstyled
The accounts-password package handles the actual logging in. The user accounts:unstyled packages provides a set of templates for accounts management.
Then add the login form to a template.
<template name="templateWithLogin">
{{> atForm state="signIn"}}
</template>
Lastly create a user (e.g. in /server/main.js).
import { Accounts } from 'meteor/accounts-base';
if (!Accounts.findUserByEmail('user#gmail.com')) {
Accounts.createUser({
username: 'User',
email: 'user#gmail.com',
password: 'securePassword'
});
}
This should be everything needed to get a functional login form. There's loads of tutorials online for creating additional functionality. The main documentation is here.
you can use {{>loginButtons}} to get the ui and {{#if currentUser }} for the functionality.

Run code in specific part of URL in Iron Router

I have an application which makes heavy use of features, separated by specific users, which have different roles.
The problem is that I want to restrict access to some templates, if, for instance, the user is not an Admin.
Currently, I have this:
Router.route('createUser', {
path: '/admin/users/',
onBeforeAction: function() {
if(!isAdmin()) {
Router.go('/');
}
this.next();
}
});
But, specifying that if(isAdmin()) call to every other route is a pain. I want to know if there is any other easy and less error prone way to do it.
Maybe some regex magic would do, but I don't seem to find any examples of use.
First i will recommend you to read this meteor:common-mistakes on the profile editing part
So i will recommend you to better use the alanningroles-meteor package.
Is super easy to use, here is a Online DEMO and the Source Code if you have doubts.
On the router level you can create an onBefore hooks like this.
isAdmin = function(){
var currentUser = Meteor.user()
isUserSuperAdmin = Roles.userIsInRole(currentUser,'Super-Admin'); //using alaning roles.
if(isUserSuperAdmin){ //or use isAdmin();
this.next();
}else{
this.render('accessDenied')
}
}
Router.onBeforeAction('accessDenied', {only: ['admin','otherAdminRoute',etc]});
You can have an onBeforeAction hook combined with only for all routes like so:
var isAdmin = function() {
// Whatever logic you have for checking admin
if (!admin) {
Router.go("/");
}
this.next();
}
Router.onBeforeAction(isAdmin, {
only: ["admin/users"] // Specify other admin templates here
});

Publishing all Meteor.users doesn't work

I'm trying to publish all the usernames to the clients, even if not signed in. For that, on the server I have:
Meteor.publish("users", function() {
return Meteor.users.find({}, {fields : { username : 1 } });
});
And on the client:
Meteor.subscribe("users");
However, when I try to access the Meteor.users collection, I find nothing there.
(This is essentially the same as the question here: Listing of all users in the users collection not working first time with meteor js, only without checking the roles for admin first. Still doesn't seem to work..)
I'm probably missing something silly..
I find the same issue, and after doing a research i find this package, i think it may should help you.
Take a look and hope it help you
Update
First move the subscription to the /lib folder, just to make sure its the first thing meteor do when start, also change a little bit the subscription like this on the /lib, folder.
Tracker.autorun(function() {
if(Meteor.isClient) {
if (!Meteor.user()) {
console.log("sorry you need to be logged in to subscribe this collection")
}else{
Meteor.subscribe('users');
}
}
});
For better security we just subscribe to the users collection when the client its logged in
This code outputs all the usernames to the clients, even if not signed in (in this case on /users page):
server/publications.js:
Meteor.publish("userlist", function () {
return Meteor.users.find({},{fields:{username:1}});
});
client/users_list.js:
Template.usersList.helpers({
users: function () {
return Meteor.users.find();
}
});
client/users_list.html:
<template name="usersList">
{{#each users}}
{{username}}
{{/each}}
</template>
lib/router.js (using iron:router package):
Router.route('/users', {
name: 'usersList',
waitOn: function(){
return Meteor.subscribe("userlist");
}
});
Hope it helps.

How to restrict a route to an admin user in Meteor?

as an iOS developer primarily, I'm very new to webdev. I'm looking into Meteor and have some questions regarding routing -- my apologies if they are very easy.
I am using the Meteor Router package to create routes, but I would like to have some pages only accessible to the admin user.
Meteor.Router.add({
'/' : 'home',
'/admin' : 'admin'
});
So I have a simple route setup as above, but I'm not sure how to restrict access to the /admin route.
Is it as simple as something like this? What would be a good way to restrict the route to the /admin page and show a warning or perhaps even redirect them back to the / page?
Thank you!
client.html
<head>
<title>My App</title>
</head>
<body>
{{renderPage}}
</body>
<template name="home">
{{greeting}}
</template>
<template name="admin">
{{greeting}}
</template>
client.js
Template.admin.greeting = function () {
var currentUser = Meteor.user();
if (null !== currentUser && 'admin' === currentUser.username) {
return "Hello Admin!";
}
else{
return "Sorry, only admins can see this page";
}
};
The best way to restrict access to a route is with the router itself (rather than pushing the problem to your controller). You have a couple of choices in how you do this:
Routing Function
You could make the /admin route look like:
'/admin': function() {
return {
as: 'admin',
to: function() {
if (Meteor.user() && Meteor.user().username === 'admin') {
return 'admin';
} else {
return 'unauthorized';
}
}
};
}
I'm assuming you have an unauthorized template that renders a 403 page or something informative.
Filter
Alternatively, you can leave your original /admin route as it was and add a filter:
Meteor.Router.filters({
'needsAdmin': function(page) {
if (Meteor.user() && Meteor.user().username === 'admin') {
return page;
} else {
return 'unauthorized';
}
}
});
and use it like so:
Meteor.Router.filter('needsAdmin', {only: 'admin'});
Personally, I like the filter option because it's reusable and it's a little more obvious what's going on.
Another solution is to use Roles package and make sure the user has the 'admin' role before serving data.
$ mrt add roles
Then you can check for roles like with a nice syntax:
if(!Roles.userIsInRole(Meteor.user(), ['admin'])) {
// Redirect...
}
Roles is integrated with the Meteor accounts system and plays nicely with most of the accounts packages.
If you are looking to manage accounts (create/delete Roles and add/remove Roles from a given user) I've created the package Accounts Admin UI. The README has a quickstart and some some notes on how to integrate this with other routing packages.
$ mrt add accounts-admin-ui-bootstrap-3
Use the and parameter:
Meteor.Router.add({
'/admin': { to: 'admin', and: function() {
if (!Meteor.user() || Meteor.user().name != 'admin'){
Meteor.Router.to('/');
}
}}
});
Everyone here has made great points on how to protect an admin panel on the router level. Another possibility is to skip the router all together. I've recently done this with Meteor Candy, a drop-in admin package for Meteor.
The idea is, you could create a Reactive-Dict to hold the state of the admin interface. If you place it into a package, you can ensure that it never collides with your application code. And with the new Dynamic Imports feature, you can virtually keep it off the client until its needed.
Here's how that might work:
<template name="adminPanel">
{{#if show}}
{{> adminPanelUI}}
{{/if}}
</template>
AdminUI = new ReactiveDict();
Meteor.defer(function () {
Blaze.render(Template.MeteorCandy, document.body);
});
Template.adminPanel.helpers({
show: function () {
if (AdminUI.get('show')) {
return true;
}
}
})
On top of that, all you would need is to define the occasion that sets "show" to a truth-y value.

Resources