Meteor 如何仅制作注册邀请?

Meteor 如何仅制作注册邀请?,meteor,user-accounts,Meteor,User Accounts,使用Meteor帐户(和帐户ui)是否有一种简单的方法可以仅邀请新用户注册?例如,通过提供邀请链接或邀请代码 我能在Meteor文档中找到的唯一相关的东西是,它并不能解决我的问题。您可以使用内置包来完成这项工作,但我发现推出一个简单的实现要简单得多,功能强大得多 您需要: 创建一个集合,例如userinvestments,以包含成为用户的邀请 创建用于制作用户邀请的UI/使用meteor mongo插入一些邀请 使用iron router或类似工具创建路由,例如: Router.map -&g

使用Meteor帐户(和
帐户ui
)是否有一种简单的方法可以仅邀请新用户注册?例如,通过提供邀请链接或邀请代码


我能在Meteor文档中找到的唯一相关的东西是,它并不能解决我的问题。

您可以使用内置包来完成这项工作,但我发现推出一个简单的实现要简单得多,功能强大得多

您需要:

  • 创建一个集合,例如
    userinvestments
    ,以包含成为用户的邀请
  • 创建用于制作用户邀请的UI/使用meteor mongo插入一些邀请
  • 使用
    iron router
    或类似工具创建路由,例如:

    Router.map ->
      @route 'register',
        path: '/register/:invitationId'
        template: 'userRegistration'
        data: ->
          return {
            invitationId: @params.invitationId
          }
        onBeforeAction: ->
          if Meteor.userId()?
            Router.go('home')
          return
    
  • 提交
    userRegistration
    中的表单时-调用

    Accounts.createUser({invitationId: Template.instance().data.invitationId /*,.. other fields */})
    
  • 在服务器上,创建一个
    帐户。onCreateUser
    钩子将
    邀请ID
    从选项传递给用户

    Accounts.onCreateUser(function(options, user){
      user.invitationId = options.invitationId
      return user;
    });
    
  • 此外,在服务器上创建一个
    Accounts.validateNewUser
    钩子,以检查
    邀请ID
    ,并将邀请标记为已使用

    Accounts.validateNewUser(function(user){
      check(user.invitationId, String);
      // validate invitation
      invitation = UserInvitations.findOne({_id: user.invitationId, used: false});
      if (!invitation){
        throw new Meteor.Error(403, "Please provide a valid invitation");
      }
      // prevent the token being re-used.
      UserInvitations.update({_id: user.invitationId, used: false}, {$set: {used: true}});
    
      return true
    });
    
现在,只有拥有有效未使用的
邀请ID
的用户才能注册


编辑:2014年10月-更新为使用meteor 0.9.x API

来处理内置内容,您可以将现有的
帐户垂直排列在一起。sendEnrollmentEmail
-但是它比给出的其他解决方案稍微复杂一点

使用下面的示例代码,按如下方式调用
enroll
方法:

Meteor.call('enroll', 'john.smith', 'js@harvard.edu', {name: 'John Smith'});
Meteor随后将通过电子邮件向用户发送链接(您可以使用
帐户配置模板。emailTemplates

当他们点击链接时,meteor调用传递给账户的函数。OneRollmentLink——在这种情况下,您可以将他们带到密码设置页面;但是你必须处理他们的
done
回调

修改以下代码,其中显示
在此处插入XXX
;然后在代码中,如果用户取消,则调用
SomeGlobalRollmentObjectThing.cancel()
;如果用户提交新密码,则调用
SomeGlobalRollmentObjectThing.complete(用户密码)

if (Meteor.isServer){
  Meteor.methods({
    "enroll": function(username, email, profile){
      var userId;
      check(username, String);
      check(email, String); // Or email validator
      check(profile, {
        name: String
      }); // your own schema

      // check that the current user is privileged (using roles package)
      if (!Roles.isInRole(this.userId, 'admin')){
        throw new Meteor.Error(403);
      }

      userId = Accounts.createUser({
        username: username,
        email: email,
        profile: profile
      });

      Accounts.sendEnrollmentEmail(userId);

    }
  });
} else {
  // uses `underscore`, `reactive-var` and `tracker` packages

  function Enrollment(){
    this.computation = null;
    this.token = new ReactiveVar(null);
    this.password = new ReactiveVar(null);
    this.cancelled = new ReactiveVar(false);
    this.done = null;
    this._bind();
  }

  _.extend(Enrollment.prototype, {

    _bind: function(){
      Accounts.onEnrollmentLink(_.bind(this.action, this));
    },

    reset: function(){
      this.token.set(null);
      this.password.set(null);
      this.cancelled.set(false);
      this.done = null;
      if (this.computation !== null){
        this.computation.stop();
        this.computation = null;
      }
    },

    cancel: function(){
      this.cancelled.set(true);
    },

    complete: function(password){
      this.password.set(password);
    },

    action: function(token, done){
      this.reset();
      this.token.set(token);
      this.done = done;
      this.computation = Tracker.autorun(_.bind(this._computation, this));
      // --- INSERT REDIRECT LOGIC HERE [TAKE TO PASSWORD SETUP PAGE]--- //
    },

    _computation: function(){
      var password;
      if (this.cancelled.get()){
        this.reset();
        this.done();
        // --- INSERT REDIRECT LOGIC HERE [USER CANCELLED]--- //
      } else {
        password = this.password.get();
        if (password !== null){
          Accounts.resetPassword(this.token.get(), password, _.bind(this._complete, this));
        }
      }
    },

    _complete: function(err){
      // TODO - check if we were reset before callback completed
      this.reset();
      this.done();
      if (err){
        // --- INSERT REDIRECT LOGIC HERE [RESET FAILED] --- //
      } else {
        // --- INSERT REDIRECT LOGIC HERE [SUCCESS] --- //
      }
    }
  });

  SomeGlobalEnrollmentObjectThing = new Enrollment();
}

我创建了一个,因为所有其他解决方案只允许您显式创建基于密码的帐户。
t3db0t:accounts invite
包仅在您允许的情况下才允许使用任何服务创建帐户,例如使用“接受邀请”路由

感谢您概述了这方面的实现。我本来希望有一个内置的选项,但会求助于实现它自己。