added new sitesAdminOrOwner filter + deleted old way
MODIFY
src/authorization/AuthorizationsDefinition.ts
src/authorization/AuthorizationsDefinition.ts
@@ -255,12 +255,12 @@ export const AUTHORIZATION_DEFINITION: AuthorizationDefinition = {
{
resource: Entity.USERS_SITES, action: Action.LIST,
attributes: [
- 'user.id', 'user.name', 'user.firstName', 'user.email', 'user.role', 'siteAdmin', 'siteOwner', 'siteID'
+ 'user.id', 'user.name', 'user.firstName', 'user.email', 'user.role', 'siteID',
+ 'site.id', 'site.name', 'site.address.city', 'site.address.country', 'siteAdmin', 'siteOwner', 'userID'
]
},
{
- resource: Entity.USERS_SITES,
- action: [Action.ASSIGN, Action.UNASSIGN, Action.READ],
+ resource: Entity.USERS_SITES, action: [Action.ASSIGN, Action.READ, Action.UPDATE],
condition: {
Fn: 'custom:dynamicAuthorizations',
args: {
@@ -268,6 +268,21 @@ export const AUTHORIZATION_DEFINITION: AuthorizationDefinition = {
filters: ['LocalIssuer']
}
},
+ attributes: [
+ 'user.id', 'user.name', 'user.firstName', 'user.email', 'user.role', 'siteID',
+ 'site.id', 'site.name', 'site.address.city', 'site.address.country', 'siteAdmin', 'siteOwner', 'userID'
+ ]
+ },
+ {
+ resource: Entity.USERS_SITES,
+ action: Action.UNASSIGN,
+ // condition: {
+ // Fn: 'custom:dynamicAuthorizations',
+ // args: {
+ // asserts: [],
+ // filters: ['-OwnUser', 'LocalIssuer']
+ // }
+ // }
},
{
resource: Entity.SITE_AREA, action: Action.LIST,
@@ -1141,18 +1156,30 @@ export const AUTHORIZATION_DEFINITION: AuthorizationDefinition = {
}
},
{
- resource: Entity.USERS_SITES, action: [Action.LIST, Action.UNASSIGN, Action.READ],
+ resource: Entity.USERS_SITES, action: [Action.ASSIGN, Action.READ, Action.UPDATE, Action.LIST],
condition: {
Fn: 'custom:dynamicAuthorizations',
args: {
asserts: [],
- filters: ['SitesAdmin', 'LocalIssuer']
+ filters: ['SitesAdminOrOwner', 'LocalIssuer']
}
},
attributes: [
- 'user.id', 'user.name', 'user.firstName', 'user.email', 'user.role', 'siteAdmin', 'siteOwner', 'siteID'
+ 'user.id', 'user.name', 'user.firstName', 'user.email', 'user.role', 'siteID',
+ 'site.id', 'site.name', 'site.address.city', 'site.address.country', 'siteAdmin', 'siteOwner', 'userID'
]
},
+ {
+ resource: Entity.USERS_SITES,
+ action: Action.UNASSIGN,
+ condition: {
+ Fn: 'custom:dynamicAuthorizations',
+ args: {
+ asserts: [],
+ filters: ['-OwnUser', 'LocalIssuer']
+ }
+ },
+ },
{
resource: Entity.SITE, action: [Action.UPDATE, Action.MAINTAIN_PRICING_DEFINITIONS],
condition: {
@@ -1580,6 +1607,31 @@ export const AUTHORIZATION_DEFINITION: AuthorizationDefinition = {
'phone', 'mobile', 'iNumber', 'costCenter', 'address'
],
},
+ {
+ resource: Entity.USERS_SITES, action: [Action.ASSIGN, Action.READ, Action.LIST],
+ condition: {
+ Fn: 'custom:dynamicAuthorizations',
+ args: {
+ asserts: [],
+ filters: ['SitesAdminOrOwner', 'LocalIssuer']
+ }
+ },
+ attributes: [
+ 'user.id', 'user.name', 'user.firstName', 'user.email', 'user.role', 'siteID',
+ 'site.id', 'site.name', 'site.address.city', 'site.address.country', 'siteAdmin', 'siteOwner', 'userID'
+ ]
+ },
+ {
+ resource: Entity.USERS_SITES,
+ action: Action.UNASSIGN,
+ condition: {
+ Fn: 'custom:dynamicAuthorizations',
+ args: {
+ asserts: [],
+ filters: ['-OwnUser', 'LocalIssuer']
+ }
+ },
+ },
{
resource: Entity.TRANSACTION, action: [Action.READ, Action.REFUND_TRANSACTION],
condition: {

MODIFY
src/authorization/DynamicAuthorizationFactory.ts
src/authorization/DynamicAuthorizationFactory.ts
@@ -18,6 +18,8 @@ import PoolCarDynamicAuthorizationAssert from './dynamic-assert/PoolCarDynamicAu
import SiteAreaMandatoryDynamicAuthorizationAssert from './dynamic-assert/SiteAreaMandatoryDynamicAuthorizationAssert';
import SitesAdminDynamicAuthorizationDataSource from './dynamic-data-source/SitesAdminDynamicAuthorizationDataSource';
import SitesAdminDynamicAuthorizationFilter from './dynamic-filters/SitesAdminDynamicAuthorizationFilter';
+import SitesAdminOrOwnerDynamicAuthorizationDataSource from './dynamic-data-source/SitesAdminOrOwnerDynamicAuthorizationDataSource';
+import SitesAdminOrOwnerDynamicAuthorizationFilter from './dynamic-filters/SitesAdminOrOwnerDynamicAuthorizationFilter';
import SitesOwnerDynamicAuthorizationDataSource from './dynamic-data-source/SitesOwnerDynamicAuthorizationDataSource';
import SitesOwnerDynamicAuthorizationFilter from './dynamic-filters/SitesOwnerDynamicAuthorizationFilter';
import Tenant from '../types/Tenant';
@@ -59,6 +61,9 @@ export default class DynamicAuthorizationFactory {
case DynamicAuthorizationFilterName.LOCAL_ISSUER:
dynamicFilter = new LocalIssuerDynamicAuthorizationFilter(tenant, userToken, negateFilter);
break;
+ case DynamicAuthorizationFilterName.SITES_ADMIN_OR_OWNER:
+ dynamicFilter = new SitesAdminOrOwnerDynamicAuthorizationFilter(tenant, userToken, negateFilter);
+ break;
}
// Init Data Source
if (dynamicFilter) {
@@ -118,6 +123,9 @@ export default class DynamicAuthorizationFactory {
case DynamicAuthorizationDataSourceName.EXCLUDE_ACTION:
dataSource = new ExcludeActionDynamicAuthorizationDataSource(tenant, user);
break;
+ case DynamicAuthorizationDataSourceName.SITES_ADMIN_OR_OWNER:
+ dataSource = new SitesAdminOrOwnerDynamicAuthorizationDataSource(tenant, user);
+ break;
}
// Load data
if (dataSource) {

ADD
src/authorization/dynamic-filters/SitesAdminOrOwnerDynamicAuthorizationFilter.ts
+import { AuthorizationFilter, DynamicAuthorizationDataSourceName, Entity } from '../../types/Authorization';
+
+import DynamicAuthorizationFilter from '../DynamicAuthorizationFilter';
+import { EntityData } from '../../types/GlobalType';
+import SitesAdminOrOwnerDynamicAuthorizationDataSource from '../dynamic-data-source/SitesAdminOrOwnerDynamicAuthorizationDataSource';
+import Utils from '../../utils/Utils';
+
+export default class SitesAdminOrOwnerDynamicAuthorizationFilter extends DynamicAuthorizationFilter {
+ public processFilter(authorizationFilters: AuthorizationFilter, extraFilters: Record<string, any>, entityData?: EntityData): void {
+ // Get Site IDs
+ const sitesAdminOrOwnerDataSource = this.getDataSource(
+ DynamicAuthorizationDataSourceName.SITES_ADMIN_OR_OWNER) as SitesAdminOrOwnerDynamicAuthorizationDataSource;
+ const { siteIDs } = sitesAdminOrOwnerDataSource.getData();
+ // Clear
+ authorizationFilters.filters.siteIDs = [];
+ if (!Utils.isEmptyArray(siteIDs)) {
+ // Force the filter
+ authorizationFilters.filters.siteIDs = siteIDs;
+ // Check if filter is provided
+ if (Utils.objectHasProperty(extraFilters, 'SiteID') &&
+ !Utils.isNullOrUndefined(extraFilters['SiteID'])) {
+ const filteredSiteIDs: string[] = extraFilters['SiteID'].split('|');
+ // Override
+ authorizationFilters.filters.siteIDs = filteredSiteIDs.filter(
+ (siteID) => authorizationFilters.filters.siteIDs.includes(siteID));
+ }
+ }
+ if (!Utils.isEmptyArray(authorizationFilters.filters.siteIDs)) {
+ authorizationFilters.authorized = true;
+ }
+ }
+
+ public getApplicableEntities(): Entity[] {
+ return [
+ Entity.SITE,
+ Entity.USER
+ ];
+ }
+
+ public getApplicableDataSources(): DynamicAuthorizationDataSourceName[] {
+ return [
+ DynamicAuthorizationDataSourceName.SITES_ADMIN_OR_OWNER
+ ];
+ }
+}

MODIFY
src/server/rest/v1/service/AuthorizationService.ts
src/server/rest/v1/service/AuthorizationService.ts
import { Action, AuthorizationActions, AuthorizationContext, AuthorizationFilter, Entity } from '../../../../types/Authorization';
-import { AssetDataResult, BillingInvoiceDataResult, BillingPaymentMethodDataResult, CarCatalogDataResult, CarDataResult, CompanyDataResult, DataResult, LogDataResult, PricingDefinitionDataResult, RegistrationTokenDataResult, SiteAreaDataResult, SiteDataResult, TagDataResult, UserDataResult } from '../../../../types/DataResult';
+import { AssetDataResult, BillingInvoiceDataResult, BillingPaymentMethodDataResult, CarCatalogDataResult, CarDataResult, CompanyDataResult, DataResult, LogDataResult, PricingDefinitionDataResult, RegistrationTokenDataResult, SiteAreaDataResult, SiteDataResult, SiteUserDataResult, TagDataResult, UserDataResult, UserSiteDataResult } from '../../../../types/DataResult';
import { BillingInvoice, BillingPaymentMethod } from '../../../../types/Billing';
import { Car, CarCatalog } from '../../../../types/Car';
import { HttpAssetRequest, HttpAssetsRequest } from '../../../../types/requests/HttpAssetRequest';
@@ -36,7 +36,6 @@ import SiteArea from '../../../../types/SiteArea';
import Tag from '../../../../types/Tag';
import UserToken from '../../../../types/UserToken';
import Utils from '../../../../utils/Utils';
-import _ from 'lodash';
const MODULE_NAME = 'AuthorizationService';
@@ -57,6 +56,20 @@ export default class AuthorizationService {
tenant, Entity.LOGGING, userToken, filteredRequest, filteredRequest.ID ? { LogID: filteredRequest.ID } : {}, authAction, entityData);
}
+ public static async addUserSitesAuthorizations(tenant: Tenant, userToken: UserToken, userSites: UserSiteDataResult, authorizationFilter: AuthorizationFilter): Promise<void> {
+ // Add Meta Data
+ userSites.metadata = authorizationFilter.metadata;
+ // Add Authorizations
+ userSites.canUpdateUserSite = await AuthorizationService.canPerformAuthorizationAction(tenant, userToken, Entity.USERS_SITES, Action.UPDATE, authorizationFilter);
+ }
+
+ public static async addSiteUsersAuthorizations(tenant: Tenant, userToken: UserToken, siteUsers: SiteUserDataResult, authorizationFilter: AuthorizationFilter): Promise<void> {
+ // Add Meta Data
+ siteUsers.metadata = authorizationFilter.metadata;
+ // Add Authorizations
+ siteUsers.canUpdateUserSite = await AuthorizationService.canPerformAuthorizationAction(tenant, userToken, Entity.USERS_SITES, Action.UPDATE, authorizationFilter);
+ }
+
public static async addSitesAuthorizations(tenant: Tenant, userToken: UserToken, sites: SiteDataResult, authorizationFilter: AuthorizationFilter): Promise<void> {
// Add Meta Data
sites.metadata = authorizationFilter.metadata;
@@ -154,15 +167,14 @@ export default class AuthorizationService {
const authorizations: AuthorizationFilter = {
filters: {},
dataSources: new Map(),
- projectFields: [
- 'site.id', 'site.name', 'site.address.city', 'site.address.country', 'siteAdmin', 'siteOwner', 'userID'
- ],
- authorized: userToken.role === UserRole.ADMIN,
+ projectFields: [],
+ authorized: false,
};
// Filter projected fields
authorizations.projectFields = AuthorizationService.filterProjectFields(authorizations.projectFields, filteredRequest.ProjectFields);
// Handle Sites
- await AuthorizationService.checkAssignedSiteAdminsAndOwners(tenant, userToken, null, authorizations);
+ await this.canPerformAuthorizationAction(tenant, userToken, Entity.USERS_SITES, Action.LIST,
+ authorizations, filteredRequest, null, true);
return authorizations;
}
@@ -198,7 +210,7 @@ export default class AuthorizationService {
}
public static async checkAndGetUsersInErrorAuthorizations(tenant: Tenant, userToken: UserToken,
- filteredRequest: Partial<HttpUsersRequest>): Promise<AuthorizationFilter> {
+ authAction: Action, filteredRequest: Partial<HttpUsersRequest>): Promise<AuthorizationFilter> {
const authorizations: AuthorizationFilter = {
filters: {},
dataSources: new Map(),
@@ -206,7 +218,7 @@ export default class AuthorizationService {
authorized: false
};
// Check static & dynamic authorization
- await this.canPerformAuthorizationAction(tenant, userToken, Entity.USER, Action.IN_ERROR,
+ await this.canPerformAuthorizationAction(tenant, userToken, Entity.USER, authAction,
authorizations, filteredRequest, null, true);
return authorizations;
}
@@ -234,12 +246,13 @@ export default class AuthorizationService {
tenant, userToken, Entity.USER, Action.DELETE, authorizationFilter, { UserID: user.id }, user);
user.canAssignSites = await AuthorizationService.canPerformAuthorizationAction(
tenant, userToken, Entity.USERS_SITES, Action.ASSIGN, authorizationFilter, { UserID: user.id }, user);
- // Optimize data over the net
+ user.canUnassignSites = await AuthorizationService.canPerformAuthorizationAction(
+ tenant, userToken, Entity.USERS_SITES, Action.UNASSIGN, authorizationFilter, { UserID: user.id }, user);
Utils.removeCanPropertiesWithFalseValue(user);
}
public static async checkAndGetUsersAuthorizations(tenant: Tenant, userToken: UserToken,
- filteredRequest: Partial<HttpUsersRequest>, failsWithException = true): Promise<AuthorizationFilter> {
+ authAction: Action, filteredRequest: Partial<HttpUsersRequest>, failsWithException = true): Promise<AuthorizationFilter> {
const authorizations: AuthorizationFilter = {
filters: {},
dataSources: new Map(),
@@ -248,7 +261,7 @@ export default class AuthorizationService {
};
// Check static & dynamic authorization
await AuthorizationService.canPerformAuthorizationAction(
- tenant, userToken, Entity.USER, Action.LIST, authorizations, filteredRequest, null, failsWithException);
+ tenant, userToken, Entity.USER, authAction, authorizations, filteredRequest, null, failsWithException);
return authorizations;
}
@@ -863,34 +876,6 @@ export default class AuthorizationService {
}
}
- private static async checkAssignedSiteAdminsAndOwners(tenant: Tenant, userToken: UserToken,
- filteredRequest: { SiteID?: string }, authorizationFilters: AuthorizationFilter): Promise<void> {
- if (userToken.role !== UserRole.ADMIN && userToken.role !== UserRole.SUPER_ADMIN) {
- if (Utils.isTenantComponentActive(tenant, TenantComponents.ORGANIZATION)) {
- // Get Site IDs from Site Admin & Site Owner flag
- const siteAdminSiteIDs = await Authorizations.getSiteAdminSiteIDs(tenant, userToken);
- const siteOwnerSiteIDs = await Authorizations.getSiteOwnerSiteIDs(tenant, userToken);
- const allSites = _.uniq([...siteAdminSiteIDs, ...siteOwnerSiteIDs]);
- if (!Utils.isEmptyArray(allSites)) {
- // Force the filters
- authorizationFilters.filters.siteIDs = allSites;
- // Check if filter is provided
- if (filteredRequest?.SiteID) {
- const filteredSiteIDs: string[] = filteredRequest.SiteID.split('|');
- // Override
- authorizationFilters.filters.siteIDs = filteredSiteIDs.filter(
- (filteredSiteID) => authorizationFilters.filters.siteIDs.includes(filteredSiteID));
- }
- }
- if (!Utils.isEmptyArray(authorizationFilters.filters.siteIDs)) {
- authorizationFilters.authorized = true;
- }
- } else {
- authorizationFilters.authorized = true;
- }
- }
- }
-
private static filterProjectFields(authFields: string[], httpProjectField: string): string[] {
let fields = authFields;
// Only allow projected fields

MODIFY
src/server/rest/v1/service/SiteService.ts
src/server/rest/v1/service/SiteService.ts
-import { Action, DynamicAuthorizationDataSourceName, Entity } from '../../../../types/Authorization';
-import { HTTPAuthError, HTTPError } from '../../../../types/HTTPError';
+import { Action, Entity } from '../../../../types/Authorization';
import { NextFunction, Request, Response } from 'express';
+import { SiteDataResult, UserSiteDataResult } from '../../../../types/DataResult';
-import AppAuthError from '../../../../exception/AppAuthError';
import AppError from '../../../../exception/AppError';
import AuthorizationService from './AuthorizationService';
import ChargingStationStorage from '../../../../storage/mongodb/ChargingStationStorage';
import Constants from '../../../../utils/Constants';
-import DynamicAuthorizationFactory from '../../../../authorization/DynamicAuthorizationFactory';
+import { HTTPError } from '../../../../types/HTTPError';
import Logging from '../../../../utils/Logging';
import LoggingHelper from '../../../../utils/LoggingHelper';
import { ServerAction } from '../../../../types/Server';
import Site from '../../../../types/Site';
-import { SiteDataResult } from '../../../../types/DataResult';
import SiteStorage from '../../../../storage/mongodb/SiteStorage';
import SiteValidator from '../validator/SiteValidator';
-import SitesAdminDynamicAuthorizationDataSource from '../../../../authorization/dynamic-data-source/SitesAdminDynamicAuthorizationDataSource';
import { StatusCodes } from 'http-status-codes';
import { TenantComponents } from '../../../../types/Tenant';
import TenantStorage from '../../../../storage/mongodb/TenantStorage';
@@ -96,7 +93,7 @@ export default class SiteService {
const site = await UtilsService.checkAndGetSiteAuthorization(
req.tenant, req.user, filteredRequest.siteID, Action.READ, action);
// Check and Get Users
- const users = await UtilsService.checkSiteUsersAuthorization(
+ const users = await UtilsService.checkAndGetSiteUsersAuthorization(
req.tenant, req.user, site, filteredRequest.userIDs, action);
// Save
if (action === ServerAction.ADD_USERS_TO_SITE) {
@@ -147,6 +144,8 @@ export default class SiteService {
},
authorizations.projectFields
);
+ // add user auth
+ await AuthorizationService.addUserSitesAuthorizations(req.tenant, req.user, users as UserSiteDataResult, authorizations);
res.json(users);
next();
}
@@ -210,13 +209,6 @@ export default class SiteService {
UtilsService.sendEmptyDataResult(res, next);
return;
}
- // Check Site Admin filter
- if (filteredRequest.SiteAdmin) {
- // Override Site IDs
- const siteAdminDataSource = await DynamicAuthorizationFactory.getDynamicDataSource(
- req.tenant, req.user, DynamicAuthorizationDataSourceName.SITES_ADMIN) as SitesAdminDynamicAuthorizationDataSource;
- authorizations.filters = { ...authorizations.filters, ...siteAdminDataSource.getData() };
- }
// Get the sites
const sites = await SiteStorage.getSites(req.tenant,
{

MODIFY
src/server/rest/v1/service/UserService.ts
src/server/rest/v1/service/UserService.ts
@@ -3,7 +3,7 @@ import { ActionsResponse, ImportStatus } from '../../../../types/GlobalType';
import { AsyncTaskType, AsyncTasks } from '../../../../types/AsyncTask';
import Busboy, { FileInfo } from 'busboy';
import { Car, CarType } from '../../../../types/Car';
-import { DataResult, UserDataResult } from '../../../../types/DataResult';
+import { DataResult, SiteUserDataResult, UserDataResult } from '../../../../types/DataResult';
import { HTTPAuthError, HTTPError } from '../../../../types/HTTPError';
import { NextFunction, Request, Response } from 'express';
import Tenant, { TenantComponents } from '../../../../types/Tenant';
@@ -113,7 +113,7 @@ export default class UserService {
const user = await UtilsService.checkAndGetUserAuthorization(
req.tenant, req.user, filteredRequest.userID, Action.READ, action);
// Check and Get Sites
- const sites = await UtilsService.checkUserSitesAuthorization(
+ const sites = await UtilsService.checkAndGetUserSitesAuthorization(
req.tenant, req.user, user, filteredRequest.siteIDs, action);
// Save
if (action === ServerAction.ADD_SITES_TO_USER) {
@@ -367,6 +367,8 @@ export default class UserService {
siteOwner: userSite.siteOwner,
site: userSite.site
}));
+ // Add Auth flags
+ await AuthorizationService.addSiteUsersAuthorizations(req.tenant, req.user, sites as SiteUserDataResult , authorizations);
res.json(sites);
next();
}

MODIFY
src/server/rest/v1/service/UtilsService.ts
src/server/rest/v1/service/UtilsService.ts
@@ -27,9 +27,9 @@ import Cypher from '../../../../utils/Cypher';
import { DataResult } from '../../../../types/DataResult';
import { EntityData } from '../../../../types/GlobalType';
import { Log } from '../../../../types/Log';
+import LogStorage from '../../../../storage/mongodb/LogStorage';
import Logging from '../../../../utils/Logging';
import LoggingHelper from '../../../../utils/LoggingHelper';
-import LogStorage from '../../../../storage/mongodb/LogStorage';
import OCPIEndpoint from '../../../../types/ocpi/OCPIEndpoint';
import OICPEndpoint from '../../../../types/oicp/OICPEndpoint';
import PDFDocument from 'pdfkit';
@@ -447,7 +447,7 @@ export default class UtilsService {
return log;
}
- public static async checkUserSitesAuthorization(tenant: Tenant, userToken: UserToken, user: User, siteIDs: string[],
+ public static async checkAndGetUserSitesAuthorization(tenant: Tenant, userToken: UserToken, user: User, siteIDs: string[],
action: ServerAction, additionalFilters: Record<string, any> = {}, applyProjectFields = false): Promise<Site[]> {
// Check mandatory fields
UtilsService.assertIdIsProvided(action, user.id, MODULE_NAME, 'checkUserSitesAuthorization', userToken);
@@ -486,7 +486,7 @@ export default class UtilsService {
return sites;
}
- public static async checkSiteUsersAuthorization(tenant: Tenant, userToken: UserToken, site: Site, userIDs: string[],
+ public static async checkAndGetSiteUsersAuthorization(tenant: Tenant, userToken: UserToken, site: Site, userIDs: string[],
action: ServerAction, additionalFilters: Record<string, any> = {}, applyProjectFields = false): Promise<User[]> {
// Check mandatory fields
UtilsService.assertIdIsProvided(action, site.id, MODULE_NAME, 'checkSiteUsersAuthorization', userToken);

MODIFY
src/types/Authorization.ts
src/types/Authorization.ts
@@ -189,6 +189,7 @@ export interface AuthorizationActions {
export interface UserAuthorizationActions extends AuthorizationActions {
canAssignSites?: boolean;
+ canUnassignSites?: boolean;
}
export interface TagAuthorizationActions extends AuthorizationActions {
@@ -240,6 +241,7 @@ export enum DynamicAuthorizationFilterName {
OWN_USER = 'OwnUser',
LOCAL_ISSUER = 'LocalIssuer',
EXCLUDE_ACTION = 'ExcludeAction',
+ SITES_ADMIN_OR_OWNER = 'SitesAdminOrOwner',
}
export enum DynamicAuthorizationAssertName {
@@ -257,6 +259,7 @@ export enum DynamicAuthorizationDataSourceName {
ASSIGNED_SITES = 'AssignedSites',
OWN_USER = 'OwnUser',
EXCLUDE_ACTION = 'ExcludeAction',
+ SITES_ADMIN_OR_OWNER = 'SitesAdminOrOwner',
}
export interface DynamicAuthorizationDataSourceData { }
@@ -269,6 +272,10 @@ export interface SitesAdminDynamicAuthorizationDataSourceData extends DynamicAut
siteIDs?: string[];
}
+export interface SitesAdminOrOwnerDynamicAuthorizationDataSourceData extends DynamicAuthorizationDataSourceData {
+ siteIDs?: string[];
+}
+
export interface SitesOwnerDynamicAuthorizationDataSourceData extends DynamicAuthorizationDataSourceData {
siteIDs?: string[];
}

MODIFY
src/types/DataResult.ts
src/types/DataResult.ts
import { BillingInvoice, BillingPaymentMethod } from './Billing';
import { Car, CarCatalog } from './Car';
+import Site, { SiteUser } from './Site';
import Transaction, { TransactionStats } from './Transaction';
+import User, { UserSite } from './User';
import Asset from './Asset';
import { AuthorizationDefinitionFieldMetadata } from './Authorization';
@@ -8,10 +10,8 @@ import Company from './Company';
import { Log } from './Log';
import PricingDefinition from './Pricing';
import RegistrationToken from './RegistrationToken';
-import Site from './Site';
import SiteArea from './SiteArea';
import Tag from './Tag';
-import User from './User';
export interface DeletedResult {
acknowledged?: boolean;
@@ -44,6 +44,14 @@ export interface SiteDataResult extends DataResult<Site> {
canListCompanies: boolean;
}
+export interface UserSiteDataResult extends DataResult<UserSite> {
+ canUpdateUserSite: boolean;
+}
+
+export interface SiteUserDataResult extends DataResult<SiteUser> {
+ canUpdateUserSite: boolean;
+}
+
export interface LogDataResult extends DataResult<Log> {
canExport: boolean;
}

added new sitesAdminOrOwner filter + deleted old way