161 lines
5.1 KiB
JavaScript
161 lines
5.1 KiB
JavaScript
|
module.exports = {
|
||
|
|
||
|
|
||
|
friendlyName: 'Update profile',
|
||
|
|
||
|
|
||
|
description: 'Update the profile for the logged-in user.',
|
||
|
|
||
|
|
||
|
inputs: {
|
||
|
|
||
|
fullName: {
|
||
|
type: 'string'
|
||
|
},
|
||
|
|
||
|
emailAddress: {
|
||
|
type: 'string'
|
||
|
},
|
||
|
|
||
|
},
|
||
|
|
||
|
|
||
|
exits: {
|
||
|
|
||
|
emailAlreadyInUse: {
|
||
|
statusCode: 409,
|
||
|
description: 'The provided email address is already in use.',
|
||
|
},
|
||
|
|
||
|
},
|
||
|
|
||
|
|
||
|
fn: async function ({fullName, emailAddress}) {
|
||
|
|
||
|
var newEmailAddress = emailAddress;
|
||
|
if (newEmailAddress !== undefined) {
|
||
|
newEmailAddress = newEmailAddress.toLowerCase();
|
||
|
}
|
||
|
|
||
|
// Determine if this request wants to change the current user's email address,
|
||
|
// revert her pending email address change, modify her pending email address
|
||
|
// change, or if the email address won't be affected at all.
|
||
|
var desiredEmailEffect;// ('change-immediately', 'begin-change', 'cancel-pending-change', 'modify-pending-change', or '')
|
||
|
if (
|
||
|
newEmailAddress === undefined ||
|
||
|
(this.req.me.emailStatus !== 'change-requested' && newEmailAddress === this.req.me.emailAddress) ||
|
||
|
(this.req.me.emailStatus === 'change-requested' && newEmailAddress === this.req.me.emailChangeCandidate)
|
||
|
) {
|
||
|
desiredEmailEffect = '';
|
||
|
} else if (this.req.me.emailStatus === 'change-requested' && newEmailAddress === this.req.me.emailAddress) {
|
||
|
desiredEmailEffect = 'cancel-pending-change';
|
||
|
} else if (this.req.me.emailStatus === 'change-requested' && newEmailAddress !== this.req.me.emailAddress) {
|
||
|
desiredEmailEffect = 'modify-pending-change';
|
||
|
} else if (!sails.config.custom.verifyEmailAddresses || this.req.me.emailStatus === 'unconfirmed') {
|
||
|
desiredEmailEffect = 'change-immediately';
|
||
|
} else {
|
||
|
desiredEmailEffect = 'begin-change';
|
||
|
}
|
||
|
|
||
|
|
||
|
// If the email address is changing, make sure it is not already being used.
|
||
|
if (_.contains(['begin-change', 'change-immediately', 'modify-pending-change'], desiredEmailEffect)) {
|
||
|
let conflictingUser = await User.findOne({
|
||
|
or: [
|
||
|
{ emailAddress: newEmailAddress },
|
||
|
{ emailChangeCandidate: newEmailAddress }
|
||
|
]
|
||
|
});
|
||
|
if (conflictingUser) {
|
||
|
throw 'emailAlreadyInUse';
|
||
|
}
|
||
|
}
|
||
|
|
||
|
|
||
|
// Start building the values to set in the db.
|
||
|
// (We always set the fullName if provided.)
|
||
|
var valuesToSet = {
|
||
|
fullName,
|
||
|
};
|
||
|
|
||
|
switch (desiredEmailEffect) {
|
||
|
|
||
|
// Change now
|
||
|
case 'change-immediately':
|
||
|
_.extend(valuesToSet, {
|
||
|
emailAddress: newEmailAddress,
|
||
|
emailChangeCandidate: '',
|
||
|
emailProofToken: '',
|
||
|
emailProofTokenExpiresAt: 0,
|
||
|
emailStatus: this.req.me.emailStatus === 'unconfirmed' ? 'unconfirmed' : 'confirmed'
|
||
|
});
|
||
|
break;
|
||
|
|
||
|
// Begin new email change, or modify a pending email change
|
||
|
case 'begin-change':
|
||
|
case 'modify-pending-change':
|
||
|
_.extend(valuesToSet, {
|
||
|
emailChangeCandidate: newEmailAddress,
|
||
|
emailProofToken: await sails.helpers.strings.random('url-friendly'),
|
||
|
emailProofTokenExpiresAt: Date.now() + sails.config.custom.emailProofTokenTTL,
|
||
|
emailStatus: 'change-requested'
|
||
|
});
|
||
|
break;
|
||
|
|
||
|
// Cancel pending email change
|
||
|
case 'cancel-pending-change':
|
||
|
_.extend(valuesToSet, {
|
||
|
emailChangeCandidate: '',
|
||
|
emailProofToken: '',
|
||
|
emailProofTokenExpiresAt: 0,
|
||
|
emailStatus: 'confirmed'
|
||
|
});
|
||
|
break;
|
||
|
|
||
|
// Otherwise, do nothing re: email
|
||
|
}
|
||
|
|
||
|
// Save to the db
|
||
|
await User.updateOne({id: this.req.me.id })
|
||
|
.set(valuesToSet);
|
||
|
|
||
|
// If this is an immediate change, and billing features are enabled,
|
||
|
// then also update the billing email for this user's linked customer entry
|
||
|
// in the Stripe API to make sure they receive email receipts.
|
||
|
// > Note: If there was not already a Stripe customer entry for this user,
|
||
|
// > then one will be set up implicitly, so we'll need to persist it to our
|
||
|
// > database. (This could happen if Stripe credentials were not configured
|
||
|
// > at the time this user was originally created.)
|
||
|
if(desiredEmailEffect === 'change-immediately' && sails.config.custom.enableBillingFeatures) {
|
||
|
let didNotAlreadyHaveCustomerId = (! this.req.me.stripeCustomerId);
|
||
|
let stripeCustomerId = await sails.helpers.stripe.saveBillingInfo.with({
|
||
|
stripeCustomerId: this.req.me.stripeCustomerId,
|
||
|
emailAddress: newEmailAddress
|
||
|
}).timeout(5000).retry();
|
||
|
if (didNotAlreadyHaveCustomerId){
|
||
|
await User.updateOne({ id: this.req.me.id })
|
||
|
.set({
|
||
|
stripeCustomerId
|
||
|
});
|
||
|
}
|
||
|
}
|
||
|
|
||
|
// If an email address change was requested, and re-confirmation is required,
|
||
|
// send the "confirm account" email.
|
||
|
if (desiredEmailEffect === 'begin-change' || desiredEmailEffect === 'modify-pending-change') {
|
||
|
await sails.helpers.sendTemplateEmail.with({
|
||
|
to: newEmailAddress,
|
||
|
subject: 'Your account has been updated',
|
||
|
template: 'email-verify-new-email',
|
||
|
templateData: {
|
||
|
fullName: fullName||this.req.me.fullName,
|
||
|
token: valuesToSet.emailProofToken
|
||
|
}
|
||
|
});
|
||
|
}
|
||
|
|
||
|
}
|
||
|
|
||
|
|
||
|
};
|