// Copyright 2019 Campbell Crowley. All rights reserved. // Author: Campbell Crowley (dev@campbellcrowley.com) /** * @classdesc The user data injected to be sent along with all user request to * the web API. * @class */ class WebUserData { /** * @description Create an instance of the user metadata. * @param {string} id User ID of user performing request. * @param {string} ip IP of current request client. */ constructor(id, ip) { /** * @description The user's ID. * * @see {WebUserData~id} * * @private * @type {string} * @constant */ this._id = id; /** * @description IP address of requesting client. Used for logging and rate * limiting. * * @see {WebUserData~ip} * * @private * @type {string} * @constant */ this._ip = ip; /** * @description Array of guild IDs this user is a part of. This will only be * available if request was made using the user's token with 'guilds' as a * scope, and thus may not exist in all requests.* It may be used to improve * efficiency, to prevent looking up all guilds with the user performing the * request. * * @see {WebUserData~guilds} * * @private * @type {null|string[]} * @default */ this._guilds = null; /** * @description Is this user data, and this request, from the public API. If * false, there are fewer restrictions because this request is from a * private filtered internal source. * * @private * @type {boolean} * @default */ this.apiRequest = false; /** * @description Session ID for the user request. Null if request was not * made as a session. * @private * @type {?string} * @default */ this._sessionId = null; /** * @description Session expiration timestamp for the user request. * @private * @type {?number} * @default */ this._sessionExpirationDate = null; /** * @description Legacy session data. * @private * @type {object} * @deprecated * @default */ this._session = { id: this.sessionId, expiration_date: this.sessionExpirationDate, }; /** * @description User's username. * * {@link * https://discordapp.com/developers/docs/resources/user#user-object}. * * @public * @type {?string} * @default */ this.username = null; /** * @description User's account discriminator. * * {@link * https://discordapp.com/developers/docs/resources/user#user-object}. * * @public * @type {?string} * @default */ this.discriminator = null; /** * @description User's avatar hash. * * {@link * https://discordapp.com/developers/docs/resources/user#user-object}. * * @public * @type {?string} * @default */ this.avatar = null; /** * @description Is this user a bot. * * {@link * https://discordapp.com/developers/docs/resources/user#user-object}. * * @public * @type {?boolean} * @default */ this.bot = null; /** * @description Is two factor authentication enabled on this user's account. * * {@link * https://discordapp.com/developers/docs/resources/user#user-object}. * * @public * @type {?boolean} * @default */ this.mfaEnabled = null; /** * @description The user's chosen language option. * * {@link * https://discordapp.com/developers/docs/resources/user#user-object}. * * @public * @type {?string} * @default */ this.locale = null; /** * @description Discord user flags. * * {@link * https://discordapp.com/developers/docs/resources/user#user-object}. * * @public * @type {?number} * @default */ this.flags = null; /** * @description User's Nitro status. * * {@link * https://discordapp.com/developers/docs/resources/user#user-object}. * * @public * @type {?number} * @default */ this.premiumType = null; } /** * @description Getter for user ID. * @see {@link WebUserData~_id} * @public * @returns {string} User's ID. */ get id() { return this._id; } /** * @description Getter for client IP address. * @see {@link WebUserData~_ip} * @public * @returns {string} Client's IP. */ get ip() { return this._ip; } /** * @description Getter for guild list. * @see {@link WebUserData~_guilds} * @public * @returns {null|string[]} Guild ID list. */ get guilds() { return this._guilds; } /** * @description Getter for session ID. * @see {@link WebUserData~_sessionId} * @public * @returns {?string} Session ID if it exists. */ get sessionId() { return this._sessionId; } /** * @description Setter for session ID and expiration date. * @see {@link WebUserData~_sessionId} * @see {@link WebUserData~_sessionExpirationDate} * @param {?string} sId Session ID or null to unset. * @param {?number|Date|string} date Date or timestamp, or null to unset. */ setSession(sId, date) { this.setSessionId(sId); this.setSessionExpirationDate(date); } /** * @description Setter for session ID. * @see {@link WebUserData~_sessionId} * @param {?string} sId Session ID or null to unset. */ setSessionId(sId) { this._sessionId = sId; this._session.id = sId; } /** * @description Getter for session expiration timestamp. * @see {@link WebUserData~_sessionExpirationDate} * @public * @returns {?number} Session expiration timestamp if it exists. */ get sessionExpirationDate() { return this._sessionExpirationDate; } /** * @description Setter for session expiration timestamp. * @see {@link WebUserData~_sessionExpirationDate} * @param {?number|Date|string} sED Date or timestamp, or null to unset. */ setSessionExpirationDate(sED) { if (sED === null) { this._sessionExpirationDate = null; } else { this._sessionExpirationDate = new Date(sED).getTime(); } this._session.expiration_date = this._sessionExpirationDate; } /** * @description Set the list of guilds for this user. * @see {@link https://discordapp.com/developers/docs/resources/user#get-current-user-guilds} * @public * @param {object[]} guilds Array of guild data for this user. */ setGuilds(guilds) { if (!Array.isArray(guilds) || typeof guilds[0] !== 'object') { throw new TypeError('Guild data is not array of guild data.'); } this._guilds = guilds; } /** * @description Get a serializable version of this class instance. Behaves * differently than HG serializable getters in that private variables are * converted to public instead of being removed. Assumes all variables are * serializable if they aren't a function. * @public * @returns {object} Serializable version of this instance. */ get serializable() { const all = Object.entries(Object.getOwnPropertyDescriptors(this)); const output = {}; for (const one of all) { const name = one[0].replace(/^_/, ''); if (typeof one[1].value === 'function') { continue; } else if (one[1].value && one[1].value.serializable) { output[name] = one[1].value.serializable; } else { output[name] = one[1].value; } } return output; } /** * @description Create this object from a Discord User Object response data. * @public * @static * @param {object} obj Object data from Discord. * @returns {WebUserData} Created object. */ static from(obj) { const out = new WebUserData(obj.id); out.username = obj.username || null; out.discriminator = obj.discriminator || null; out.avatar = obj.avatar || null; out.bot = typeof obj.bot === 'boolean' ? obj.bot : null; out.mfaEnabled = typeof obj.mfa_enabled === 'boolean' ? obj.mfa_enabled : (typeof obj.mfaEnabled === 'boolean' ? obj.mfaEnabled : null); out.locale = obj.locale || null; out.flags = typeof obj.flags === 'number' ? obj.flags : null; out.premiumType = typeof obj.premium_type === 'number' ? obj.premium_type : (typeof obj.premiumType === 'number' ? obj.premiumType : null); return out; } } module.exports = WebUserData;