如何只提供注册邀请?

问题描述 投票:8回答:3

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

我在Meteor文档中找到的唯一相关内容是Meteor.sendEnrollmentEmail,但它并没有解决我的问题。

meteor user-accounts
3个回答
17
投票

您可以使用内置程序包执行此操作,但我发现滚动简单实现更简单,更强大。

你需要:

  • 创建一个集合,例如UserInvitations以包含成为用户的邀请。
  • 使用meteor mongo创建UI以进行UserInvitations /插入一些
  • 使用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 */}) 
  • 在服务器上,创建一个Accounts.onCreateUser挂钩,将invitationId从选项传递给用户

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

     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 }); 

现在,只有具有有效未使用的invitationId用户才能注册。

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


2
投票

要使用内置的东西,您可以将现有的Accounts.sendEnrollmentEmail连接在一起 - 但是它比给出的其他解决方案稍微复杂一些。

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

Meteor.call('enroll', 'john.smith', '[email protected]', {name: 'John Smith'});

然后Meteor会向用户发送一个链接(您可以使用Accounts.emailTemplates配置模板)

当他们点击链接时,meteor调用传递给Accounts.onEnrollmentLink的函数 - 在这种情况下,您可以将它们带到密码设置页面; 但你必须搞乱他们done回调。

修改以下代码,其中INSERT XXX HERE ; 然后在你的代码中调用SomeGlobalEnrollmentObjectThing.cancel()如果用户取消,或SomeGlobalEnrollmentObjectThing.complete(theUsersNewPassword)如果他们提交新密码。

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();
}

2
投票

我已经为此创建了一个特定的解决方案 ,因为所有其他解决方案只允许您显式创建基于密码的帐户。 t3db0t:accounts-invite包允许仅在您允许时使用任何服务创建帐户,例如使用“接受邀请”路由。 现场演示

© www.soinside.com 2019 - 2024. All rights reserved.