Подключить службу к существующему счету метеоров

Я создаю приложение meteor, которое включает в себя регистрацию с именем пользователя и паролем, а затем, надеюсь, подключение этой учетной записи к facebook и твиттеру.

У меня есть первая часть, работающая легко, просто с пакетом учетных записей. Но когда у меня есть зарегистрированный пользовательский вызов Meteor.loginWithFacebook(), он регистрирует их и создает новую учетную запись. То, что я хочу, - это то, что добавляет учетные данные в facebook для текущего пользователя.

Метеоритные документы имеют следующее:

{
  _id: "bbca5d6a-2156-41c4-89da-0329e8c99a4f",  // Meteor.userId()
  username: "cool_kid_13", // unique name
  emails: [
    // each email address can only belong to one user.
    { address: "[email protected]", verified: true },
    { address: "[email protected]", verified: false }
  ],
  createdAt: Wed Aug 21 2013 15:16:52 GMT-0700 (PDT),
  profile: {
    // The profile is writable by the user by default.
    name: "Joe Schmoe"
  },
  services: {
    facebook: {
      id: "709050", // facebook id
      accessToken: "AAACCgdX7G2...AbV9AZDZD"
    },
    resume: {
      loginTokens: [
        { token: "97e8c205-c7e4-47c9-9bea-8e2ccc0694cd",
          when: 1349761684048 }
      ]
    }
  }
}

который, как представляется, является учетной записью с именем пользователя, которое также аутентифицируется с помощью Facebook. Но я не уверен, что это просто пример, которого вы не можете достичь с помощью основного материала Meteor.

То, что я пытаюсь сделать, в основном

Meteor.connectWithExternalAccount();

который выполняет тот же процесс, что и Meteor.loginWithExternalAccount(), но просто добавляет информацию к зарегистрированному в данный момент пользователю.

Если кто-то может просто немного объяснить базовый пакет учетных записей, чтобы я мог знать, с чего начать для себя, это было бы здорово.

Кроме того, кто-нибудь знает, будет ли это включено в любые будущие версии Meteor?

Ответ 1

Итак, была работа по решению этой проблемы, но, к сожалению, запрос на перенос https://github.com/meteor/meteor/pull/1133 никогда не сливался. Вероятно, ваш лучший выбор - проверить группы Meteor-core Google и посмотреть, есть ли какие-либо комментарии к нему, а если нет, посмотрите, можете ли вы заставить основного разработчика прокомментировать это.

Если вы хотите использовать запрос pull, то вы можете удалить различные пакеты Meteor accounts-*, а затем в корневом каталоге вашего проекта создать папку /packages и скопировать пакеты yubozhao patched accounts-* в там (возможно, smart to append -custom). Затем вы добавили meteor add accounts-base-custom и т.д., Чтобы добавить их в свой проект.

Обратите внимание, что yubozhao написал это 6-7 месяцев назад, и вам, возможно, придется придерживаться любой версии Meteor, которая была текущей, а затем для ее работы.

Обновление апреля 2014 года: Там пакет Atmosphere теперь имеет аналогичный вариант использования, который может быть полезен: https://atmospherejs.com/package/accounts-merge

Ответ 2

Вот код, который работал у меня (внутри папки сервера):

Accounts.onCreateUser(function(options, user) {
    var email, oldUser, service;
    /*
    user.groups = {
        created: "",
        invited:"",
        RSVP:{
            coming:"",
            notComing:"",
            noReplay:""
        }
    };
    */
    if (user.profile == null) {
        user.profile = options.profile
    }
    if (user.services != null) {
        service = _.keys(user.services)[0];
        email = user.services[service].email;
        if (email != null) {
            oldUser = Meteor.users.findOne({
                "emails.address": email
            });
            if (oldUser != null) {
                if (oldUser.services == null) {
                    oldUser.services = {};
                }
                if (service === "google" || service === "facebook") {
                    oldUser.services[service] = user.services[service];
                    Meteor.users.remove(oldUser._id);
                    user = oldUser;
                }
            } else {
                if (service === "google" || service === "facebook") {
                    if (user.services[service].email != null) {
                        user.emails = [
                            {
                                address: user.services[service].email,
                                verified: true
                            }
                        ];
                    } else {
                        throw new Meteor.Error(500, "" + service + " account has no email attached");
                    }
                    user.profile.name = user.services[service].name;
                }
            }
        }
    }
    return user;
});

userAddOauthCredentials: function(token, userId, service) {
        var data, oldUser, selector, updateSelector;
        switch (service) {
            case "facebook":
                data = Facebook.retrieveCredential(token).serviceData;
                break;
            case "google":
                data = Google.retrieveCredential(token).serviceData;
        }
        selector = "services." + service + ".id";
        oldUser = Meteor.users.findOne({
            selector: data.id
        });
        if (oldUser != null) {
            throw new Meteor.Error(500, ("This " + service + " account has already") + "been assigned to another user.");
        }
        updateSelector = "services." + service;
        Meteor.users.update(userId, {
            $set: {
                updateSelector: data
            }
        });
        if (!_.contains(Meteor.user().emails, data.email)) {
            return Meteor.users.update(userId, {
                $push: {
                    "emails": {
                        address: data.email,
                        verified: true
                    }
                }
            });
        }
    }

внутри папки js клиента:

var addUserService;

addUserService = function(service) {
    if (service === "email") {
} else {
    switch (service) {
        case "facebook":
            return Facebook.requestCredential({
                requestPermissions: ["email", "user_friends", "manage_notifications"]
            }, function(token) {
                return Meteor.call("userAddOauthCredentials", token, Meteor.userId(), service, function(err, resp) {
                    if (err != null) {
                        return Meteor.userError.throwError(err.reason);
                    }
                });
            });
        case "google":
            return Google.requestCredential({
                requestPermissions: ["email", "https://www.googleapis.com/auth/calendar"],
                requestOfflineToken: true
            }, function(token) {
                return Meteor.call("userAddOauthCredentials", token, Meteor.userId(), service, function(err, resp) {
                    if (err != null) {
                        return Meteor.userError.throwError(err.reason);
                    }
                });
            });
    }
}

};

тот же самый файл js внутри событий шаблона:

"click a": function(e) {
       var service;
        e.preventDefault();
        service = $(event.target).data("service");
        return addUserService(service);
    }

и только для html:

<div class="social"><a id="fb" data-service="facebook"><img src="/../facebook.png"></a></div>
    <div class="social"><a id="go" data-service="google"><img src="/../googleplus.png"></a></div>

в основном вам необходимо установить службу данных для вашей службы, тогда событие click шаблона принимает службу данных и выполняет addUserService (данные переданы).

надеюсь, что это сработает, пожалуйста, дайте мне знать.