update-profile.js 5.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161
  1. module.exports = {
  2. friendlyName: 'Update profile',
  3. description: 'Update the profile for the logged-in user.',
  4. inputs: {
  5. fullName: {
  6. type: 'string'
  7. },
  8. emailAddress: {
  9. type: 'string'
  10. },
  11. },
  12. exits: {
  13. emailAlreadyInUse: {
  14. statusCode: 409,
  15. description: 'The provided email address is already in use.',
  16. },
  17. },
  18. fn: async function (inputs, exits) {
  19. var newEmailAddress = inputs.emailAddress;
  20. if (newEmailAddress !== undefined) {
  21. newEmailAddress = newEmailAddress.toLowerCase();
  22. }
  23. // Determine if this request wants to change the current user's email address,
  24. // revert her pending email address change, modify her pending email address
  25. // change, or if the email address won't be affected at all.
  26. var desiredEffectReEmail;// ('changeImmediately', 'beginChange', 'cancelPendingChange', 'modifyPendingChange', or '')
  27. if (
  28. newEmailAddress === undefined ||
  29. (this.req.me.emailStatus !== 'changeRequested' && newEmailAddress === this.req.me.emailAddress) ||
  30. (this.req.me.emailStatus === 'changeRequested' && newEmailAddress === this.req.me.emailChangeCandidate)
  31. ) {
  32. desiredEffectReEmail = '';
  33. } else if (this.req.me.emailStatus === 'changeRequested' && newEmailAddress === this.req.me.emailAddress) {
  34. desiredEffectReEmail = 'cancelPendingChange';
  35. } else if (this.req.me.emailStatus === 'changeRequested' && newEmailAddress !== this.req.me.emailAddress) {
  36. desiredEffectReEmail = 'modifyPendingChange';
  37. } else if (!sails.config.custom.verifyEmailAddresses || this.req.me.emailStatus === 'unconfirmed') {
  38. desiredEffectReEmail = 'changeImmediately';
  39. } else {
  40. desiredEffectReEmail = 'beginChange';
  41. }
  42. // If the email address is changing, make sure it is not already being used.
  43. if (_.contains(['beginChange', 'changeImmediately', 'modifyPendingChange'], desiredEffectReEmail)) {
  44. let conflictingUser = await User.findOne({
  45. or: [
  46. { emailAddress: newEmailAddress },
  47. { emailChangeCandidate: newEmailAddress }
  48. ]
  49. });
  50. if (conflictingUser) {
  51. throw 'emailAlreadyInUse';
  52. }
  53. }
  54. // Start building the values to set in the db.
  55. // (We always set the fullName if provided.)
  56. var valuesToSet = {
  57. fullName: inputs.fullName,
  58. };
  59. switch (desiredEffectReEmail) {
  60. // Change now
  61. case 'changeImmediately':
  62. Object.assign(valuesToSet, {
  63. emailAddress: newEmailAddress,
  64. emailChangeCandidate: '',
  65. emailProofToken: '',
  66. emailProofTokenExpiresAt: 0,
  67. emailStatus: this.req.me.emailStatus === 'unconfirmed' ? 'unconfirmed' : 'confirmed'
  68. });
  69. break;
  70. // Begin new email change, or modify a pending email change
  71. case 'beginChange':
  72. case 'modifyPendingChange':
  73. Object.assign(valuesToSet, {
  74. emailChangeCandidate: newEmailAddress,
  75. emailProofToken: await sails.helpers.strings.random('url-friendly'),
  76. emailProofTokenExpiresAt: Date.now() + sails.config.custom.emailProofTokenTTL,
  77. emailStatus: 'changeRequested'
  78. });
  79. break;
  80. // Cancel pending email change
  81. case 'cancelPendingChange':
  82. Object.assign(valuesToSet, {
  83. emailChangeCandidate: '',
  84. emailProofToken: '',
  85. emailProofTokenExpiresAt: 0,
  86. emailStatus: 'confirmed'
  87. });
  88. break;
  89. // Otherwise, do nothing re: email
  90. }
  91. // Save to the db
  92. await User.update({id: this.req.me.id }).set(valuesToSet);
  93. // If this is an immediate change, and billing features are enabled,
  94. // then also update the billing email for this user's linked customer entry
  95. // in the Stripe API to make sure they receive email receipts.
  96. // > Note: If there was not already a Stripe customer entry for this user,
  97. // > then one will be set up implicitly, so we'll need to persist it to our
  98. // > database. (This could happen if Stripe credentials were not configured
  99. // > at the time this user was originally created.)
  100. if(desiredEffectReEmail === 'changeImmediately' && sails.config.custom.enableBillingFeatures) {
  101. let didNotAlreadyHaveCustomerId = (! this.req.me.stripeCustomerId);
  102. let stripeCustomerId = await sails.helpers.stripe.saveBillingInfo.with({
  103. stripeCustomerId: this.req.me.stripeCustomerId,
  104. emailAddress: newEmailAddress
  105. });
  106. if (didNotAlreadyHaveCustomerId){
  107. await User.update({ id: this.req.me.id }).set({
  108. stripeCustomerId
  109. });
  110. }
  111. }
  112. // If an email address change was requested, and re-confirmation is required,
  113. // send the "confirm account" email.
  114. if (desiredEffectReEmail === 'beginChange' || desiredEffectReEmail === 'modifyPendingChange') {
  115. await sails.helpers.sendTemplateEmail.with({
  116. to: newEmailAddress,
  117. subject: 'Your account has been updated',
  118. template: 'email-verify-new-email',
  119. templateData: {
  120. fullName: inputs.fullName||this.req.me.fullName,
  121. token: valuesToSet.emailProofToken
  122. }
  123. });
  124. }
  125. return exits.success();
  126. }
  127. };