diff --git a/api/src/services/meta.ts b/api/src/services/meta.ts index ff51ae45b4..f14c1f9785 100644 --- a/api/src/services/meta.ts +++ b/api/src/services/meta.ts @@ -3,6 +3,8 @@ import database from '../database'; import { AbstractServiceOptions, Accountability, SchemaOverview } from '../types'; import { Knex } from 'knex'; import { applyFilter, applySearch } from '../utils/apply-query'; +import { ForbiddenException } from '../exceptions'; +import { parseFilter } from '../utils/parse-filter'; export class MetaService { knex: Knex; @@ -34,15 +36,48 @@ export class MetaService { } async totalCount(collection: string) { - const records = await this.knex(collection).count('*', { as: 'count' }); - return Number(records[0].count); + const dbQuery = this.knex(collection).count('*', { as: 'count' }).first(); + + if (this.accountability?.admin !== true) { + const permissionsRecord = this.schema.permissions.find((permission) => { + return permission.action === 'read' && permission.collection === collection; + }); + + if (!permissionsRecord) throw new ForbiddenException(); + + const permissions = parseFilter(permissionsRecord.permissions, this.accountability); + + applyFilter(this.schema, dbQuery, permissions, collection); + } + + const result = await dbQuery; + + return Number(result?.count ?? 0); } async filterCount(collection: string, query: Query) { const dbQuery = this.knex(collection).count('*', { as: 'count' }); - if (query.filter) { - applyFilter(this.schema, dbQuery, query.filter, collection); + let filter = query.filter || {}; + + if (this.accountability?.admin !== true) { + const permissionsRecord = this.schema.permissions.find((permission) => { + return permission.action === 'read' && permission.collection === collection; + }); + + if (!permissionsRecord) throw new ForbiddenException(); + + const permissions = parseFilter(permissionsRecord.permissions, this.accountability); + + if (Object.keys(filter).length > 0) { + filter = { _and: [permissions, filter] }; + } else { + filter = permissions; + } + } + + if (Object.keys(filter).length > 0) { + applyFilter(this.schema, dbQuery, filter, collection); } if (query.search) {