Skip to content
Snippets Groups Projects
Commit 43dfafd3 authored by Gabriel Engel's avatar Gabriel Engel Committed by GitHub
Browse files

Merge pull request #5794 from RocketChat/coffee2js/server-part-1

Convert serrver/configuration and server/lib to JS
parents 9cb35b85 d76cdbed
No related branches found
No related tags found
No related merge requests found
......@@ -67,7 +67,7 @@
"curly": [2, "all"],
"eqeqeq": [2, "allow-null"],
"new-cap": [2, {
"capIsNewExceptions": ["Match.Optional", "Match.Maybe", "Match.ObjectIncluding"]
"capIsNewExceptions": ["Match.Optional", "Match.Maybe", "Match.ObjectIncluding", "Push.Configure"]
}],
"use-isnan": 2,
"valid-typeof": 2,
......
orig_updateOrCreateUserFromExternalService = Accounts.updateOrCreateUserFromExternalService
Accounts.updateOrCreateUserFromExternalService = (serviceName, serviceData, options) ->
if serviceName not in ['facebook', 'github', 'gitlab', 'google', 'meteor-developer', 'linkedin', 'twitter', 'sandstorm'] and serviceData._OAuthCustom isnt true
return
if serviceName is 'meteor-developer'
if _.isArray serviceData?.emails
serviceData.emails.sort (a, b) ->
return a.primary isnt true
for email in serviceData.emails
if email.verified is true
serviceData.email = email.address
break
if serviceName is 'linkedin'
serviceData.email = serviceData.emailAddress
if serviceData.email
# Find user with given email
user = RocketChat.models.Users.findOneByEmailAddress serviceData.email
if user?
# If email is not verified, reset password and require password change
if not _.findWhere user.emails, { address: serviceData.email, verified: true }
RocketChat.models.Users.resetPasswordAndSetRequirePasswordChange(user._id, true, 'This_email_has_already_been_used_and_has_not_been_verified__Please_change_your_password')
# Merge accounts
RocketChat.models.Users.setServiceId user._id, serviceName, serviceData.id
# Validate email
RocketChat.models.Users.setEmailVerified user._id, serviceData.email
return orig_updateOrCreateUserFromExternalService.apply(this, arguments)
const orig_updateOrCreateUserFromExternalService = Accounts.updateOrCreateUserFromExternalService;
Accounts.updateOrCreateUserFromExternalService = function(serviceName, serviceData = {} /*, options*/) {
const services = [
'facebook',
'github',
'gitlab',
'google',
'meteor-developer',
'linkedin',
'twitter',
'sandstorm'
];
if (services.includes(serviceName) === false && serviceData._OAuthCustom !== true) {
return;
}
if (serviceName === 'meteor-developer') {
if (Array.isArray(serviceData.emails)) {
serviceData.email = serviceData.emails.sort(a => a.primary !== true).filter(item => item.verified === true)[0];
}
}
if (serviceName === 'linkedin') {
serviceData.email = serviceData.emailAddress;
}
if (serviceData.email) {
const user = RocketChat.models.Users.findOneByEmailAddress(serviceData.email);
if (user != null) {
const findQuery = {
address: serviceData.email,
verified: true
};
if (!_.findWhere(user.emails, findQuery)) {
RocketChat.models.Users.resetPasswordAndSetRequirePasswordChange(user._id, true, 'This_email_has_already_been_used_and_has_not_been_verified__Please_change_your_password');
}
RocketChat.models.Users.setServiceId(user._id, serviceName, serviceData.id);
RocketChat.models.Users.setEmailVerified(user._id, serviceData.email);
}
}
return orig_updateOrCreateUserFromExternalService.apply(this, arguments);
};
# Deny Account.createUser in client and set Meteor.loginTokenExpires
accountsConfig = { forbidClientAccountCreation: true, loginExpirationInDays: RocketChat.settings.get 'Accounts_LoginExpiration' }
Accounts.config accountsConfig
Accounts.emailTemplates.siteName = RocketChat.settings.get 'Site_Name';
Accounts.emailTemplates.from = "#{RocketChat.settings.get 'Site_Name'} <#{RocketChat.settings.get 'From_Email'}>";
verifyEmailHtml = Accounts.emailTemplates.verifyEmail.text
Accounts.emailTemplates.verifyEmail.html = (user, url) ->
url = url.replace Meteor.absoluteUrl(), Meteor.absoluteUrl() + 'login/'
verifyEmailHtml user, url
resetPasswordHtml = Accounts.emailTemplates.resetPassword.text
Accounts.emailTemplates.resetPassword.html = (user, url) ->
url = url.replace /\/#\//, '/'
resetPasswordHtml user, url
Accounts.emailTemplates.enrollAccount.subject = (user) ->
if RocketChat.settings.get 'Accounts_Enrollment_Customized'
subject = RocketChat.settings.get 'Accounts_Enrollment_Email_Subject'
else
subject = TAPi18n.__('Accounts_Enrollment_Email_Subject_Default', { lng: user?.language || RocketChat.settings.get('language') || 'en' })
return RocketChat.placeholders.replace(subject);
Accounts.emailTemplates.enrollAccount.html = (user, url) ->
if RocketChat.settings.get 'Accounts_Enrollment_Customized'
html = RocketChat.settings.get 'Accounts_Enrollment_Email'
else
html = TAPi18n.__('Accounts_Enrollment_Email_Default', { lng: user?.language || RocketChat.settings.get('language') || 'en' })
header = RocketChat.placeholders.replace(RocketChat.settings.get('Email_Header') || "")
footer = RocketChat.placeholders.replace(RocketChat.settings.get('Email_Footer') || "")
html = RocketChat.placeholders.replace(html, {
name: user.name,
email: user.emails?[0]?.address
});
return header + html + footer;
Accounts.onCreateUser (options, user) ->
# console.log 'onCreateUser ->',JSON.stringify arguments, null, ' '
# console.log 'options ->',JSON.stringify options, null, ' '
# console.log 'user ->',JSON.stringify user, null, ' '
RocketChat.callbacks.run 'beforeCreateUser', options, user
user.status = 'offline'
user.active = not RocketChat.settings.get 'Accounts_ManuallyApproveNewUsers'
if not user?.name? or user.name is ''
if options.profile?.name?
user.name = options.profile?.name
if user.services?
for serviceName, service of user.services
if not user?.name? or user.name is ''
if service.name?
user.name = service.name
else if service.username?
user.name = service.username
if not user.emails? and service.email?
user.emails = [
address: service.email
verified: true
]
return user
# Wrap insertUserDoc to allow executing code after Accounts.insertUserDoc is run
Accounts.insertUserDoc = _.wrap Accounts.insertUserDoc, (insertUserDoc, options, user) ->
roles = []
if Match.test(user.globalRoles, [String]) and user.globalRoles.length > 0
roles = roles.concat user.globalRoles
delete user.globalRoles
user.type ?= 'user'
_id = insertUserDoc.call(Accounts, options, user)
# Get user from db again to get all fields added by middlewares like
# validateNewUser and others.
user = Meteor.users.findOne({_id: _id});
# Add user to default channels
if user.username? and options.joinDefaultChannels isnt false and user.joinDefaultChannels isnt false
Meteor.runAsUser _id, ->
Meteor.call('joinDefaultChannels', options.joinDefaultChannelsSilenced)
if roles.length is 0
# when inserting first user give them admin privileges otherwise make a regular user
hasAdmin = RocketChat.models.Users.findOne({ roles: 'admin' }, {fields: {_id: 1}})
if hasAdmin?
roles.push 'user'
else
roles.push 'admin'
RocketChat.authz.addUserRoles(_id, roles)
Meteor.defer ->
RocketChat.callbacks.run 'afterCreateUser', options, user
return _id
Accounts.validateLoginAttempt (login) ->
login = RocketChat.callbacks.run 'beforeValidateLogin', login
if login.allowed isnt true
return login.allowed
# bypass for livechat users
if login.user.type is 'visitor'
return true
if !!login.user?.active isnt true
throw new Meteor.Error 'error-user-is-not-activated', 'User is not activated', { function: 'Accounts.validateLoginAttempt' }
return false
# If user is admin, no need to check if email is verified
if 'admin' not in login.user?.roles and login.type is 'password' and RocketChat.settings.get('Accounts_EmailVerification') is true
validEmail = login.user.emails.filter (email) ->
return email.verified is true
if validEmail.length is 0
throw new Meteor.Error 'error-invalid-email', 'Invalid email __email__'
return false
RocketChat.models.Users.updateLastLoginById login.user._id
Meteor.defer ->
RocketChat.callbacks.run 'afterValidateLogin', login
return true
Accounts.validateNewUser (user) ->
# bypass for livechat users
if user.type is 'visitor'
return true
if RocketChat.settings.get('Accounts_Registration_AuthenticationServices_Enabled') is false and RocketChat.settings.get('LDAP_Enable') is false and not user.services?.password?
throw new Meteor.Error 'registration-disabled-authentication-services', 'User registration is disabled for authentication services'
return true
Accounts.validateNewUser (user) ->
# bypass for livechat users
if user.type is 'visitor'
return true
domainWhiteList = RocketChat.settings.get('Accounts_AllowedDomainsList')
if _.isEmpty s.trim(domainWhiteList)
return true
domainWhiteList = _.map(domainWhiteList.split(','), (domain) -> domain.trim())
if user.emails?.length > 0
ret = false
email = user.emails[0].address
for domain in domainWhiteList
if email.match('@' + RegExp.escape(domain) + '$')
ret = true
break
if not ret
throw new Meteor.Error 'error-invalid-domain'
return true
const accountsConfig = {
forbidClientAccountCreation: true,
loginExpirationInDays: RocketChat.settings.get('Accounts_LoginExpiration')
};
Accounts.config(accountsConfig);
Accounts.emailTemplates.siteName = RocketChat.settings.get('Site_Name');
Accounts.emailTemplates.from = `${RocketChat.settings.get('Site_Name')} <${RocketChat.settings.get('From_Email')}>`;
const verifyEmailHtml = Accounts.emailTemplates.verifyEmail.text;
Accounts.emailTemplates.verifyEmail.html = function(user, url) {
url = url.replace(Meteor.absoluteUrl(), `${Meteor.absoluteUrl()}login/`);
return verifyEmailHtml(user, url);
};
const resetPasswordHtml = Accounts.emailTemplates.resetPassword.text;
Accounts.emailTemplates.resetPassword.html = function(user, url) {
url = url.replace(/\/#\//, '/');
return resetPasswordHtml(user, url);
};
Accounts.emailTemplates.enrollAccount.subject = function(user = {}) {
let subject;
if (RocketChat.settings.get('Accounts_Enrollment_Customized')) {
subject = RocketChat.settings.get('Accounts_Enrollment_Email_Subject');
} else {
subject = TAPi18n.__('Accounts_Enrollment_Email_Subject_Default', {
lng: user.language || RocketChat.settings.get('language') || 'en'
});
}
return RocketChat.placeholders.replace(subject);
};
Accounts.emailTemplates.enrollAccount.html = function(user = {}/*, url*/) {
let html;
if (RocketChat.settings.get('Accounts_Enrollment_Customized')) {
html = RocketChat.settings.get('Accounts_Enrollment_Email');
} else {
html = TAPi18n.__('Accounts_Enrollment_Email_Default', {
lng: user.language || RocketChat.settings.get('language') || 'en'
});
}
const header = RocketChat.placeholders.replace(RocketChat.settings.get('Email_Header') || '');
const footer = RocketChat.placeholders.replace(RocketChat.settings.get('Email_Footer') || '');
html = RocketChat.placeholders.replace(html, {
name: user.name,
email: user.emails && user.emails[0] && user.emails[0].address
});
return header + html + footer;
};
Accounts.onCreateUser(function(options, user = {}) {
RocketChat.callbacks.run('beforeCreateUser', options, user);
user.status = 'offline';
user.active = !RocketChat.settings.get('Accounts_ManuallyApproveNewUsers');
if (!user.name) {
if (options.profile && options.profile.name) {
user.name = options.profile.name;
}
}
if (user.services) {
for (const service of Object.values(user.services)) {
if (!user.name) {
user.name = service.name || service.username;
}
if (!user.emails && service.email) {
user.emails = [{
address: service.email,
verified: true
}];
}
}
}
return user;
});
Accounts.insertUserDoc = _.wrap(Accounts.insertUserDoc, function(insertUserDoc, options, user) {
let roles = [];
if (Match.test(user.globalRoles, [String]) && user.globalRoles.length > 0) {
roles = roles.concat(user.globalRoles);
}
delete user.globalRoles;
if (!user.type) {
user.type = 'user';
}
const _id = insertUserDoc.call(Accounts, options, user);
user = Meteor.users.findOne({
_id: _id
});
if (user.username && options.joinDefaultChannels !== false && user.joinDefaultChannels !== false) {
Meteor.runAsUser(_id, function() {
return Meteor.call('joinDefaultChannels', options.joinDefaultChannelsSilenced);
});
}
if (roles.length === 0) {
const hasAdmin = RocketChat.models.Users.findOne({
roles: 'admin'
}, {
fields: {
_id: 1
}
});
if (hasAdmin) {
roles.push('user');
} else {
roles.push('admin');
}
}
RocketChat.authz.addUserRoles(_id, roles);
Meteor.defer(function() {
return RocketChat.callbacks.run('afterCreateUser', options, user);
});
return _id;
});
Accounts.validateLoginAttempt(function(login) {
login = RocketChat.callbacks.run('beforeValidateLogin', login);
if (login.allowed !== true) {
return login.allowed;
}
if (login.user.type === 'visitor') {
return true;
}
if (!!login.user.active !== true) {
throw new Meteor.Error('error-user-is-not-activated', 'User is not activated', {
'function': 'Accounts.validateLoginAttempt'
});
}
if (login.user.roles.includes('admin') === false && login.type === 'password' && RocketChat.settings.get('Accounts_EmailVerification') === true) {
const validEmail = login.user.emails.filter(email => email.verified === true);
if (validEmail.length === 0) {
throw new Meteor.Error('error-invalid-email', 'Invalid email __email__');
}
}
RocketChat.models.Users.updateLastLoginById(login.user._id);
Meteor.defer(function() {
return RocketChat.callbacks.run('afterValidateLogin', login);
});
return true;
});
Accounts.validateNewUser(function(user) {
if (user.type === 'visitor') {
return true;
}
if (RocketChat.settings.get('Accounts_Registration_AuthenticationServices_Enabled') === false && RocketChat.settings.get('LDAP_Enable') === false && !(user.services && user.services.password)) {
throw new Meteor.Error('registration-disabled-authentication-services', 'User registration is disabled for authentication services');
}
return true;
});
Accounts.validateNewUser(function(user) {
if (user.type === 'visitor') {
return true;
}
let domainWhiteList = RocketChat.settings.get('Accounts_AllowedDomainsList');
if (_.isEmpty(s.trim(domainWhiteList))) {
return true;
}
domainWhiteList = domainWhiteList.split(',').map(domain => domain.trim());
if (user.emails && user.emails.length > 0) {
const email = user.emails[0].address;
const inWhiteList = domainWhiteList.some(domain => email.match('@' + RegExp.escape(domain) + '$'));
if (inWhiteList === false) {
throw new Meteor.Error('error-invalid-domain');
}
}
return true;
});
Meteor.methods
log: ->
console.log.apply console, arguments
push_test: ->
user = Meteor.user()
if not user?
throw new Meteor.Error 'error-not-allowed', 'Not allowed', { method: 'push_test' }
if not RocketChat.authz.hasRole(user._id, 'admin')
throw new Meteor.Error 'error-not-allowed', 'Not allowed', { method: 'push_test' }
if Push.enabled isnt true
throw new Meteor.Error 'error-push-disabled', 'Push is disabled', { method: 'push_test' }
query =
$and: [
userId: user._id
{
$or: [
{ 'token.apn': { $exists: true } }
{ 'token.gcm': { $exists: true } }
]
}
]
tokens = Push.appCollection.find(query).count()
if tokens is 0
throw new Meteor.Error 'error-no-tokens-for-this-user', "There are no tokens for this user", { method: 'push_test' }
Push.send
from: 'push'
title: "@#{user.username}"
text: TAPi18n.__ "This_is_a_push_test_messsage"
apn:
text: "@#{user.username}:\n" + TAPi18n.__ "This_is_a_push_test_messsage"
sound: 'default'
query:
userId: user._id
return {} =
message: "Your_push_was_sent_to_s_devices"
params: [tokens]
configurePush = ->
if RocketChat.settings.get 'Push_debug'
Push.debug = true
console.log 'Push: configuring...'
if RocketChat.settings.get('Push_enable') is true
Push.allow
send: (userId, notification) ->
return RocketChat.authz.hasRole(userId, 'admin')
apn = undefined
gcm = undefined
if RocketChat.settings.get('Push_enable_gateway') is false
gcm =
apiKey: RocketChat.settings.get 'Push_gcm_api_key'
projectNumber: RocketChat.settings.get 'Push_gcm_project_number'
apn =
passphrase: RocketChat.settings.get 'Push_apn_passphrase'
keyData: RocketChat.settings.get 'Push_apn_key'
certData: RocketChat.settings.get 'Push_apn_cert'
if RocketChat.settings.get('Push_production') isnt true
apn =
passphrase: RocketChat.settings.get 'Push_apn_dev_passphrase'
keyData: RocketChat.settings.get 'Push_apn_dev_key'
certData: RocketChat.settings.get 'Push_apn_dev_cert'
gateway: 'gateway.sandbox.push.apple.com'
if not apn.keyData? or apn.keyData.trim() is '' or not apn.keyData? or apn.keyData.trim() is ''
apn = undefined
if not gcm.apiKey? or gcm.apiKey.trim() is '' or not gcm.projectNumber? or gcm.projectNumber.trim() is ''
gcm = undefined
Push.Configure
apn: apn
gcm: gcm
production: RocketChat.settings.get 'Push_production'
sendInterval: 1000
sendBatchSize: 10
if RocketChat.settings.get('Push_enable_gateway') is true
Push.serverSend = (options) ->
options = options or { badge: 0 }
query = undefined
if options.from isnt ''+options.from
throw new Error('Push.send: option "from" not a string')
if options.title isnt ''+options.title
throw new Error('Push.send: option "title" not a string')
if options.text isnt ''+options.text
throw new Error('Push.send: option "text" not a string')
if RocketChat.settings.get 'Push_debug'
console.log('Push: send message "' + options.title + '" via query', options.query)
query =
$and: [
options.query
{
$or: [
{ 'token.apn': { $exists: true } }
{ 'token.gcm': { $exists: true } }
]
}
]
Push.appCollection.find(query).forEach (app) ->
if RocketChat.settings.get 'Push_debug'
console.log('Push: send to token', app.token)
if app.token.apn?
service = 'apn'
token = app.token.apn
else if app.token.gcm?
service = 'gcm'
token = app.token.gcm
sendPush service, token, options
Push.enabled = true
sendPush = (service, token, options, tries=0) ->
data =
data:
token: token
options: options
HTTP.post RocketChat.settings.get('Push_gateway') + "/push/#{service}/send", data, (error, response) ->
if response?.statusCode is 406
console.log('removing push token', token)
Push.appCollection.remove({
$or: [
{ 'token.apn': token }
{ 'token.gcm': token }
]
})
return
if not error?
return
SystemLogger.error 'Error sending push to gateway ('+tries+' try) ->', error
if tries <= 6
milli = Math.pow(10, tries+2)
SystemLogger.log 'Trying sending push to gateway again in', milli, 'milliseconds'
# Try again in 0.1s, 1s, 10s, 1m40s, 16m40s, 2h46m40s and 27h46m40s
Meteor.setTimeout ->
sendPush service, token, options, tries+1
, milli
Meteor.startup ->
configurePush()
## Prepared to reconfigure the push plugin
#
# keys = [
# 'Push_enable'
# 'Push_enable_gateway'
# 'Push_gcm_api_key'
# 'Push_gcm_project_number'
# 'Push_apn_passphrase'
# 'Push_apn_key'
# 'Push_apn_cert'
# 'Push_production'
# 'Push_apn_dev_passphrase'
# 'Push_apn_dev_key'
# 'Push_apn_dev_cert'
# 'Push_gateway'
# ]
# configurePushDebounce = _.debounce Meteor.bindEnvironment(configurePush), 1000
# RocketChat.settings.onload keys, ->
# configurePushDebounce()
/* global Push, SystemLogger */
Meteor.methods({
// log() {
// return console.log(...arguments);
// },
push_test() {
const user = Meteor.user();
if (!user) {
throw new Meteor.Error('error-not-allowed', 'Not allowed', {
method: 'push_test'
});
}
if (!RocketChat.authz.hasRole(user._id, 'admin')) {
throw new Meteor.Error('error-not-allowed', 'Not allowed', {
method: 'push_test'
});
}
if (Push.enabled !== true) {
throw new Meteor.Error('error-push-disabled', 'Push is disabled', {
method: 'push_test'
});
}
const query = {
$and: [{
userId: user._id
}, {
$or: [{
'token.apn': {
$exists: true
}
}, {
'token.gcm': {
$exists: true
}
}]
}]
};
const tokens = Push.appCollection.find(query).count();
if (tokens === 0) {
throw new Meteor.Error('error-no-tokens-for-this-user', 'There are no tokens for this user', {
method: 'push_test'
});
}
Push.send({
from: 'push',
title: `@${user.username}`,
text: TAPi18n.__('This_is_a_push_test_messsage'),
apn: {
text: `@${user.username}:\n${TAPi18n.__('This_is_a_push_test_messsage')}`
},
sound: 'default',
query: {
userId: user._id
}
});
return {
message: 'Your_push_was_sent_to_s_devices',
params: [tokens]
};
}
});
function sendPush(service, token, options, tries = 0) {
const data = {
data: {
token: token,
options: options
}
};
return HTTP.post(RocketChat.settings.get('Push_gateway') + `/push/${service}/send`, data, function(error, response) {
if (response && response.statusCode === 406) {
console.log('removing push token', token);
Push.appCollection.remove({
$or: [{
'token.apn': token
}, {
'token.gcm': token
}]
});
return;
}
if (!error) {
return;
}
SystemLogger.error(`Error sending push to gateway (${tries} try) ->`, error);
if (tries <= 6) {
const milli = Math.pow(10, tries + 2);
SystemLogger.log('Trying sending push to gateway again in', milli, 'milliseconds');
return Meteor.setTimeout(function() {
return sendPush(service, token, options, tries + 1);
}, milli);
}
});
}
function configurePush() {
if (RocketChat.settings.get('Push_debug')) {
Push.debug = true;
console.log('Push: configuring...');
}
if (RocketChat.settings.get('Push_enable') === true) {
Push.allow({
send: function(userId/*, notification*/) {
return RocketChat.authz.hasRole(userId, 'admin');
}
});
let apn, gcm;
if (RocketChat.settings.get('Push_enable_gateway') === false) {
gcm = {
apiKey: RocketChat.settings.get('Push_gcm_api_key'),
projectNumber: RocketChat.settings.get('Push_gcm_project_number')
};
apn = {
passphrase: RocketChat.settings.get('Push_apn_passphrase'),
keyData: RocketChat.settings.get('Push_apn_key'),
certData: RocketChat.settings.get('Push_apn_cert')
};
if (RocketChat.settings.get('Push_production') !== true) {
apn = {
passphrase: RocketChat.settings.get('Push_apn_dev_passphrase'),
keyData: RocketChat.settings.get('Push_apn_dev_key'),
certData: RocketChat.settings.get('Push_apn_dev_cert'),
gateway: 'gateway.sandbox.push.apple.com'
};
}
if (!apn.keyData || apn.keyData.trim() === '' || !apn.certData || apn.certData.trim() === '') {
apn = undefined;
}
if (!gcm.apiKey || gcm.apiKey.trim() === '' || !gcm.projectNumber || gcm.projectNumber.trim() === '') {
gcm = undefined;
}
}
Push.Configure({
apn: apn,
gcm: gcm,
production: RocketChat.settings.get('Push_production'),
sendInterval: 1000,
sendBatchSize: 10
});
if (RocketChat.settings.get('Push_enable_gateway') === true) {
Push.serverSend = function(options = {badge: 0}) {
if (options.from !== String(options.from)) {
throw new Error('Push.send: option "from" not a string');
}
if (options.title !== String(options.title)) {
throw new Error('Push.send: option "title" not a string');
}
if (options.text !== String(options.text)) {
throw new Error('Push.send: option "text" not a string');
}
if (RocketChat.settings.get('Push_debug')) {
console.log(`Push: send message "${options.title}" via query`, options.query);
}
const query = {
$and: [options.query, {
$or: [{
'token.apn': {
$exists: true
}
}, {
'token.gcm': {
$exists: true
}
}]
}]
};
return Push.appCollection.find(query).forEach((app) => {
if (RocketChat.settings.get('Push_debug')) {
console.log('Push: send to token', app.token);
}
if (app.token.apn) {
return sendPush('apn', app.token.apn, options);
}
if (app.token.gcm) {
return sendPush('gcm', app.token.gcm, options);
}
});
};
}
return Push.enabled = true;
}
}
Meteor.startup(function() {
return configurePush();
});
Accounts.registerLoginHandler (loginRequest) ->
if not loginRequest.cordova
return undefined
loginRequest = loginRequest.authResponse
identity = getIdentity(loginRequest.accessToken)
serviceData =
accessToken: loginRequest.accessToken
expiresAt: (+new Date) + (1000 * loginRequest.expiresIn)
whitelisted = ['id', 'email', 'name', 'first_name', 'last_name', 'link', 'username', 'gender', 'locale', 'age_range']
fields = _.pick(identity, whitelisted)
_.extend(serviceData, fields)
options = {profile: {}}
profileFields = _.pick(identity, whitelisted)
_.extend(options.profile, profileFields)
return Accounts.updateOrCreateUserFromExternalService("facebook", serviceData, options)
getIdentity = (accessToken) ->
try
return HTTP.get("https://graph.facebook.com/me", {params: {access_token: accessToken}}).data
catch err
throw _.extend new Error("Failed to fetch identity from Facebook. " + err.message), {response: err.response}
\ No newline at end of file
function getIdentity(accessToken) {
try {
return HTTP.get('https://graph.facebook.com/me', {
params: {
access_token: accessToken
}
}).data;
} catch (error) {
throw _.extend(new Error(`Failed to fetch identity from Facebook. ${error.message}`), {
response: error.response
});
}
}
Accounts.registerLoginHandler(function(loginRequest) {
if (!loginRequest.cordova) {
return;
}
loginRequest = loginRequest.authResponse;
const identity = getIdentity(loginRequest.accessToken);
const serviceData = {
accessToken: loginRequest.accessToken,
expiresAt: Date.now() + 1000 * loginRequest.expiresIn
};
const whitelisted = ['id', 'email', 'name', 'first_name', 'last_name', 'link', 'username', 'gender', 'locale', 'age_range'];
const fields = _.pick(identity, whitelisted);
const options = {
profile: {}
};
_.extend(serviceData, fields);
_.extend(options.profile, fields);
return Accounts.updateOrCreateUserFromExternalService('facebook', serviceData, options);
});
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment