123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364 |
- "use strict";
- Object.defineProperty(exports, "__esModule", {
- value: true
- });
- exports.default = exports.UserController = void 0;
- var _cryptoUtils = require("../cryptoUtils");
- var _triggers = require("../triggers");
- var _AdaptableController = _interopRequireDefault(require("./AdaptableController"));
- var _MailAdapter = _interopRequireDefault(require("../Adapters/Email/MailAdapter"));
- var _rest = _interopRequireDefault(require("../rest"));
- var _node = _interopRequireDefault(require("parse/node"));
- var _AccountLockout = _interopRequireDefault(require("../AccountLockout"));
- var _Config = _interopRequireDefault(require("../Config"));
- function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }
- function ownKeys(e, r) { var t = Object.keys(e); if (Object.getOwnPropertySymbols) { var o = Object.getOwnPropertySymbols(e); r && (o = o.filter(function (r) { return Object.getOwnPropertyDescriptor(e, r).enumerable; })), t.push.apply(t, o); } return t; }
- function _objectSpread(e) { for (var r = 1; r < arguments.length; r++) { var t = null != arguments[r] ? arguments[r] : {}; r % 2 ? ownKeys(Object(t), !0).forEach(function (r) { _defineProperty(e, r, t[r]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(e, Object.getOwnPropertyDescriptors(t)) : ownKeys(Object(t)).forEach(function (r) { Object.defineProperty(e, r, Object.getOwnPropertyDescriptor(t, r)); }); } return e; }
- function _defineProperty(e, r, t) { return (r = _toPropertyKey(r)) in e ? Object.defineProperty(e, r, { value: t, enumerable: !0, configurable: !0, writable: !0 }) : e[r] = t, e; }
- function _toPropertyKey(t) { var i = _toPrimitive(t, "string"); return "symbol" == typeof i ? i : i + ""; }
- function _toPrimitive(t, r) { if ("object" != typeof t || !t) return t; var e = t[Symbol.toPrimitive]; if (void 0 !== e) { var i = e.call(t, r || "default"); if ("object" != typeof i) return i; throw new TypeError("@@toPrimitive must return a primitive value."); } return ("string" === r ? String : Number)(t); }
- var RestQuery = require('../RestQuery');
- var Auth = require('../Auth');
- class UserController extends _AdaptableController.default {
- constructor(adapter, appId, options = {}) {
- super(adapter, appId, options);
- }
- get config() {
- return _Config.default.get(this.appId);
- }
- validateAdapter(adapter) {
-
- if (!adapter && !this.shouldVerifyEmails) {
- return;
- }
- super.validateAdapter(adapter);
- }
- expectedAdapterType() {
- return _MailAdapter.default;
- }
- get shouldVerifyEmails() {
- return (this.config || this.options).verifyUserEmails;
- }
- async setEmailVerifyToken(user, req, storage = {}) {
- const shouldSendEmail = this.shouldVerifyEmails === true || typeof this.shouldVerifyEmails === 'function' && (await Promise.resolve(this.shouldVerifyEmails(req))) === true;
- if (!shouldSendEmail) {
- return false;
- }
- storage.sendVerificationEmail = true;
- user._email_verify_token = (0, _cryptoUtils.randomString)(25);
- if (!storage.fieldsChangedByTrigger || !storage.fieldsChangedByTrigger.includes('emailVerified')) {
- user.emailVerified = false;
- }
- if (this.config.emailVerifyTokenValidityDuration) {
- user._email_verify_token_expires_at = _node.default._encode(this.config.generateEmailVerifyTokenExpiresAt());
- }
- return true;
- }
- async verifyEmail(username, token) {
- if (!this.shouldVerifyEmails) {
-
-
- throw undefined;
- }
- const query = {
- username: username,
- _email_verify_token: token
- };
- const updateFields = {
- emailVerified: true,
- _email_verify_token: {
- __op: 'Delete'
- }
- };
-
-
- if (this.config.emailVerifyTokenValidityDuration) {
- query.emailVerified = false;
- query._email_verify_token_expires_at = {
- $gt: _node.default._encode(new Date())
- };
- updateFields._email_verify_token_expires_at = {
- __op: 'Delete'
- };
- }
- const maintenanceAuth = Auth.maintenance(this.config);
- var findUserForEmailVerification = await RestQuery({
- method: RestQuery.Method.get,
- config: this.config,
- auth: maintenanceAuth,
- className: '_User',
- restWhere: {
- username
- }
- });
- return findUserForEmailVerification.execute().then(result => {
- if (result.results.length && result.results[0].emailVerified) {
- return Promise.resolve(result.results.length[0]);
- } else if (result.results.length) {
- query.objectId = result.results[0].objectId;
- }
- return _rest.default.update(this.config, maintenanceAuth, '_User', query, updateFields);
- });
- }
- checkResetTokenValidity(username, token) {
- return this.config.database.find('_User', {
- username: username,
- _perishable_token: token
- }, {
- limit: 1
- }, Auth.maintenance(this.config)).then(results => {
- if (results.length != 1) {
- throw 'Failed to reset password: username / email / token is invalid';
- }
- if (this.config.passwordPolicy && this.config.passwordPolicy.resetTokenValidityDuration) {
- let expiresDate = results[0]._perishable_token_expires_at;
- if (expiresDate && expiresDate.__type == 'Date') {
- expiresDate = new Date(expiresDate.iso);
- }
- if (expiresDate < new Date()) throw 'The password reset link has expired';
- }
- return results[0];
- });
- }
- async getUserIfNeeded(user) {
- var where = {};
- if (user.username) {
- where.username = user.username;
- }
- if (user.email) {
- where.email = user.email;
- }
- var query = await RestQuery({
- method: RestQuery.Method.get,
- config: this.config,
- runBeforeFind: false,
- auth: Auth.master(this.config),
- className: '_User',
- restWhere: where
- });
- const result = await query.execute();
- if (result.results.length != 1) {
- throw undefined;
- }
- return result.results[0];
- }
- async sendVerificationEmail(user, req) {
- if (!this.shouldVerifyEmails) {
- return;
- }
- const token = encodeURIComponent(user._email_verify_token);
-
-
- const fetchedUser = await this.getUserIfNeeded(user);
- let shouldSendEmail = this.config.sendUserEmailVerification;
- if (typeof shouldSendEmail === 'function') {
- var _req$auth;
- const response = await Promise.resolve(this.config.sendUserEmailVerification({
- user: _node.default.Object.fromJSON(_objectSpread({
- className: '_User'
- }, fetchedUser)),
- master: (_req$auth = req.auth) === null || _req$auth === void 0 ? void 0 : _req$auth.isMaster
- }));
- shouldSendEmail = !!response;
- }
- if (!shouldSendEmail) {
- return;
- }
- const username = encodeURIComponent(fetchedUser.username);
- const link = buildEmailLink(this.config.verifyEmailURL, username, token, this.config);
- const options = {
- appName: this.config.appName,
- link: link,
- user: (0, _triggers.inflate)('_User', fetchedUser)
- };
- if (this.adapter.sendVerificationEmail) {
- this.adapter.sendVerificationEmail(options);
- } else {
- this.adapter.sendMail(this.defaultVerificationEmail(options));
- }
- }
-
- async regenerateEmailVerifyToken(user, master, installationId, ip) {
- const {
- _email_verify_token
- } = user;
- let {
- _email_verify_token_expires_at
- } = user;
- if (_email_verify_token_expires_at && _email_verify_token_expires_at.__type === 'Date') {
- _email_verify_token_expires_at = _email_verify_token_expires_at.iso;
- }
- if (this.config.emailVerifyTokenReuseIfValid && this.config.emailVerifyTokenValidityDuration && _email_verify_token && new Date() < new Date(_email_verify_token_expires_at)) {
- return Promise.resolve(true);
- }
- const shouldSend = await this.setEmailVerifyToken(user, {
- object: _node.default.User.fromJSON(Object.assign({
- className: '_User'
- }, user)),
- master,
- installationId,
- ip,
- resendRequest: true
- });
- if (!shouldSend) {
- return;
- }
- return this.config.database.update('_User', {
- username: user.username
- }, user);
- }
- async resendVerificationEmail(username, req) {
- var _req$auth2, _req$auth3;
- const aUser = await this.getUserIfNeeded({
- username: username
- });
- if (!aUser || aUser.emailVerified) {
- throw undefined;
- }
- const generate = await this.regenerateEmailVerifyToken(aUser, (_req$auth2 = req.auth) === null || _req$auth2 === void 0 ? void 0 : _req$auth2.isMaster, (_req$auth3 = req.auth) === null || _req$auth3 === void 0 ? void 0 : _req$auth3.installationId, req.ip);
- if (generate) {
- this.sendVerificationEmail(aUser, req);
- }
- }
- setPasswordResetToken(email) {
- const token = {
- _perishable_token: (0, _cryptoUtils.randomString)(25)
- };
- if (this.config.passwordPolicy && this.config.passwordPolicy.resetTokenValidityDuration) {
- token._perishable_token_expires_at = _node.default._encode(this.config.generatePasswordResetTokenExpiresAt());
- }
- return this.config.database.update('_User', {
- $or: [{
- email
- }, {
- username: email,
- email: {
- $exists: false
- }
- }]
- }, token, {}, true);
- }
- async sendPasswordResetEmail(email) {
- if (!this.adapter) {
- throw 'Trying to send a reset password but no adapter is set';
-
- }
- let user;
- if (this.config.passwordPolicy && this.config.passwordPolicy.resetTokenReuseIfValid && this.config.passwordPolicy.resetTokenValidityDuration) {
- const results = await this.config.database.find('_User', {
- $or: [{
- email,
- _perishable_token: {
- $exists: true
- }
- }, {
- username: email,
- email: {
- $exists: false
- },
- _perishable_token: {
- $exists: true
- }
- }]
- }, {
- limit: 1
- }, Auth.maintenance(this.config));
- if (results.length == 1) {
- let expiresDate = results[0]._perishable_token_expires_at;
- if (expiresDate && expiresDate.__type == 'Date') {
- expiresDate = new Date(expiresDate.iso);
- }
- if (expiresDate > new Date()) {
- user = results[0];
- }
- }
- }
- if (!user || !user._perishable_token) {
- user = await this.setPasswordResetToken(email);
- }
- const token = encodeURIComponent(user._perishable_token);
- const username = encodeURIComponent(user.username);
- const link = buildEmailLink(this.config.requestResetPasswordURL, username, token, this.config);
- const options = {
- appName: this.config.appName,
- link: link,
- user: (0, _triggers.inflate)('_User', user)
- };
- if (this.adapter.sendPasswordResetEmail) {
- this.adapter.sendPasswordResetEmail(options);
- } else {
- this.adapter.sendMail(this.defaultResetPasswordEmail(options));
- }
- return Promise.resolve(user);
- }
- updatePassword(username, token, password) {
- return this.checkResetTokenValidity(username, token).then(user => updateUserPassword(user, password, this.config)).then(user => {
- const accountLockoutPolicy = new _AccountLockout.default(user, this.config);
- return accountLockoutPolicy.unlockAccount();
- }).catch(error => {
- if (error && error.message) {
-
- return Promise.reject(error.message);
- } else {
- return Promise.reject(error);
- }
- });
- }
- defaultVerificationEmail({
- link,
- user,
- appName
- }) {
- const text = 'Hi,\n\n' + 'You are being asked to confirm the e-mail address ' + user.get('email') + ' with ' + appName + '\n\n' + '' + 'Click here to confirm it:\n' + link;
- const to = user.get('email');
- const subject = 'Please verify your e-mail for ' + appName;
- return {
- text,
- to,
- subject
- };
- }
- defaultResetPasswordEmail({
- link,
- user,
- appName
- }) {
- const text = 'Hi,\n\n' + 'You requested to reset your password for ' + appName + (user.get('username') ? " (your username is '" + user.get('username') + "')" : '') + '.\n\n' + '' + 'Click here to reset it:\n' + link;
- const to = user.get('email') || user.get('username');
- const subject = 'Password Reset for ' + appName;
- return {
- text,
- to,
- subject
- };
- }
- }
- exports.UserController = UserController;
- function updateUserPassword(user, password, config) {
- return _rest.default.update(config, Auth.master(config), '_User', {
- objectId: user.objectId
- }, {
- password: password
- }).then(() => user);
- }
- function buildEmailLink(destination, username, token, config) {
- const usernameAndToken = `token=${token}&username=${username}`;
- if (config.parseFrameURL) {
- const destinationWithoutHost = destination.replace(config.publicServerURL, '');
- return `${config.parseFrameURL}?link=${encodeURIComponent(destinationWithoutHost)}&${usernameAndToken}`;
- } else {
- return `${destination}?${usernameAndToken}`;
- }
- }
- var _default = exports.default = UserController;
|