339 lines
8.4 KiB
JavaScript
339 lines
8.4 KiB
JavaScript
const _ = require('underscore');
|
|
const Backbone = require('backbone');
|
|
const UserUrlModel = require('dashboard/data/user-url-model');
|
|
|
|
const UserModel = Backbone.Model.extend({
|
|
urlRoot: '/api/v1/users',
|
|
|
|
defaults: {
|
|
avatar_url: 'http://cartodb.s3.amazonaws.com/static/public_dashboard_default_avatar.png',
|
|
username: ''
|
|
},
|
|
|
|
initialize: function (attrs, opts) {
|
|
attrs = attrs || {};
|
|
opts = opts || {};
|
|
this.tables = [];
|
|
// Removing avatar_url attribute if it comes as null
|
|
// Due to a Backbone Model constructor uses _.extends
|
|
// instead of _.defaults
|
|
if (this.get('avatar_url') === null) {
|
|
this.set('avatar_url', this.defaults.avatar_url);
|
|
}
|
|
|
|
this.email = (typeof attrs.email !== 'undefined') ? attrs.email : '';
|
|
|
|
if (opts.groups) {
|
|
this.setGroups(opts.groups);
|
|
}
|
|
|
|
if (opts.organization) {
|
|
this.setOrganization(opts.organization);
|
|
}
|
|
},
|
|
|
|
setGroups: function (groups) {
|
|
this.groups = groups;
|
|
},
|
|
|
|
setOrganization: function (organization) {
|
|
this.organization = organization;
|
|
|
|
if (this.groups) {
|
|
this.groups.organization = organization;
|
|
}
|
|
},
|
|
|
|
isInsideOrg: function () {
|
|
if (this.organization) {
|
|
return this.organization.id !== false || this.isOrgOwner();
|
|
}
|
|
return false;
|
|
},
|
|
|
|
isAuthUsernamePasswordEnabled: function () {
|
|
if (this.organization) {
|
|
return this.organization.get('auth_username_password_enabled');
|
|
}
|
|
return false;
|
|
},
|
|
|
|
isOrgOwner: function () {
|
|
if (this.organization) {
|
|
return this.organization.owner.get('id') === this.get('id');
|
|
}
|
|
return false;
|
|
},
|
|
|
|
isOrgAdmin: function () {
|
|
if (this.organization) {
|
|
return this.organization.isOrgAdmin(this);
|
|
}
|
|
return false;
|
|
},
|
|
|
|
isViewer: function () {
|
|
return this.get('viewer') === true;
|
|
},
|
|
|
|
isBuilder: function () {
|
|
return !this.isViewer();
|
|
},
|
|
|
|
role: function () {
|
|
return this.get('role_display');
|
|
},
|
|
|
|
isDOEnabled: function () {
|
|
return this.get('do_enabled');
|
|
},
|
|
|
|
isEnterprise: function () {
|
|
return this.get('is_enterprise');
|
|
},
|
|
|
|
isIndividualUser: function () {
|
|
const proUsers = ['Individual', 'Annual Individual'];
|
|
return proUsers.indexOf(this.get('account_type')) > -1;
|
|
},
|
|
|
|
isFree2020User: function () {
|
|
return this.get('account_type').toLowerCase().indexOf('free 2020') !== -1;
|
|
},
|
|
|
|
nameOrUsername: function () {
|
|
return this.fullName() || this.get('username');
|
|
},
|
|
|
|
fullName: function () {
|
|
var name = this.get('name') || '';
|
|
var lastName = this.get('last_name') || '';
|
|
if (name || lastName) {
|
|
return name + (name && lastName ? ' ' : '') + lastName;
|
|
}
|
|
return '';
|
|
},
|
|
|
|
renderData: function (currentUser) {
|
|
var name = this.get('username');
|
|
|
|
if (currentUser && currentUser.id === this.id) {
|
|
name = _t('You');
|
|
}
|
|
|
|
return {
|
|
username: name,
|
|
avatar_url: this.get('avatar_url')
|
|
};
|
|
},
|
|
|
|
hasCreateDatasetsFeature: function () {
|
|
return this.isBuilder();
|
|
},
|
|
|
|
canCreateDatasets: function () {
|
|
if (!this.get('remaining_byte_quota') || this.get('remaining_byte_quota') <= 0) {
|
|
return false;
|
|
}
|
|
|
|
return this.hasCreateDatasetsFeature();
|
|
},
|
|
|
|
hasCreateMapsFeature: function () {
|
|
return this.isBuilder();
|
|
},
|
|
|
|
canAddLayerTo: function (map) {
|
|
if (!map || !map.layers || !map.layers.getDataLayers) {
|
|
throw new Error('Map model is not defined or wrong');
|
|
}
|
|
var dataLayers = map.layers.getDataLayers();
|
|
return dataLayers.length < this.getMaxLayers();
|
|
},
|
|
|
|
getMaxLayers: function () {
|
|
return (this.get('limits') && this.get('limits').max_layers) || 5;
|
|
},
|
|
|
|
hasPublicMapsLimits: function () {
|
|
const userWithLimits = this.isIndividualUser() || this.isFree2020User();
|
|
return userWithLimits && !this.hasUnlimitedPublicMaps();
|
|
},
|
|
|
|
hasRemainingPublicMaps: function () {
|
|
if (this.hasPublicMapsLimits()) {
|
|
return this.get('public_map_quota') > this.getTotalPublicMapsCount();
|
|
}
|
|
return true;
|
|
},
|
|
|
|
hasUnlimitedPublicMaps: function () {
|
|
return this.get('public_map_quota') === null;
|
|
},
|
|
|
|
getTotalPublicMapsCount: function () {
|
|
var totalPublicPrivacyMapsCount = this.get('public_privacy_map_count') || 0;
|
|
var totalPasswordPrivacyMapsCount = this.get('password_privacy_map_count') || 0;
|
|
var totalLinkPrivacyMapsCount = this.get('link_privacy_map_count') || 0;
|
|
|
|
return totalPublicPrivacyMapsCount + totalPasswordPrivacyMapsCount + totalLinkPrivacyMapsCount;
|
|
},
|
|
|
|
hasPrivateMapsLimits: function () {
|
|
const userWithLimits = this.isFree2020User();
|
|
return userWithLimits && !this.hasUnlimitedPrivateMaps();
|
|
},
|
|
|
|
hasRemainingPrivateMaps: function () {
|
|
if (this.hasPrivateMapsLimits()) {
|
|
return this.get('private_map_quota') > this.getTotalPrivateMapsCount();
|
|
}
|
|
return true;
|
|
},
|
|
|
|
hasUnlimitedPrivateMaps: function () {
|
|
return this.get('private_map_quota') === null;
|
|
},
|
|
|
|
getTotalPrivateMapsCount: function () {
|
|
return this.get('private_privacy_map_count');
|
|
},
|
|
|
|
getMaxConcurrentImports: function () {
|
|
return (this.get('limits') && this.get('limits').concurrent_imports) || 1;
|
|
},
|
|
|
|
featureEnabled: function (name) {
|
|
var featureFlags = this.get('feature_flags');
|
|
|
|
if (!featureFlags || featureFlags.length === 0 || !name) {
|
|
return false;
|
|
}
|
|
|
|
return _.contains(featureFlags, name);
|
|
},
|
|
|
|
isCloseToLimits: function () {
|
|
var quota = this.get('quota_in_bytes');
|
|
var remainingQuota = this.get('remaining_byte_quota');
|
|
|
|
return ((remainingQuota * 100) / quota) < 20;
|
|
},
|
|
|
|
getOrganizationName: function () {
|
|
return this.isInsideOrg() ? this.organization.get('name') : '';
|
|
},
|
|
|
|
getOrgName: function () {
|
|
return this.isInsideOrg() ? this.organization.get('name') : '';
|
|
},
|
|
|
|
getMaxLayersPerMap: function () {
|
|
return this.get('max_layers') || 4;
|
|
},
|
|
|
|
canStartTrial: function () {
|
|
return !this.isInsideOrg() && this.get('account_type') === 'FREE' && this.get('table_count') > 0;
|
|
},
|
|
|
|
canCreatePrivateDatasets: function () {
|
|
var actions = this.get('actions');
|
|
return actions && actions.private_tables;
|
|
},
|
|
|
|
canCreateTwitterDataset: function () {
|
|
return this.hasOwnTwitterCredentials();
|
|
},
|
|
|
|
canSelectPremiumOptions: function (visModel) {
|
|
return this.get('actions')[ visModel.isVisualization() ? 'private_maps' : 'private_tables' ];
|
|
},
|
|
|
|
hasOwnTwitterCredentials: function () {
|
|
var twitter = this.get('twitter');
|
|
return (twitter && twitter.customized_config) || false;
|
|
},
|
|
|
|
equals: function (otherUser) {
|
|
if (otherUser.get) {
|
|
return this.get('id') === otherUser.get('id');
|
|
}
|
|
},
|
|
|
|
viewUrl: function () {
|
|
return new UserUrlModel({
|
|
base_url: this.get('base_url'),
|
|
is_org_admin: this.isOrgAdmin()
|
|
});
|
|
},
|
|
|
|
upgradeContactEmail: function () {
|
|
if (this.isInsideOrg()) {
|
|
if (this.isOrgOwner()) {
|
|
return 'enterprise-support@carto.com';
|
|
} else {
|
|
return this.organization.owner.get('email');
|
|
}
|
|
} else {
|
|
return 'support@carto.com';
|
|
}
|
|
},
|
|
|
|
needsPasswordConfirmation: function () {
|
|
return this.get('needs_password_confirmation');
|
|
},
|
|
|
|
usedQuotaPercentage: function () {
|
|
return (this.get('db_size_in_bytes') * 100) / this.organization.get('available_quota_for_user');
|
|
},
|
|
|
|
assignedQuotaInRoundedMb: function () {
|
|
return Math.floor(this.get('quota_in_bytes') / 1024 / 1024).toFixed(0);
|
|
},
|
|
|
|
assignedQuotaPercentage: function () {
|
|
return (this.get('quota_in_bytes') * 100) / this.organization.get('available_quota_for_user');
|
|
},
|
|
|
|
getGoogleApiKey: function () {
|
|
return this.get('google_maps_private_key');
|
|
},
|
|
|
|
hasGoogleMaps: function () {
|
|
return !!this.getGoogleApiKey();
|
|
},
|
|
|
|
showGoogleApiKeys: function () {
|
|
return this.hasGoogleMaps() && (!this.isInsideOrg() || this.isOrgOwner());
|
|
},
|
|
|
|
getSchema: function () {
|
|
return this.isInsideOrg() ? this.get('username') : 'public';
|
|
},
|
|
|
|
getAuthToken: function () {
|
|
return btoa(`${this.get('username')}:${this.get('api_key')}`);
|
|
},
|
|
|
|
getModelType: () => 'user',
|
|
|
|
isActionEnabled: function (action) {
|
|
return this.get('actions') && this.get('actions')[action];
|
|
},
|
|
|
|
hasAccountType: function (accountType) {
|
|
return this.get('account_type') === accountType;
|
|
},
|
|
|
|
// Public sharing
|
|
hasPublicMapSharingDisabled: function () {
|
|
return this.get('public_map_quota') === 0;
|
|
},
|
|
|
|
hasPublicDatasetSharingDisabled: function () {
|
|
return this.get('public_dataset_quota') === 0;
|
|
}
|
|
});
|
|
|
|
module.exports = UserModel;
|