import Identity from './models/communities/Identity';
import ConflictUser from './models/communities/ConflictUser';
import UserUpdate from './models/UserUpdate';
import BanInfo from './models/BanInfo';
import SDK from './sdk';
import { Storage } from './storage';
import "./thrift/exceptions_types";
import { isAValidImage, uploadFile } from './utils';
export default class CurrentUser {
/**
* Creates a new CurrentUser instance from the provider parameters.
*
* @constructor CurrentUser
* @param {Object} userMap - Public User parameters
* @param {string} userMap.id - User ID
* @param {string} userMap.displayName - User Display name
* @param {string} [userMap.avatarUrl] - User Avatar URL
* @param {Object[]} [userMap.identities=[]] - User identities map
* @param {Object<string, string>} [userMap.publicProperties={}] - User public properties
* @param {Object<string, string>} [userMap.privateProperties={}] - User private properties
* * @param {boolean} [userMap.verified=false] - True if user is verified
*/
constructor(userMap) {
this.id = userMap.id;
this.displayName = userMap.displayName;
this.avatarUrl = userMap.avatarUrl || null;
this.identities = userMap.identities || [];
this.publicProperties = userMap.publicProperties || {};
this.privateProperties = userMap.privateProperties || {};
this.verified = userMap.verified || false;
Object.freeze(this);
}
/**
* Requests a bulk change of properties for the current user.
*
* @memberof CurrentUser
* @instance
* @param {UserUpdate} update - New user details.
* @return {Promise<boolean>} Promise to indicate if this operation was successful.
*/
updateDetails(update) {
let promise = Promise.resolve();
if (update.avatarFile) {
if (update.avatarFile.size > SDK._uploadFileSizeLimit) {
const oneMb = 1024 * 1024;
return Promise.reject(new Error(
`Avatar is too big (${(update.avatarFile.size / oneMb).toFixed(2)}Mb), limit is ${Math.round(SDK._uploadFileSizeLimit / oneMb)}Mb`
));
}
if (!isAValidImage(update.avatarFile)) {
return Promise.reject(new Error(
`File must be an image. Type ${update.avatarFile.type} is not supported`
));
}
promise = uploadFile(update.avatarFile, 'USER_AVATAR')
.then((resource) => {
update.avatarUrl = resource.jpg
? resource.jpg
: resource[Object.keys(resource).pop()];
});
}
return promise.then(() => {
return SDK.request('updateUser', update)
.then((user) => {
Storage.updateUser(user);
SDK._currentUser = CurrentUser.create(user);
return true;
})
.catch(() => false);
});
}
/**
* Returns if current user has any authentication info attached.
*
* @memberof CurrentUser
* @instance
* @return {bool} true, if user does not have any authentication info attached.
*/
isAnonymous() {
return Object.keys(this.identities).length === 0;
}
/**
* Adds Identity for the specified provider.
*
* @memberof CurrentUser
* @instance
* @param {Identity} identity - AuthIdentity to be added.
* @return {Promise} Promise successfull if identity added or error in case of ConflictUser or any other issue.
*/
addIdentity(identity) {
return SDK.request('addIdentity', identity.getTHIdentity())
.then((res) => {
return !!res;
})
.catch((err) => {
if (err &&
(err.errorCode === THErrorCode.IdentityAlreadyExists ||
err.errorCode === THErrorCode.EMResourceAlreadyExists)) {
return SDK.request(
'getPrivateUserByIdentity',
identity.getTHIdentity()
)
.then((res) => {
throw new ConflictUser(res);
})
.catch ((err) => { throw err });
} else {
throw err;
}
});
}
/**
* Removes Identity for the specified provider.
*
* @memberof CurrentUser
* @instance
* @param {string} provider - The provider connected to an auth identity on the current user.
* @return {Promise} Promise resolves when operation finishes.
*/
removeIdentity(provider) {
return SDK.request('removeIdentity', { provider })
.then(() => true);
}
/**
* Refresh user properties.
*
* @memberof CurrentUser
* @instance
* @return {Promise} Promise resolves when operation finishes.
*/
refresh() {
return SDK.request('getPrivateUser', this.id)
.then((res) => {
Storage.updateUser(res);
SDK._banInfo = res.internalPrivateProperties.ban_expiry
? new BanInfo({
expiration: res.internalPrivateProperties.ban_expiry,
reason: res.internalPrivateProperties.ban_reason
})
: null;
SDK._currentUser = CurrentUser.create(res);
return;
})
}
/**
* Returns reason and expiration of the ban of the current user.
*
* @memberof CurrentUser
* @instance
* @return {BanInfo} Ban information
*/
getBanInfo() {
const now = parseInt((new Date()).getTime()/1000);
// Check if expiration time is in the past
if (SDK._banInfo &&
SDK._banInfo.expiration &&
SDK._banInfo.expiration < now) {
// Clear ban info
SDK._banInfo = null;
}
return SDK._banInfo;
}
/**
* Returns if user is banned or not.
*
* @memberof CurrentUser
* @instance
* @return {bool} True, if user is banned, otherwise false.
*/
isBanned() {
return !!this.getBanInfo();
}
/**
* Create CurrentUser from THPrivateUser
*
* @memberof CurrentUser
* @param {Object} user - THPrivateUser instance
* @returns {CurrentUser} CurrentUser instance
* @ignore
*/
static create(user) {
return new CurrentUser({
...user,
verified: user.isVerified ||
user.verified ||
(user.internalPublicProperties &&
!!user.internalPublicProperties.verified)
});
}
}