我使用Autoform和SimpleSchema创建帐户,并使用自定义emailAvailable
验证方法来防止欺骗。这很好用,我得到了一个很好的Email must be unique
消息。但是,在使用相同的设置(减去密码字段)以允许用户更改其电子邮件地址时,我遇到了问题。
我的第一个问题是即使emailAvailable
方法按预期工作并阻止用户将其电子邮件地址更改为已使用的电子邮件地址,它也会无声地失败并且错误不会出现在表单中。我知道SimpleSchema会捕获验证错误,因为感谢SimpleSchema.debug = true
,我看到一条包含SimpleSchema invalid keys for "account" context
错误的name: email, type: notUnique
消息。
我的第二个问题是,尽管验证明显失败,但仍会调用更新帐户的服务器方法。这会产生Exception while invoking method 'updateAccount' MongoError: E11000 duplicate key error index: meteor.users.$emails.address_1
消息。我理解SimpleSchema的文档解释说这可能发生,因为验证是在客户端而不是服务器上运行的,但我很困惑为什么在验证帐户创建失败时不会发生同样的错误。
谢谢!相关代码如下:
我的帐户创建架构:
// create account
Schema.users= new SimpleSchema({
email: {
type: String,
unique: true,
regEx: SimpleSchema.RegEx.Email,
// check for duplicate email address
custom: function () {
if (Meteor.isClient && this.isSet) {
Meteor.call('emailAvailable', this.value, function (error, result) {
if (!result) {
Schema.users.namedContext('register').addInvalidKeys([{name: 'email', type: 'notUnique'}]);
}
});
}
}
},
password: {
type: String
},
name: {
type: String
}
});
我的帐户更新架构:
// update account
Schema.profile = new SimpleSchema({
email: {
type: String,
unique: true,
regEx: SimpleSchema.RegEx.Email,
// check for duplicate email address
custom: function () {
if (Meteor.isClient && this.isSet) {
Meteor.call('emailAvailable', this.value, function (error, result) {
if (!result) {
Schema.users.namedContext('account').addInvalidKeys([{name: 'email', type: 'notUnique'}]);
}
});
}
}
},
name: {
type: String
}
});
我的支票电子邮件方法:
emailAvailable: function(email) {
var currentId = "";
if (Meteor.user()) {
var currentId = Meteor.user()._id;
}
var findEmail = Meteor.users.find(
{_id:
{
$ne: currentId
}
,emails:
{
$elemMatch:{
address:email
}
}
}
);
var findEmailCount = findEmail.count();
if (findEmailCount == 0) {
return true;
}
return false;
}
我的服务器方法:
Meteor.methods({
registerAccount: function(doc) {
check(doc, Schema.users;
Accounts.createUser({
email: doc.email,
profile: {
name: doc.name
},
password : doc.password
});
},
updateAccount: function(doc) {
check(doc, Schema.profile);
Meteor.users.update(
{_id:Meteor.user()._id},
{$set:
{
"profile.name": doc.name,
"emails": [ {address:doc.email} ]
}
});
},
emailAvailable: function(email) {
var currentId = "";
if (Meteor.user()) {
var currentId = Meteor.user()._id;
}
var findEmail = Meteor.users.find(
{_id:
{
$ne: currentId
}
,emails:
{
$elemMatch:{
address:email
}
}
}
);
var findEmailCount = findEmail.count();
if (findEmailCount == 0) {
return true;
}
return false;
}
});