@casl/mongoose 7.3.1 → 8.0.0
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/es6c/index.js +119 -1
- package/dist/es6c/index.js.map +1 -1
- package/dist/es6m/index.mjs +113 -1
- package/dist/es6m/index.mjs.map +1 -1
- package/dist/types/accessibleBy.d.ts +3 -4
- package/dist/types/plugins/accessible_fields.d.ts +0 -24
- package/dist/types/plugins/accessible_records.d.ts +0 -24
- package/package.json +1 -1
package/dist/es6c/index.js
CHANGED
|
@@ -1,2 +1,120 @@
|
|
|
1
|
-
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
var extra = require('@casl/ability/extra');
|
|
4
|
+
var ability = require('@casl/ability');
|
|
5
|
+
var mongoose = require('mongoose');
|
|
6
|
+
|
|
7
|
+
function convertToMongoQuery(rule) {
|
|
8
|
+
const conditions = rule.conditions;
|
|
9
|
+
return rule.inverted ? {
|
|
10
|
+
$nor: [conditions]
|
|
11
|
+
} : conditions;
|
|
12
|
+
}
|
|
13
|
+
const EMPTY_RESULT_QUERY = {
|
|
14
|
+
$expr: {
|
|
15
|
+
$eq: [0, 1]
|
|
16
|
+
}
|
|
17
|
+
};
|
|
18
|
+
class AccessibleRecords {
|
|
19
|
+
constructor(_ability, _action) {
|
|
20
|
+
this._ability = _ability;
|
|
21
|
+
this._action = _action;
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
/**
|
|
25
|
+
* In case action is not allowed, it returns `{ $expr: { $eq: [0, 1] } }`
|
|
26
|
+
*/
|
|
27
|
+
ofType(subjectType) {
|
|
28
|
+
const query = extra.rulesToQuery(this._ability, this._action, subjectType, convertToMongoQuery);
|
|
29
|
+
return query === null ? EMPTY_RESULT_QUERY : query;
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
/**
|
|
34
|
+
* Returns accessible records Mongo query per record type (i.e., entity type) based on provided Ability and action.
|
|
35
|
+
*/
|
|
36
|
+
function accessibleBy(ability, action = 'read') {
|
|
37
|
+
return new AccessibleRecords(ability, action);
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
function accessibleRecords(baseQuery, ability, action) {
|
|
41
|
+
const subjectType = ability.detectSubjectType({
|
|
42
|
+
constructor: baseQuery.model
|
|
43
|
+
});
|
|
44
|
+
if (!subjectType) {
|
|
45
|
+
throw new TypeError(`Cannot detect subject type of "${baseQuery.model.modelName}" to return accessible records`);
|
|
46
|
+
}
|
|
47
|
+
const query = accessibleBy(ability, action).ofType(subjectType);
|
|
48
|
+
return baseQuery.and([query]);
|
|
49
|
+
}
|
|
50
|
+
function modelAccessibleBy(ability, action) {
|
|
51
|
+
return accessibleRecords(this.where(), ability, action);
|
|
52
|
+
}
|
|
53
|
+
function queryAccessibleBy(ability, action) {
|
|
54
|
+
return accessibleRecords(this, ability, action);
|
|
55
|
+
}
|
|
56
|
+
function accessibleRecordsPlugin(schema) {
|
|
57
|
+
schema.query.accessibleBy = queryAccessibleBy;
|
|
58
|
+
schema.statics.accessibleBy = modelAccessibleBy;
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
const getSchemaPaths = schema => Object.keys(schema.paths);
|
|
62
|
+
function fieldsOf(schema, options) {
|
|
63
|
+
const fields = options.getFields(schema);
|
|
64
|
+
if (!options || !('except' in options)) {
|
|
65
|
+
return fields;
|
|
66
|
+
}
|
|
67
|
+
const excludedFields = ability.wrapArray(options.except);
|
|
68
|
+
return fields.filter(field => excludedFields.indexOf(field) === -1);
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
/**
|
|
72
|
+
* @deprecated Mongoose recommends against `extends Document`, prefer to use `AccessibleFieldsModel` instead.
|
|
73
|
+
* See here: https://mongoosejs.com/docs/typescript.html#using-extends-document
|
|
74
|
+
*/
|
|
75
|
+
|
|
76
|
+
function getAllSchemaFieldsFactory() {
|
|
77
|
+
let getAllFields;
|
|
78
|
+
return (schema, options) => {
|
|
79
|
+
if (!getAllFields) {
|
|
80
|
+
const ALL_FIELDS = options && 'only' in options ? ability.wrapArray(options.only) : fieldsOf(schema, options);
|
|
81
|
+
getAllFields = () => ALL_FIELDS;
|
|
82
|
+
}
|
|
83
|
+
return getAllFields;
|
|
84
|
+
};
|
|
85
|
+
}
|
|
86
|
+
function accessibleFieldsPlugin(schema, rawOptions) {
|
|
87
|
+
const options = Object.assign({
|
|
88
|
+
getFields: getSchemaPaths
|
|
89
|
+
}, rawOptions);
|
|
90
|
+
const getAllFields = getAllSchemaFieldsFactory();
|
|
91
|
+
function instanceAccessibleFields(ability, action) {
|
|
92
|
+
return new extra.AccessibleFields(ability, action || 'read', getAllFields(schema, options)).of(this);
|
|
93
|
+
}
|
|
94
|
+
function modelAccessibleFields(ability, action) {
|
|
95
|
+
// using fake document because at this point we don't know how Ability's detectSubjectType was configured:
|
|
96
|
+
// does it use classes or strings?
|
|
97
|
+
const fakeDocument = {
|
|
98
|
+
constructor: this
|
|
99
|
+
};
|
|
100
|
+
return new extra.AccessibleFields(ability, action || 'read', getAllFields(schema, options)).of(fakeDocument);
|
|
101
|
+
}
|
|
102
|
+
schema.statics.accessibleFieldsBy = modelAccessibleFields;
|
|
103
|
+
schema.method('accessibleFieldsBy', instanceAccessibleFields);
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
const getSubjectTypeAllFieldsExtractor = type => {
|
|
107
|
+
const Model = typeof type === 'string' ? mongoose.models[type] : type;
|
|
108
|
+
if (!Model) throw new Error(`Unknown mongoose model "${type}"`);
|
|
109
|
+
return 'schema' in Model ? Object.keys(Model.schema.paths) : [];
|
|
110
|
+
};
|
|
111
|
+
function accessibleFieldsBy(ability, action = 'read') {
|
|
112
|
+
return new extra.AccessibleFields(ability, action, getSubjectTypeAllFieldsExtractor);
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
exports.accessibleBy = accessibleBy;
|
|
116
|
+
exports.accessibleFieldsBy = accessibleFieldsBy;
|
|
117
|
+
exports.accessibleFieldsPlugin = accessibleFieldsPlugin;
|
|
118
|
+
exports.accessibleRecordsPlugin = accessibleRecordsPlugin;
|
|
119
|
+
exports.getSchemaPaths = getSchemaPaths;
|
|
2
120
|
//# sourceMappingURL=index.js.map
|
package/dist/es6c/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sources":["../../src/accessibleBy.ts","../../src/plugins/accessible_records.ts","../../src/plugins/accessible_fields.ts","../../src/accessibleFieldsBy.ts"],"sourcesContent":["import { AnyMongoAbility, Generics, SubjectType, Abilities, AbilityTuple, ExtractSubjectType } from '@casl/ability';\nimport { rulesToQuery } from '@casl/ability/extra';\n\nfunction convertToMongoQuery(rule: AnyMongoAbility['rules'][number]) {\n const conditions = rule.conditions!;\n return rule.inverted ? { $nor: [conditions] } : conditions;\n}\n\nexport const EMPTY_RESULT_QUERY = { $expr: { $eq: [0, 1] } };\nexport class AccessibleRecords<T extends SubjectType> {\n constructor(\n private readonly _ability: AnyMongoAbility,\n private readonly _action: string\n ) {}\n\n /**\n * In case action is not allowed, it returns `{ $expr: { $eq: [0, 1] } }`\n */\n ofType(subjectType: T): Record<string, unknown> {\n const query = rulesToQuery(this._ability, this._action, subjectType, convertToMongoQuery);\n return query === null ? EMPTY_RESULT_QUERY : query as Record<string, unknown>;\n }\n}\n\ntype SubjectTypes<T extends Abilities> = T extends AbilityTuple\n ? ExtractSubjectType<T[1]>\n : never;\n\n/**\n * Returns accessible records Mongo query per record type (i.e., entity type) based on provided Ability and action.\n */\nexport function accessibleBy<T extends AnyMongoAbility>(\n ability: T,\n action: Parameters<T['rulesFor']>[0] = 'read'\n): AccessibleRecords<SubjectTypes<Generics<T>['abilities']>> {\n return new AccessibleRecords(ability, action);\n}\n","import { AnyMongoAbility, Generics, Normalize } from '@casl/ability';\nimport { Document, HydratedDocument, Model, Query, QueryWithHelpers, Schema } from 'mongoose';\nimport { accessibleBy } from '../accessibleBy';\n\nfunction accessibleRecords<T extends AnyMongoAbility>(\n baseQuery: Query<any, any>,\n ability: T,\n action?: Normalize<Generics<T>['abilities']>[0]\n): QueryWithHelpers<Document, Document> {\n const subjectType = ability.detectSubjectType({\n constructor: baseQuery.model\n });\n\n if (!subjectType) {\n throw new TypeError(`Cannot detect subject type of \"${baseQuery.model.modelName}\" to return accessible records`);\n }\n\n const query = accessibleBy(ability, action).ofType(subjectType);\n\n return baseQuery.and([query]);\n}\n\ntype GetAccessibleRecords<T, TQueryHelpers, TMethods, TVirtuals> = <U extends AnyMongoAbility>(\n ability: U,\n action?: Normalize<Generics<U>['abilities']>[0]\n) => QueryWithHelpers<\nArray<T>,\nT,\nAccessibleRecordQueryHelpers<T, TQueryHelpers, TMethods, TVirtuals>\n>;\n\nexport type AccessibleRecordQueryHelpers<T, TQueryHelpers = {}, TMethods = {}, TVirtuals = {}> = {\n /** @deprecated use accessibleBy helper instead */\n accessibleBy: GetAccessibleRecords<\n HydratedDocument<T, TMethods, TVirtuals>,\n TQueryHelpers,\n TMethods,\n TVirtuals\n >\n};\nexport interface AccessibleRecordModel<\n T,\n TQueryHelpers = {},\n TMethods = {},\n TVirtuals = {}\n> extends Model<T,\n TQueryHelpers & AccessibleRecordQueryHelpers<T, TQueryHelpers, TMethods, TVirtuals>,\n TMethods,\n TVirtuals> {\n /** @deprecated use accessibleBy helper instead */\n accessibleBy: GetAccessibleRecords<\n HydratedDocument<T, TMethods, TVirtuals>,\n TQueryHelpers,\n TMethods,\n TVirtuals\n >\n}\n\nfunction modelAccessibleBy(this: Model<unknown>, ability: AnyMongoAbility, action?: string) {\n return accessibleRecords(this.where(), ability, action);\n}\n\nfunction queryAccessibleBy(\n this: Query<unknown, unknown>,\n ability: AnyMongoAbility,\n action?: string\n) {\n return accessibleRecords(this, ability, action);\n}\n\nexport function accessibleRecordsPlugin(schema: Schema<any>): void {\n (schema.query as Record<string, unknown>).accessibleBy = queryAccessibleBy;\n schema.statics.accessibleBy = modelAccessibleBy;\n}\n","import { AnyMongoAbility, Generics, Normalize, wrapArray } from '@casl/ability';\nimport { AccessibleFields, GetSubjectTypeAllFieldsExtractor } from '@casl/ability/extra';\nimport type { Document, Model, Schema } from 'mongoose';\n\nexport type AccessibleFieldsOptions =\n {\n getFields(schema: Schema<Document>): string[]\n } &\n ({ only: string | string[] } | { except: string | string[] });\n\nexport const getSchemaPaths: AccessibleFieldsOptions['getFields'] = schema => Object.keys((schema as { paths: object }).paths);\n\nfunction fieldsOf(schema: Schema<Document>, options: Partial<AccessibleFieldsOptions>) {\n const fields = options.getFields!(schema);\n\n if (!options || !('except' in options)) {\n return fields;\n }\n\n const excludedFields = wrapArray(options.except);\n return fields.filter(field => excludedFields.indexOf(field) === -1);\n}\n\ntype GetAccessibleFields<T> = <U extends AnyMongoAbility>(\n this: Model<T> | T,\n ability: U,\n action?: Normalize<Generics<U>['abilities']>[0]\n) => string[];\n\nexport interface AccessibleFieldsModel<\n T,\n TQueryHelpers = {},\n TMethods = {},\n TVirtuals = {}\n> extends Model<T, TQueryHelpers, TMethods & AccessibleFieldDocumentMethods<T>, TVirtuals> {\n accessibleFieldsBy: GetAccessibleFields<T>\n}\n\nexport interface AccessibleFieldDocumentMethods<T = Document> {\n accessibleFieldsBy: GetAccessibleFields<T>\n}\n\n/**\n * @deprecated Mongoose recommends against `extends Document`, prefer to use `AccessibleFieldsModel` instead.\n * See here: https://mongoosejs.com/docs/typescript.html#using-extends-document\n */\nexport interface AccessibleFieldsDocument extends Document, AccessibleFieldDocumentMethods {}\n\nfunction getAllSchemaFieldsFactory() {\n let getAllFields: GetSubjectTypeAllFieldsExtractor;\n return (schema: Schema<any>, options: Partial<AccessibleFieldsOptions>) => {\n if (!getAllFields) {\n const ALL_FIELDS = options && 'only' in options\n ? wrapArray(options.only as string[])\n : fieldsOf(schema, options);\n getAllFields = () => ALL_FIELDS;\n }\n\n return getAllFields;\n };\n}\n\nexport function accessibleFieldsPlugin(\n schema: Schema<any>,\n rawOptions?: Partial<AccessibleFieldsOptions>\n): void {\n const options = { getFields: getSchemaPaths, ...rawOptions };\n const getAllFields = getAllSchemaFieldsFactory();\n\n function instanceAccessibleFields(this: Document, ability: AnyMongoAbility, action?: string) {\n return new AccessibleFields(ability, action || 'read', getAllFields(schema, options)).of(this);\n }\n\n function modelAccessibleFields(this: Model<unknown>, ability: AnyMongoAbility, action?: string) {\n // using fake document because at this point we don't know how Ability's detectSubjectType was configured:\n // does it use classes or strings?\n const fakeDocument = { constructor: this };\n return new AccessibleFields(ability, action || 'read', getAllFields(schema, options)).of(fakeDocument);\n }\n\n schema.statics.accessibleFieldsBy = modelAccessibleFields;\n schema.method('accessibleFieldsBy', instanceAccessibleFields);\n}\n","import { AnyMongoAbility, Generics } from \"@casl/ability\";\nimport { AccessibleFields, GetSubjectTypeAllFieldsExtractor } from \"@casl/ability/extra\";\nimport mongoose from 'mongoose';\n\nconst getSubjectTypeAllFieldsExtractor: GetSubjectTypeAllFieldsExtractor = (type) => {\n const Model = typeof type === 'string' ? mongoose.models[type] : type;\n if (!Model) throw new Error(`Unknown mongoose model \"${type}\"`);\n return 'schema' in Model ? Object.keys((Model.schema as any).paths) : [];\n};\n\nexport function accessibleFieldsBy<T extends AnyMongoAbility>(\n ability: T,\n action: Parameters<T['rulesFor']>[0] = 'read'\n): AccessibleFields<Extract<Generics<T>['abilities'], unknown[]>[1]> {\n return new AccessibleFields(ability, action, getSubjectTypeAllFieldsExtractor);\n}\n"],"names":["convertToMongoQuery","rule","conditions","inverted","$nor","EMPTY_RESULT_QUERY","$expr","$eq","AccessibleRecords","constructor","_ability","_action","this","ofType","subjectType","query","rulesToQuery","accessibleBy","ability","action","accessibleRecords","baseQuery","detectSubjectType","model","TypeError","modelName","and","modelAccessibleBy","where","queryAccessibleBy","accessibleRecordsPlugin","schema","statics","getSchemaPaths","Object","keys","paths","fieldsOf","options","fields","getFields","excludedFields","wrapArray","except","filter","field","indexOf","getAllSchemaFieldsFactory","getAllFields","ALL_FIELDS","only","accessibleFieldsPlugin","rawOptions","assign","instanceAccessibleFields","AccessibleFields","of","modelAccessibleFields","fakeDocument","accessibleFieldsBy","method","getSubjectTypeAllFieldsExtractor","type","Model","mongoose","models","Error"],"mappings":"2GAGA,SAASA,EAAoBC,GAC3B,MAAMC,EAAaD,EAAKC,WACxB,OAAOD,EAAKE,SAAW,CAAEC,KAAM,CAACF,IAAgBA,CAClD,CAEO,MAAMG,EAAqB,CAAEC,MAAO,CAAEC,IAAK,CAAC,EAAG,KAC/C,MAAMC,EACXC,WAAAA,CACmBC,EACAC,GACjBC,KAFiBF,EAAAA,EAAyBE,KACzBD,EAAAA,CAChB,CAKHE,MAAAA,CAAOC,GACL,MAAMC,EAAQC,EAAYA,aAACJ,KAAKF,EAAUE,KAAKD,EAASG,EAAad,GACrE,OAAOe,IAAU,KAAOV,EAAqBU,CAC/C,EAUK,SAASE,EACdC,EACAC,EAAuC,QAEvC,OAAO,IAAIX,EAAkBU,EAASC,EACxC,CChCA,SAASC,EACPC,EACAH,EACAC,GAEA,MAAML,EAAcI,EAAQI,kBAAkB,CAC5Cb,YAAaY,EAAUE,QAGzB,IAAKT,EACH,MAAM,IAAIU,UAAW,kCAAiCH,EAAUE,MAAME,2CAGxE,MAAMV,EAAQE,EAAaC,EAASC,GAAQN,OAAOC,GAEnD,OAAOO,EAAUK,IAAI,CAACX,GACxB,CAsCA,SAASY,EAAwCT,EAA0BC,GACzE,OAAOC,EAAkBR,KAAKgB,QAASV,EAASC,EAClD,CAEA,SAASU,EAEPX,EACAC,GAEA,OAAOC,EAAkBR,KAAMM,EAASC,EAC1C,CAEO,SAASW,EAAwBC,GACrCA,EAAOhB,MAAkCE,aAAeY,EACzDE,EAAOC,QAAQf,aAAeU,CAChC,CC/DaM,MAAAA,EAAuDF,GAAUG,OAAOC,KAAMJ,EAA6BK,OAExH,SAASC,EAASN,EAA0BO,GAC1C,MAAMC,EAASD,EAAQE,UAAWT,GAElC,IAAKO,KAAa,WAAYA,GAC5B,OAAOC,EAGT,MAAME,EAAiBC,EAAAA,UAAUJ,EAAQK,QACzC,OAAOJ,EAAOK,QAAOC,GAASJ,EAAeK,QAAQD,MAAY,GACnE,CA2BA,SAASE,IACP,IAAIC,EACJ,MAAO,CAACjB,EAAqBO,KAC3B,IAAKU,EAAc,CACjB,MAAMC,EAAaX,GAAW,SAAUA,EACpCI,EAASA,UAACJ,EAAQY,MAClBb,EAASN,EAAQO,GACrBU,EAAeA,IAAMC,CACvB,CAEA,OAAOD,CAAY,CAEvB,CAEO,SAASG,EACdpB,EACAqB,GAEA,MAAMd,EAAOJ,OAAAmB,OAAA,CAAKb,UAAWP,GAAmBmB,GAChD,MAAMJ,EAAeD,IAErB,SAASO,EAAyCpC,EAA0BC,GAC1E,OAAO,IAAIoC,EAAgBA,iBAACrC,EAASC,GAAU,OAAQ6B,EAAajB,EAAQO,IAAUkB,GAAG5C,KAC3F,CAEA,SAAS6C,EAA4CvC,EAA0BC,GAG7E,MAAMuC,EAAe,CAAEjD,YAAaG,MACpC,OAAO,IAAI2C,EAAgBA,iBAACrC,EAASC,GAAU,OAAQ6B,EAAajB,EAAQO,IAAUkB,GAAGE,EAC3F,CAEA3B,EAAOC,QAAQ2B,mBAAqBF,EACpC1B,EAAO6B,OAAO,qBAAsBN,EACtC,CC9EA,MAAMO,EAAsEC,IAC1E,MAAMC,SAAeD,IAAS,SAAWE,EAASC,OAAOH,GAAQA,EACjE,IAAKC,EAAO,MAAM,IAAIG,MAAO,2BAA0BJ,MACvD,MAAO,WAAYC,EAAQ7B,OAAOC,KAAM4B,EAAMhC,OAAeK,OAAS,EAAE,EAGnE,SAASuB,EACdzC,EACAC,EAAuC,QAEvC,OAAO,IAAIoC,EAAAA,iBAAiBrC,EAASC,EAAQ0C,EAC/C"}
|
|
1
|
+
{"version":3,"file":"index.js","sources":["../../src/accessibleBy.ts","../../src/plugins/accessible_records.ts","../../src/plugins/accessible_fields.ts","../../src/accessibleFieldsBy.ts"],"sourcesContent":["import { AnyMongoAbility, Generics, SubjectType } from '@casl/ability';\nimport { ToAbilityTypes } from '@casl/ability/dist/types/types';\nimport { rulesToQuery } from '@casl/ability/extra';\n\nfunction convertToMongoQuery(rule: AnyMongoAbility['rules'][number]) {\n const conditions = rule.conditions!;\n return rule.inverted ? { $nor: [conditions] } : conditions;\n}\n\nexport const EMPTY_RESULT_QUERY = { $expr: { $eq: [0, 1] } };\nexport class AccessibleRecords<T extends SubjectType> {\n constructor(\n private readonly _ability: AnyMongoAbility,\n private readonly _action: string\n ) {}\n\n /**\n * In case action is not allowed, it returns `{ $expr: { $eq: [0, 1] } }`\n */\n ofType(subjectType: T): Record<string, unknown> {\n const query = rulesToQuery(this._ability, this._action, subjectType, convertToMongoQuery);\n return query === null ? EMPTY_RESULT_QUERY : query as Record<string, unknown>;\n }\n}\n\n/**\n * Returns accessible records Mongo query per record type (i.e., entity type) based on provided Ability and action.\n */\nexport function accessibleBy<T extends AnyMongoAbility>(\n ability: T,\n action: Parameters<T['rulesFor']>[0] = 'read'\n): AccessibleRecords<ToAbilityTypes<Generics<T>['abilities']>[1]> {\n return new AccessibleRecords(ability, action);\n}\n","import { AnyMongoAbility, Generics, Normalize } from '@casl/ability';\nimport { Document, HydratedDocument, Model, Query, QueryWithHelpers, Schema } from 'mongoose';\nimport { accessibleBy } from '../accessibleBy';\n\nfunction accessibleRecords<T extends AnyMongoAbility>(\n baseQuery: Query<any, any>,\n ability: T,\n action?: Normalize<Generics<T>['abilities']>[0]\n): QueryWithHelpers<Document, Document> {\n const subjectType = ability.detectSubjectType({\n constructor: baseQuery.model\n });\n\n if (!subjectType) {\n throw new TypeError(`Cannot detect subject type of \"${baseQuery.model.modelName}\" to return accessible records`);\n }\n\n const query = accessibleBy(ability, action).ofType(subjectType);\n\n return baseQuery.and([query]);\n}\n\ntype GetAccessibleRecords<T, TQueryHelpers, TMethods, TVirtuals> = <U extends AnyMongoAbility>(\n ability: U,\n action?: Normalize<Generics<U>['abilities']>[0]\n) => QueryWithHelpers<\nArray<T>,\nT,\nAccessibleRecordQueryHelpers<T, TQueryHelpers, TMethods, TVirtuals>\n>;\n\nexport type AccessibleRecordQueryHelpers<T, TQueryHelpers = {}, TMethods = {}, TVirtuals = {}> = {\n /** @deprecated use accessibleBy helper instead */\n accessibleBy: GetAccessibleRecords<\n HydratedDocument<T, TMethods, TVirtuals>,\n TQueryHelpers,\n TMethods,\n TVirtuals\n >\n};\nexport interface AccessibleRecordModel<\n T,\n TQueryHelpers = {},\n TMethods = {},\n TVirtuals = {}\n> extends Model<T,\n TQueryHelpers & AccessibleRecordQueryHelpers<T, TQueryHelpers, TMethods, TVirtuals>,\n TMethods,\n TVirtuals> {\n /** @deprecated use accessibleBy helper instead */\n accessibleBy: GetAccessibleRecords<\n HydratedDocument<T, TMethods, TVirtuals>,\n TQueryHelpers,\n TMethods,\n TVirtuals\n >\n}\n\nfunction modelAccessibleBy(this: Model<unknown>, ability: AnyMongoAbility, action?: string) {\n return accessibleRecords(this.where(), ability, action);\n}\n\nfunction queryAccessibleBy(\n this: Query<unknown, unknown>,\n ability: AnyMongoAbility,\n action?: string\n) {\n return accessibleRecords(this, ability, action);\n}\n\nexport function accessibleRecordsPlugin(schema: Schema<any>): void {\n (schema.query as Record<string, unknown>).accessibleBy = queryAccessibleBy;\n schema.statics.accessibleBy = modelAccessibleBy;\n}\n","import { AnyMongoAbility, Generics, Normalize, wrapArray } from '@casl/ability';\nimport { AccessibleFields, GetSubjectTypeAllFieldsExtractor } from '@casl/ability/extra';\nimport type { Document, Model, Schema } from 'mongoose';\n\nexport type AccessibleFieldsOptions =\n {\n getFields(schema: Schema<Document>): string[]\n } &\n ({ only: string | string[] } | { except: string | string[] });\n\nexport const getSchemaPaths: AccessibleFieldsOptions['getFields'] = schema => Object.keys((schema as { paths: object }).paths);\n\nfunction fieldsOf(schema: Schema<Document>, options: Partial<AccessibleFieldsOptions>) {\n const fields = options.getFields!(schema);\n\n if (!options || !('except' in options)) {\n return fields;\n }\n\n const excludedFields = wrapArray(options.except);\n return fields.filter(field => excludedFields.indexOf(field) === -1);\n}\n\ntype GetAccessibleFields<T> = <U extends AnyMongoAbility>(\n this: Model<T> | T,\n ability: U,\n action?: Normalize<Generics<U>['abilities']>[0]\n) => string[];\n\nexport interface AccessibleFieldsModel<\n T,\n TQueryHelpers = {},\n TMethods = {},\n TVirtuals = {}\n> extends Model<T, TQueryHelpers, TMethods & AccessibleFieldDocumentMethods<T>, TVirtuals> {\n accessibleFieldsBy: GetAccessibleFields<T>\n}\n\nexport interface AccessibleFieldDocumentMethods<T = Document> {\n accessibleFieldsBy: GetAccessibleFields<T>\n}\n\n/**\n * @deprecated Mongoose recommends against `extends Document`, prefer to use `AccessibleFieldsModel` instead.\n * See here: https://mongoosejs.com/docs/typescript.html#using-extends-document\n */\nexport interface AccessibleFieldsDocument extends Document, AccessibleFieldDocumentMethods {}\n\nfunction getAllSchemaFieldsFactory() {\n let getAllFields: GetSubjectTypeAllFieldsExtractor;\n return (schema: Schema<any>, options: Partial<AccessibleFieldsOptions>) => {\n if (!getAllFields) {\n const ALL_FIELDS = options && 'only' in options\n ? wrapArray(options.only as string[])\n : fieldsOf(schema, options);\n getAllFields = () => ALL_FIELDS;\n }\n\n return getAllFields;\n };\n}\n\nexport function accessibleFieldsPlugin(\n schema: Schema<any>,\n rawOptions?: Partial<AccessibleFieldsOptions>\n): void {\n const options = { getFields: getSchemaPaths, ...rawOptions };\n const getAllFields = getAllSchemaFieldsFactory();\n\n function instanceAccessibleFields(this: Document, ability: AnyMongoAbility, action?: string) {\n return new AccessibleFields(ability, action || 'read', getAllFields(schema, options)).of(this);\n }\n\n function modelAccessibleFields(this: Model<unknown>, ability: AnyMongoAbility, action?: string) {\n // using fake document because at this point we don't know how Ability's detectSubjectType was configured:\n // does it use classes or strings?\n const fakeDocument = { constructor: this };\n return new AccessibleFields(ability, action || 'read', getAllFields(schema, options)).of(fakeDocument);\n }\n\n schema.statics.accessibleFieldsBy = modelAccessibleFields;\n schema.method('accessibleFieldsBy', instanceAccessibleFields);\n}\n","import { AnyMongoAbility, Generics } from \"@casl/ability\";\nimport { AccessibleFields, GetSubjectTypeAllFieldsExtractor } from \"@casl/ability/extra\";\nimport mongoose from 'mongoose';\n\nconst getSubjectTypeAllFieldsExtractor: GetSubjectTypeAllFieldsExtractor = (type) => {\n const Model = typeof type === 'string' ? mongoose.models[type] : type;\n if (!Model) throw new Error(`Unknown mongoose model \"${type}\"`);\n return 'schema' in Model ? Object.keys((Model.schema as any).paths) : [];\n};\n\nexport function accessibleFieldsBy<T extends AnyMongoAbility>(\n ability: T,\n action: Parameters<T['rulesFor']>[0] = 'read'\n): AccessibleFields<Extract<Generics<T>['abilities'], unknown[]>[1]> {\n return new AccessibleFields(ability, action, getSubjectTypeAllFieldsExtractor);\n}\n"],"names":["convertToMongoQuery","rule","conditions","inverted","$nor","EMPTY_RESULT_QUERY","$expr","$eq","AccessibleRecords","constructor","_ability","_action","ofType","subjectType","query","rulesToQuery","accessibleBy","ability","action","accessibleRecords","baseQuery","detectSubjectType","model","TypeError","modelName","and","modelAccessibleBy","where","queryAccessibleBy","accessibleRecordsPlugin","schema","statics","getSchemaPaths","Object","keys","paths","fieldsOf","options","fields","getFields","excludedFields","wrapArray","except","filter","field","indexOf","getAllSchemaFieldsFactory","getAllFields","ALL_FIELDS","only","accessibleFieldsPlugin","rawOptions","assign","instanceAccessibleFields","AccessibleFields","of","modelAccessibleFields","fakeDocument","accessibleFieldsBy","method","getSubjectTypeAllFieldsExtractor","type","Model","mongoose","models","Error"],"mappings":"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"}
|
package/dist/es6m/index.mjs
CHANGED
|
@@ -1,2 +1,114 @@
|
|
|
1
|
-
import{rulesToQuery
|
|
1
|
+
import { rulesToQuery, AccessibleFields } from '@casl/ability/extra';
|
|
2
|
+
import { wrapArray } from '@casl/ability';
|
|
3
|
+
import mongoose from 'mongoose';
|
|
4
|
+
|
|
5
|
+
function convertToMongoQuery(rule) {
|
|
6
|
+
const conditions = rule.conditions;
|
|
7
|
+
return rule.inverted ? {
|
|
8
|
+
$nor: [conditions]
|
|
9
|
+
} : conditions;
|
|
10
|
+
}
|
|
11
|
+
const EMPTY_RESULT_QUERY = {
|
|
12
|
+
$expr: {
|
|
13
|
+
$eq: [0, 1]
|
|
14
|
+
}
|
|
15
|
+
};
|
|
16
|
+
class AccessibleRecords {
|
|
17
|
+
constructor(_ability, _action) {
|
|
18
|
+
this._ability = _ability;
|
|
19
|
+
this._action = _action;
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
/**
|
|
23
|
+
* In case action is not allowed, it returns `{ $expr: { $eq: [0, 1] } }`
|
|
24
|
+
*/
|
|
25
|
+
ofType(subjectType) {
|
|
26
|
+
const query = rulesToQuery(this._ability, this._action, subjectType, convertToMongoQuery);
|
|
27
|
+
return query === null ? EMPTY_RESULT_QUERY : query;
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
/**
|
|
32
|
+
* Returns accessible records Mongo query per record type (i.e., entity type) based on provided Ability and action.
|
|
33
|
+
*/
|
|
34
|
+
function accessibleBy(ability, action = 'read') {
|
|
35
|
+
return new AccessibleRecords(ability, action);
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
function accessibleRecords(baseQuery, ability, action) {
|
|
39
|
+
const subjectType = ability.detectSubjectType({
|
|
40
|
+
constructor: baseQuery.model
|
|
41
|
+
});
|
|
42
|
+
if (!subjectType) {
|
|
43
|
+
throw new TypeError(`Cannot detect subject type of "${baseQuery.model.modelName}" to return accessible records`);
|
|
44
|
+
}
|
|
45
|
+
const query = accessibleBy(ability, action).ofType(subjectType);
|
|
46
|
+
return baseQuery.and([query]);
|
|
47
|
+
}
|
|
48
|
+
function modelAccessibleBy(ability, action) {
|
|
49
|
+
return accessibleRecords(this.where(), ability, action);
|
|
50
|
+
}
|
|
51
|
+
function queryAccessibleBy(ability, action) {
|
|
52
|
+
return accessibleRecords(this, ability, action);
|
|
53
|
+
}
|
|
54
|
+
function accessibleRecordsPlugin(schema) {
|
|
55
|
+
schema.query.accessibleBy = queryAccessibleBy;
|
|
56
|
+
schema.statics.accessibleBy = modelAccessibleBy;
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
const getSchemaPaths = schema => Object.keys(schema.paths);
|
|
60
|
+
function fieldsOf(schema, options) {
|
|
61
|
+
const fields = options.getFields(schema);
|
|
62
|
+
if (!options || !('except' in options)) {
|
|
63
|
+
return fields;
|
|
64
|
+
}
|
|
65
|
+
const excludedFields = wrapArray(options.except);
|
|
66
|
+
return fields.filter(field => excludedFields.indexOf(field) === -1);
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
/**
|
|
70
|
+
* @deprecated Mongoose recommends against `extends Document`, prefer to use `AccessibleFieldsModel` instead.
|
|
71
|
+
* See here: https://mongoosejs.com/docs/typescript.html#using-extends-document
|
|
72
|
+
*/
|
|
73
|
+
|
|
74
|
+
function getAllSchemaFieldsFactory() {
|
|
75
|
+
let getAllFields;
|
|
76
|
+
return (schema, options) => {
|
|
77
|
+
if (!getAllFields) {
|
|
78
|
+
const ALL_FIELDS = options && 'only' in options ? wrapArray(options.only) : fieldsOf(schema, options);
|
|
79
|
+
getAllFields = () => ALL_FIELDS;
|
|
80
|
+
}
|
|
81
|
+
return getAllFields;
|
|
82
|
+
};
|
|
83
|
+
}
|
|
84
|
+
function accessibleFieldsPlugin(schema, rawOptions) {
|
|
85
|
+
const options = Object.assign({
|
|
86
|
+
getFields: getSchemaPaths
|
|
87
|
+
}, rawOptions);
|
|
88
|
+
const getAllFields = getAllSchemaFieldsFactory();
|
|
89
|
+
function instanceAccessibleFields(ability, action) {
|
|
90
|
+
return new AccessibleFields(ability, action || 'read', getAllFields(schema, options)).of(this);
|
|
91
|
+
}
|
|
92
|
+
function modelAccessibleFields(ability, action) {
|
|
93
|
+
// using fake document because at this point we don't know how Ability's detectSubjectType was configured:
|
|
94
|
+
// does it use classes or strings?
|
|
95
|
+
const fakeDocument = {
|
|
96
|
+
constructor: this
|
|
97
|
+
};
|
|
98
|
+
return new AccessibleFields(ability, action || 'read', getAllFields(schema, options)).of(fakeDocument);
|
|
99
|
+
}
|
|
100
|
+
schema.statics.accessibleFieldsBy = modelAccessibleFields;
|
|
101
|
+
schema.method('accessibleFieldsBy', instanceAccessibleFields);
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
const getSubjectTypeAllFieldsExtractor = type => {
|
|
105
|
+
const Model = typeof type === 'string' ? mongoose.models[type] : type;
|
|
106
|
+
if (!Model) throw new Error(`Unknown mongoose model "${type}"`);
|
|
107
|
+
return 'schema' in Model ? Object.keys(Model.schema.paths) : [];
|
|
108
|
+
};
|
|
109
|
+
function accessibleFieldsBy(ability, action = 'read') {
|
|
110
|
+
return new AccessibleFields(ability, action, getSubjectTypeAllFieldsExtractor);
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
export { accessibleBy, accessibleFieldsBy, accessibleFieldsPlugin, accessibleRecordsPlugin, getSchemaPaths };
|
|
2
114
|
//# sourceMappingURL=index.mjs.map
|
package/dist/es6m/index.mjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.mjs","sources":["../../src/accessibleBy.ts","../../src/plugins/accessible_records.ts","../../src/plugins/accessible_fields.ts","../../src/accessibleFieldsBy.ts"],"sourcesContent":["import { AnyMongoAbility, Generics, SubjectType, Abilities, AbilityTuple, ExtractSubjectType } from '@casl/ability';\nimport { rulesToQuery } from '@casl/ability/extra';\n\nfunction convertToMongoQuery(rule: AnyMongoAbility['rules'][number]) {\n const conditions = rule.conditions!;\n return rule.inverted ? { $nor: [conditions] } : conditions;\n}\n\nexport const EMPTY_RESULT_QUERY = { $expr: { $eq: [0, 1] } };\nexport class AccessibleRecords<T extends SubjectType> {\n constructor(\n private readonly _ability: AnyMongoAbility,\n private readonly _action: string\n ) {}\n\n /**\n * In case action is not allowed, it returns `{ $expr: { $eq: [0, 1] } }`\n */\n ofType(subjectType: T): Record<string, unknown> {\n const query = rulesToQuery(this._ability, this._action, subjectType, convertToMongoQuery);\n return query === null ? EMPTY_RESULT_QUERY : query as Record<string, unknown>;\n }\n}\n\ntype SubjectTypes<T extends Abilities> = T extends AbilityTuple\n ? ExtractSubjectType<T[1]>\n : never;\n\n/**\n * Returns accessible records Mongo query per record type (i.e., entity type) based on provided Ability and action.\n */\nexport function accessibleBy<T extends AnyMongoAbility>(\n ability: T,\n action: Parameters<T['rulesFor']>[0] = 'read'\n): AccessibleRecords<SubjectTypes<Generics<T>['abilities']>> {\n return new AccessibleRecords(ability, action);\n}\n","import { AnyMongoAbility, Generics, Normalize } from '@casl/ability';\nimport { Document, HydratedDocument, Model, Query, QueryWithHelpers, Schema } from 'mongoose';\nimport { accessibleBy } from '../accessibleBy';\n\nfunction accessibleRecords<T extends AnyMongoAbility>(\n baseQuery: Query<any, any>,\n ability: T,\n action?: Normalize<Generics<T>['abilities']>[0]\n): QueryWithHelpers<Document, Document> {\n const subjectType = ability.detectSubjectType({\n constructor: baseQuery.model\n });\n\n if (!subjectType) {\n throw new TypeError(`Cannot detect subject type of \"${baseQuery.model.modelName}\" to return accessible records`);\n }\n\n const query = accessibleBy(ability, action).ofType(subjectType);\n\n return baseQuery.and([query]);\n}\n\ntype GetAccessibleRecords<T, TQueryHelpers, TMethods, TVirtuals> = <U extends AnyMongoAbility>(\n ability: U,\n action?: Normalize<Generics<U>['abilities']>[0]\n) => QueryWithHelpers<\nArray<T>,\nT,\nAccessibleRecordQueryHelpers<T, TQueryHelpers, TMethods, TVirtuals>\n>;\n\nexport type AccessibleRecordQueryHelpers<T, TQueryHelpers = {}, TMethods = {}, TVirtuals = {}> = {\n /** @deprecated use accessibleBy helper instead */\n accessibleBy: GetAccessibleRecords<\n HydratedDocument<T, TMethods, TVirtuals>,\n TQueryHelpers,\n TMethods,\n TVirtuals\n >\n};\nexport interface AccessibleRecordModel<\n T,\n TQueryHelpers = {},\n TMethods = {},\n TVirtuals = {}\n> extends Model<T,\n TQueryHelpers & AccessibleRecordQueryHelpers<T, TQueryHelpers, TMethods, TVirtuals>,\n TMethods,\n TVirtuals> {\n /** @deprecated use accessibleBy helper instead */\n accessibleBy: GetAccessibleRecords<\n HydratedDocument<T, TMethods, TVirtuals>,\n TQueryHelpers,\n TMethods,\n TVirtuals\n >\n}\n\nfunction modelAccessibleBy(this: Model<unknown>, ability: AnyMongoAbility, action?: string) {\n return accessibleRecords(this.where(), ability, action);\n}\n\nfunction queryAccessibleBy(\n this: Query<unknown, unknown>,\n ability: AnyMongoAbility,\n action?: string\n) {\n return accessibleRecords(this, ability, action);\n}\n\nexport function accessibleRecordsPlugin(schema: Schema<any>): void {\n (schema.query as Record<string, unknown>).accessibleBy = queryAccessibleBy;\n schema.statics.accessibleBy = modelAccessibleBy;\n}\n","import { AnyMongoAbility, Generics, Normalize, wrapArray } from '@casl/ability';\nimport { AccessibleFields, GetSubjectTypeAllFieldsExtractor } from '@casl/ability/extra';\nimport type { Document, Model, Schema } from 'mongoose';\n\nexport type AccessibleFieldsOptions =\n {\n getFields(schema: Schema<Document>): string[]\n } &\n ({ only: string | string[] } | { except: string | string[] });\n\nexport const getSchemaPaths: AccessibleFieldsOptions['getFields'] = schema => Object.keys((schema as { paths: object }).paths);\n\nfunction fieldsOf(schema: Schema<Document>, options: Partial<AccessibleFieldsOptions>) {\n const fields = options.getFields!(schema);\n\n if (!options || !('except' in options)) {\n return fields;\n }\n\n const excludedFields = wrapArray(options.except);\n return fields.filter(field => excludedFields.indexOf(field) === -1);\n}\n\ntype GetAccessibleFields<T> = <U extends AnyMongoAbility>(\n this: Model<T> | T,\n ability: U,\n action?: Normalize<Generics<U>['abilities']>[0]\n) => string[];\n\nexport interface AccessibleFieldsModel<\n T,\n TQueryHelpers = {},\n TMethods = {},\n TVirtuals = {}\n> extends Model<T, TQueryHelpers, TMethods & AccessibleFieldDocumentMethods<T>, TVirtuals> {\n accessibleFieldsBy: GetAccessibleFields<T>\n}\n\nexport interface AccessibleFieldDocumentMethods<T = Document> {\n accessibleFieldsBy: GetAccessibleFields<T>\n}\n\n/**\n * @deprecated Mongoose recommends against `extends Document`, prefer to use `AccessibleFieldsModel` instead.\n * See here: https://mongoosejs.com/docs/typescript.html#using-extends-document\n */\nexport interface AccessibleFieldsDocument extends Document, AccessibleFieldDocumentMethods {}\n\nfunction getAllSchemaFieldsFactory() {\n let getAllFields: GetSubjectTypeAllFieldsExtractor;\n return (schema: Schema<any>, options: Partial<AccessibleFieldsOptions>) => {\n if (!getAllFields) {\n const ALL_FIELDS = options && 'only' in options\n ? wrapArray(options.only as string[])\n : fieldsOf(schema, options);\n getAllFields = () => ALL_FIELDS;\n }\n\n return getAllFields;\n };\n}\n\nexport function accessibleFieldsPlugin(\n schema: Schema<any>,\n rawOptions?: Partial<AccessibleFieldsOptions>\n): void {\n const options = { getFields: getSchemaPaths, ...rawOptions };\n const getAllFields = getAllSchemaFieldsFactory();\n\n function instanceAccessibleFields(this: Document, ability: AnyMongoAbility, action?: string) {\n return new AccessibleFields(ability, action || 'read', getAllFields(schema, options)).of(this);\n }\n\n function modelAccessibleFields(this: Model<unknown>, ability: AnyMongoAbility, action?: string) {\n // using fake document because at this point we don't know how Ability's detectSubjectType was configured:\n // does it use classes or strings?\n const fakeDocument = { constructor: this };\n return new AccessibleFields(ability, action || 'read', getAllFields(schema, options)).of(fakeDocument);\n }\n\n schema.statics.accessibleFieldsBy = modelAccessibleFields;\n schema.method('accessibleFieldsBy', instanceAccessibleFields);\n}\n","import { AnyMongoAbility, Generics } from \"@casl/ability\";\nimport { AccessibleFields, GetSubjectTypeAllFieldsExtractor } from \"@casl/ability/extra\";\nimport mongoose from 'mongoose';\n\nconst getSubjectTypeAllFieldsExtractor: GetSubjectTypeAllFieldsExtractor = (type) => {\n const Model = typeof type === 'string' ? mongoose.models[type] : type;\n if (!Model) throw new Error(`Unknown mongoose model \"${type}\"`);\n return 'schema' in Model ? Object.keys((Model.schema as any).paths) : [];\n};\n\nexport function accessibleFieldsBy<T extends AnyMongoAbility>(\n ability: T,\n action: Parameters<T['rulesFor']>[0] = 'read'\n): AccessibleFields<Extract<Generics<T>['abilities'], unknown[]>[1]> {\n return new AccessibleFields(ability, action, getSubjectTypeAllFieldsExtractor);\n}\n"],"names":["convertToMongoQuery","rule","conditions","inverted","$nor","EMPTY_RESULT_QUERY","$expr","$eq","AccessibleRecords","constructor","_ability","_action","this","ofType","subjectType","query","rulesToQuery","accessibleBy","ability","action","accessibleRecords","baseQuery","detectSubjectType","model","TypeError","modelName","and","modelAccessibleBy","where","queryAccessibleBy","accessibleRecordsPlugin","schema","statics","getSchemaPaths","Object","keys","paths","fieldsOf","options","fields","getFields","excludedFields","wrapArray","except","filter","field","indexOf","getAllSchemaFieldsFactory","getAllFields","ALL_FIELDS","only","accessibleFieldsPlugin","rawOptions","assign","instanceAccessibleFields","AccessibleFields","of","modelAccessibleFields","fakeDocument","accessibleFieldsBy","method","getSubjectTypeAllFieldsExtractor","type","Model","mongoose","models","Error"],"mappings":"2IAGA,SAASA,EAAoBC,GAC3B,MAAMC,EAAaD,EAAKC,WACxB,OAAOD,EAAKE,SAAW,CAAEC,KAAM,CAACF,IAAgBA,CAClD,CAEO,MAAMG,EAAqB,CAAEC,MAAO,CAAEC,IAAK,CAAC,EAAG,KAC/C,MAAMC,EACXC,WAAAA,CACmBC,EACAC,GACjBC,KAFiBF,EAAAA,EAAyBE,KACzBD,EAAAA,CAChB,CAKHE,MAAAA,CAAOC,GACL,MAAMC,EAAQC,EAAaJ,KAAKF,EAAUE,KAAKD,EAASG,EAAad,GACrE,OAAOe,IAAU,KAAOV,EAAqBU,CAC/C,EAUK,SAASE,EACdC,EACAC,EAAuC,QAEvC,OAAO,IAAIX,EAAkBU,EAASC,EACxC,CChCA,SAASC,EACPC,EACAH,EACAC,GAEA,MAAML,EAAcI,EAAQI,kBAAkB,CAC5Cb,YAAaY,EAAUE,QAGzB,IAAKT,EACH,MAAM,IAAIU,UAAW,kCAAiCH,EAAUE,MAAME,2CAGxE,MAAMV,EAAQE,EAAaC,EAASC,GAAQN,OAAOC,GAEnD,OAAOO,EAAUK,IAAI,CAACX,GACxB,CAsCA,SAASY,EAAwCT,EAA0BC,GACzE,OAAOC,EAAkBR,KAAKgB,QAASV,EAASC,EAClD,CAEA,SAASU,EAEPX,EACAC,GAEA,OAAOC,EAAkBR,KAAMM,EAASC,EAC1C,CAEO,SAASW,EAAwBC,GACrCA,EAAOhB,MAAkCE,aAAeY,EACzDE,EAAOC,QAAQf,aAAeU,CAChC,CC/DaM,MAAAA,EAAuDF,GAAUG,OAAOC,KAAMJ,EAA6BK,OAExH,SAASC,EAASN,EAA0BO,GAC1C,MAAMC,EAASD,EAAQE,UAAWT,GAElC,IAAKO,KAAa,WAAYA,GAC5B,OAAOC,EAGT,MAAME,EAAiBC,EAAUJ,EAAQK,QACzC,OAAOJ,EAAOK,QAAOC,GAASJ,EAAeK,QAAQD,MAAY,GACnE,CA2BA,SAASE,IACP,IAAIC,EACJ,MAAO,CAACjB,EAAqBO,KAC3B,IAAKU,EAAc,CACjB,MAAMC,EAAaX,GAAW,SAAUA,EACpCI,EAAUJ,EAAQY,MAClBb,EAASN,EAAQO,GACrBU,EAAeA,IAAMC,CACvB,CAEA,OAAOD,CAAY,CAEvB,CAEO,SAASG,EACdpB,EACAqB,GAEA,MAAMd,EAAOJ,OAAAmB,OAAA,CAAKb,UAAWP,GAAmBmB,GAChD,MAAMJ,EAAeD,IAErB,SAASO,EAAyCpC,EAA0BC,GAC1E,OAAO,IAAIoC,EAAiBrC,EAASC,GAAU,OAAQ6B,EAAajB,EAAQO,IAAUkB,GAAG5C,KAC3F,CAEA,SAAS6C,EAA4CvC,EAA0BC,GAG7E,MAAMuC,EAAe,CAAEjD,YAAaG,MACpC,OAAO,IAAI2C,EAAiBrC,EAASC,GAAU,OAAQ6B,EAAajB,EAAQO,IAAUkB,GAAGE,EAC3F,CAEA3B,EAAOC,QAAQ2B,mBAAqBF,EACpC1B,EAAO6B,OAAO,qBAAsBN,EACtC,CC9EA,MAAMO,EAAsEC,IAC1E,MAAMC,SAAeD,IAAS,SAAWE,EAASC,OAAOH,GAAQA,EACjE,IAAKC,EAAO,MAAM,IAAIG,MAAO,2BAA0BJ,MACvD,MAAO,WAAYC,EAAQ7B,OAAOC,KAAM4B,EAAMhC,OAAeK,OAAS,EAAE,EAGnE,SAASuB,EACdzC,EACAC,EAAuC,QAEvC,OAAO,IAAIoC,EAAiBrC,EAASC,EAAQ0C,EAC/C"}
|
|
1
|
+
{"version":3,"file":"index.mjs","sources":["../../src/accessibleBy.ts","../../src/plugins/accessible_records.ts","../../src/plugins/accessible_fields.ts","../../src/accessibleFieldsBy.ts"],"sourcesContent":["import { AnyMongoAbility, Generics, SubjectType } from '@casl/ability';\nimport { ToAbilityTypes } from '@casl/ability/dist/types/types';\nimport { rulesToQuery } from '@casl/ability/extra';\n\nfunction convertToMongoQuery(rule: AnyMongoAbility['rules'][number]) {\n const conditions = rule.conditions!;\n return rule.inverted ? { $nor: [conditions] } : conditions;\n}\n\nexport const EMPTY_RESULT_QUERY = { $expr: { $eq: [0, 1] } };\nexport class AccessibleRecords<T extends SubjectType> {\n constructor(\n private readonly _ability: AnyMongoAbility,\n private readonly _action: string\n ) {}\n\n /**\n * In case action is not allowed, it returns `{ $expr: { $eq: [0, 1] } }`\n */\n ofType(subjectType: T): Record<string, unknown> {\n const query = rulesToQuery(this._ability, this._action, subjectType, convertToMongoQuery);\n return query === null ? EMPTY_RESULT_QUERY : query as Record<string, unknown>;\n }\n}\n\n/**\n * Returns accessible records Mongo query per record type (i.e., entity type) based on provided Ability and action.\n */\nexport function accessibleBy<T extends AnyMongoAbility>(\n ability: T,\n action: Parameters<T['rulesFor']>[0] = 'read'\n): AccessibleRecords<ToAbilityTypes<Generics<T>['abilities']>[1]> {\n return new AccessibleRecords(ability, action);\n}\n","import { AnyMongoAbility, Generics, Normalize } from '@casl/ability';\nimport { Document, HydratedDocument, Model, Query, QueryWithHelpers, Schema } from 'mongoose';\nimport { accessibleBy } from '../accessibleBy';\n\nfunction accessibleRecords<T extends AnyMongoAbility>(\n baseQuery: Query<any, any>,\n ability: T,\n action?: Normalize<Generics<T>['abilities']>[0]\n): QueryWithHelpers<Document, Document> {\n const subjectType = ability.detectSubjectType({\n constructor: baseQuery.model\n });\n\n if (!subjectType) {\n throw new TypeError(`Cannot detect subject type of \"${baseQuery.model.modelName}\" to return accessible records`);\n }\n\n const query = accessibleBy(ability, action).ofType(subjectType);\n\n return baseQuery.and([query]);\n}\n\ntype GetAccessibleRecords<T, TQueryHelpers, TMethods, TVirtuals> = <U extends AnyMongoAbility>(\n ability: U,\n action?: Normalize<Generics<U>['abilities']>[0]\n) => QueryWithHelpers<\nArray<T>,\nT,\nAccessibleRecordQueryHelpers<T, TQueryHelpers, TMethods, TVirtuals>\n>;\n\nexport type AccessibleRecordQueryHelpers<T, TQueryHelpers = {}, TMethods = {}, TVirtuals = {}> = {\n /** @deprecated use accessibleBy helper instead */\n accessibleBy: GetAccessibleRecords<\n HydratedDocument<T, TMethods, TVirtuals>,\n TQueryHelpers,\n TMethods,\n TVirtuals\n >\n};\nexport interface AccessibleRecordModel<\n T,\n TQueryHelpers = {},\n TMethods = {},\n TVirtuals = {}\n> extends Model<T,\n TQueryHelpers & AccessibleRecordQueryHelpers<T, TQueryHelpers, TMethods, TVirtuals>,\n TMethods,\n TVirtuals> {\n /** @deprecated use accessibleBy helper instead */\n accessibleBy: GetAccessibleRecords<\n HydratedDocument<T, TMethods, TVirtuals>,\n TQueryHelpers,\n TMethods,\n TVirtuals\n >\n}\n\nfunction modelAccessibleBy(this: Model<unknown>, ability: AnyMongoAbility, action?: string) {\n return accessibleRecords(this.where(), ability, action);\n}\n\nfunction queryAccessibleBy(\n this: Query<unknown, unknown>,\n ability: AnyMongoAbility,\n action?: string\n) {\n return accessibleRecords(this, ability, action);\n}\n\nexport function accessibleRecordsPlugin(schema: Schema<any>): void {\n (schema.query as Record<string, unknown>).accessibleBy = queryAccessibleBy;\n schema.statics.accessibleBy = modelAccessibleBy;\n}\n","import { AnyMongoAbility, Generics, Normalize, wrapArray } from '@casl/ability';\nimport { AccessibleFields, GetSubjectTypeAllFieldsExtractor } from '@casl/ability/extra';\nimport type { Document, Model, Schema } from 'mongoose';\n\nexport type AccessibleFieldsOptions =\n {\n getFields(schema: Schema<Document>): string[]\n } &\n ({ only: string | string[] } | { except: string | string[] });\n\nexport const getSchemaPaths: AccessibleFieldsOptions['getFields'] = schema => Object.keys((schema as { paths: object }).paths);\n\nfunction fieldsOf(schema: Schema<Document>, options: Partial<AccessibleFieldsOptions>) {\n const fields = options.getFields!(schema);\n\n if (!options || !('except' in options)) {\n return fields;\n }\n\n const excludedFields = wrapArray(options.except);\n return fields.filter(field => excludedFields.indexOf(field) === -1);\n}\n\ntype GetAccessibleFields<T> = <U extends AnyMongoAbility>(\n this: Model<T> | T,\n ability: U,\n action?: Normalize<Generics<U>['abilities']>[0]\n) => string[];\n\nexport interface AccessibleFieldsModel<\n T,\n TQueryHelpers = {},\n TMethods = {},\n TVirtuals = {}\n> extends Model<T, TQueryHelpers, TMethods & AccessibleFieldDocumentMethods<T>, TVirtuals> {\n accessibleFieldsBy: GetAccessibleFields<T>\n}\n\nexport interface AccessibleFieldDocumentMethods<T = Document> {\n accessibleFieldsBy: GetAccessibleFields<T>\n}\n\n/**\n * @deprecated Mongoose recommends against `extends Document`, prefer to use `AccessibleFieldsModel` instead.\n * See here: https://mongoosejs.com/docs/typescript.html#using-extends-document\n */\nexport interface AccessibleFieldsDocument extends Document, AccessibleFieldDocumentMethods {}\n\nfunction getAllSchemaFieldsFactory() {\n let getAllFields: GetSubjectTypeAllFieldsExtractor;\n return (schema: Schema<any>, options: Partial<AccessibleFieldsOptions>) => {\n if (!getAllFields) {\n const ALL_FIELDS = options && 'only' in options\n ? wrapArray(options.only as string[])\n : fieldsOf(schema, options);\n getAllFields = () => ALL_FIELDS;\n }\n\n return getAllFields;\n };\n}\n\nexport function accessibleFieldsPlugin(\n schema: Schema<any>,\n rawOptions?: Partial<AccessibleFieldsOptions>\n): void {\n const options = { getFields: getSchemaPaths, ...rawOptions };\n const getAllFields = getAllSchemaFieldsFactory();\n\n function instanceAccessibleFields(this: Document, ability: AnyMongoAbility, action?: string) {\n return new AccessibleFields(ability, action || 'read', getAllFields(schema, options)).of(this);\n }\n\n function modelAccessibleFields(this: Model<unknown>, ability: AnyMongoAbility, action?: string) {\n // using fake document because at this point we don't know how Ability's detectSubjectType was configured:\n // does it use classes or strings?\n const fakeDocument = { constructor: this };\n return new AccessibleFields(ability, action || 'read', getAllFields(schema, options)).of(fakeDocument);\n }\n\n schema.statics.accessibleFieldsBy = modelAccessibleFields;\n schema.method('accessibleFieldsBy', instanceAccessibleFields);\n}\n","import { AnyMongoAbility, Generics } from \"@casl/ability\";\nimport { AccessibleFields, GetSubjectTypeAllFieldsExtractor } from \"@casl/ability/extra\";\nimport mongoose from 'mongoose';\n\nconst getSubjectTypeAllFieldsExtractor: GetSubjectTypeAllFieldsExtractor = (type) => {\n const Model = typeof type === 'string' ? mongoose.models[type] : type;\n if (!Model) throw new Error(`Unknown mongoose model \"${type}\"`);\n return 'schema' in Model ? Object.keys((Model.schema as any).paths) : [];\n};\n\nexport function accessibleFieldsBy<T extends AnyMongoAbility>(\n ability: T,\n action: Parameters<T['rulesFor']>[0] = 'read'\n): AccessibleFields<Extract<Generics<T>['abilities'], unknown[]>[1]> {\n return new AccessibleFields(ability, action, getSubjectTypeAllFieldsExtractor);\n}\n"],"names":["convertToMongoQuery","rule","conditions","inverted","$nor","EMPTY_RESULT_QUERY","$expr","$eq","AccessibleRecords","constructor","_ability","_action","ofType","subjectType","query","rulesToQuery","accessibleBy","ability","action","accessibleRecords","baseQuery","detectSubjectType","model","TypeError","modelName","and","modelAccessibleBy","where","queryAccessibleBy","accessibleRecordsPlugin","schema","statics","getSchemaPaths","Object","keys","paths","fieldsOf","options","fields","getFields","excludedFields","wrapArray","except","filter","field","indexOf","getAllSchemaFieldsFactory","getAllFields","ALL_FIELDS","only","accessibleFieldsPlugin","rawOptions","assign","instanceAccessibleFields","AccessibleFields","of","modelAccessibleFields","fakeDocument","accessibleFieldsBy","method","getSubjectTypeAllFieldsExtractor","type","Model","mongoose","models","Error"],"mappings":"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"}
|
|
@@ -1,4 +1,5 @@
|
|
|
1
|
-
import { AnyMongoAbility, Generics, SubjectType
|
|
1
|
+
import { AnyMongoAbility, Generics, SubjectType } from '@casl/ability';
|
|
2
|
+
import { ToAbilityTypes } from '@casl/ability/dist/types/types';
|
|
2
3
|
export declare const EMPTY_RESULT_QUERY: {
|
|
3
4
|
$expr: {
|
|
4
5
|
$eq: number[];
|
|
@@ -13,9 +14,7 @@ export declare class AccessibleRecords<T extends SubjectType> {
|
|
|
13
14
|
*/
|
|
14
15
|
ofType(subjectType: T): Record<string, unknown>;
|
|
15
16
|
}
|
|
16
|
-
type SubjectTypes<T extends Abilities> = T extends AbilityTuple ? ExtractSubjectType<T[1]> : never;
|
|
17
17
|
/**
|
|
18
18
|
* Returns accessible records Mongo query per record type (i.e., entity type) based on provided Ability and action.
|
|
19
19
|
*/
|
|
20
|
-
export declare function accessibleBy<T extends AnyMongoAbility>(ability: T, action?: Parameters<T['rulesFor']>[0]): AccessibleRecords<
|
|
21
|
-
export {};
|
|
20
|
+
export declare function accessibleBy<T extends AnyMongoAbility>(ability: T, action?: Parameters<T['rulesFor']>[0]): AccessibleRecords<ToAbilityTypes<Generics<T>['abilities']>[1]>;
|
|
@@ -1,27 +1,3 @@
|
|
|
1
|
-
/// <reference types="mongoose/types/aggregate" />
|
|
2
|
-
/// <reference types="mongoose/types/callback" />
|
|
3
|
-
/// <reference types="mongoose/types/collection" />
|
|
4
|
-
/// <reference types="mongoose/types/connection" />
|
|
5
|
-
/// <reference types="mongoose/types/cursor" />
|
|
6
|
-
/// <reference types="mongoose/types/document" />
|
|
7
|
-
/// <reference types="mongoose/types/error" />
|
|
8
|
-
/// <reference types="mongoose/types/expressions" />
|
|
9
|
-
/// <reference types="mongoose/types/helpers" />
|
|
10
|
-
/// <reference types="mongoose/types/middlewares" />
|
|
11
|
-
/// <reference types="mongoose/types/indexes" />
|
|
12
|
-
/// <reference types="mongoose/types/models" />
|
|
13
|
-
/// <reference types="mongoose/types/mongooseoptions" />
|
|
14
|
-
/// <reference types="mongoose/types/pipelinestage" />
|
|
15
|
-
/// <reference types="mongoose/types/populate" />
|
|
16
|
-
/// <reference types="mongoose/types/query" />
|
|
17
|
-
/// <reference types="mongoose/types/schemaoptions" />
|
|
18
|
-
/// <reference types="mongoose/types/schematypes" />
|
|
19
|
-
/// <reference types="mongoose/types/session" />
|
|
20
|
-
/// <reference types="mongoose/types/types" />
|
|
21
|
-
/// <reference types="mongoose/types/utility" />
|
|
22
|
-
/// <reference types="mongoose/types/validation" />
|
|
23
|
-
/// <reference types="mongoose/types/virtuals" />
|
|
24
|
-
/// <reference types="mongoose/types/inferschematype" />
|
|
25
1
|
import { AnyMongoAbility, Generics, Normalize } from '@casl/ability';
|
|
26
2
|
import type { Document, Model, Schema } from 'mongoose';
|
|
27
3
|
export type AccessibleFieldsOptions = {
|
|
@@ -1,27 +1,3 @@
|
|
|
1
|
-
/// <reference types="mongoose/types/aggregate" />
|
|
2
|
-
/// <reference types="mongoose/types/callback" />
|
|
3
|
-
/// <reference types="mongoose/types/collection" />
|
|
4
|
-
/// <reference types="mongoose/types/connection" />
|
|
5
|
-
/// <reference types="mongoose/types/cursor" />
|
|
6
|
-
/// <reference types="mongoose/types/document" />
|
|
7
|
-
/// <reference types="mongoose/types/error" />
|
|
8
|
-
/// <reference types="mongoose/types/expressions" />
|
|
9
|
-
/// <reference types="mongoose/types/helpers" />
|
|
10
|
-
/// <reference types="mongoose/types/middlewares" />
|
|
11
|
-
/// <reference types="mongoose/types/indexes" />
|
|
12
|
-
/// <reference types="mongoose/types/models" />
|
|
13
|
-
/// <reference types="mongoose/types/mongooseoptions" />
|
|
14
|
-
/// <reference types="mongoose/types/pipelinestage" />
|
|
15
|
-
/// <reference types="mongoose/types/populate" />
|
|
16
|
-
/// <reference types="mongoose/types/query" />
|
|
17
|
-
/// <reference types="mongoose/types/schemaoptions" />
|
|
18
|
-
/// <reference types="mongoose/types/schematypes" />
|
|
19
|
-
/// <reference types="mongoose/types/session" />
|
|
20
|
-
/// <reference types="mongoose/types/types" />
|
|
21
|
-
/// <reference types="mongoose/types/utility" />
|
|
22
|
-
/// <reference types="mongoose/types/validation" />
|
|
23
|
-
/// <reference types="mongoose/types/virtuals" />
|
|
24
|
-
/// <reference types="mongoose/types/inferschematype" />
|
|
25
1
|
import { AnyMongoAbility, Generics, Normalize } from '@casl/ability';
|
|
26
2
|
import { HydratedDocument, Model, QueryWithHelpers, Schema } from 'mongoose';
|
|
27
3
|
type GetAccessibleRecords<T, TQueryHelpers, TMethods, TVirtuals> = <U extends AnyMongoAbility>(ability: U, action?: Normalize<Generics<U>['abilities']>[0]) => QueryWithHelpers<Array<T>, T, AccessibleRecordQueryHelpers<T, TQueryHelpers, TMethods, TVirtuals>>;
|