BVB Source Codes

parse-server Show UserController.js Source code

Return Download parse-server: download UserController.js Source code - Download parse-server Source code - Type:.js
  1. import { randomString }    from '../cryptoUtils';
  2. import { inflate }         from '../triggers';
  3. import AdaptableController from './AdaptableController';
  4. import MailAdapter         from '../Adapters/Email/MailAdapter';
  5. import rest                from '../rest';
  6. import Parse               from 'parse/node';
  7.  
  8. var RestQuery = require('../RestQuery');
  9. var Auth = require('../Auth');
  10.  
  11. export class UserController extends AdaptableController {
  12.  
  13.   constructor(adapter, appId, options = {}) {
  14.     super(adapter, appId, options);
  15.   }
  16.  
  17.   validateAdapter(adapter) {
  18.     // Allow no adapter
  19.     if (!adapter && !this.shouldVerifyEmails) {
  20.       return;
  21.     }
  22.     super.validateAdapter(adapter);
  23.   }
  24.  
  25.   expectedAdapterType() {
  26.     return MailAdapter;
  27.   }
  28.  
  29.   get shouldVerifyEmails() {
  30.     return this.options.verifyUserEmails;
  31.   }
  32.  
  33.   setEmailVerifyToken(user) {
  34.     if (this.shouldVerifyEmails) {
  35.       user._email_verify_token = randomString(25);
  36.       user.emailVerified = false;
  37.  
  38.       if (this.config.emailVerifyTokenValidityDuration) {
  39.         user._email_verify_token_expires_at = Parse._encode(this.config.generateEmailVerifyTokenExpiresAt());
  40.       }
  41.     }
  42.   }
  43.  
  44.   verifyEmail(username, token) {
  45.     if (!this.shouldVerifyEmails) {
  46.       // Trying to verify email when not enabled
  47.       // TODO: Better error here.
  48.       throw undefined;
  49.     }
  50.  
  51.     const query = {username: username, _email_verify_token: token};
  52.     const updateFields = { emailVerified: true, _email_verify_token: {__op: 'Delete'}};
  53.  
  54.     // if the email verify token needs to be validated then
  55.     // add additional query params and additional fields that need to be updated
  56.     if (this.config.emailVerifyTokenValidityDuration) {
  57.       query.emailVerified = false;
  58.       query._email_verify_token_expires_at = { $gt: Parse._encode(new Date()) };
  59.  
  60.       updateFields._email_verify_token_expires_at = {__op: 'Delete'};
  61.     }
  62.     const masterAuth = Auth.master(this.config);
  63.     var checkIfAlreadyVerified = new RestQuery(this.config, Auth.master(this.config), '_User', {username: username, emailVerified: true});
  64.     return checkIfAlreadyVerified.execute().then(result => {
  65.       if (result.results.length) {
  66.         return Promise.resolve(result.results.length[0]);
  67.       }
  68.       return rest.update(this.config, masterAuth, '_User', query, updateFields);
  69.     });
  70.   }
  71.  
  72.   checkResetTokenValidity(username, token) {
  73.     return this.config.database.find('_User', {
  74.       username: username,
  75.       _perishable_token: token
  76.     }, {limit: 1}).then(results => {
  77.       if (results.length != 1) {
  78.         throw undefined;
  79.       }
  80.  
  81.       if (this.config.passwordPolicy && this.config.passwordPolicy.resetTokenValidityDuration) {
  82.         let expiresDate = results[0]._perishable_token_expires_at;
  83.         if (expiresDate && expiresDate.__type == 'Date') {
  84.           expiresDate = new Date(expiresDate.iso);
  85.         }
  86.         if (expiresDate < new Date())
  87.           throw 'The password reset link has expired';
  88.       }
  89.  
  90.       return results[0];
  91.     });
  92.   }
  93.  
  94.   getUserIfNeeded(user) {
  95.     if (user.username && user.email) {
  96.       return Promise.resolve(user);
  97.     }
  98.     var where = {};
  99.     if (user.username) {
  100.       where.username = user.username;
  101.     }
  102.     if (user.email) {
  103.       where.email = user.email;
  104.     }
  105.  
  106.     var query = new RestQuery(this.config, Auth.master(this.config), '_User', where);
  107.     return query.execute().then(function(result){
  108.       if (result.results.length != 1) {
  109.         throw undefined;
  110.       }
  111.       return result.results[0];
  112.     })
  113.   }
  114.  
  115.   sendVerificationEmail(user) {
  116.     if (!this.shouldVerifyEmails) {
  117.       return;
  118.     }
  119.     const token = encodeURIComponent(user._email_verify_token);
  120.     // We may need to fetch the user in case of update email
  121.     this.getUserIfNeeded(user).then((user) => {
  122.       const username = encodeURIComponent(user.username);
  123.  
  124.       const link = buildEmailLink(this.config.verifyEmailURL, username, token, this.config);
  125.       const options = {
  126.         appName: this.config.appName,
  127.         link: link,
  128.         user: inflate('_User', user),
  129.       };
  130.       if (this.adapter.sendVerificationEmail) {
  131.         this.adapter.sendVerificationEmail(options);
  132.       } else {
  133.         this.adapter.sendMail(this.defaultVerificationEmail(options));
  134.       }
  135.     });
  136.   }
  137.  
  138.   resendVerificationEmail(username) {
  139.     return this.getUserIfNeeded({username: username}).then((aUser) => {
  140.       if (!aUser || aUser.emailVerified) {
  141.         throw undefined;
  142.       }
  143.       this.setEmailVerifyToken(aUser);
  144.       return this.config.database.update('_User', {username}, aUser).then(() => {
  145.         this.sendVerificationEmail(aUser);
  146.       });
  147.     });
  148.   }
  149.  
  150.   setPasswordResetToken(email) {
  151.     const token = { _perishable_token: randomString(25) };
  152.  
  153.     if (this.config.passwordPolicy && this.config.passwordPolicy.resetTokenValidityDuration) {
  154.       token._perishable_token_expires_at = Parse._encode(this.config.generatePasswordResetTokenExpiresAt());
  155.     }
  156.  
  157.     return this.config.database.update('_User', { $or: [{email}, {username: email, email: {$exists: false}}] }, token, {}, true)
  158.   }
  159.  
  160.   sendPasswordResetEmail(email) {
  161.     if (!this.adapter) {
  162.       throw "Trying to send a reset password but no adapter is set";
  163.       //  TODO: No adapter?
  164.     }
  165.  
  166.     return this.setPasswordResetToken(email)
  167.     .then(user => {
  168.       const token = encodeURIComponent(user._perishable_token);
  169.       const username = encodeURIComponent(user.username);
  170.  
  171.       const link = buildEmailLink(this.config.requestResetPasswordURL, username, token, this.config);
  172.       const options = {
  173.         appName: this.config.appName,
  174.         link: link,
  175.         user: inflate('_User', user),
  176.       };
  177.  
  178.       if (this.adapter.sendPasswordResetEmail) {
  179.         this.adapter.sendPasswordResetEmail(options);
  180.       } else {
  181.         this.adapter.sendMail(this.defaultResetPasswordEmail(options));
  182.       }
  183.  
  184.       return Promise.resolve(user);
  185.     });
  186.   }
  187.  
  188.   updatePassword(username, token, password) {
  189.     return this.checkResetTokenValidity(username, token)
  190.       .then(user => updateUserPassword(user.objectId, password, this.config))
  191.       // clear reset password token
  192.       .then(() => this.config.database.update('_User', {username}, {
  193.         _perishable_token: {__op: 'Delete'},
  194.         _perishable_token_expires_at: {__op: 'Delete'}
  195.       })).catch((error) => {
  196.         if (error.message) {  // in case of Parse.Error, fail with the error message only
  197.           return Promise.reject(error.message);
  198.         } else {
  199.           return Promise.reject(error);
  200.         }
  201.       });
  202.   }
  203.  
  204.   defaultVerificationEmail({link, user, appName, }) {
  205.     const text = "Hi,\n\n" +
  206.         "You are being asked to confirm the e-mail address " + user.get("email") + " with " + appName + "\n\n" +
  207.         "" +
  208.         "Click here to confirm it:\n" + link;
  209.     const to = user.get("email");
  210.     const subject = 'Please verify your e-mail for ' + appName;
  211.     return { text, to, subject };
  212.   }
  213.  
  214.   defaultResetPasswordEmail({link, user, appName, }) {
  215.     const text = "Hi,\n\n" +
  216.         "You requested to reset your password for " + appName + ".\n\n" +
  217.         "" +
  218.         "Click here to reset it:\n" + link;
  219.     const to = user.get("email") || user.get('username');
  220.     const subject =  'Password Reset for ' + appName;
  221.     return { text, to, subject };
  222.   }
  223. }
  224.  
  225. // Mark this private
  226. function updateUserPassword(userId, password, config) {
  227.   return rest.update(config, Auth.master(config), '_User', { objectId: userId }, {
  228.     password: password
  229.   });
  230. }
  231.  
  232. function buildEmailLink(destination, username, token, config) {
  233.   const usernameAndToken = `token=${token}&username=${username}`
  234.  
  235.   if (config.parseFrameURL) {
  236.     const destinationWithoutHost = destination.replace(config.publicServerURL, '');
  237.  
  238.     return `${config.parseFrameURL}?link=${encodeURIComponent(destinationWithoutHost)}&${usernameAndToken}`;
  239.   } else {
  240.     return `${destination}?${usernameAndToken}`;
  241.   }
  242. }
  243.  
  244. export default UserController;
  245.  
downloadUserController.js Source code - Download parse-server Source code
Related Source Codes/Software:
react-boilerplate - 2017-06-07
webtorrent - Streaming torrent client for the web ... 2017-06-06
machine-learning-for-software-engineers - A complete daily plan for studying to become a mac... 2017-06-06
upterm - A terminal emulator for the 21st century. 2017-06-06
lottie-android - Render After Effects animations natively on Androi... 2017-06-07
AsyncDisplayKit - Smooth asynchronous user interfaces for iOS apps. ... 2017-06-07
ionicons - The premium icon font for Ionic ... 2017-06-07
storybook - 2017-06-07
prettier - Prettier is an opinionated JavaScript formatter. ... 2017-06-08
CRYENGINE - CRYENGINE is a powerful real-time game development... 2017-06-11
postal - 2017-06-11
reactide - Reactide is the first dedicated IDE for React web ... 2017-06-11
rkt - rkt is a pod-native container engine for Linux. It... 2017-06-11
uWebSockets - Tiny WebSockets https://for... 2017-06-11
realworld - TodoMVC for the RealWorld - Exemplary fullstack Me... 2017-06-11
goreplay - GoReplay is an open-source tool for capturing and ... 2017-06-10
pyenv - Simple Python version management 2017-06-10
redux-saga - An alternative side effect model for Redux apps ... 2017-06-10
angular-starter - 2017-06-10

 Back to top