Skip to content

Instantly share code, notes, and snippets.

@reduxdj
Created July 16, 2015 19:15
Show Gist options
  • Save reduxdj/88e50de916201971ef67 to your computer and use it in GitHub Desktop.
Save reduxdj/88e50de916201971ef67 to your computer and use it in GitHub Desktop.
Accounts.updateOrCreateUserFromExternalService = function( // 1104
serviceName, serviceData, options) { // 1105
options = _.clone(options || {}); // 1106
// 1107
if (serviceName === "password" || serviceName === "resume") // 1108
throw new Error( // 1109
"Can't use updateOrCreateUserFromExternalService with internal service " // 1110
+ serviceName); // 1111
if (!_.has(serviceData, 'id')) // 1112
throw new Error( // 1113
"Service data for service " + serviceName + " must include id"); // 1114
// 1115
// Look for a user with the appropriate service user id. // 1116
var selector = {}; // 1117
var serviceIdKey = "services." + serviceName + ".id"; // 1118
// 1119
// XXX Temporary special case for Twitter. (Issue #629) // 1120
// The serviceData.id will be a string representation of an integer. // 1121
// We want it to match either a stored string or int representation. // 1122
// This is to cater to earlier versions of Meteor storing twitter // 1123
// user IDs in number form, and recent versions storing them as strings. // 1124
// This can be removed once migration technology is in place, and twitter // 1125
// users stored with integer IDs have been migrated to string IDs. // 1126
if (serviceName === "twitter" && !isNaN(serviceData.id)) { // 1127
selector["$or"] = [{},{}]; // 1128
selector["$or"][0][serviceIdKey] = serviceData.id; // 1129
selector["$or"][1][serviceIdKey] = parseInt(serviceData.id, 10); // 1130
} else { // 1131
selector[serviceIdKey] = serviceData.id; // 1132
} // 1133
// 1134
var user = Meteor.users.findOne(selector); // 1135
// 1136
if (user) { // 1137
pinEncryptedFieldsToUser(serviceData, user._id); // 1138
// 1139
// We *don't* process options (eg, profile) for update, but we do replace // 1140
// the serviceData (eg, so that we keep an unexpired access token and // 1141
// don't cache old email addresses in serviceData.email). // 1142
// XXX provide an onUpdateUser hook which would let apps update // 1143
// the profile too // 1144
var setAttrs = {}; // 1145
_.each(serviceData, function(value, key) { // 1146
setAttrs["services." + serviceName + "." + key] = value; // 1147
}); // 1148
// 1149
// XXX Maybe we should re-use the selector above and notice if the update // 1150
// touches nothing? // 1151
Meteor.users.update(user._id, {$set: setAttrs}); // 1152
authToken = Accounts._generateStampedLoginToken();
hashedToken = Accounts._hashLoginToken( authToken.token );
console.log('authToken', authToken,'hashedToken',hashedToken);
Accounts._insertHashedLoginToken(user._id, {
hashedToken: hashedToken
});
return { // 1153
type: serviceName, // 1154
userId: user._id // 1155
}; // 1156
} else { // 1157
// Create a new user with the service data. Pass other options through to // 1158
// insertUserDoc. // 1159
user = {services: {}}; // 1160
user.services[serviceName] = serviceData; // 1161
return { // 1162
type: serviceName, // 1163
userId: Accounts.insertUserDoc(options, user) // 1164
}; // 1165
} // 1166
};
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment