"use strict"; var _Reflect$construct = require("@babel/runtime-corejs3/core-js-stable/reflect/construct"); var _Object$defineProperty2 = require("@babel/runtime-corejs3/core-js-stable/object/define-property"); var _interopRequireDefault = require("@babel/runtime-corejs3/helpers/interopRequireDefault"); _Object$defineProperty2(exports, "__esModule", { value: true }); exports.default = void 0; var _regenerator = _interopRequireDefault(require("@babel/runtime-corejs3/regenerator")); var _promise = _interopRequireDefault(require("@babel/runtime-corejs3/core-js-stable/promise")); var _defineProperty = _interopRequireDefault(require("@babel/runtime-corejs3/core-js-stable/object/define-property")); var _stringify = _interopRequireDefault(require("@babel/runtime-corejs3/core-js-stable/json/stringify")); var _asyncToGenerator2 = _interopRequireDefault(require("@babel/runtime-corejs3/helpers/asyncToGenerator")); var _typeof2 = _interopRequireDefault(require("@babel/runtime-corejs3/helpers/typeof")); var _classCallCheck2 = _interopRequireDefault(require("@babel/runtime-corejs3/helpers/classCallCheck")); var _createClass2 = _interopRequireDefault(require("@babel/runtime-corejs3/helpers/createClass")); var _get2 = _interopRequireDefault(require("@babel/runtime-corejs3/helpers/get")); var _inherits2 = _interopRequireDefault(require("@babel/runtime-corejs3/helpers/inherits")); var _possibleConstructorReturn2 = _interopRequireDefault(require("@babel/runtime-corejs3/helpers/possibleConstructorReturn")); var _getPrototypeOf2 = _interopRequireDefault(require("@babel/runtime-corejs3/helpers/getPrototypeOf")); var _CoreManager = _interopRequireDefault(require("./CoreManager")); var _isRevocableSession = _interopRequireDefault(require("./isRevocableSession")); var _ParseError = _interopRequireDefault(require("./ParseError")); var _ParseObject2 = _interopRequireDefault(require("./ParseObject")); var _ParseSession = _interopRequireDefault(require("./ParseSession")); var _Storage = _interopRequireDefault(require("./Storage")); function _createSuper(Derived) { var hasNativeReflectConstruct = _isNativeReflectConstruct(); return function () { var Super = (0, _getPrototypeOf2.default)(Derived), result; if (hasNativeReflectConstruct) { var NewTarget = (0, _getPrototypeOf2.default)(this).constructor; result = _Reflect$construct(Super, arguments, NewTarget); } else { result = Super.apply(this, arguments); } return (0, _possibleConstructorReturn2.default)(this, result); }; } function _isNativeReflectConstruct() { if (typeof Reflect === "undefined" || !_Reflect$construct) return false; if (_Reflect$construct.sham) return false; if (typeof Proxy === "function") return true; try { Boolean.prototype.valueOf.call(_Reflect$construct(Boolean, [], function () {})); return true; } catch (e) { return false; } } /** * @flow */ /*:: import type { AttributeMap } from './ObjectStateMutations';*/ /*:: import type { RequestOptions, FullOptions } from './RESTController';*/ /*:: export type AuthData = ?{ [key: string]: mixed };*/ var CURRENT_USER_KEY = 'currentUser'; var canUseCurrentUser = !_CoreManager.default.get('IS_NODE'); var currentUserCacheMatchesDisk = false; var currentUserCache = null; var authProviders = {}; /** *

A Parse.User object is a local representation of a user persisted to the * Parse cloud. This class is a subclass of a Parse.Object, and retains the * same functionality of a Parse.Object, but also extends it with various * user specific methods, like authentication, signing up, and validation of * uniqueness.

* * @alias Parse.User * @augments Parse.Object */ var ParseUser = /*#__PURE__*/function (_ParseObject) { (0, _inherits2.default)(ParseUser, _ParseObject); var _super = _createSuper(ParseUser); /** * @param {object} attributes The initial set of data to store in the user. */ function ParseUser(attributes /*: ?AttributeMap*/) { var _this; (0, _classCallCheck2.default)(this, ParseUser); _this = _super.call(this, '_User'); if (attributes && (0, _typeof2.default)(attributes) === 'object') { if (!_this.set(attributes || {})) { throw new Error("Can't create an invalid Parse User"); } } return _this; } /** * Request a revocable session token to replace the older style of token. * * @param {object} options * @returns {Promise} A promise that is resolved when the replacement * token has been fetched. */ (0, _createClass2.default)(ParseUser, [{ key: "_upgradeToRevocableSession", value: function (options /*: RequestOptions*/) /*: Promise*/{ options = options || {}; var upgradeOptions = {}; if (options.hasOwnProperty('useMasterKey')) { upgradeOptions.useMasterKey = options.useMasterKey; } var controller = _CoreManager.default.getUserController(); return controller.upgradeToRevocableSession(this, upgradeOptions); } /** * Parse allows you to link your users with {@link https://docs.parseplatform.org/parse-server/guide/#oauth-and-3rd-party-authentication 3rd party authentication}, enabling * your users to sign up or log into your application using their existing identities. * Since 2.9.0 * * @see {@link https://docs.parseplatform.org/js/guide/#linking-users Linking Users} * @param {string | AuthProvider} provider Name of auth provider or {@link https://parseplatform.org/Parse-SDK-JS/api/master/AuthProvider.html AuthProvider} * @param {object} options * * @param {object} saveOpts useMasterKey / sessionToken * @returns {Promise} A promise that is fulfilled with the user is linked */ }, { key: "linkWith", value: function (provider /*: any*/, options /*: { authData?: AuthData }*/) /*: Promise*/{ var _this2 = this; var saveOpts /*:: ?: FullOptions*/ = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {}; saveOpts.sessionToken = saveOpts.sessionToken || this.getSessionToken() || ''; var authType; if (typeof provider === 'string') { authType = provider; if (authProviders[provider]) { provider = authProviders[provider]; } else { var authProvider = { restoreAuthentication: function () { return true; }, getAuthType: function () { return authType; } }; authProviders[authProvider.getAuthType()] = authProvider; provider = authProvider; } } else { authType = provider.getAuthType(); } if (options && options.hasOwnProperty('authData')) { var authData = this.get('authData') || {}; if ((0, _typeof2.default)(authData) !== 'object') { throw new Error('Invalid type: authData field should be an object'); } authData[authType] = options.authData; var controller = _CoreManager.default.getUserController(); return controller.linkWith(this, authData, saveOpts); } else { return new _promise.default(function (resolve, reject) { provider.authenticate({ success: function (provider, result) { var opts = {}; opts.authData = result; _this2.linkWith(provider, opts, saveOpts).then(function () { resolve(_this2); }, function (error) { reject(error); }); }, error: function (provider, _error) { reject(_error); } }); }); } } /** * @param provider * @param options * @param saveOpts * @deprecated since 2.9.0 see {@link https://parseplatform.org/Parse-SDK-JS/api/master/Parse.User.html#linkWith linkWith} * @returns {Promise} */ }, { key: "_linkWith", value: function (provider /*: any*/, options /*: { authData?: AuthData }*/) /*: Promise*/{ var saveOpts /*:: ?: FullOptions*/ = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {}; return this.linkWith(provider, options, saveOpts); } /** * Synchronizes auth data for a provider (e.g. puts the access token in the * right place to be used by the Facebook SDK). * * @param provider */ }, { key: "_synchronizeAuthData", value: function (provider /*: string*/) { if (!this.isCurrent() || !provider) { return; } var authType; if (typeof provider === 'string') { authType = provider; provider = authProviders[authType]; } else { authType = provider.getAuthType(); } var authData = this.get('authData'); if (!provider || !authData || (0, _typeof2.default)(authData) !== 'object') { return; } var success = provider.restoreAuthentication(authData[authType]); if (!success) { this._unlinkFrom(provider); } } /** * Synchronizes authData for all providers. */ }, { key: "_synchronizeAllAuthData", value: function () { var authData = this.get('authData'); if ((0, _typeof2.default)(authData) !== 'object') { return; } for (var _key in authData) { this._synchronizeAuthData(_key); } } /** * Removes null values from authData (which exist temporarily for unlinking) */ }, { key: "_cleanupAuthData", value: function () { if (!this.isCurrent()) { return; } var authData = this.get('authData'); if ((0, _typeof2.default)(authData) !== 'object') { return; } for (var _key2 in authData) { if (!authData[_key2]) { delete authData[_key2]; } } } /** * Unlinks a user from a service. * * @param {string | AuthProvider} provider Name of auth provider or {@link https://parseplatform.org/Parse-SDK-JS/api/master/AuthProvider.html AuthProvider} * @param {object} options MasterKey / SessionToken * @returns {Promise} A promise that is fulfilled when the unlinking * finishes. */ }, { key: "_unlinkFrom", value: function (provider /*: any*/, options /*:: ?: FullOptions*/) /*: Promise*/{ var _this3 = this; return this.linkWith(provider, { authData: null }, options).then(function () { _this3._synchronizeAuthData(provider); return _promise.default.resolve(_this3); }); } /** * Checks whether a user is linked to a service. * * @param {object} provider service to link to * @returns {boolean} true if link was successful */ }, { key: "_isLinked", value: function (provider /*: any*/) /*: boolean*/{ var authType; if (typeof provider === 'string') { authType = provider; } else { authType = provider.getAuthType(); } var authData = this.get('authData') || {}; if ((0, _typeof2.default)(authData) !== 'object') { return false; } return !!authData[authType]; } /** * Deauthenticates all providers. */ }, { key: "_logOutWithAll", value: function () { var authData = this.get('authData'); if ((0, _typeof2.default)(authData) !== 'object') { return; } for (var _key3 in authData) { this._logOutWith(_key3); } } /** * Deauthenticates a single provider (e.g. removing access tokens from the * Facebook SDK). * * @param {object} provider service to logout of */ }, { key: "_logOutWith", value: function (provider /*: any*/) { if (!this.isCurrent()) { return; } if (typeof provider === 'string') { provider = authProviders[provider]; } if (provider && provider.deauthenticate) { provider.deauthenticate(); } } /** * Class instance method used to maintain specific keys when a fetch occurs. * Used to ensure that the session token is not lost. * * @returns {object} sessionToken */ }, { key: "_preserveFieldsOnFetch", value: function () /*: AttributeMap*/{ return { sessionToken: this.get('sessionToken') }; } /** * Returns true if current would return this user. * * @returns {boolean} true if user is cached on disk */ }, { key: "isCurrent", value: function () /*: boolean*/{ var current = ParseUser.current(); return !!current && current.id === this.id; } /** * Returns true if current would return this user. * * @returns {Promise} true if user is cached on disk */ }, { key: "isCurrentAsync", value: function () { var _isCurrentAsync = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee() { var current; return _regenerator.default.wrap(function (_context) { while (1) switch (_context.prev = _context.next) { case 0: _context.next = 2; return ParseUser.currentAsync(); case 2: current = _context.sent; return _context.abrupt("return", !!current && current.id === this.id); case 4: case "end": return _context.stop(); } }, _callee, this); })); function isCurrentAsync() { return _isCurrentAsync.apply(this, arguments); } return isCurrentAsync; }() /** * Returns get("username"). * * @returns {string} */ }, { key: "getUsername", value: function () /*: ?string*/{ var username = this.get('username'); if (username == null || typeof username === 'string') { return username; } return ''; } /** * Calls set("username", username, options) and returns the result. * * @param {string} username */ }, { key: "setUsername", value: function (username /*: string*/) { // Strip anonymity var authData = this.get('authData'); if (authData && (0, _typeof2.default)(authData) === 'object' && authData.hasOwnProperty('anonymous')) { // We need to set anonymous to null instead of deleting it in order to remove it from Parse. authData.anonymous = null; } this.set('username', username); } /** * Calls set("password", password, options) and returns the result. * * @param {string} password User's Password */ }, { key: "setPassword", value: function (password /*: string*/) { this.set('password', password); } /** * Returns get("email"). * * @returns {string} User's Email */ }, { key: "getEmail", value: function () /*: ?string*/{ var email = this.get('email'); if (email == null || typeof email === 'string') { return email; } return ''; } /** * Calls set("email", email) and returns the result. * * @param {string} email * @returns {boolean} */ }, { key: "setEmail", value: function (email /*: string*/) { return this.set('email', email); } /** * Returns the session token for this user, if the user has been logged in, * or if it is the result of a query with the master key. Otherwise, returns * undefined. * * @returns {string} the session token, or undefined */ }, { key: "getSessionToken", value: function () /*: ?string*/{ var token = this.get('sessionToken'); if (token == null || typeof token === 'string') { return token; } return ''; } /** * Checks whether this user is the current user and has been authenticated. * * @returns {boolean} whether this user is the current user and is logged in. */ }, { key: "authenticated", value: function () /*: boolean*/{ var current = ParseUser.current(); return !!this.get('sessionToken') && !!current && current.id === this.id; } /** * Signs up a new user. You should call this instead of save for * new Parse.Users. This will create a new Parse.User on the server, and * also persist the session on disk so that you can access the user using * current. * *

A username and password must be set before calling signUp.

* * @param {object} attrs Extra fields to set on the new user, or null. * @param {object} options * @returns {Promise} A promise that is fulfilled when the signup * finishes. */ }, { key: "signUp", value: function (attrs /*: AttributeMap*/, options /*:: ?: FullOptions*/) /*: Promise*/{ options = options || {}; var signupOptions = {}; if (options.hasOwnProperty('useMasterKey')) { signupOptions.useMasterKey = options.useMasterKey; } if (options.hasOwnProperty('installationId')) { signupOptions.installationId = options.installationId; } if (options.hasOwnProperty('context') && Object.prototype.toString.call(options.context) === '[object Object]') { signupOptions.context = options.context; } var controller = _CoreManager.default.getUserController(); return controller.signUp(this, attrs, signupOptions); } /** * Logs in a Parse.User. On success, this saves the session to disk, * so you can retrieve the currently logged in user using * current. * *

A username and password must be set before calling logIn.

* * @param {object} options * @returns {Promise} A promise that is fulfilled with the user when * the login is complete. */ }, { key: "logIn", value: function (options /*:: ?: FullOptions*/) /*: Promise*/{ options = options || {}; var loginOptions = { usePost: true }; if (options.hasOwnProperty('useMasterKey')) { loginOptions.useMasterKey = options.useMasterKey; } if (options.hasOwnProperty('installationId')) { loginOptions.installationId = options.installationId; } if (options.hasOwnProperty('usePost')) { loginOptions.usePost = options.usePost; } var controller = _CoreManager.default.getUserController(); return controller.logIn(this, loginOptions); } /** * Wrap the default save behavior with functionality to save to local * storage if this is current user. * * @param {...any} args * @returns {Promise} */ }, { key: "save", value: function () { var _save = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee2() { var _len, args, _key4, current, _args2 = arguments; return _regenerator.default.wrap(function (_context2) { while (1) switch (_context2.prev = _context2.next) { case 0: for (_len = _args2.length, args = new Array(_len), _key4 = 0; _key4 < _len; _key4++) { args[_key4] = _args2[_key4]; } _context2.next = 3; return (0, _get2.default)((0, _getPrototypeOf2.default)(ParseUser.prototype), "save", this).apply(this, args); case 3: _context2.next = 5; return this.isCurrentAsync(); case 5: current = _context2.sent; if (!current) { _context2.next = 8; break; } return _context2.abrupt("return", _CoreManager.default.getUserController().updateUserOnDisk(this)); case 8: return _context2.abrupt("return", this); case 9: case "end": return _context2.stop(); } }, _callee2, this); })); function save() { return _save.apply(this, arguments); } return save; }() /** * Wrap the default destroy behavior with functionality that logs out * the current user when it is destroyed * * @param {...any} args * @returns {Parse.User} */ }, { key: "destroy", value: function () { var _destroy = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee3() { var _len2, args, _key5, current, _args3 = arguments; return _regenerator.default.wrap(function (_context3) { while (1) switch (_context3.prev = _context3.next) { case 0: for (_len2 = _args3.length, args = new Array(_len2), _key5 = 0; _key5 < _len2; _key5++) { args[_key5] = _args3[_key5]; } _context3.next = 3; return (0, _get2.default)((0, _getPrototypeOf2.default)(ParseUser.prototype), "destroy", this).apply(this, args); case 3: _context3.next = 5; return this.isCurrentAsync(); case 5: current = _context3.sent; if (!current) { _context3.next = 8; break; } return _context3.abrupt("return", _CoreManager.default.getUserController().removeUserFromDisk()); case 8: return _context3.abrupt("return", this); case 9: case "end": return _context3.stop(); } }, _callee3, this); })); function destroy() { return _destroy.apply(this, arguments); } return destroy; }() /** * Wrap the default fetch behavior with functionality to save to local * storage if this is current user. * * @param {...any} args * @returns {Parse.User} */ }, { key: "fetch", value: function () { var _fetch = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee4() { var _len3, args, _key6, current, _args4 = arguments; return _regenerator.default.wrap(function (_context4) { while (1) switch (_context4.prev = _context4.next) { case 0: for (_len3 = _args4.length, args = new Array(_len3), _key6 = 0; _key6 < _len3; _key6++) { args[_key6] = _args4[_key6]; } _context4.next = 3; return (0, _get2.default)((0, _getPrototypeOf2.default)(ParseUser.prototype), "fetch", this).apply(this, args); case 3: _context4.next = 5; return this.isCurrentAsync(); case 5: current = _context4.sent; if (!current) { _context4.next = 8; break; } return _context4.abrupt("return", _CoreManager.default.getUserController().updateUserOnDisk(this)); case 8: return _context4.abrupt("return", this); case 9: case "end": return _context4.stop(); } }, _callee4, this); })); function fetch() { return _fetch.apply(this, arguments); } return fetch; }() /** * Wrap the default fetchWithInclude behavior with functionality to save to local * storage if this is current user. * * @param {...any} args * @returns {Parse.User} */ }, { key: "fetchWithInclude", value: function () { var _fetchWithInclude = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee5() { var _len4, args, _key7, current, _args5 = arguments; return _regenerator.default.wrap(function (_context5) { while (1) switch (_context5.prev = _context5.next) { case 0: for (_len4 = _args5.length, args = new Array(_len4), _key7 = 0; _key7 < _len4; _key7++) { args[_key7] = _args5[_key7]; } _context5.next = 3; return (0, _get2.default)((0, _getPrototypeOf2.default)(ParseUser.prototype), "fetchWithInclude", this).apply(this, args); case 3: _context5.next = 5; return this.isCurrentAsync(); case 5: current = _context5.sent; if (!current) { _context5.next = 8; break; } return _context5.abrupt("return", _CoreManager.default.getUserController().updateUserOnDisk(this)); case 8: return _context5.abrupt("return", this); case 9: case "end": return _context5.stop(); } }, _callee5, this); })); function fetchWithInclude() { return _fetchWithInclude.apply(this, arguments); } return fetchWithInclude; }() /** * Verify whether a given password is the password of the current user. * * @param {string} password A password to be verified * @param {object} options * @returns {Promise} A promise that is fulfilled with a user * when the password is correct. */ }, { key: "verifyPassword", value: function (password /*: string*/, options /*:: ?: RequestOptions*/) /*: Promise*/{ var username = this.getUsername() || ''; return ParseUser.verifyPassword(username, password, options); } }], [{ key: "readOnlyAttributes", value: function () { return ['sessionToken']; } /** * Adds functionality to the existing Parse.User class. * * @param {object} protoProps A set of properties to add to the prototype * @param {object} classProps A set of static properties to add to the class * @static * @returns {Parse.User} The newly extended Parse.User class */ }, { key: "extend", value: function (protoProps /*: { [prop: string]: any }*/, classProps /*: { [prop: string]: any }*/) { if (protoProps) { for (var _prop in protoProps) { if (_prop !== 'className') { (0, _defineProperty.default)(ParseUser.prototype, _prop, { value: protoProps[_prop], enumerable: false, writable: true, configurable: true }); } } } if (classProps) { for (var _prop2 in classProps) { if (_prop2 !== 'className') { (0, _defineProperty.default)(ParseUser, _prop2, { value: classProps[_prop2], enumerable: false, writable: true, configurable: true }); } } } return ParseUser; } /** * Retrieves the currently logged in ParseUser with a valid session, * either from memory or localStorage, if necessary. * * @static * @returns {Parse.Object} The currently logged in Parse.User. */ }, { key: "current", value: function () /*: ?ParseUser*/{ if (!canUseCurrentUser) { return null; } var controller = _CoreManager.default.getUserController(); return controller.currentUser(); } /** * Retrieves the currently logged in ParseUser from asynchronous Storage. * * @static * @returns {Promise} A Promise that is resolved with the currently * logged in Parse User */ }, { key: "currentAsync", value: function () /*: Promise*/{ if (!canUseCurrentUser) { return _promise.default.resolve(null); } var controller = _CoreManager.default.getUserController(); return controller.currentUserAsync(); } /** * Signs up a new user with a username (or email) and password. * This will create a new Parse.User on the server, and also persist the * session in localStorage so that you can access the user using * {@link #current}. * * @param {string} username The username (or email) to sign up with. * @param {string} password The password to sign up with. * @param {object} attrs Extra fields to set on the new user. * @param {object} options * @static * @returns {Promise} A promise that is fulfilled with the user when * the signup completes. */ }, { key: "signUp", value: function (username /*: string*/, password /*: string*/, attrs /*: AttributeMap*/, options /*:: ?: FullOptions*/) { attrs = attrs || {}; attrs.username = username; attrs.password = password; var user = new this(attrs); return user.signUp({}, options); } /** * Logs in a user with a username (or email) and password. On success, this * saves the session to disk, so you can retrieve the currently logged in * user using current. * * @param {string} username The username (or email) to log in with. * @param {string} password The password to log in with. * @param {object} options * @static * @returns {Promise} A promise that is fulfilled with the user when * the login completes. */ }, { key: "logIn", value: function (username /*: string*/, password /*: string*/, options /*:: ?: FullOptions*/) { if (typeof username !== 'string') { return _promise.default.reject(new _ParseError.default(_ParseError.default.OTHER_CAUSE, 'Username must be a string.')); } else if (typeof password !== 'string') { return _promise.default.reject(new _ParseError.default(_ParseError.default.OTHER_CAUSE, 'Password must be a string.')); } var user = new this(); user._finishFetch({ username: username, password: password }); return user.logIn(options); } /** * Logs in a user with an objectId. On success, this saves the session * to disk, so you can retrieve the currently logged in user using * current. * * @param {string} userId The objectId for the user. * @static * @returns {Promise} A promise that is fulfilled with the user when * the login completes. */ }, { key: "loginAs", value: function (userId /*: string*/) { if (!userId) { throw new _ParseError.default(_ParseError.default.USERNAME_MISSING, 'Cannot log in as user with an empty user id'); } var controller = _CoreManager.default.getUserController(); var user = new this(); return controller.loginAs(user, userId); } /** * Logs in a user with a session token. On success, this saves the session * to disk, so you can retrieve the currently logged in user using * current. * * @param {string} sessionToken The sessionToken to log in with. * @param {object} options * @static * @returns {Promise} A promise that is fulfilled with the user when * the login completes. */ }, { key: "become", value: function (sessionToken /*: string*/, options /*:: ?: RequestOptions*/) { if (!canUseCurrentUser) { throw new Error('It is not memory-safe to become a user in a server environment'); } options = options || {}; var becomeOptions /*: RequestOptions*/ = { sessionToken: sessionToken }; if (options.hasOwnProperty('useMasterKey')) { becomeOptions.useMasterKey = options.useMasterKey; } var controller = _CoreManager.default.getUserController(); var user = new this(); return controller.become(user, becomeOptions); } /** * Retrieves a user with a session token. * * @param {string} sessionToken The sessionToken to get user with. * @param {object} options * @static * @returns {Promise} A promise that is fulfilled with the user is fetched. */ }, { key: "me", value: function (sessionToken /*: string*/) { var options /*:: ?: RequestOptions*/ = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {}; var controller = _CoreManager.default.getUserController(); var meOptions /*: RequestOptions*/ = { sessionToken: sessionToken }; if (options.useMasterKey) { meOptions.useMasterKey = options.useMasterKey; } var user = new this(); return controller.me(user, meOptions); } /** * Logs in a user with a session token. On success, this saves the session * to disk, so you can retrieve the currently logged in user using * current. If there is no session token the user will not logged in. * * @param {object} userJSON The JSON map of the User's data * @static * @returns {Promise} A promise that is fulfilled with the user when * the login completes. */ }, { key: "hydrate", value: function (userJSON /*: AttributeMap*/) { var controller = _CoreManager.default.getUserController(); var user = new this(); return controller.hydrate(user, userJSON); } /** * Static version of {@link https://parseplatform.org/Parse-SDK-JS/api/master/Parse.User.html#linkWith linkWith} * * @param provider * @param options * @param saveOpts * @static * @returns {Promise} */ }, { key: "logInWith", value: function (provider /*: any*/, options /*: { authData?: AuthData }*/, saveOpts /*:: ?: FullOptions*/) /*: Promise*/{ var user = new this(); return user.linkWith(provider, options, saveOpts); } /** * Logs out the currently logged in user session. This will remove the * session from disk, log out of linked services, and future calls to * current will return null. * * @param {object} options * @static * @returns {Promise} A promise that is resolved when the session is * destroyed on the server. */ }, { key: "logOut", value: function () { var options /*: RequestOptions*/ = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {}; var controller = _CoreManager.default.getUserController(); return controller.logOut(options); } /** * Requests a password reset email to be sent to the specified email address * associated with the user account. This email allows the user to securely * reset their password on the Parse site. * * @param {string} email The email address associated with the user that * forgot their password. * @param {object} options * @static * @returns {Promise} */ }, { key: "requestPasswordReset", value: function (email /*: string*/, options /*:: ?: RequestOptions*/) { options = options || {}; var requestOptions = {}; if (options.hasOwnProperty('useMasterKey')) { requestOptions.useMasterKey = options.useMasterKey; } var controller = _CoreManager.default.getUserController(); return controller.requestPasswordReset(email, requestOptions); } /** * Request an email verification. * * @param {string} email The email address associated with the user that * needs to verify their email. * @param {object} options * @static * @returns {Promise} */ }, { key: "requestEmailVerification", value: function (email /*: string*/, options /*:: ?: RequestOptions*/) { options = options || {}; var requestOptions = {}; if (options.hasOwnProperty('useMasterKey')) { requestOptions.useMasterKey = options.useMasterKey; } var controller = _CoreManager.default.getUserController(); return controller.requestEmailVerification(email, requestOptions); } /** * Verify whether a given password is the password of the current user. * * @param {string} username A username to be used for identificaiton * @param {string} password A password to be verified * @param {object} options * @static * @returns {Promise} A promise that is fulfilled with a user * when the password is correct. */ }, { key: "verifyPassword", value: function (username /*: string*/, password /*: string*/, options /*:: ?: RequestOptions*/) { if (typeof username !== 'string') { return _promise.default.reject(new _ParseError.default(_ParseError.default.OTHER_CAUSE, 'Username must be a string.')); } if (typeof password !== 'string') { return _promise.default.reject(new _ParseError.default(_ParseError.default.OTHER_CAUSE, 'Password must be a string.')); } options = options || {}; var verificationOption = {}; if (options.hasOwnProperty('useMasterKey')) { verificationOption.useMasterKey = options.useMasterKey; } var controller = _CoreManager.default.getUserController(); return controller.verifyPassword(username, password, verificationOption); } /** * Allow someone to define a custom User class without className * being rewritten to _User. The default behavior is to rewrite * User to _User for legacy reasons. This allows developers to * override that behavior. * * @param {boolean} isAllowed Whether or not to allow custom User class * @static */ }, { key: "allowCustomUserClass", value: function (isAllowed /*: boolean*/) { _CoreManager.default.set('PERFORM_USER_REWRITE', !isAllowed); } /** * Allows a legacy application to start using revocable sessions. If the * current session token is not revocable, a request will be made for a new, * revocable session. * It is not necessary to call this method from cloud code unless you are * handling user signup or login from the server side. In a cloud code call, * this function will not attempt to upgrade the current token. * * @param {object} options * @static * @returns {Promise} A promise that is resolved when the process has * completed. If a replacement session token is requested, the promise * will be resolved after a new token has been fetched. */ }, { key: "enableRevocableSession", value: function (options /*:: ?: RequestOptions*/) { options = options || {}; _CoreManager.default.set('FORCE_REVOCABLE_SESSION', true); if (canUseCurrentUser) { var current = ParseUser.current(); if (current) { return current._upgradeToRevocableSession(options); } } return _promise.default.resolve(); } /** * Enables the use of become or the current user in a server * environment. These features are disabled by default, since they depend on * global objects that are not memory-safe for most servers. * * @static */ }, { key: "enableUnsafeCurrentUser", value: function () { canUseCurrentUser = true; } /** * Disables the use of become or the current user in any environment. * These features are disabled on servers by default, since they depend on * global objects that are not memory-safe for most servers. * * @static */ }, { key: "disableUnsafeCurrentUser", value: function () { canUseCurrentUser = false; } /** * When registering users with {@link https://parseplatform.org/Parse-SDK-JS/api/master/Parse.User.html#linkWith linkWith} a basic auth provider * is automatically created for you. * * For advanced authentication, you can register an Auth provider to * implement custom authentication, deauthentication. * * @param provider * @see {@link https://parseplatform.org/Parse-SDK-JS/api/master/AuthProvider.html AuthProvider} * @see {@link https://docs.parseplatform.org/js/guide/#custom-authentication-module Custom Authentication Module} * @static */ }, { key: "_registerAuthenticationProvider", value: function (provider /*: any*/) { authProviders[provider.getAuthType()] = provider; // Synchronize the current user with the auth provider. ParseUser.currentAsync().then(function (current) { if (current) { current._synchronizeAuthData(provider.getAuthType()); } }); } /** * @param provider * @param options * @param saveOpts * @deprecated since 2.9.0 see {@link https://parseplatform.org/Parse-SDK-JS/api/master/Parse.User.html#logInWith logInWith} * @static * @returns {Promise} */ }, { key: "_logInWith", value: function (provider /*: any*/, options /*: { authData?: AuthData }*/, saveOpts /*:: ?: FullOptions*/) { var user = new this(); return user.linkWith(provider, options, saveOpts); } }, { key: "_clearCache", value: function () { currentUserCache = null; currentUserCacheMatchesDisk = false; } }, { key: "_setCurrentUserCache", value: function (user /*: ParseUser*/) { currentUserCache = user; } }]); return ParseUser; }(_ParseObject2.default); _ParseObject2.default.registerSubclass('_User', ParseUser); var DefaultController = { updateUserOnDisk: function (user) { var path = _Storage.default.generatePath(CURRENT_USER_KEY); var json = user.toJSON(); delete json.password; json.className = '_User'; var userData = (0, _stringify.default)(json); if (_CoreManager.default.get('ENCRYPTED_USER')) { var crypto = _CoreManager.default.getCryptoController(); userData = crypto.encrypt(json, _CoreManager.default.get('ENCRYPTED_KEY')); } return _Storage.default.setItemAsync(path, userData).then(function () { return user; }); }, removeUserFromDisk: function () { var path = _Storage.default.generatePath(CURRENT_USER_KEY); currentUserCacheMatchesDisk = true; currentUserCache = null; return _Storage.default.removeItemAsync(path); }, setCurrentUser: function (user) { currentUserCache = user; user._cleanupAuthData(); user._synchronizeAllAuthData(); return DefaultController.updateUserOnDisk(user); }, currentUser: function () /*: ?ParseUser*/{ if (currentUserCache) { return currentUserCache; } if (currentUserCacheMatchesDisk) { return null; } if (_Storage.default.async()) { throw new Error('Cannot call currentUser() when using a platform with an async ' + 'storage system. Call currentUserAsync() instead.'); } var path = _Storage.default.generatePath(CURRENT_USER_KEY); var userData = _Storage.default.getItem(path); currentUserCacheMatchesDisk = true; if (!userData) { currentUserCache = null; return null; } if (_CoreManager.default.get('ENCRYPTED_USER')) { var crypto = _CoreManager.default.getCryptoController(); userData = crypto.decrypt(userData, _CoreManager.default.get('ENCRYPTED_KEY')); } userData = JSON.parse(userData); if (!userData.className) { userData.className = '_User'; } if (userData._id) { if (userData.objectId !== userData._id) { userData.objectId = userData._id; } delete userData._id; } if (userData._sessionToken) { userData.sessionToken = userData._sessionToken; delete userData._sessionToken; } var current = _ParseObject2.default.fromJSON(userData); currentUserCache = current; current._synchronizeAllAuthData(); return current; }, currentUserAsync: function () /*: Promise*/{ if (currentUserCache) { return _promise.default.resolve(currentUserCache); } if (currentUserCacheMatchesDisk) { return _promise.default.resolve(null); } var path = _Storage.default.generatePath(CURRENT_USER_KEY); return _Storage.default.getItemAsync(path).then(function (userData) { currentUserCacheMatchesDisk = true; if (!userData) { currentUserCache = null; return _promise.default.resolve(null); } if (_CoreManager.default.get('ENCRYPTED_USER')) { var crypto = _CoreManager.default.getCryptoController(); userData = crypto.decrypt(userData.toString(), _CoreManager.default.get('ENCRYPTED_KEY')); } userData = JSON.parse(userData); if (!userData.className) { userData.className = '_User'; } if (userData._id) { if (userData.objectId !== userData._id) { userData.objectId = userData._id; } delete userData._id; } if (userData._sessionToken) { userData.sessionToken = userData._sessionToken; delete userData._sessionToken; } var current = _ParseObject2.default.fromJSON(userData); currentUserCache = current; current._synchronizeAllAuthData(); return _promise.default.resolve(current); }); }, signUp: function (user /*: ParseUser*/, attrs /*: AttributeMap*/, options /*: RequestOptions*/) /*: Promise*/{ var username = attrs && attrs.username || user.get('username'); var password = attrs && attrs.password || user.get('password'); if (!username || !username.length) { return _promise.default.reject(new _ParseError.default(_ParseError.default.OTHER_CAUSE, 'Cannot sign up user with an empty username.')); } if (!password || !password.length) { return _promise.default.reject(new _ParseError.default(_ParseError.default.OTHER_CAUSE, 'Cannot sign up user with an empty password.')); } return user.save(attrs, options).then(function () { // Clear the password field user._finishFetch({ password: undefined }); if (canUseCurrentUser) { return DefaultController.setCurrentUser(user); } return user; }); }, logIn: function (user /*: ParseUser*/, options /*: RequestOptions*/) /*: Promise*/{ var RESTController = _CoreManager.default.getRESTController(); var stateController = _CoreManager.default.getObjectStateController(); var auth = { username: user.get('username'), password: user.get('password') }; return RESTController.request(options.usePost ? 'POST' : 'GET', 'login', auth, options).then(function (response) { user._migrateId(response.objectId); user._setExisted(true); stateController.setPendingOp(user._getStateIdentifier(), 'username', undefined); stateController.setPendingOp(user._getStateIdentifier(), 'password', undefined); response.password = undefined; user._finishFetch(response); if (!canUseCurrentUser) { // We can't set the current user, so just return the one we logged in return _promise.default.resolve(user); } return DefaultController.setCurrentUser(user); }); }, loginAs: function (user /*: ParseUser*/, userId /*: string*/) /*: Promise*/{ var RESTController = _CoreManager.default.getRESTController(); return RESTController.request('POST', 'loginAs', { userId: userId }, { useMasterKey: true }).then(function (response) { user._finishFetch(response); user._setExisted(true); if (!canUseCurrentUser) { return _promise.default.resolve(user); } return DefaultController.setCurrentUser(user); }); }, become: function (user /*: ParseUser*/, options /*: RequestOptions*/) /*: Promise*/{ var RESTController = _CoreManager.default.getRESTController(); return RESTController.request('GET', 'users/me', {}, options).then(function (response) { user._finishFetch(response); user._setExisted(true); return DefaultController.setCurrentUser(user); }); }, hydrate: function (user /*: ParseUser*/, userJSON /*: AttributeMap*/) /*: Promise*/{ user._finishFetch(userJSON); user._setExisted(true); if (userJSON.sessionToken && canUseCurrentUser) { return DefaultController.setCurrentUser(user); } else { return _promise.default.resolve(user); } }, me: function (user /*: ParseUser*/, options /*: RequestOptions*/) /*: Promise*/{ var RESTController = _CoreManager.default.getRESTController(); return RESTController.request('GET', 'users/me', {}, options).then(function (response) { user._finishFetch(response); user._setExisted(true); return user; }); }, logOut: function (options /*: RequestOptions*/) /*: Promise*/{ var RESTController = _CoreManager.default.getRESTController(); if (options.sessionToken) { return RESTController.request('POST', 'logout', {}, options); } return DefaultController.currentUserAsync().then(function (currentUser) { var path = _Storage.default.generatePath(CURRENT_USER_KEY); var promise = _Storage.default.removeItemAsync(path); if (currentUser !== null) { var currentSession = currentUser.getSessionToken(); if (currentSession && (0, _isRevocableSession.default)(currentSession)) { promise = promise.then(function () { return RESTController.request('POST', 'logout', {}, { sessionToken: currentSession }); }); } currentUser._logOutWithAll(); currentUser._finishFetch({ sessionToken: undefined }); } currentUserCacheMatchesDisk = true; currentUserCache = null; return promise; }); }, requestPasswordReset: function (email /*: string*/, options /*: RequestOptions*/) { var RESTController = _CoreManager.default.getRESTController(); return RESTController.request('POST', 'requestPasswordReset', { email: email }, options); }, upgradeToRevocableSession: function (user /*: ParseUser*/, options /*: RequestOptions*/) { return (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee6() { var token, RESTController, result, session, current; return _regenerator.default.wrap(function (_context6) { while (1) switch (_context6.prev = _context6.next) { case 0: token = user.getSessionToken(); if (token) { _context6.next = 3; break; } return _context6.abrupt("return", _promise.default.reject(new _ParseError.default(_ParseError.default.SESSION_MISSING, 'Cannot upgrade a user with no session token'))); case 3: options.sessionToken = token; RESTController = _CoreManager.default.getRESTController(); _context6.next = 7; return RESTController.request('POST', 'upgradeToRevocableSession', {}, options); case 7: result = _context6.sent; session = new _ParseSession.default(); session._finishFetch(result); user._finishFetch({ sessionToken: session.getSessionToken() }); _context6.next = 13; return user.isCurrentAsync(); case 13: current = _context6.sent; if (!current) { _context6.next = 16; break; } return _context6.abrupt("return", DefaultController.setCurrentUser(user)); case 16: return _context6.abrupt("return", _promise.default.resolve(user)); case 17: case "end": return _context6.stop(); } }, _callee6); }))(); }, linkWith: function (user /*: ParseUser*/, authData /*: AuthData*/, options /*: FullOptions*/) { return user.save({ authData: authData }, options).then(function () { if (canUseCurrentUser) { return DefaultController.setCurrentUser(user); } return user; }); }, verifyPassword: function (username /*: string*/, password /*: string*/, options /*: RequestOptions*/) { var RESTController = _CoreManager.default.getRESTController(); return RESTController.request('GET', 'verifyPassword', { username: username, password: password }, options); }, requestEmailVerification: function (email /*: string*/, options /*: RequestOptions*/) { var RESTController = _CoreManager.default.getRESTController(); return RESTController.request('POST', 'verificationEmailRequest', { email: email }, options); } }; _CoreManager.default.setUserController(DefaultController); var _default = ParseUser; exports.default = _default;