@flowerforce/flowerbase 1.3.1-beta.2 → 1.3.1-beta.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/features/functions/utils.d.ts +9 -7
- package/dist/features/functions/utils.d.ts.map +1 -1
- package/dist/features/functions/utils.js +16 -2
- package/dist/services/mongodb-atlas/index.d.ts.map +1 -1
- package/dist/services/mongodb-atlas/index.js +10 -0
- package/dist/services/mongodb-atlas/model.d.ts +1 -0
- package/dist/services/mongodb-atlas/model.d.ts.map +1 -1
- package/dist/services/mongodb-atlas/utils.d.ts +1 -1
- package/dist/services/mongodb-atlas/utils.d.ts.map +1 -1
- package/dist/utils/crypto/index.js +1 -1
- package/package.json +1 -1
- package/src/features/functions/utils.ts +23 -4
- package/src/services/mongodb-atlas/__tests__/count.test.ts +87 -0
- package/src/services/mongodb-atlas/index.ts +11 -0
- package/src/services/mongodb-atlas/model.ts +3 -0
- package/src/services/mongodb-atlas/utils.ts +1 -1
- package/src/utils/crypto/index.ts +1 -1
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { Document } from 'mongodb';
|
|
1
2
|
import { ExecuteQueryParams, Functions } from './interface';
|
|
2
3
|
/**
|
|
3
4
|
* > Loads the functions config json file
|
|
@@ -13,13 +14,14 @@ export declare const loadFunctions: (rootDir?: string) => Promise<Functions>;
|
|
|
13
14
|
export declare const executeQuery: ({ currentMethod, query, update, filter, options, returnNewDocument, document, documents, pipeline, isClient }: ExecuteQueryParams) => Promise<{
|
|
14
15
|
find: () => Promise<any[]>;
|
|
15
16
|
findOne: () => Promise<unknown>;
|
|
17
|
+
count: () => Promise<number>;
|
|
16
18
|
deleteOne: () => Promise<unknown>;
|
|
17
|
-
insertOne: () => Promise<import("mongodb
|
|
18
|
-
updateOne: () => Promise<unknown> | import("mongodb
|
|
19
|
-
findOneAndUpdate: () => Promise<
|
|
20
|
-
aggregate: () => Promise<
|
|
21
|
-
insertMany: () => Promise<import("mongodb
|
|
22
|
-
updateMany: () => Promise<import("mongodb
|
|
23
|
-
deleteMany: () => Promise<import("mongodb
|
|
19
|
+
insertOne: () => Promise<import("mongodb").InsertOneResult<Document>>;
|
|
20
|
+
updateOne: () => Promise<unknown> | import("mongodb").FindCursor<any> | import("mongodb").ChangeStream<Document, Document> | import("mongodb").AggregationCursor<Document>;
|
|
21
|
+
findOneAndUpdate: () => Promise<Document | null>;
|
|
22
|
+
aggregate: () => Promise<Document[]>;
|
|
23
|
+
insertMany: () => Promise<import("mongodb").InsertManyResult<Document>>;
|
|
24
|
+
updateMany: () => Promise<import("mongodb").UpdateResult<Document>>;
|
|
25
|
+
deleteMany: () => Promise<import("mongodb").DeleteResult>;
|
|
24
26
|
}>;
|
|
25
27
|
//# sourceMappingURL=utils.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"utils.d.ts","sourceRoot":"","sources":["../../../src/features/functions/utils.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"utils.d.ts","sourceRoot":"","sources":["../../../src/features/functions/utils.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,QAAQ,EAAE,MAAM,SAAS,CAAA;AAGlC,OAAO,EAAE,kBAAkB,EAAE,SAAS,EAAE,MAAM,aAAa,CAAA;AAE3D;;;GAGG;AACH,eAAO,MAAM,aAAa,GAAU,gBAAuB,KAAG,OAAO,CAAC,SAAS,CAwB9E,CAAA;AAED;;;;;GAKG;AACH,eAAO,MAAM,YAAY,GAAU,+GAWhC,kBAAkB;;;;;;;;;;;;EA4EpB,CAAA"}
|
|
@@ -70,15 +70,29 @@ const executeQuery = (_a) => __awaiter(void 0, [_a], void 0, function* ({ curren
|
|
|
70
70
|
: typeof returnNewDocument === 'boolean'
|
|
71
71
|
? { returnDocument: returnNewDocument ? 'after' : 'before' }
|
|
72
72
|
: undefined;
|
|
73
|
+
const parsedOptions = resolvedOptions ? bson_1.EJSON.deserialize(resolvedOptions) : undefined;
|
|
73
74
|
return {
|
|
74
75
|
find: () => __awaiter(void 0, void 0, void 0, function* () {
|
|
75
|
-
return yield
|
|
76
|
+
return yield (() => {
|
|
77
|
+
const cursor = currentMethod(bson_1.EJSON.deserialize(resolvedQuery));
|
|
78
|
+
if (parsedOptions === null || parsedOptions === void 0 ? void 0 : parsedOptions.sort) {
|
|
79
|
+
cursor.sort(parsedOptions.sort);
|
|
80
|
+
}
|
|
81
|
+
if (typeof (parsedOptions === null || parsedOptions === void 0 ? void 0 : parsedOptions.skip) === 'number') {
|
|
82
|
+
cursor.skip(parsedOptions.skip);
|
|
83
|
+
}
|
|
84
|
+
if (typeof (parsedOptions === null || parsedOptions === void 0 ? void 0 : parsedOptions.limit) === 'number') {
|
|
85
|
+
cursor.limit(parsedOptions.limit);
|
|
86
|
+
}
|
|
87
|
+
return cursor.toArray();
|
|
88
|
+
})();
|
|
76
89
|
}),
|
|
77
90
|
findOne: () => currentMethod(bson_1.EJSON.deserialize(resolvedQuery)),
|
|
91
|
+
count: () => currentMethod(bson_1.EJSON.deserialize(resolvedQuery), parsedOptions),
|
|
78
92
|
deleteOne: () => currentMethod(bson_1.EJSON.deserialize(resolvedQuery)),
|
|
79
93
|
insertOne: () => currentMethod(bson_1.EJSON.deserialize(document)),
|
|
80
94
|
updateOne: () => currentMethod(bson_1.EJSON.deserialize(resolvedQuery), bson_1.EJSON.deserialize(resolvedUpdate)),
|
|
81
|
-
findOneAndUpdate: () => currentMethod(bson_1.EJSON.deserialize(resolvedQuery), bson_1.EJSON.deserialize(resolvedUpdate),
|
|
95
|
+
findOneAndUpdate: () => currentMethod(bson_1.EJSON.deserialize(resolvedQuery), bson_1.EJSON.deserialize(resolvedUpdate), parsedOptions),
|
|
82
96
|
aggregate: () => __awaiter(void 0, void 0, void 0, function* () {
|
|
83
97
|
return (yield currentMethod(bson_1.EJSON.deserialize(pipeline), {}, // TODO -> ADD OPTIONS
|
|
84
98
|
isClient)).toArray();
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/services/mongodb-atlas/index.ts"],"names":[],"mappings":"AAaA,OAAO,EAAyC,oBAAoB,EAAE,MAAM,SAAS,CAAA;
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/services/mongodb-atlas/index.ts"],"names":[],"mappings":"AAaA,OAAO,EAAyC,oBAAoB,EAAE,MAAM,SAAS,CAAA;AA4yBrF,QAAA,MAAM,YAAY,EAAE,oBAsBlB,CAAA;AAEF,eAAe,YAAY,CAAA"}
|
|
@@ -401,6 +401,16 @@ const getOperators = (collection, { rules, collName, user, run_as_system }) => {
|
|
|
401
401
|
// System mode: return original unfiltered cursor
|
|
402
402
|
return collection.find(query);
|
|
403
403
|
},
|
|
404
|
+
count: (query, options) => {
|
|
405
|
+
if (!run_as_system) {
|
|
406
|
+
(0, utils_2.checkDenyOperation)(normalizedRules, collection.collectionName, model_1.CRUD_OPERATIONS.READ);
|
|
407
|
+
const formattedQuery = (0, utils_2.getFormattedQuery)(filters, query, user);
|
|
408
|
+
const currentQuery = formattedQuery.length ? { $and: formattedQuery } : {};
|
|
409
|
+
logService('count query', { collName, currentQuery });
|
|
410
|
+
return collection.countDocuments(currentQuery, options);
|
|
411
|
+
}
|
|
412
|
+
return collection.countDocuments(query, options);
|
|
413
|
+
},
|
|
404
414
|
/**
|
|
405
415
|
* Watches changes on a MongoDB collection with optional role-based filtering of change events.
|
|
406
416
|
*
|
|
@@ -30,6 +30,7 @@ export type GetOperatorsFunction = (collection: Collection<Document>, { rules, c
|
|
|
30
30
|
updateOne: (...params: Parameters<Method<'updateOne'>>) => ReturnType<Method<'updateOne'>>;
|
|
31
31
|
findOneAndUpdate: (filter: MongoFilter<Document>, update: UpdateFilter<Document> | Document[], options?: FindOneAndUpdateOptions) => Promise<Document | null>;
|
|
32
32
|
find: (...params: Parameters<Method<'find'>>) => FindCursor;
|
|
33
|
+
count: (...params: Parameters<Method<'countDocuments'>>) => ReturnType<Method<'countDocuments'>>;
|
|
33
34
|
watch: (...params: Parameters<Method<'watch'>>) => ReturnType<Method<'watch'>>;
|
|
34
35
|
aggregate: (...params: [...Parameters<Method<'aggregate'>>, isClient: boolean]) => ReturnType<Method<'aggregate'>>;
|
|
35
36
|
insertMany: (...params: Parameters<Method<'insertMany'>>) => ReturnType<Method<'insertMany'>>;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"model.d.ts","sourceRoot":"","sources":["../../../src/services/mongodb-atlas/model.ts"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"model.d.ts","sourceRoot":"","sources":["../../../src/services/mongodb-atlas/model.ts"],"names":[],"mappings":"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"}
|
|
@@ -5,7 +5,7 @@ import { AggregationPipeline, Filter, Projection, Rules } from '../../features/r
|
|
|
5
5
|
import { Role } from '../../utils/roles/interface';
|
|
6
6
|
import { CRUD_OPERATIONS, GetValidRuleParams } from './model';
|
|
7
7
|
export declare const getValidRule: <T extends Role | Filter>({ filters, user, record }: GetValidRuleParams<T>) => T[];
|
|
8
|
-
export declare const getFormattedQuery: (filters
|
|
8
|
+
export declare const getFormattedQuery: (filters?: Filter[], query?: Parameters<Collection<Document>["findOne"]>[0], user?: User) => FilterMongoDB<Document>[];
|
|
9
9
|
export declare const getFormattedProjection: (filters?: Filter[], user?: User) => Projection | null;
|
|
10
10
|
export declare const applyAccessControlToPipeline: (pipeline: AggregationPipeline, rules: Record<string, {
|
|
11
11
|
filters?: Filter[];
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"utils.d.ts","sourceRoot":"","sources":["../../../src/services/mongodb-atlas/utils.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,SAAS,CAAA;AAElC,OAAO,EAAE,UAAU,EAAE,QAAQ,EAAE,MAAM,IAAI,aAAa,EAAE,MAAM,SAAS,CAAA;AACvE,OAAO,EAAE,IAAI,EAAE,MAAM,iBAAiB,CAAA;AACtC,OAAO,EACL,mBAAmB,EAEnB,MAAM,EAEN,UAAU,EACV,KAAK,EAGN,MAAM,gCAAgC,CAAA;AACvC,OAAO,EAAE,IAAI,EAAE,MAAM,6BAA6B,CAAA;AAGlD,OAAO,EAAE,eAAe,EAAE,kBAAkB,EAAE,MAAM,SAAS,CAAA;AAE7D,eAAO,MAAM,YAAY,GAAI,CAAC,SAAS,IAAI,GAAG,MAAM,EAAE,2BAInD,kBAAkB,CAAC,CAAC,CAAC,QA8BvB,CAAA;AAED,eAAO,MAAM,iBAAiB,GAC5B,
|
|
1
|
+
{"version":3,"file":"utils.d.ts","sourceRoot":"","sources":["../../../src/services/mongodb-atlas/utils.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,SAAS,CAAA;AAElC,OAAO,EAAE,UAAU,EAAE,QAAQ,EAAE,MAAM,IAAI,aAAa,EAAE,MAAM,SAAS,CAAA;AACvE,OAAO,EAAE,IAAI,EAAE,MAAM,iBAAiB,CAAA;AACtC,OAAO,EACL,mBAAmB,EAEnB,MAAM,EAEN,UAAU,EACV,KAAK,EAGN,MAAM,gCAAgC,CAAA;AACvC,OAAO,EAAE,IAAI,EAAE,MAAM,6BAA6B,CAAA;AAGlD,OAAO,EAAE,eAAe,EAAE,kBAAkB,EAAE,MAAM,SAAS,CAAA;AAE7D,eAAO,MAAM,YAAY,GAAI,CAAC,SAAS,IAAI,GAAG,MAAM,EAAE,2BAInD,kBAAkB,CAAC,CAAC,CAAC,QA8BvB,CAAA;AAED,eAAO,MAAM,iBAAiB,GAC5B,UAAS,MAAM,EAAO,EACtB,QAAQ,UAAU,CAAC,UAAU,CAAC,QAAQ,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC,EACtD,OAAO,IAAI,8BAcZ,CAAA;AAED,eAAO,MAAM,sBAAsB,GACjC,UAAS,MAAM,EAAO,EACtB,OAAO,IAAI,KACV,UAAU,GAAG,IAaf,CAAA;AAED,eAAO,MAAM,4BAA4B,GACvC,UAAU,mBAAmB,EAC7B,OAAO,MAAM,CACX,MAAM,EACN;IACE,OAAO,CAAC,EAAE,MAAM,EAAE,CAAA;IAClB,KAAK,CAAC,EAAE,IAAI,EAAE,CAAA;CACf,CACF,EACD,MAAM,IAAI,EACV,gBAAgB,MAAM,EACtB,UAAU;IACR,gBAAgB,CAAC,EAAE,OAAO,CAAA;CAC3B,KACA,mBA6GF,CAAA;AAED,eAAO,MAAM,kBAAkB,GAC7B,OAAO,KAAK,EACZ,gBAAgB,MAAM,EACtB,WAAW,eAAe,SAM3B,CAAA;AAED,wBAAgB,cAAc,CAAC,KAAK,EAAE,aAAa,CAAC,QAAQ,CAAC,EAAE;;;;;;;;iBA2HuvrS,CAAC;sBAAgC,CAAC;2BAAsC,CAAC;;;;IAnH93rS;AAED,eAAO,MAAM,0BAA0B,GAAI,UAAU,QAAQ,EAAE,aAgC9D,CAAA;AAYD,wBAAgB,0BAA0B,CAAC,QAAQ,EAAE,mBAAmB,QA+BvE;AAED,wBAAgB,8BAA8B,CAAC,WAAW,CAAC,EAAE;IAAE,KAAK,CAAC,EAAE,IAAI,EAAE,CAAA;CAAE,YAK9E;AAyBD,wBAAgB,iBAAiB,CAAC,QAAQ,EAAE,mBAAmB,EAAE,YAAY,EAAE,MAAM,EAAE,uBAKtF"}
|
|
@@ -36,7 +36,7 @@ exports.hashPassword = hashPassword;
|
|
|
36
36
|
const comparePassword = (plaintext, storedPassword) => __awaiter(void 0, void 0, void 0, function* () {
|
|
37
37
|
const [storedHash, storedSalt] = storedPassword.split('.');
|
|
38
38
|
if (!storedHash || !storedSalt) {
|
|
39
|
-
throw new Error(
|
|
39
|
+
throw new Error('Invalid credentials');
|
|
40
40
|
}
|
|
41
41
|
const storedBuffer = Buffer.from(storedHash, 'hex');
|
|
42
42
|
const buffer = (yield scrypt(plaintext, storedSalt, 64));
|
package/package.json
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import fs from 'fs'
|
|
2
2
|
import path from 'node:path'
|
|
3
|
+
import { Document } from 'mongodb'
|
|
3
4
|
import { EJSON } from 'bson'
|
|
4
5
|
import { GetOperatorsFunction } from '../../services/mongodb-atlas/model'
|
|
5
6
|
import { ExecuteQueryParams, Functions } from './interface'
|
|
@@ -65,15 +66,33 @@ export const executeQuery = async ({
|
|
|
65
66
|
: typeof returnNewDocument === 'boolean'
|
|
66
67
|
? { returnDocument: returnNewDocument ? 'after' : 'before' }
|
|
67
68
|
: undefined
|
|
69
|
+
const parsedOptions = resolvedOptions ? EJSON.deserialize(resolvedOptions) : undefined
|
|
68
70
|
return {
|
|
69
71
|
find: async () =>
|
|
70
|
-
await (
|
|
71
|
-
|
|
72
|
-
|
|
72
|
+
await (() => {
|
|
73
|
+
const cursor = (currentMethod as ReturnType<GetOperatorsFunction>['find'])(
|
|
74
|
+
EJSON.deserialize(resolvedQuery)
|
|
75
|
+
)
|
|
76
|
+
if (parsedOptions?.sort) {
|
|
77
|
+
cursor.sort(parsedOptions.sort as Document)
|
|
78
|
+
}
|
|
79
|
+
if (typeof parsedOptions?.skip === 'number') {
|
|
80
|
+
cursor.skip(parsedOptions.skip)
|
|
81
|
+
}
|
|
82
|
+
if (typeof parsedOptions?.limit === 'number') {
|
|
83
|
+
cursor.limit(parsedOptions.limit)
|
|
84
|
+
}
|
|
85
|
+
return cursor.toArray()
|
|
86
|
+
})(),
|
|
73
87
|
findOne: () =>
|
|
74
88
|
(currentMethod as ReturnType<GetOperatorsFunction>['findOne'])(
|
|
75
89
|
EJSON.deserialize(resolvedQuery)
|
|
76
90
|
),
|
|
91
|
+
count: () =>
|
|
92
|
+
(currentMethod as ReturnType<GetOperatorsFunction>['count'])(
|
|
93
|
+
EJSON.deserialize(resolvedQuery),
|
|
94
|
+
parsedOptions
|
|
95
|
+
),
|
|
77
96
|
deleteOne: () =>
|
|
78
97
|
(currentMethod as ReturnType<GetOperatorsFunction>['deleteOne'])(
|
|
79
98
|
EJSON.deserialize(resolvedQuery)
|
|
@@ -87,7 +106,7 @@ export const executeQuery = async ({
|
|
|
87
106
|
(currentMethod as ReturnType<GetOperatorsFunction>['findOneAndUpdate'])(
|
|
88
107
|
EJSON.deserialize(resolvedQuery),
|
|
89
108
|
EJSON.deserialize(resolvedUpdate),
|
|
90
|
-
|
|
109
|
+
parsedOptions
|
|
91
110
|
),
|
|
92
111
|
aggregate: async () =>
|
|
93
112
|
(await (currentMethod as ReturnType<GetOperatorsFunction>['aggregate'])(
|
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
import MongoDbAtlas from '..'
|
|
2
|
+
import { Rules } from '../../../features/rules/interface'
|
|
3
|
+
|
|
4
|
+
const createAppWithCollection = (collection: Record<string, unknown>) => ({
|
|
5
|
+
mongo: {
|
|
6
|
+
client: {
|
|
7
|
+
db: jest.fn().mockReturnValue({
|
|
8
|
+
collection: jest.fn().mockReturnValue(collection)
|
|
9
|
+
})
|
|
10
|
+
}
|
|
11
|
+
}
|
|
12
|
+
})
|
|
13
|
+
|
|
14
|
+
const createRules = (overrides?: Partial<Rules[keyof Rules]>): Rules => ({
|
|
15
|
+
todos: {
|
|
16
|
+
database: 'db',
|
|
17
|
+
collection: 'todos',
|
|
18
|
+
filters: overrides?.filters ?? [],
|
|
19
|
+
roles: overrides?.roles ?? [
|
|
20
|
+
{
|
|
21
|
+
name: 'reader',
|
|
22
|
+
apply_when: {},
|
|
23
|
+
insert: true,
|
|
24
|
+
delete: true,
|
|
25
|
+
search: true,
|
|
26
|
+
read: true,
|
|
27
|
+
write: true
|
|
28
|
+
}
|
|
29
|
+
],
|
|
30
|
+
...overrides
|
|
31
|
+
}
|
|
32
|
+
})
|
|
33
|
+
|
|
34
|
+
describe('mongodb-atlas count', () => {
|
|
35
|
+
it('applies formatted query for RBAC before counting', async () => {
|
|
36
|
+
const countDocuments = jest.fn().mockResolvedValue(7)
|
|
37
|
+
const collection = {
|
|
38
|
+
collectionName: 'todos',
|
|
39
|
+
countDocuments
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
const rules = {
|
|
43
|
+
filters: [
|
|
44
|
+
{
|
|
45
|
+
name: 'ownerFilter',
|
|
46
|
+
query: { ownerId: 'user-1' },
|
|
47
|
+
apply_when: {}
|
|
48
|
+
}
|
|
49
|
+
]
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
const operators = MongoDbAtlas(createAppWithCollection(collection) as any, {
|
|
53
|
+
rules: createRules(rules),
|
|
54
|
+
user: { id: 'user-1' }
|
|
55
|
+
})
|
|
56
|
+
.db('db')
|
|
57
|
+
.collection('todos')
|
|
58
|
+
|
|
59
|
+
const result = await operators.count({ workspace: 'workspace-1' })
|
|
60
|
+
|
|
61
|
+
expect(result).toBe(7)
|
|
62
|
+
expect(countDocuments).toHaveBeenCalledWith(
|
|
63
|
+
{ $and: [{ ownerId: 'user-1' }, { workspace: 'workspace-1' }] },
|
|
64
|
+
undefined
|
|
65
|
+
)
|
|
66
|
+
})
|
|
67
|
+
|
|
68
|
+
it('delegates directly when running as system', async () => {
|
|
69
|
+
const countDocuments = jest.fn().mockResolvedValue(42)
|
|
70
|
+
const collection = {
|
|
71
|
+
collectionName: 'todos',
|
|
72
|
+
countDocuments
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
const operators = MongoDbAtlas(createAppWithCollection(collection) as any, {
|
|
76
|
+
run_as_system: true
|
|
77
|
+
})
|
|
78
|
+
.db('db')
|
|
79
|
+
.collection('todos')
|
|
80
|
+
|
|
81
|
+
const options = { maxTimeMS: 500 }
|
|
82
|
+
const result = await operators.count({ workspace: 'workspace-2' }, options)
|
|
83
|
+
|
|
84
|
+
expect(result).toBe(42)
|
|
85
|
+
expect(countDocuments).toHaveBeenCalledWith({ workspace: 'workspace-2' }, options)
|
|
86
|
+
})
|
|
87
|
+
})
|
|
@@ -473,6 +473,17 @@ const getOperators: GetOperatorsFunction = (
|
|
|
473
473
|
// System mode: return original unfiltered cursor
|
|
474
474
|
return collection.find(query)
|
|
475
475
|
},
|
|
476
|
+
count: (query, options) => {
|
|
477
|
+
if (!run_as_system) {
|
|
478
|
+
checkDenyOperation(normalizedRules, collection.collectionName, CRUD_OPERATIONS.READ)
|
|
479
|
+
const formattedQuery = getFormattedQuery(filters, query, user)
|
|
480
|
+
const currentQuery = formattedQuery.length ? { $and: formattedQuery } : {}
|
|
481
|
+
logService('count query', { collName, currentQuery })
|
|
482
|
+
return collection.countDocuments(currentQuery, options)
|
|
483
|
+
}
|
|
484
|
+
|
|
485
|
+
return collection.countDocuments(query, options)
|
|
486
|
+
},
|
|
476
487
|
/**
|
|
477
488
|
* Watches changes on a MongoDB collection with optional role-based filtering of change events.
|
|
478
489
|
*
|
|
@@ -64,6 +64,9 @@ export type GetOperatorsFunction = (
|
|
|
64
64
|
options?: FindOneAndUpdateOptions
|
|
65
65
|
) => Promise<Document | null>
|
|
66
66
|
find: (...params: Parameters<Method<'find'>>) => FindCursor
|
|
67
|
+
count: (
|
|
68
|
+
...params: Parameters<Method<'countDocuments'>>
|
|
69
|
+
) => ReturnType<Method<'countDocuments'>>
|
|
67
70
|
watch: (...params: Parameters<Method<'watch'>>) => ReturnType<Method<'watch'>>
|
|
68
71
|
aggregate: (
|
|
69
72
|
...params: [...Parameters<Method<'aggregate'>>, isClient: boolean]
|
|
@@ -55,7 +55,7 @@ export const getValidRule = <T extends Role | Filter>({
|
|
|
55
55
|
|
|
56
56
|
export const getFormattedQuery = (
|
|
57
57
|
filters: Filter[] = [],
|
|
58
|
-
query
|
|
58
|
+
query?: Parameters<Collection<Document>['findOne']>[0],
|
|
59
59
|
user?: User
|
|
60
60
|
) => {
|
|
61
61
|
const preFilter = getValidRule({ filters, user })
|
|
@@ -24,7 +24,7 @@ export const comparePassword = async (plaintext: string, storedPassword: string)
|
|
|
24
24
|
const [storedHash, storedSalt] = storedPassword.split('.')
|
|
25
25
|
|
|
26
26
|
if (!storedHash || !storedSalt) {
|
|
27
|
-
throw new Error(
|
|
27
|
+
throw new Error('Invalid credentials');
|
|
28
28
|
}
|
|
29
29
|
|
|
30
30
|
const storedBuffer = Buffer.from(storedHash, 'hex')
|