@fleetbase/ember-core
Version:
Provides all the core services, decorators and utilities for building a Fleetbase extension for the Console.
284 lines (228 loc) • 7.93 kB
JavaScript
import Service from '@ember/service';
import Evented from '@ember/object/evented';
import { inject as service } from '@ember/service';
import { tracked } from '@glimmer/tracking';
import { dasherize } from '@ember/string';
import { computed, get } from '@ember/object';
import { isBlank } from '@ember/utils';
import { alias } from '@ember/object/computed';
import { storageFor } from 'ember-local-storage';
import { debug } from '@ember/debug';
export default class CurrentUserService extends Service.extend(Evented) {
session;
store;
fetch;
theme;
notifications;
intl;
user = { id: 'anon' };
userSnapshot = { id: 'anon' };
company = {};
permissions = [];
organizations = [];
whoisData = {};
locale = 'en-us';
options;
id;
name;
phone;
email;
avatarUrl;
isAdmin;
companyId;
companyName;
roleName;
role;
get optionsPrefix() {
return `${this.id}:`;
}
get latitude() {
return this.whois('latitude');
}
get longitude() {
return this.whois('longitude');
}
get currency() {
return this.whois('currency.code');
}
get city() {
return this.whois('city');
}
get country() {
return this.whois('country_code');
}
async load() {
if (this.session.isAuthenticated) {
const user = await this.store.findRecord('user', 'me');
const snapshot = await this.getUserSnapshot(user);
this.set('user', user);
this.set('userSnapshot', snapshot);
this.trigger('user.loaded', user);
// Set permissions
this.permissions = this.getUserPermissions(user);
// Load preferences
await this.loadPreferences();
return user;
}
return null;
}
async promiseUser(options = {}) {
const NoUserAuthenticatedError = new Error('Failed to authenticate user.');
if (!this.session.isAuthenticated) {
throw NoUserAuthenticatedError;
}
try {
const user = await this.store.queryRecord('user', { me: true });
const snapshot = await this.getUserSnapshot(user);
// Set current user
this.set('user', user);
this.set('userSnapshot', snapshot);
this.trigger('user.loaded', user);
// Set permissions
this.permissions = this.getUserPermissions(user);
// Set environment from user option
this.theme.setEnvironment();
// Set locale
if (user.locale) {
this.setLocale(user.locale);
} else {
await this.loadLocale();
}
// Load user whois data
await this.loadWhois();
// Load user organizations
await this.loadOrganizations();
// Optional callback
if (typeof options?.onUserResolved === 'function') {
options.onUserResolved(user);
}
return user;
} catch (error) {
debug(`Error loading current user : ${error.message}`);
throw error;
}
}
async loadPreferences() {
await this.loadLocale();
await this.loadWhois();
await this.loadOrganizations();
}
async loadLocale() {
try {
const { locale } = await this.fetch.get('users/locale');
this.setLocale(locale);
return locale;
} catch (error) {
this.notifications.serverError(error);
}
}
async loadOrganizations() {
try {
const organizations = await this.fetch.get('auth/organizations', {}, { normalizeToEmberData: true, normalizeModelType: 'company' });
this.setOption('organizations', organizations);
this.organizations = organizations;
return organizations;
} catch (error) {
this.notifications.serverError(error);
}
}
async loadWhois() {
this.fetch.shouldResetCache();
try {
const whois = await this.fetch.cachedGet(
'lookup/whois',
{},
{
expirationInterval: 60,
expirationIntervalUnit: 'minutes',
}
);
this.setOption('whois', whois);
this.whoisData = whois;
return whois;
} catch (error) {
this.notifications.serverError(error);
}
}
getCompany() {
this.company = this.store.peekRecord('company', this.user.company_uuid);
return this.company;
}
getUserPermissions(user) {
const permissions = [];
// get direct applied permissions
if (user.get('permissions')) {
permissions.pushObjects(user.get('permissions').toArray());
}
// get role permissions and role policies permissions
if (user.get('role')) {
if (user.get('role.permissions')) {
permissions.pushObjects(user.get('role.permissions').toArray());
}
if (user.get('role.policies')) {
for (let i = 0; i < user.get('role.policies').length; i++) {
const policy = user.get('role.policies').objectAt(i);
if (policy.get('permissions')) {
permissions.pushObjects(policy.get('permissions').toArray());
}
}
}
}
// get direct applied policy permissions
if (user.get('policies')) {
for (let i = 0; i < user.get('policies').length; i++) {
const policy = user.get('policies').objectAt(i);
if (policy.get('permissions')) {
permissions.pushObjects(policy.get('permissions').toArray());
}
}
}
return permissions;
}
whois(key) {
return this.getWhoisProperty(key);
}
setLocale(locale) {
this.setOption('locale', locale);
this.intl.setLocale(locale);
this.locale = locale;
return this;
}
setOption(key, value) {
key = `${this.optionsPrefix}${dasherize(key)}`;
this.options.set(key, value);
return this;
}
getOption(key, defaultValue = null) {
key = `${this.optionsPrefix}${dasherize(key)}`;
const value = this.options.get(key);
return value !== undefined ? value : defaultValue;
}
getWhoisProperty(prop) {
const whois = this.getOption('whois');
if (!whois || typeof whois !== 'object') {
return null;
}
return get(whois, prop);
}
hasOption(key) {
return this.getOption(key) !== undefined;
}
filledOption(key) {
return !isBlank(this.getOption(key));
}
async getUserSnapshot(user) {
const role = await user.get('role');
const snapshot = user.serialize({ includeId: true });
return {
...snapshot,
id: snapshot.uuid,
company_name: user.get('company_name'),
role_name: user.get('role_name'),
role: {
...role.serialize({ includeId: true }),
id: role.get('id'),
},
};
}
}