Multiple login providers for the same user? - meteor

I have just glanced over the MongoDB collection for users and it seems to allow multiple login providers for a single user. From what I see, everything seems to be "there": Multiple services, different resume tokens ...
But is there currently a documented way to "associate" a new login provider with an existing user? I couldn't find anything in the official Docs :(
Or is there anything preventing this in the collection "schema"? Just in case, here is how it looks for a single user using the "password" login service.
{
"createdAt" : 123456,
"services" : {
"password" : {
"srp" : {
"identity" : "XXX",
"salt" : "XXX",
"verifier" : "XXX"
}
},
"resume" : {
"loginTokens" : [
{
"token" : "XXX",
"when" : 123456
}
]
}
},
"emails" : [
{
"address" : "foo#example.org",
"verified" : false
}
],
"_id" : "7f98645e-df24-4015-8075-2463c6c8cfc5"
}

With the current version of meteor (0.8.0.3) it is not possible to make use of multiple login providers out of the box. But there is package on athmosphere which allows this.

I haven't tested this, but from what I know you can login the user with password, and then call Meteor.loginWithFacebook, for example, while the user is logged in. This should add the Facebook information to the current user's data.

Related

Meteor application reset password

I'm using meteor-accounts and accounts-password in an application and would like users to be able to reset their passwords. At present there's no need for any customisation of any of the forms and so I've used a common layout with {{> atForm }} and a configuration file of /lib/config.js containing the following:
AccountsTemplates.configure({
showForgotPasswordLink: true,
enablePasswordChange: true,
sendVerificationEmail: true,
enforceEmailVerification: true,
confirmPassword: true,
showResendVerificationEmailLink: true,
continuousValidation: true,
privacyUrl: 'privacy',
});
Clicking on a 'reset password' link produces URLs like the following:
http://localhost:3000/#/reset-password/hMny_A8tdOpNubxtk8mC3BE0vYSJm35K80B2hwwV1CR
However, these are completely useless in that they redirect to the root URL for the application whilst apparently changing the password; users therefore can't log in after clicking on one of these links. A user account looks like this after clicking one:
{ "_id" : "LcQSCiG7ib5F49tPN", "createdAt" : ISODate("2017-03-04T21:33:57.050Z"), "services" : { "password" : { "bcrypt" : "<redacted>", "reset" : { "token" : "l4HdPzoKkeIUdUeUC5x9NmUiQMnRsY1MRLvYk6Wvqw1", "email" : "<redacted>", "when" : ISODate("2017-03-04T21:51:32.171Z"), "reason" : "reset" } }, "email" : { "verificationTokens" : [ { "token" : "K88HXjzI2UO8vARZv6l6Qf0mUJ1hstInnrJK-8hayzk", "address" : "<redacted>", "when" : ISODate("2017-03-04T21:33:57.072Z") }, { "token" : "NMGLelAWKcCFglRj7aQvZoP85N-_YdWJZ2FcPWu5U8D", "address" : "<redacted>", "when" : ISODate("2017-03-04T21:52:55.930Z") } ] }, "resume" : { "loginTokens" : [ ] } }, "emails" : [ { "address" : "<redacted>", "verified" : false } ] }
Everything else works (e.g. signing up with confirmation emails). I'm using Blaze templates and Flow Router including useraccounts:flow-routing.
I seem to be missing something here and would appreciate it if someone would be able to point me in the correct direction to get this working.
Based on your explanation, I think you are missing some keys things to get this working.
First, remember that useraccounts:flow-routing does not provide routes out of the box.
There are no routes provided by default, but you can easily configure routes for sign in, sign up, forgot password, reset password, change password, enroll account using AccountsTemplates.configureRoute
Given that info, you need to at least configure the default route for reset password.
The simplest way is to make the call passing in only a route code (available route codes are: signIn, signUp, changePwd, forgotPwd, resetPwd, enrollAccount).
Here is an example.
AccountsTemplates.configureRoute('resetPwd');
The default will route the user to the fullPageAtForm so they can re-enter a new password.
Take a look at the useraccounts:flow-routing readme for more details.

How to make consistent delete in Firebase database when the data lies in multiple paths in a fan out way? [duplicate]

This question already has an answer here:
Firebase -- Bulk delete child nodes
(1 answer)
Closed 6 years ago.
With Firebase fan out data to different nodes and paths is recommended by Firebase like below example from Firebase sample:
{
"post-comments" : {
"PostId1" : {
"CommentID1" : {
"author" : "User1",
"text" : "Comment1!",
"uid" : "UserId1"
}
}
},
"posts" : {
"PostId1" : {
"author" : "user1",
"body" : "Firebase Mobile platform",
"starCount" : 1,
"stars" : {
"UserId1" : true
},
"title" : "About firebase",
"uid" : "UserId1"
}
},
"user-posts" : {
"UserId1" : {
"PostId1" : {
"author" : "user1",
"body" : "Firebase Mobile platform",
"starCount" : 1,
"stars" : {
"UserId1" : true
},
"title" : "About firebase",
"uid" : "UserId1"
}
}
},
"users" : {
"UserId1" : {
"email" : "user1#gmail.com",
"username" : "user1"
}
}
}
With multipath updates we can atomically update all the paths for a post, however if we want to delete a blog post in above kind of schema then how can we do it atomically? There is no multi path delete, I guess. If client losses network connection while deleting then only few paths would be deleted!
Also in case there is a requirement like when a user is deleted for all the post he has starred, we should remove the stars and unstar the post for that user. This becomes difficult as there is no direct tracking of what posts user has starred. For this do we need to fan out the starring of posts as well like have a node user-stars. Then while deleting we know what all activity the user has done and act on it while deleting user. Is there a better way of handling this?
"user-stars":{
"UserId1":{
"PostID1":true
}
}
In both cases the question on atomically or consistently deleting the data from multipaths (either all or nothing) is seemingly not available.
In that case the only option available looks to be putting the delete command in Firebase queue which will resolve the task in queue only if everything is deleted. That will be eventually consistent option but should be fine. But that is expensive option requiring server. Is there a better way?
You can implement a multi-path delete, by writing a value of null to the paths.
So:
var updates = {
"user-posts/UserId1/PostId1": null,
"post-comments/PostId1": null,
"posts/PostId1": null
}
ref.update(updates);
I had already answered this before: Firebase -- Bulk delete child nodes
It's also quite explicitly mentioned in the documentation on deleting data:
You can also delete by specifying null as the value for another write operation such as set() or update(). You can use this technique with update() to delete multiple children in a single API call.

Activate a meteor user without sending an activation email

I have an application that i have built and i want to create login credentials for users. Since the app is only available on a local network(intra-net) i want the users to skip having to activate their accounts via email.
I created an account with this code
Accounts.createUser({email: "hidden#gmail.com",password:"123456"});
and this is the account in the
db.users.find().pretty()
this is the result
{
"_id" : "up6WA7JmPzEQtXznt",
"createdAt" : ISODate("2016-04-22T20:46:14.299Z"),
"services" : {
"password" : {
"bcrypt" : "$2a$10$INrFYYAfQ4nUqQjM8TCmKez2Ni0NPU9s51AOolX4I0sXHZFi5WxkK"
},
"resume" : {
"loginTokens" : [
{
"when" : ISODate("2016-04-22T20:46:14.385Z"),
"hashedToken" : "w9W2/XZNS8r3zGdo8tIFqf2zPFiRuuMhpQIAIlle8Jk="
}
]
}
},
"emails" : [
{
"address" : "hidden#gmail.com",
"verified" : false
}
]
}
How can i verify my email without sending an activation email?.
I found this function http://docs.meteor.com/#/full/accounts_verifyemail
to verify the account. How can i obtain the token to start with?.
You don't need to verify your users at all. Meteor.loginWithPassword would work with unverified email addresses just as fine.
Verification flag is more like a hint for you. You could for example disable parts of your app until you're certain that the address really belongs to the user. But in your case it's unnecessary.

Meteor Accounts - Users Logged Out on Refresh

I am using the 'accounts-base' and 'accounts-password' packages and the Accounts.createUser method to create users from a login form (i.e. I am not using the accounts-ui package).
the documentation explains that the user thus created includes a 'services' object
"containing data used by particular login services. For example, its
reset field contains tokens used by forgot password links, and its
resume field contains tokens used to keep you logged in between
sessions."
This is true and accounts created using my login form all have loginTokens. However, when I refresh the browser, these tokens are deleted and the user is logged-out.
The documentation appears to suggest that resume tokens are handled automatically by the accounts-base / accounts-password packages. What have I missed?
Accounts.createUser({
username: username,
email: username,
password: password
}, function (err) {
if (err) {
alert(err)
} else {
Router.go('/member/' + Meteor.userId() +'/edit')
}
});
creates:
"resume" :
{ "loginTokens" :
[
{
"when" : ISODate("2014-04-17T22:13:50.832Z"),
"hashedToken" : "KstqsW9aHqlw6pjfyQcO6jbGCiCiW3LGAXJaVS9fQ+o="
}
]
}
...but on refresh:
"resume" : { "loginTokens" : [ ] } },
After an exhaustive audit of my code I found that I was (idiotically) invoking the Accounts.logout method outside the confines of the log-out button event. It had somehow become 'orphaned' during an earlier re-factoring of the code
So all my fault.

How to add new rules in drupal

I'm trying to add some rules programmatically, I'm following this tutorial to manage different price list depending of the rules. To create the rules it usesa default_rules_configuration hook which will be executed "when the rules will be loaded".
1 - It's not really clear, when "rules are being loaded", apparently running the cron do it. Is it the only way to trigger it ?
2 - Is there a way to add rules programmatically, so rule can be added in the insert role hook, or is this default_rules hook the only way to do it ?
Thanks
1 - According to hook_default_rules_configuration() documentation:
This hook is invoked when rules configurations are loaded.
The function is actually called when you clear your cache as this is when Drupal rebuilds the default entities provided in code through entity_defaults_rebuild().
You can examine the full call stack as to how hook_default_rules_configuration function is called using debug_backtrace()
2 - To set a rule that reacts on inserting a role, you actually have to create a rule that reacts on a user insert action and then check the role saved to see if it matches the role that you're interested in reacting to.
I find it easier to do this via the UI. Here's an export of a rule that checks to see if the user is assigned the anonymous role and sends an email to admin if so:
{ "rules_role_change_rule" : {
"LABEL" : "Role change rule",
"PLUGIN" : "reaction rule",
"REQUIRES" : [ "rules" ],
"ON" : [ "user_insert" ],
"IF" : [
{ "user_has_role" : { "account" : [ "account" ], "roles" : { "value" : { "1" : "1" } } } }
],
"DO" : [
{ "mail" : {
"to" : "admin#website.com",
"subject" : "User role changed",
"message" : "User role has changed",
"from" : "drupal#website.com",
"language" : [ "" ]
}
}
]
}
}
You would still have to implement hook_default_rules_configuration but replace the rule in the tutorial with one that suits your needs.

Resources