{"_id":"query-bouncer-mongoose-plugin","_rev":"40-61943a05bb0c63a6abfa1ea52c6bcbed","name":"query-bouncer-mongoose-plugin","dist-tags":{"latest":"2.0.2","beta":"1.5.2-beta.7","dev":"2.0.2-0"},"versions":{"1.0.0":{"name":"query-bouncer-mongoose-plugin","version":"1.0.0","description":"Mongoose Plugin for Query Bouncer","main":"./dist/index.js","scripts":{"start":"node ./dist/index.js","test":"nyc mocha","build":"tsc --watch false --declaration","lint":"eslint --ignore-path .gitignore .","tsc":"tsc"},"_moduleAliases":{"@root":".","@":"dist/src","@test":"dist/test"},"author":{"name":"Relief.Melone"},"license":"MIT","dependencies":{"axios":"^0.19.1","module-alias":"^2.2.2","mongodb":"^3.5.0","mongoose":"^5.8.7"},"devDependencies":{"@types/chai":"latest","@types/express":"latest","@types/mocha":"latest","@types/mongodb":"^3.3.14","@types/mongoose":"^5.5.41","@types/moxios":"^0.4.9","@types/node":"latest","@typescript-eslint/eslint-plugin":"latest","@typescript-eslint/parser":"latest","axios-mock-adapter":"^1.17.0","chai":"latest","chai-exclude":"^2.0.2","eslint":"latest","eslint-import-resolver-alias":"latest","eslint-plugin-import":"latest","mocha":"latest","mongodb-memory-server":"latest","nyc":"latest","sinon":"^8.0.4","typescript":"latest"},"gitHead":"515c10f9ae160c2c161ef1ba56649460684dc011","_id":"query-bouncer-mongoose-plugin@1.0.0","_nodeVersion":"12.13.1","_npmVersion":"6.13.6","dist":{"integrity":"sha512-GBz9ReqqN/AcNMG97DWC7XeVUfbnQvVnmI6zcS/2OAEHKz3qFd3Yp5GerjTPorYZUnRCwBEA2/HuKNt974NOMA==","shasum":"88c9b58d21d7111029a7b8dae664e0ff9314f211","tarball":"https://registry.npmjs.org/query-bouncer-mongoose-plugin/-/query-bouncer-mongoose-plugin-1.0.0.tgz","fileCount":53,"unpackedSize":86816,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJeKxDHCRA9TVsSAnZWagAAtgYQAJcx2biuTAgBYrUxbLbH\nQ28IgnpmAW+Bt5OlObLScb6VTJaM5B/Dl09k3yk6awEhnrwsiRaJIMfLX66d\nD/CHquT6/Sj9XRIVgRDRyRyEQOmP4jRLZDjvZyRX41L/iR4cfF8R8xZtAvKF\nc1dfG5WUpfbIaUvvfEezLtNFHSvHRH/tI9FV/2ol+NF8DUhrGZi/pr26v62B\nnf22S78NZCgjvPfA087YBd/CYPvOXeC18TeU+gXViNi1dXaarVTTymqhCHWv\nltgIiiQLIBUJOXL4SS4FKWQHc5domYYO/Q9cgIg+EZCA0itsW07/zOECLqo2\nS117IUN394z9kmEiSGxcJJrAcENlIHpp97V1IJVdkVDENIZcHvHG6coQeGQI\nZQXcnn8FwNLlxbIanjhcjdxkuJ1B9CmyKaRLL8ZwouT5b/XR4Mn5BMFAfWf6\nFiu5UulSiObicrGsJA2dNI4CAX+trop92mv08AYZ8/OPUf4XoMG9fic/XJZJ\njMWxZMX1gnKsKkkkDOjEPfAyR/GZeVrDlixBiJzls/vMhJkFnesg024TETt/\ndwK0ko67ITKD9R09NcZ1mZ/YCfEDIKfxcVv/E1RrgiEOlaGMqRgVgt1OusyN\nMlUxVaKd9D4H8z53mlUKd3po97ynphwPTpBmJCylA4IaSdr59yRjK1Mf81LH\nq7i5\r\n=mJtr\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEYCIQDxRyUtztKFoK2OJPNpd3lu1OVMk+q+CZYCv6k0DJ2o9gIhALaen2LBIXc49zLs1kzl9VOv1IGWOKIa/YzTN0n8Wd2j"}]},"maintainers":[{"name":"relief.melone","email":"relief.melone@gmail.com"}],"_npmUser":{"name":"relief.melone","email":"relief.melone@gmail.com"},"directories":{},"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/query-bouncer-mongoose-plugin_1.0.0_1579880646694_0.045785186421160695"},"_hasShrinkwrap":false,"deprecated":"typings for mongoose will not be extended in versions prior to 1.3.1"},"1.0.1":{"name":"query-bouncer-mongoose-plugin","version":"1.0.1","description":"Mongoose Plugin for Query Bouncer","main":"./dist/index.js","scripts":{"start":"node ./dist/index.js","test":"nyc mocha","build":"tsc --watch false --declaration","lint":"eslint --ignore-path .gitignore .","tsc":"tsc"},"_moduleAliases":{"@root":".","@":"dist/src","@test":"dist/test"},"author":{"name":"Relief.Melone"},"license":"MIT","dependencies":{"axios":"^0.19.1","module-alias":"^2.2.2","mongodb":"^3.5.0","mongoose":"^5.8.7"},"devDependencies":{"@types/chai":"latest","@types/express":"latest","@types/mocha":"latest","@types/mongodb":"^3.3.14","@types/mongoose":"^5.5.41","@types/moxios":"^0.4.9","@types/node":"latest","@typescript-eslint/eslint-plugin":"latest","@typescript-eslint/parser":"latest","axios-mock-adapter":"^1.17.0","chai":"latest","chai-exclude":"^2.0.2","eslint":"latest","eslint-import-resolver-alias":"latest","eslint-plugin-import":"latest","mocha":"latest","mongodb-memory-server":"latest","nyc":"latest","sinon":"^8.0.4","typescript":"latest"},"gitHead":"61bc4ac5e394861db2578dbf1c36249e4e4485ef","_id":"query-bouncer-mongoose-plugin@1.0.1","_nodeVersion":"12.13.0","_npmVersion":"6.12.0","dist":{"integrity":"sha512-shhKylh5acIHdb40w0/tRS/0Wn8GVEBu/AQslG9i0Vtif5BHpYnACUe3nDTnlsdqy9ZLeZgtelMr7xvXEu/fDg==","shasum":"36935fe48a8cf7f4d395aacc538e7024fe12e446","tarball":"https://registry.npmjs.org/query-bouncer-mongoose-plugin/-/query-bouncer-mongoose-plugin-1.0.1.tgz","fileCount":53,"unpackedSize":86866,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJeLsXNCRA9TVsSAnZWagAABOsP/2WbYxANV4duQMeFMTLs\nzj7nF/Hyu7nc+k/vV0+MYM/o5xm02d5v7K5Tu5oxFe/8Vml9O1L3Lcx4boD6\nLMcbEyVwQytUHZbAUAay/d2N44FZNG9kcPo0dD7uAsTDhP8IHhqr8Z+2EQ9a\nzRe5dIclP5Cq2+72RKf+l/0h2pkgSfIa1hnyUzE+ozcB/IWAV0SOOSUZTgac\nTicQGlc+1oLwyXHxYvtvdjEbIzk93xsjIIQzG22mvahtLmU1+4kBnp3Lnnmi\nRhU75lKIfrGipQGTpPnCa/c5ht5pt97i2CCy9h/howXN28K8/5m9B1ZOnV/L\nEesNqnvHhi3NE7jZH9RmVSpULz2VxLuJfq4CryATp6mkxnnw2b5CCKhZOepc\nPYgQlooLQT2OZu/SUzhBefdJ9Nx9x46vMOkY1fn8MBlpezaBBK7WyoYwfY+5\n+LC2TttqI7mmx5YxxxqJIFH1YDr9k/60EK9Fy2Lj6r1/8bdN5zQBCvIa8JtJ\na1RyluJCBEznHH2BLaEjaRsMnyTa1niw13KimFglZMk6znuoMdYKx2gz7Lva\nuwVIG6T3rT7nbpibD9CxK5z3RcezFC4YqZY4BPjx4gW6JVWblC9etEuVlDiX\nmLcITO9XxOrBxS9csRcGT8DFsd7Hj7gKKB+D0bxYgdLgIWKo69S7bekmRfaZ\n05/w\r\n=j0rA\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIQCvEh/ZrqqGhSu2yDP2j3fKJPUHFcw9Avv1wCm8ijapyAIgIW4oqooOmYVGaNko4nk3w954TXcDDUcBi1rjqgaeOOg="}]},"maintainers":[{"name":"relief.melone","email":"relief.melone@gmail.com"}],"_npmUser":{"name":"relief.melone","email":"relief.melone@gmail.com"},"directories":{},"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/query-bouncer-mongoose-plugin_1.0.1_1580123596884_0.8776276337127025"},"_hasShrinkwrap":false,"deprecated":"typings for mongoose will not be extended in versions prior to 1.3.1"},"1.0.2":{"name":"query-bouncer-mongoose-plugin","version":"1.0.2","description":"Mongoose Plugin for Query Bouncer","main":"./dist/index.js","scripts":{"start":"node ./dist/index.js","test":"nyc mocha","build":"tsc --watch false --declaration","lint":"eslint --ignore-path .gitignore .","tsc":"tsc"},"_moduleAliases":{"@root":".","@":"dist/src","@test":"dist/test"},"author":{"name":"Relief.Melone"},"license":"MIT","dependencies":{"axios":"^0.19.1","module-alias":"^2.2.2","mongodb":"^3.5.0","mongoose":"^5.8.7"},"devDependencies":{"@types/chai":"latest","@types/express":"latest","@types/mocha":"latest","@types/mongodb":"^3.3.14","@types/mongoose":"^5.5.41","@types/moxios":"^0.4.9","@types/node":"latest","@typescript-eslint/eslint-plugin":"latest","@typescript-eslint/parser":"latest","axios-mock-adapter":"^1.17.0","chai":"latest","chai-exclude":"^2.0.2","eslint":"latest","eslint-import-resolver-alias":"latest","eslint-plugin-import":"latest","mocha":"latest","mongodb-memory-server":"latest","nyc":"latest","sinon":"^8.0.4","typescript":"latest"},"gitHead":"450e1e6f29fd55d3083512b8bcd34e9ceffd1125","_id":"query-bouncer-mongoose-plugin@1.0.2","_nodeVersion":"12.13.0","_npmVersion":"6.12.0","dist":{"integrity":"sha512-VHiWXqo6AtKKqpQo3x7w31ku+RQUyH2Cznt11PNc7IU3khfvQMyADPSzYK/A/TvvUBuWEMPj7DG9Z5+RrPMhig==","shasum":"416642c51d6eee5f971d270015225e2010aeb5e3","tarball":"https://registry.npmjs.org/query-bouncer-mongoose-plugin/-/query-bouncer-mongoose-plugin-1.0.2.tgz","fileCount":55,"unpackedSize":130534,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJeN98xCRA9TVsSAnZWagAA/2AP/Rqw2qJIEOYb64Rq/Izx\n3O0sSvNZyB/x3UTG+mUwkclzdKvPdsaolw5VBWa6LLaqkU/OWT/g4dpzcN4F\nLHl7nta0z0WRFQ/BnFxbpRgaJyftr3ORv1L0m9+7y1fG8xdbuicEwJ1veIXz\nEE5mOeOoU+g6Y1cv8Jqu6r96OkRijH+gV2me92B+FvzwkMd4AE03jSTnBe4n\nLukOuQ2ibgqo9xIQd0s5EZJ/G9rjltVkdbtPuqVnVx+K5gDzeusUb4Ri+RBJ\n4p9Pvn6SVvdvgaJcWyczDAgMoIvEL4VHr3xvKtB5rhPXT8ocjmfGkQFy19Un\n8ooS//NPYO3dK/8MgM2zGLRmfA+sWDXaj0jg5soYBjgZAKs6MNysdLUq3JOa\nKlywGPWJztGx19ZozFFT5Kqh+UYa6IxZZWqJezsGh2v9orErwjjKc18YvcaY\nU7T/jjA/sTvimf6yMFVp0N/nwYwz7K0KPQLodXwGMGi85eArNkAD7hce6NGa\nRzuOXyKVuOI7hxNTg62EdRuCfwgKT/0YwV8usNvS6i9hcMG2utsh5EXlrHzg\nYuGaxYsyd5ffjkOfXaUJrnwbOBQnR0q6XUCCsXBAhd83m7qj7TwLNFL5GWbm\nlvlcBl4g/1qyS09hMljNItGhI0iUOd6C8fkykLmEpaTXKy6nhjocGZS4uyGb\n2pmW\r\n=Ql6e\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEQCIAfWWxgnijmZLiwgeNb+6fJtq/PXQm5FyoaCpqOaVE+eAiAbDyaJs7sYssuEoA5q2CFFkF9H2v+YdZAPxgrrzBYakw=="}]},"maintainers":[{"name":"relief.melone","email":"relief.melone@gmail.com"}],"_npmUser":{"name":"relief.melone","email":"relief.melone@gmail.com"},"directories":{},"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/query-bouncer-mongoose-plugin_1.0.2_1580719921299_0.0460437380238794"},"_hasShrinkwrap":false,"deprecated":"typings for mongoose will not be extended in versions prior to 1.3.1"},"1.0.3":{"name":"query-bouncer-mongoose-plugin","version":"1.0.3","description":"Mongoose Plugin for Query Bouncer","main":"./dist/index.js","scripts":{"start":"node ./dist/index.js","test":"nyc mocha","build":"tsc --watch false --declaration","lint":"eslint --ignore-path .gitignore .","tsc":"tsc"},"_moduleAliases":{"@root":".","@":"dist/src","@test":"dist/test"},"author":{"name":"Relief.Melone"},"license":"MIT","dependencies":{"axios":"^0.19.1","module-alias":"^2.2.2","mongodb":"^3.5.0","mongoose":"^5.8.7"},"devDependencies":{"@types/chai":"latest","@types/express":"latest","@types/mocha":"latest","@types/mongodb":"^3.3.14","@types/mongoose":"^5.5.41","@types/moxios":"^0.4.9","@types/node":"latest","@typescript-eslint/eslint-plugin":"latest","@typescript-eslint/parser":"latest","axios-mock-adapter":"^1.17.0","chai":"latest","chai-exclude":"^2.0.2","eslint":"latest","eslint-import-resolver-alias":"latest","eslint-plugin-import":"latest","mocha":"latest","mongodb-memory-server":"latest","nyc":"latest","sinon":"^8.0.4","typescript":"latest"},"gitHead":"3d7c9df0a63de2697a28bff8ac7fbcb129fd7dff","_id":"query-bouncer-mongoose-plugin@1.0.3","_nodeVersion":"12.13.0","_npmVersion":"6.12.0","dist":{"integrity":"sha512-fTVJ5sLauTK2OcbHX30d13lEyR9bKhUNHE5nBDMgtI3Ezs7gb1XZI7xucHNs/6Vf/KnhCPrEi+14OwmQyYm2jQ==","shasum":"5f6f6f00f3b580baa97e2860f91403a4ad2d9aab","tarball":"https://registry.npmjs.org/query-bouncer-mongoose-plugin/-/query-bouncer-mongoose-plugin-1.0.3.tgz","fileCount":55,"unpackedSize":130617,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJeN9/bCRA9TVsSAnZWagAAmCwQAIC5TFxFUw4/kSniYS3P\n1VPdPZHI+O1WuogUJRNHbheexvQzOMQGgjFOn5F9z1UYVGZCTvI5ETsq2qVZ\nAWG81awKS22kGwQYAkgrjin01ZXOHRL01VKVxrgaeIMrzksbBqzqX8TvN5yX\npOHkcjV4IPfdX7ogKc4q5NRrL9OY5P2hcJJChNIZMZvF5l1zwYy7jNVKt0gC\nA+fKEU0PAkwPLy7i7QmTPvR3Kqdxv00onNwDEFYfwNFOrDFgJ9WCa4nRJucL\nlDFrooLBdRetMGLAk61/qapIce7uYfoXJlFH448nuBaaEGmCFhkgcOOmXNvq\n7NQw2XC7cv1mI2IefYYNqpEAzcvfNBguyNlEtbhKWCeHFaJrXLDHV+/kGP4m\nUGu2Re5TIXOlFNk49H5hu46CHRZ5n8ePOY35EEHvqO0D+6YA7RPUZh9fJglW\noPD2WgZ5WzL4evTZw+vFcflgU90pLxwS2dHQMN1q2b6fUffaHIYBUxR0yqXm\nTRQXSPEZ1+3IbgIpDFb5Xg3jkAxKUXADb+SMkn3GLvweFZQHeMHQlbNroExJ\n7/zc/hJilLI+Qwx40dquA/CrDXxPerE6O98xYmO7yzK8pimllDLdbLew8NG7\nKpyGGR5Cacg8fgLGOSe+d0et1TBgfpbiXyghV3fOVpwBaTs2q7IKIXrR1UuW\n0cyR\r\n=7YYr\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEQCIEVUdY/Q1Tj25vcrzFXq1nnH+UvLs1mRmDzFyFWMeD7qAiAKEmCw1j8AzRH64ZW0sVvHiHDnQRBHhJGVHA1Zq5qUbg=="}]},"maintainers":[{"name":"relief.melone","email":"relief.melone@gmail.com"}],"_npmUser":{"name":"relief.melone","email":"relief.melone@gmail.com"},"directories":{},"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/query-bouncer-mongoose-plugin_1.0.3_1580720091512_0.28414961031659636"},"_hasShrinkwrap":false,"deprecated":"typings for mongoose will not be extended in versions prior to 1.3.1"},"1.2.0":{"name":"query-bouncer-mongoose-plugin","version":"1.2.0","description":"Mongoose Plugin for Query Bouncer","main":"./dist/index.js","scripts":{"start":"node ./dist/index.js","test":"nyc mocha","build":"tsc --watch false --declaration","lint":"eslint --ignore-path .gitignore .","tsc":"tsc"},"repository":{"type":"git","url":"git+https://github.com/relief-melone/query-bouncer-mongoose-plugin.git"},"author":{"name":"Relief.Melone"},"license":"MIT","dependencies":{"axios":"^0.19.1","express":"^4.17.1","mongodb":"^3.5.0","mongoose":"^5.8.7"},"devDependencies":{"@types/chai":"latest","@types/express":"^4.17.2","@types/mocha":"latest","@types/mongodb":"^3.3.14","@types/mongoose":"^5.5.41","@types/moxios":"^0.4.9","@types/node":"latest","@typescript-eslint/eslint-plugin":"latest","@typescript-eslint/parser":"latest","axios-mock-adapter":"^1.17.0","chai":"latest","chai-exclude":"^2.0.2","eslint":"latest","eslint-import-resolver-alias":"latest","eslint-plugin-import":"latest","mocha":"latest","mongodb-memory-server":"latest","nyc":"latest","sinon":"^8.0.4","typescript":"latest"},"gitHead":"5bb6677ab84aeafb0d8146bc80ddd0bd295d0ab6","bugs":{"url":"https://github.com/relief-melone/query-bouncer-mongoose-plugin/issues"},"homepage":"https://github.com/relief-melone/query-bouncer-mongoose-plugin#readme","_id":"query-bouncer-mongoose-plugin@1.2.0","_nodeVersion":"12.13.0","_npmVersion":"6.12.0","dist":{"integrity":"sha512-wqhcxL03diWTlFT/jxvRTPyLuvH1NwrvZu4jm9z4POGz1oNfsBXWP8drC2UCls0qa2YixKk51kBEanQmxAe3OQ==","shasum":"1ecedbdb53a9e2dfafb39c1664ef3f27605109d6","tarball":"https://registry.npmjs.org/query-bouncer-mongoose-plugin/-/query-bouncer-mongoose-plugin-1.2.0.tgz","fileCount":141,"unpackedSize":181836,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJeQV5ZCRA9TVsSAnZWagAATCMP/0vYjHKozbZBnvVRqyBj\nT/MpxGaOjFMF4e1C+hJdpK5zSFMWJ3OWxQQtn91NHfv60f808QYNI2kUjiSP\n56wSsAzgLYKmztNUmHYsgq78Vo1DO0VlddzZlNB3yoWJxqPfD9ZQBfjyPnk3\nSdimYs++ZeH4IJuTLm6zSAZxQDpvkJ6gYKehCFbMET94VYU9X+7V9GKkNyjS\n20nzaziV0i3hM7Wik3A0cs2VYdnNGtWXCnD3D8uZL24JbazT6tMgmjJ2pdcu\nRMybRnkLk3i3VELRnjNL7NkBDBIiWNIfdOETswFUvzu64hMlEdFKZ4kGuxk9\nXiLI2+aBs2NUYhzBuKhQt/n9MP3j4dWmYgLefzJYIDe0pE1y7ogJObtUwvFz\n1LlpuK4h/ChhwTrhtRp6kg3e9ARnQGqdVx4mw5eq6p/9KMWkkpqr5z/it49/\nKyEK+9l16cIWMRbu0osloLHzH5e/QjCE/l3BdCAx6pT3THgiDtL3F/DE6NAJ\neY97s+yAm0Zdtiz22nApzfCgleDvadFBCmuLOVD8mEtX10YoWPE+ojTZWgHK\nIKiZuJ9DGRfRbIITddci6B0jgfUL8X0tHBSsTAb+fN1wZ6a9QCC67odiv9sN\nDrhoIK0jl00extVZzQxUEbwd8AFtvJ8J6cv4NUNvr04VuA7nhE8Z8nE3SBqQ\nGtZG\r\n=uKye\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEQCIFnOdc0hu/vUZzrMjY5iAu7DbACTpCWZ8PcLvnsDT4hiAiBz/e3+wPPnMY+pPGZ+tRRAOdZbew1rN9NLuYz+fIn3Vw=="}]},"maintainers":[{"name":"relief.melone","email":"relief.melone@gmail.com"}],"_npmUser":{"name":"relief.melone","email":"relief.melone@gmail.com"},"directories":{},"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/query-bouncer-mongoose-plugin_1.2.0_1581342297296_0.5873472604512142"},"_hasShrinkwrap":false,"deprecated":"typings for mongoose will not be extended in versions prior to 1.3.1"},"1.3.1":{"name":"query-bouncer-mongoose-plugin","version":"1.3.1","description":"Mongoose Plugin for Query Bouncer","main":"./dist/index.js","scripts":{"start":"node ./dist/index.js","test":"nyc mocha","build":"tsc --watch false --declaration","lint":"eslint --ignore-path .gitignore .","tsc":"tsc"},"repository":{"type":"git","url":"git+https://github.com/relief-melone/query-bouncer-mongoose-plugin.git"},"author":{"name":"Relief.Melone"},"license":"MIT","dependencies":{"axios":"^0.19.1","express":"^4.17.1","mongodb":"^3.5.0","mongoose":"^5.8.7"},"devDependencies":{"@types/chai":"latest","@types/express":"^4.17.2","@types/mocha":"latest","@types/mongodb":"^3.3.14","@types/mongoose":"^5.5.41","@types/moxios":"^0.4.9","@types/node":"latest","@typescript-eslint/eslint-plugin":"latest","@typescript-eslint/parser":"latest","axios-mock-adapter":"^1.17.0","chai":"latest","chai-exclude":"^2.0.2","eslint":"latest","eslint-import-resolver-alias":"latest","eslint-plugin-import":"latest","mocha":"latest","mongodb-memory-server":"latest","nyc":"latest","sinon":"^8.0.4","typescript":"latest"},"gitHead":"0494534091eb24ffdae1b2736179bc02684eb288","bugs":{"url":"https://github.com/relief-melone/query-bouncer-mongoose-plugin/issues"},"homepage":"https://github.com/relief-melone/query-bouncer-mongoose-plugin#readme","_id":"query-bouncer-mongoose-plugin@1.3.1","_nodeVersion":"12.13.0","_npmVersion":"6.12.0","dist":{"integrity":"sha512-kXohbvLyRVltNfsQD+KKCq2uTb6CZtF9R6zeRUeT0SnYi02Q1jjilRaYzzXTccWh67FswYmOt44ccZ+GkSxBjw==","shasum":"eff3460d29e8a0b68cc95532ef480eeb7b61ffd4","tarball":"https://registry.npmjs.org/query-bouncer-mongoose-plugin/-/query-bouncer-mongoose-plugin-1.3.1.tgz","fileCount":144,"unpackedSize":183685,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJeQaA/CRA9TVsSAnZWagAAS3IQAI8T8ho6W3nO1Ph8486s\nOXYrJVljziGcMjrSGxU9l7WpsX20rAcIPOY5mF0rrRFyfxHHJnrUq0Cbx7u3\n2wUYWlzh78PmQ5GBHs1wGj+kECzUUCcvDU82obMIUVW1gFa8++KIAeFWwVwj\nsaHWNXYwRzNhhYhxObJJwcl44RUI5CO8ILwesq70JEw/ascN4O6jQRPzS7oD\n5E6YALVmn4CApRVUgoGfvBcWO5oUc7F+urqw1tiDrsGXD7N/5JWqNgkqUCX5\nPqt2InXHHYg3l2l2sD54lExVAu9mChB8dE/ap9wNB4EwA36wNpPvNF8Gu3R/\ngVWnNoxdW0Vc67ZPHes6KLp4aXaDM7t+gf+eZSpjXI+O3577nzBOy09rGMz9\na0YuOuCvtq4NIJlU+ywlVPKfmrbrHvYHa16HVjpUNYW8hf2TEFypm/VCtNMO\ntXijia82rDTpQu9l1drkpafRSP/CidBmcmP6Ye8UkQC6ldO2pIWN14JZf00E\nLL5OA2Em7wvK8M4xJRLIU+0wmXajD/3DmbHnXXuxiqpBMY2c1h6OakJ390z1\nMAbc5IKRNw0t/MLrJe9OdDvvlZu0072ugmd6xZTyBg6ka4I5Ee11ZFzura7c\nwA5Z9CwRUnWW6NyZyGwfjV78NLWXvsmXXz+aVqeTL+8yNF2LiVO02myss2vU\nUvO3\r\n=OOm1\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIQDqOFmOXt2x++4xjiNUfXU+RYhnHu63yzPNGJ89wk6YhgIgMJvhVefJBgs5bWzsnmliCPHJmSDk6cc5IFJXTj6rSBU="}]},"maintainers":[{"name":"relief.melone","email":"relief.melone@gmail.com"}],"_npmUser":{"name":"relief.melone","email":"relief.melone@gmail.com"},"directories":{},"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/query-bouncer-mongoose-plugin_1.3.1_1581359167388_0.18504646485624687"},"_hasShrinkwrap":false},"1.3.2":{"name":"query-bouncer-mongoose-plugin","version":"1.3.2","description":"Mongoose Plugin for Query Bouncer","main":"./dist/index.js","scripts":{"start":"node ./dist/index.js","test":"nyc mocha","build":"tsc --watch false --declaration","lint":"eslint --ignore-path .gitignore .","tsc":"tsc"},"repository":{"type":"git","url":"git+https://github.com/relief-melone/query-bouncer-mongoose-plugin.git"},"author":{"name":"Relief.Melone"},"license":"MIT","dependencies":{"axios":"^0.19.1","express":"^4.17.1","mongodb":"^3.5.0","mongoose":"^5.8.7"},"devDependencies":{"@types/chai":"latest","@types/express":"^4.17.2","@types/mocha":"latest","@types/mongodb":"^3.3.14","@types/mongoose":"^5.5.41","@types/moxios":"^0.4.9","@types/node":"latest","@typescript-eslint/eslint-plugin":"latest","@typescript-eslint/parser":"latest","axios-mock-adapter":"^1.17.0","chai":"latest","chai-exclude":"^2.0.2","eslint":"latest","eslint-import-resolver-alias":"latest","eslint-plugin-import":"latest","mocha":"^7.1.1","mongodb-memory-server":"^6.5.0","nyc":"latest","sinon":"^8.0.4","typescript":"latest"},"gitHead":"b628abf17f5e397a626b3488ec471443d391e00a","bugs":{"url":"https://github.com/relief-melone/query-bouncer-mongoose-plugin/issues"},"homepage":"https://github.com/relief-melone/query-bouncer-mongoose-plugin#readme","_id":"query-bouncer-mongoose-plugin@1.3.2","_nodeVersion":"12.13.0","_npmVersion":"6.12.0","dist":{"integrity":"sha512-DLXBsjBLv4bEdFmNP/MBfq9UzyROqyIKRgykAXDLG/Gg0fO4NnWL5h//SWeTxusLPe84MvYwmo9LRLZkKLLasQ==","shasum":"0627ae466a3cee35b036b32532bbd4475c79a1f5","tarball":"https://registry.npmjs.org/query-bouncer-mongoose-plugin/-/query-bouncer-mongoose-plugin-1.3.2.tgz","fileCount":144,"unpackedSize":185142,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJee8TwCRA9TVsSAnZWagAA/PMQAKSmqOPxdJcmQrT7IDxP\nQVi+tpHdj4f9bEWtZyhhLKzvdP0czOVm7/ojc6UJh/SL/ZKAAyLduWBcG3Zg\nqGKuyIPAul3j7dDWSvxrEm7u0sGFW6ZHV5Zlcr5pP5ULsC+zl21EAHGMT8Nk\nsbiegJ5pSY+PFirAU0naO6nWYVrlQ4HQhkGfY1PYfFFl2SXcI3SH3naSBJ5h\nWdBnQWV+njEaG+JIIeNB7KWDOC6+hxOnJoFp0Xj0JbVGj7dAyVNv6Homtud7\nZhWVbFC94Lwj3FG902pog4GjVDL7wCvpKCloEiU86nJRD2+f0A4i4ekFzWFk\n9klO3x8JMHfiXkwYgbrZl5P+VAQh5Dt8tSmQtRQco6er2yyi9TbVAec0eQ6X\niDjlNcsITXlZ5Hz1TlyyrOLSFcmW0sekRgg4SJQ6kpcwMV5xtywFR1xqpA8u\n711Tx+3k35B1t2O7TjRez9YVvA5O8iROidt+RxV2foalf3btKy9WSo1S9RSH\n3MUUhc4HR9wwclxtN8s4OF02qoDAMaR1E3OqDHXZnlF7NKmfZSPf5UlCovbO\n9x6kNhEnXinshLQR7x2XPZhr9vt3pkzrUwCJTUSNwAk03qF21Gpf0CubJ+fy\nGwsZR3b8/bXy4chraP2VBggly9NCcqEGRBCRk5NFvo8JcbV95IwUt3PsY38k\nU2ZS\r\n=txCS\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIE2EZOkZNwxkw2csUK7Egl7LHUeQUzAlX6i1fRhrhsRkAiEA1dlV0ajO9wUnaCO/kppx+Ql2J4to2m+ZbRUg6tbY/xY="}]},"maintainers":[{"name":"relief.melone","email":"relief.melone@gmail.com"}],"_npmUser":{"name":"relief.melone","email":"relief.melone@gmail.com"},"directories":{},"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/query-bouncer-mongoose-plugin_1.3.2_1585169647548_0.6417698663309233"},"_hasShrinkwrap":false},"1.3.3-beta.0":{"name":"query-bouncer-mongoose-plugin","version":"1.3.3-beta.0","description":"Mongoose Plugin for Query Bouncer","main":"./dist/index.js","scripts":{"start":"node ./dist/index.js","test":"nyc mocha","build":"tsc --watch false --declaration","lint":"eslint --ignore-path .gitignore .","tsc":"tsc"},"repository":{"type":"git","url":"git+https://github.com/relief-melone/query-bouncer-mongoose-plugin.git"},"author":{"name":"Relief.Melone"},"license":"MIT","dependencies":{"axios":"^0.19.1","express":"^4.17.1","mongodb":"^3.5.0","mongoose":"^5.8.7"},"devDependencies":{"@types/chai":"latest","@types/express":"^4.17.2","@types/mocha":"latest","@types/mongodb":"^3.3.14","@types/mongoose":"^5.5.41","@types/moxios":"^0.4.9","@types/node":"latest","@typescript-eslint/eslint-plugin":"latest","@typescript-eslint/parser":"latest","axios-mock-adapter":"^1.17.0","chai":"latest","chai-exclude":"^2.0.2","eslint":"latest","eslint-import-resolver-alias":"latest","eslint-plugin-import":"latest","mocha":"^7.1.1","mongodb-memory-server":"^6.5.0","nyc":"latest","sinon":"^8.0.4","typescript":"latest"},"gitHead":"b628abf17f5e397a626b3488ec471443d391e00a","bugs":{"url":"https://github.com/relief-melone/query-bouncer-mongoose-plugin/issues"},"homepage":"https://github.com/relief-melone/query-bouncer-mongoose-plugin#readme","_id":"query-bouncer-mongoose-plugin@1.3.3-beta.0","_nodeVersion":"14.13.1","_npmVersion":"6.14.8","dist":{"integrity":"sha512-qVj4/OvnfV0sIwaKnMnF3+Jo9Qhb849WCE8J4o+llbQtQo/TD6INePOmnr9znn87kfkLOvta60QSatjO4A/NFg==","shasum":"0d88955d46f5c9ee613307f20ac20bb56b2810b2","tarball":"https://registry.npmjs.org/query-bouncer-mongoose-plugin/-/query-bouncer-mongoose-plugin-1.3.3-beta.0.tgz","fileCount":144,"unpackedSize":193199,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.13\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJfhJdwCRA9TVsSAnZWagAAzK0P/R6Ii9qpuFSr2AgME3EX\nhrTWAeiTaenluDFmDFXGkX1/AgJVTJdqSCUQjvrYQSWuOZIv3scWh9qfnpws\nw8iRQ2C6tUMnr3jOoSKYwrYI5yBGnlo2ouvoS0rbJeLsUMQO+gFiH+tLw+f6\nkk+7Oncp+QmH4i11YLsSaKQ6sfEIxV7apfFWgotvzuotkSyFbo5Y77loGgh8\ndfyWllGibUIlkVn9O6TpV7d+Q3ENO3bVdCeupRZMOAzgcE1lt/LLpz6kC1/+\nQzNS/XGPbSzh26DMoSSLCOvwc1g00c4iUwzOSkd5oOjqMjE3w5Tdsdz2k35i\nTQY+zhcWkn6jH6Awb3SnHyHcETtAiD3pN2ILv4kRdenm8bPkJIP+meOAt8ma\ncPZifOWifOa74iwkVH2xt2FFvVta6OS/+nCNI0GhU96AUVBvQJk+2/ByCYdw\nEV5PglQlOWcJH00HgZJG7ocn8FgIUh0GQ6YD6LkZZAY+3ZANZsjqZf8/zThW\n1pFR7wqPHDshAY8xplvo5k6/WA+3NBMQvy8yClM1/NMMQ4GepCbF2vR99kmR\nTMEIWCwLYuK/NocZ+3B1u88paCzmS4rrBNZXwo+BG59wURR9QImy+7NuuKpD\noSmY1g73VMs9C5LNe1C0qoS9oWkji9n0YRhXmHCjkjhX4vw335geJxbN7Cj1\nKzDU\r\n=j+CK\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEYCIQCtaq4UiQ1rq5ejGalWRZnwAyWxTiXmDL6boQ/RYpmBBgIhANednj4MYWrjQThwsyJY7r9FeGzFttsmIcVxhFLHGu4h"}]},"maintainers":[{"name":"relief.melone","email":"relief.melone@gmail.com"}],"_npmUser":{"name":"relief.melone","email":"relief.melone@gmail.com"},"directories":{},"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/query-bouncer-mongoose-plugin_1.3.3-beta.0_1602525039832_0.020352933650253924"},"_hasShrinkwrap":false},"1.4.0":{"name":"query-bouncer-mongoose-plugin","version":"1.4.0","description":"Mongoose Plugin for Query Bouncer","main":"./dist/index.js","scripts":{"start":"node ./dist/index.js","test":"nyc mocha","build":"tsc --watch false --declaration","lint":"eslint --ignore-path .gitignore .","tsc":"tsc"},"repository":{"type":"git","url":"git+https://github.com/relief-melone/query-bouncer-mongoose-plugin.git"},"author":{"name":"Relief.Melone"},"license":"MIT","dependencies":{"axios":"^0.19.1","express":"^4.17.1","mongodb":"^3.5.0","mongoose":"^5.8.7"},"devDependencies":{"@types/chai":"latest","@types/express":"^4.17.2","@types/mocha":"latest","@types/mongodb":"^3.3.14","@types/mongoose":"^5.5.41","@types/moxios":"^0.4.9","@types/node":"latest","@typescript-eslint/eslint-plugin":"latest","@typescript-eslint/parser":"latest","axios-mock-adapter":"^1.17.0","chai":"latest","chai-exclude":"^2.0.2","eslint":"latest","eslint-import-resolver-alias":"latest","eslint-plugin-import":"latest","mocha":"^7.1.1","mongodb-memory-server":"^6.5.0","nyc":"latest","sinon":"^8.0.4","typescript":"latest"},"gitHead":"9c62dac89dfc89d41a45a04c571d7f2964dd2aa6","bugs":{"url":"https://github.com/relief-melone/query-bouncer-mongoose-plugin/issues"},"homepage":"https://github.com/relief-melone/query-bouncer-mongoose-plugin#readme","_id":"query-bouncer-mongoose-plugin@1.4.0","_nodeVersion":"14.13.1","_npmVersion":"6.14.8","dist":{"integrity":"sha512-90bt7oYHUBfYQ1FXwa3xc/08VtlBqXFcWnjmtZO9s1VgJvufgmAFKOenf4shM7NkHlaG6UuxupVtjsUbio3zTg==","shasum":"333511a8d729c96d79c247c88d852873b8d0bc21","tarball":"https://registry.npmjs.org/query-bouncer-mongoose-plugin/-/query-bouncer-mongoose-plugin-1.4.0.tgz","fileCount":144,"unpackedSize":193665,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.13\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJfjTeCCRA9TVsSAnZWagAAJ3wP/iVcrC6OE3OlyV9Mpykg\n6APvlmHPaWcZHJhGM4UshuhjMrbheudqHoJNWzr5ydJIFRJy28VyYBEoBrb+\naodGw9AjkmXwuIg4Cj523mqsbIalDXehpPR9QoQriWfFlyN6gjreX0HWBYE9\nLjFvnSOY8JAb7UAxMyxjDNMIiYtXqmlMy4FRX5xHF6+4ngx50hH5ZTbZtesp\nRzmN0bipK1LE8KGMNWqc512czU2FISJaY4lNwmCrNL7N++tWP/FM5JT6BTW/\nHAXLGs1ucwXALu7kMjqmFWLE4ISZlB23HmhI77wtRuFyEpSIEjJ4fGgxf6tY\nbvvQQ+p3R8N0MyYDc7B6iDHi0P7akev5njrqse9G59WCjVSXwMIN+CR33Xif\nDPKQ9GZ8lINccfnLf+YUNH2kzidjvpKC3wK8p9yKHj0lJnFxM316C4t6w+ty\nzUDdCYkAVvCCdZjEasAU3ea/vk7RtgAX23doHhGhA1w8UL/MiJ2VnkmuPa27\neX5eBdMvSNVnXcPv/Y69BlyHYG//OHUCLUdy7hxagtT9HkVKQnk2XdH1gKgl\npWpYzvRxjQ5Xsija5gKH3afsy4R56rpaLCN+YLCmeQCTC6WDpjlH/ASG6Cz/\nA+m6s0XHXoty1ERuju+d7masnX+uHpOG3oDGhUr19dfbjPqDf+Kz7a+RPVco\nZnhJ\r\n=vlH1\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEQCIDwJUiZIco545mBqt/gLnZtbFuBHB4nn0gTCoQyc6rSKAiBJtwlWSO3b94QZiKC3RkmU8NXsCULxnpkgkLZuPqBgCw=="}]},"maintainers":[{"name":"relief.melone","email":"relief.melone@gmail.com"}],"_npmUser":{"name":"relief.melone","email":"relief.melone@gmail.com"},"directories":{},"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/query-bouncer-mongoose-plugin_1.4.0_1603090306334_0.7284603482650611"},"_hasShrinkwrap":false},"1.5.0-beta.0":{"name":"query-bouncer-mongoose-plugin","version":"1.5.0-beta.0","description":"Mongoose Plugin for Query Bouncer","main":"./dist/index.js","scripts":{"start":"node ./dist/index.js","test":"nyc mocha","build":"tsc --watch false --declaration","lint":"eslint --ignore-path .gitignore .","tsc":"tsc"},"repository":{"type":"git","url":"git+https://github.com/relief-melone/query-bouncer-mongoose-plugin.git"},"author":{"name":"Relief.Melone"},"license":"MIT","dependencies":{"axios":"^0.19.1","express":"^4.17.1","mongodb":"^3.5.0","mongoose":"^5.8.7"},"devDependencies":{"@types/chai":"latest","@types/express":"^4.17.2","@types/mocha":"latest","@types/mongodb":"^3.3.14","@types/mongoose":"^5.5.41","@types/moxios":"^0.4.9","@types/node":"latest","@typescript-eslint/eslint-plugin":"latest","@typescript-eslint/parser":"latest","axios-mock-adapter":"^1.17.0","chai":"latest","chai-exclude":"^2.0.2","eslint":"latest","eslint-import-resolver-alias":"latest","eslint-plugin-import":"latest","mocha":"^7.1.1","mongodb-memory-server":"^6.5.0","nyc":"latest","sinon":"^8.0.4","typescript":"latest"},"readme":"# MongoBouncer - A Mongoose Plugin for Query Bouncer\n\nThe Mongoose Plugin for Query Bouncer (MongoBouncer) integrates with rm-authenticator, Query Bouncer and rm-session-populate. It's goal is to integrate the Role Based Access Control System you define in Query Bouncer easily in your Backend without having to worry about making the correct http requests and modify queries by yourself. The tasks of these components are\n\n1. **rm-authenticator:** Easy way to authenticate your user with just a Docker Container. Works with different OAuth providers like facebook, linkedin and google+. \n   - [GitHub](https://github.com/relief-melone/rm-authenticator)\n   - [Docker](https://hub.docker.com/repository/docker/reliefmelone/rm-authenticator)\n2. **rm-session-populator:** Middleware for Express. It will automatically communicate with the Authenticator and add a user object to your Express **req** with all the information you need\n   - [GitHub](https://github.com/relief-melone/rm-session-populator)\n   - [NPM](https://www.npmjs.com/package/rm-session-populator)\n3. **Query Bouncer:** Set up your Role Based Access System with a comfortable REST-API and use it to automatically modify queries and payloads based on your users permissions. \n   - [GitHub](https://github.com/relief-melone/query-bouncer)\n   - [Docker](https://hub.docker.com/r/reliefmelone/query-bouncer)\n4. **Query Bouncer Mongoose Plugin:** A Plugin that handles all the communication with the authorizer automatically so you can focus on writing your application.\n\nThis Overview illustrates a possible architecture for your application and the integration of those 4 components.\n\n![architecture](https://raw.githubusercontent.com/relief-melone/query-bouncer-mongoose-plugin/master/documentation/architectureOverview.png \"Architecture Overview\")\n\n## Instalation\n\nJust install with npm\n\n```sh\nnpm i --save query-bouncer-mongoose-plugin\n```\n\n## Usage\n\n### Prerequisites\n\nYou need a running instance of Query Bouncer to connect to. The Query Bouncer supplies the plugin with the correct queries accordingly to the users permissions. you can see how to set it up [here](https://github.com/relief-melone/query-bouncer)\n\n### How it Works\n\nQuery Bouncer will be used to easily set up your roles, permissions and roleAssignments for your Application. It supplies endpoints to send your query and payload to. The Query Bouncer will then validate the information based on your users permissions and will e.g. send back an adjusted query based on the users permissions. So what does that mean. Lets assume we have a collection called blogposts. Each BlogPost has a Title, Description and a Category. The user only has access to BlogPosts of the Category \"Cars\". So when a request to the Query Bouncer is made with the query to get all BlogPosts The Query \n\n```js\n{}\n```\nwill be returned as\n\n```js\n{ \n  $or: [ \n    {Category: \"Cars\"} \n  ] \n}\n```\n\nIn order to not having to utilize the API of rm-authorizer directly mongo-bouncer will handle all that for you. The following paragraphs will show you how to use it.\n\n\n### Initialize\n\nAs this is a mongoose plugin simply initialize the plugin like this. You only need the endpoint of your authorizer. That's it\n\n```ts\nimport mongoBouncer from \"query-bouncer-mongoose-plugin\"\n\nmongoose.plugin(mongoBouncer, {\n  baseUrl: \"https://your-authorizer.com\"\n});\n```\n\nNow with the nature of mongoose plugins this has to be made before any schemas are initialized (which most of time will be done already). So either wrap your schemas so you make sure that the plugin gets initialized first or set the plugin for each schema you want to use (**recommended**)\n\n```ts\nconst blogPostSchema = new mongoose.Schema({\n  Title: \"My new Blog Post\",\n  // ...\n});\n\nblogPostSchema.plugin(mongoBouncer, {\n  baseUrl: \"https://your-authorizer.com\"\n});\n```\n\n#### Additional Options\n**baseUrl:** The URL the MongoBouncer that you want to connect to is hosted\n**apiVersion:** The Version of the API you want to use. Defaults to v1\n**axios:** You can force the Plugin to use another Axios Instance. This is mainly for testing purposes and not recommended\n**cookieName:** By default the Authenticator is set up to give you a cookie named connect.sid. If however you changed that you can also adjust the cookieName here\n\n### Useage\n\nMongoBouncer will run all the validation before your operations are being executed. As this middleware is currently not available in mongoose plugins for all methods, we currentyl support the following\n\n- create **(See Important Information about create)**\n- find\n- findOne\n- findOneAndDelete\n- findOneAndRemove\n- findOneAndUpdate\n- findById\n- findByIdAndDelete\n- findByIdAndRemove\n- findByIdAndUpdate\n- insertMany\n- remove \n- update\n- updateOne\n- updateMany\n- deleteOne\n- deleteMany\n\nThis is an example on how to enalbe MongoBouncer on your model. req refers to the express Request here. The MongoBouncer property needs to be added to the Options Object of your method. Let's take a look at some of those methods\n\nFirst let's set up a model.\n```ts\nconst BlogPostSchema = new Schema({\n  Title: { type: String, required: true } ,\n  Description: { type: String },\n  Category: { type: String, required: true }\n});\nconst BlogPost = mongoose.model('blogpost', BlogPostSchema);\n```\n#### Create\nNow to create a Document with respect to the permissions you just add the MongoBouncer to the options. \n\nAs the Options Object in mongoose is only available if the Document is passed in array please make sure you that even of you just add a single Document you use it in an Array. If you use a single Object the Options Object will be empty internally and as a result **Permissions will not be checked!!!**\n\nAs we stated earlier our authorizer has been set up to\nallow the user to create BlogPosts only if the category is \"Cars\". So while this will work just fine.\n```ts\nconst post = await BlogPost.create([{\n  Title: \"MyBlogPost\",\n  Category: \"Cars\",\n  Description: \"Some cool information about my favourite car\"\n}], { \n  MongoBouncer : {\n    Request: req \n  }\n});\n```\nthis\n```ts\nconst post = await BlogPost.create({\n  Title: \"MyBlogPost\",\n  Category: \"Food\",\n  Description: \"Some cool information about my favourite car\"\n}, { \n  MongoBouncer : {\n    Request: req \n  }\n});\n```\nwill throw an Error as the user is not allowed to create Blog Posts in that Category\n\n#### Find\n\nLet's assume we will now try to find that document again. Again as our fictive setup is that our user will only receive BlogPosts if the Category\nCars in this case\n```ts\nBlogPost.find({ Title: \"MyBlogPost\" }, null, {\n  MongoBouncer: {\n    Request: req\n  }\n});\n```\nwe will be returned an array with the Document we added in the Create section\n\n\n#### Update\nIf we now want to update the document we created we do it just the same way. A working update call would look like this\n```ts\nBlogPost.updateOne(\n  { Title: \"MyBlogPost\", Category: \"Cars\" }, \n  { Title: \"A changed Title\"}, \n  {\n    MongoBouncer: {\n      Request: req\n    }\n  }\n);\n```\nInternally both the Payload and the QueryRestrictions will be checked. So if we use any other Category than Cars nothing will be updated. However in this case no error will be returned but the returned Object by mongoose will just state that nothing matched our Query and nothing was updated. But if we try this e.g.\n```ts\nBlogPost.updateOne(\n  { Title: \"MyBlogPost\", Category: \"Cars\" }, \n  { Title: \"A changed Title\", Category: \"Food\" }, \n  {\n    MongoBouncer: {\n      Request: req\n    }\n  }\n);\n```\nan error will be thrown as a Document will be returned but we are not allowed to invoke the changes we are trying to make.\n\n","readmeFilename":"README.md","gitHead":"9c62dac89dfc89d41a45a04c571d7f2964dd2aa6","bugs":{"url":"https://github.com/relief-melone/query-bouncer-mongoose-plugin/issues"},"homepage":"https://github.com/relief-melone/query-bouncer-mongoose-plugin#readme","_id":"query-bouncer-mongoose-plugin@1.5.0-beta.0","_nodeVersion":"14.13.1","_npmVersion":"6.14.8","dist":{"integrity":"sha512-0gOfgo0PyGyU+NOtqR9hPlK48QEKYuRtooCrmhhH1g+KNzA89z0knsmU/yAyPD4ulkSTF+tyLG4V8e+KwuSr9A==","shasum":"65227d7ed3119a4bdae4a6a68e94c1255844098e","tarball":"https://registry.npmjs.org/query-bouncer-mongoose-plugin/-/query-bouncer-mongoose-plugin-1.5.0-beta.0.tgz","fileCount":144,"unpackedSize":193587,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.13\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJfkEtYCRA9TVsSAnZWagAA6dEP/jKrSfPsM5gqiOB9lla3\nrPaWH095kdz1W3h3e9pmIVIwYfZ23MqOPu1ZDjeyfZwVuX2wAUYm41JyJtSn\nP1zX70N4z/J5MKzaocTLxMgTZ/2fbm2xMQceGJeV9bzeZW31BQA3vfhdlBv2\ndGPllsSFYM4E7Malgg2kgAJBOiW4Ot7vaPmSSMY6uJKaZUGT/0LtPd8DbmW8\nyLSmGGUXBNTZD9c1WBNAomQi26Kgqp8V/u0R9QVpNUJWSQ1xkiH+uIaCGqpO\nlkGfFPuqus4JgFzjLZU41ZhZq3C19MissH0XflMTZdF7n+p19WANrzp8Rq9D\n6HG9GxgRAV2PVAL0M+JP+BTVwMVUtFgoOaRNuwqW9hFiJ0ebYDznzMcebKUe\ny0fSDQmPovovWRaP45JS8du59YcFtYppyQ4DrahPO3iompU+na1TFXrjVh+8\n9+Ta2JGiiSR/YayE0WwlD+8H3NTqDkCrJjEQmRjBlch9giSNuM2lUFOCmTSD\ng/ii/uecPn8JuZhtAFpZrxE9Ben/YeZY4lkkSEr2iPIUQe4CnS+CoCsd0AhF\nfMS+RQKiq+ZrT0o2WdOIJtxqBNB4/CEi0FRNaOj4TIh6QP7axU02XrmaLMl4\nW3astMCxYTELQdHfNZey/B1O9QAknO0mNhiC4YGcNPI3kR4bcnWCp2d4mh4w\nxZIg\r\n=Ri0V\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIFsp3tUuQ+ATDG9L0QkIWDWjdzCxwS3nm43YTZWS+kOzAiEArjZXmJjRQX5l3eEJKgY04X5DX56Hurq5Cj4WXnlFk4o="}]},"maintainers":[{"name":"relief.melone","email":"relief.melone@gmail.com"}],"_npmUser":{"name":"relief.melone","email":"relief.melone@gmail.com"},"directories":{},"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/query-bouncer-mongoose-plugin_1.5.0-beta.0_1603291991611_0.7055514491331192"},"_hasShrinkwrap":false},"1.5.0-beta.1":{"name":"query-bouncer-mongoose-plugin","version":"1.5.0-beta.1","description":"Mongoose Plugin for Query Bouncer","main":"./dist/index.js","scripts":{"start":"node ./dist/index.js","test":"nyc mocha","build":"tsc --watch false --declaration","lint":"eslint --ignore-path .gitignore .","tsc":"tsc"},"repository":{"type":"git","url":"git+https://github.com/relief-melone/query-bouncer-mongoose-plugin.git"},"author":{"name":"Relief.Melone"},"license":"MIT","dependencies":{"axios":"^0.19.1","express":"^4.17.1","mongodb":"^3.5.0","mongoose":"^5.8.7"},"devDependencies":{"@types/chai":"latest","@types/express":"^4.17.2","@types/mocha":"latest","@types/mongodb":"^3.3.14","@types/mongoose":"^5.5.41","@types/moxios":"^0.4.9","@types/node":"latest","@typescript-eslint/eslint-plugin":"latest","@typescript-eslint/parser":"latest","axios-mock-adapter":"^1.17.0","chai":"latest","chai-exclude":"^2.0.2","eslint":"latest","eslint-import-resolver-alias":"latest","eslint-plugin-import":"latest","mocha":"^7.1.1","mongodb-memory-server":"^6.5.0","nyc":"latest","sinon":"^8.0.4","typescript":"latest"},"readme":"# MongoBouncer - A Mongoose Plugin for Query Bouncer\n\nThe Mongoose Plugin for Query Bouncer (MongoBouncer) integrates with rm-authenticator, Query Bouncer and rm-session-populate. It's goal is to integrate the Role Based Access Control System you define in Query Bouncer easily in your Backend without having to worry about making the correct http requests and modify queries by yourself. The tasks of these components are\n\n1. **rm-authenticator:** Easy way to authenticate your user with just a Docker Container. Works with different OAuth providers like facebook, linkedin and google+. \n   - [GitHub](https://github.com/relief-melone/rm-authenticator)\n   - [Docker](https://hub.docker.com/repository/docker/reliefmelone/rm-authenticator)\n2. **rm-session-populator:** Middleware for Express. It will automatically communicate with the Authenticator and add a user object to your Express **req** with all the information you need\n   - [GitHub](https://github.com/relief-melone/rm-session-populator)\n   - [NPM](https://www.npmjs.com/package/rm-session-populator)\n3. **Query Bouncer:** Set up your Role Based Access System with a comfortable REST-API and use it to automatically modify queries and payloads based on your users permissions. \n   - [GitHub](https://github.com/relief-melone/query-bouncer)\n   - [Docker](https://hub.docker.com/r/reliefmelone/query-bouncer)\n4. **Query Bouncer Mongoose Plugin:** A Plugin that handles all the communication with the authorizer automatically so you can focus on writing your application.\n\nThis Overview illustrates a possible architecture for your application and the integration of those 4 components.\n\n![architecture](https://raw.githubusercontent.com/relief-melone/query-bouncer-mongoose-plugin/master/documentation/architectureOverview.png \"Architecture Overview\")\n\n## Instalation\n\nJust install with npm\n\n```sh\nnpm i --save query-bouncer-mongoose-plugin\n```\n\n## Usage\n\n### Prerequisites\n\nYou need a running instance of Query Bouncer to connect to. The Query Bouncer supplies the plugin with the correct queries accordingly to the users permissions. you can see how to set it up [here](https://github.com/relief-melone/query-bouncer)\n\n### How it Works\n\nQuery Bouncer will be used to easily set up your roles, permissions and roleAssignments for your Application. It supplies endpoints to send your query and payload to. The Query Bouncer will then validate the information based on your users permissions and will e.g. send back an adjusted query based on the users permissions. So what does that mean. Lets assume we have a collection called blogposts. Each BlogPost has a Title, Description and a Category. The user only has access to BlogPosts of the Category \"Cars\". So when a request to the Query Bouncer is made with the query to get all BlogPosts The Query \n\n```js\n{}\n```\nwill be returned as\n\n```js\n{ \n  $or: [ \n    {Category: \"Cars\"} \n  ] \n}\n```\n\nIn order to not having to utilize the API of rm-authorizer directly mongo-bouncer will handle all that for you. The following paragraphs will show you how to use it.\n\n\n### Initialize\n\nAs this is a mongoose plugin simply initialize the plugin like this. You only need the endpoint of your authorizer. That's it\n\n```ts\nimport mongoBouncer from \"query-bouncer-mongoose-plugin\"\n\nmongoose.plugin(mongoBouncer, {\n  baseUrl: \"https://your-authorizer.com\"\n});\n```\n\nNow with the nature of mongoose plugins this has to be made before any schemas are initialized (which most of time will be done already). So either wrap your schemas so you make sure that the plugin gets initialized first or set the plugin for each schema you want to use (**recommended**)\n\n```ts\nconst blogPostSchema = new mongoose.Schema({\n  Title: \"My new Blog Post\",\n  // ...\n});\n\nblogPostSchema.plugin(mongoBouncer, {\n  baseUrl: \"https://your-authorizer.com\"\n});\n```\n\n#### Additional Options\n**baseUrl:** The URL the MongoBouncer that you want to connect to is hosted\n**apiVersion:** The Version of the API you want to use. Defaults to v1\n**axios:** You can force the Plugin to use another Axios Instance. This is mainly for testing purposes and not recommended\n**cookieName:** By default the Authenticator is set up to give you a cookie named connect.sid. If however you changed that you can also adjust the cookieName here\n\n### Useage\n\nMongoBouncer will run all the validation before your operations are being executed. As this middleware is currently not available in mongoose plugins for all methods, we currentyl support the following\n\n- create **(See Important Information about create)**\n- find\n- findOne\n- findOneAndDelete\n- findOneAndRemove\n- findOneAndUpdate\n- findById\n- findByIdAndDelete\n- findByIdAndRemove\n- findByIdAndUpdate\n- insertMany\n- remove \n- update\n- updateOne\n- updateMany\n- deleteOne\n- deleteMany\n\nThis is an example on how to enalbe MongoBouncer on your model. req refers to the express Request here. The MongoBouncer property needs to be added to the Options Object of your method. Let's take a look at some of those methods\n\nFirst let's set up a model.\n```ts\nconst BlogPostSchema = new Schema({\n  Title: { type: String, required: true } ,\n  Description: { type: String },\n  Category: { type: String, required: true }\n});\nconst BlogPost = mongoose.model('blogpost', BlogPostSchema);\n```\n#### Create\nNow to create a Document with respect to the permissions you just add the MongoBouncer to the options. \n\nAs the Options Object in mongoose is only available if the Document is passed in array please make sure you that even of you just add a single Document you use it in an Array. If you use a single Object the Options Object will be empty internally and as a result **Permissions will not be checked!!!**\n\nAs we stated earlier our authorizer has been set up to\nallow the user to create BlogPosts only if the category is \"Cars\". So while this will work just fine.\n```ts\nconst post = await BlogPost.create([{\n  Title: \"MyBlogPost\",\n  Category: \"Cars\",\n  Description: \"Some cool information about my favourite car\"\n}], { \n  MongoBouncer : {\n    Request: req \n  }\n});\n```\nthis\n```ts\nconst post = await BlogPost.create({\n  Title: \"MyBlogPost\",\n  Category: \"Food\",\n  Description: \"Some cool information about my favourite car\"\n}, { \n  MongoBouncer : {\n    Request: req \n  }\n});\n```\nwill throw an Error as the user is not allowed to create Blog Posts in that Category\n\n#### Find\n\nLet's assume we will now try to find that document again. Again as our fictive setup is that our user will only receive BlogPosts if the Category\nCars in this case\n```ts\nBlogPost.find({ Title: \"MyBlogPost\" }, null, {\n  MongoBouncer: {\n    Request: req\n  }\n});\n```\nwe will be returned an array with the Document we added in the Create section\n\n\n#### Update\nIf we now want to update the document we created we do it just the same way. A working update call would look like this\n```ts\nBlogPost.updateOne(\n  { Title: \"MyBlogPost\", Category: \"Cars\" }, \n  { Title: \"A changed Title\"}, \n  {\n    MongoBouncer: {\n      Request: req\n    }\n  }\n);\n```\nInternally both the Payload and the QueryRestrictions will be checked. So if we use any other Category than Cars nothing will be updated. However in this case no error will be returned but the returned Object by mongoose will just state that nothing matched our Query and nothing was updated. But if we try this e.g.\n```ts\nBlogPost.updateOne(\n  { Title: \"MyBlogPost\", Category: \"Cars\" }, \n  { Title: \"A changed Title\", Category: \"Food\" }, \n  {\n    MongoBouncer: {\n      Request: req\n    }\n  }\n);\n```\nan error will be thrown as a Document will be returned but we are not allowed to invoke the changes we are trying to make.\n\n","readmeFilename":"README.md","gitHead":"9c62dac89dfc89d41a45a04c571d7f2964dd2aa6","bugs":{"url":"https://github.com/relief-melone/query-bouncer-mongoose-plugin/issues"},"homepage":"https://github.com/relief-melone/query-bouncer-mongoose-plugin#readme","_id":"query-bouncer-mongoose-plugin@1.5.0-beta.1","_nodeVersion":"14.13.1","_npmVersion":"6.14.8","dist":{"integrity":"sha512-hbs5SfrACXFpF3YxV546lYVg1EPIUMbV4qaO6vCCTKZhwcJnkyfb6BfH/nRYyVibU4WVyfvp1+S9qEaOQTvG8A==","shasum":"be90b2855105f08fe973cc9824ec12134740a5a4","tarball":"https://registry.npmjs.org/query-bouncer-mongoose-plugin/-/query-bouncer-mongoose-plugin-1.5.0-beta.1.tgz","fileCount":144,"unpackedSize":193850,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.13\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJfkE0CCRA9TVsSAnZWagAATwsP/i7Jil05vI9W17EVQW/u\nJ5ivqO6dDhpgw2GaMR2eKo1nQSrI0saNkPxLhW+drXQO1917sjiWZwf7Ufan\nyu8VCaSYjv+PB9zzA+aocGGApnvMH6E73a64bhl/rkR0LLZWu6pUIdKxVMI2\nhTCwG/EJQX0CED8CnxFzyC82lQoyW+r2cOYkYO8g+Hc5qkGGVZD4mFag+NH/\n5Vl0/U6hqV1sNzQXYBE4CDtZ6qxwUIYlaDUJIgXmtlvPZyZ6CpPvdLprgFYV\npWZx6VQl/II7S8o4rOXvSbD4k8j1gmbr5kvfY8bQPU4f0jl/i3n1NvRAF+8u\nXCqA3oL18oQgQPWQwm9VDZ5bS6/9ZOE+iC46twMvmpyaOVjR5ciIW7IZ/itl\n+0YPk1uQzPZEqcpCUL95QDhHeZyRAESsRy7gLiyDsQCM5TMZmIqm1IjNPC3M\nL0h6hqO7X0G7Or9P31Cg9evk6wXlGyMapvXoNWmF6Rrk2RB0REPkvQKhzqW4\nV9k0Kpx/O710Al3qlfLZAqFqxN12P1aW/L5XefHU1IlUZXDrgyOprVRb+UZY\nmpf071uUbQmumRp4DqkA9USdmie3/Tvk7bRRoGxA2Fjw43nS6eBbipblFfCJ\nP24qDyq4u1z9W9CnI5QejJqR3VKfqON1AS6q5+elOPdaerWk7FdAfLB4CaDC\nZfW1\r\n=Re+X\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEYCIQDin2mqd4tWUuqEgp4FOC4R5FYZZC1dISuHpdd75KW3AQIhAKdPjhCMUICXRQicAxIGM40v7jbXDsKknJ9py+hl/Ii0"}]},"maintainers":[{"name":"relief.melone","email":"relief.melone@gmail.com"}],"_npmUser":{"name":"relief.melone","email":"relief.melone@gmail.com"},"directories":{},"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/query-bouncer-mongoose-plugin_1.5.0-beta.1_1603292418091_0.06506758760895592"},"_hasShrinkwrap":false},"1.5.0":{"name":"query-bouncer-mongoose-plugin","version":"1.5.0","description":"Mongoose Plugin for Query Bouncer","main":"./dist/index.js","scripts":{"start":"node ./dist/index.js","test":"nyc mocha","build":"tsc --watch false --declaration","lint":"eslint --ignore-path .gitignore .","tsc":"tsc"},"repository":{"type":"git","url":"git+https://github.com/relief-melone/query-bouncer-mongoose-plugin.git"},"author":{"name":"Relief.Melone"},"license":"MIT","dependencies":{"axios":"^0.19.1","express":"^4.17.1","mongodb":"^3.5.0","mongoose":"^5.8.7"},"devDependencies":{"@types/chai":"latest","@types/express":"^4.17.2","@types/mocha":"latest","@types/mongodb":"^3.3.14","@types/mongoose":"^5.5.41","@types/moxios":"^0.4.9","@types/node":"latest","@typescript-eslint/eslint-plugin":"latest","@typescript-eslint/parser":"latest","axios-mock-adapter":"^1.17.0","chai":"latest","chai-exclude":"^2.0.2","eslint":"latest","eslint-import-resolver-alias":"latest","eslint-plugin-import":"latest","mocha":"^7.1.1","mongodb-memory-server":"^6.5.0","nyc":"latest","sinon":"^8.0.4","typescript":"latest"},"gitHead":"b5fad0f1cb5c77aa505326913e77f0ef61015abf","bugs":{"url":"https://github.com/relief-melone/query-bouncer-mongoose-plugin/issues"},"homepage":"https://github.com/relief-melone/query-bouncer-mongoose-plugin#readme","_id":"query-bouncer-mongoose-plugin@1.5.0","_nodeVersion":"14.13.1","_npmVersion":"6.14.8","dist":{"integrity":"sha512-nNkO4at0M726Y1Hz5+TOETeiquHtomWrlFQjPYqsXxY9ly9CWXlYkxjaPs10tJPxZaLHdADGboUZPANo4NnIKQ==","shasum":"6fb733b121cab91a3277f30a84c2857a8ec3328f","tarball":"https://registry.npmjs.org/query-bouncer-mongoose-plugin/-/query-bouncer-mongoose-plugin-1.5.0.tgz","fileCount":144,"unpackedSize":193843,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.13\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJfkUuVCRA9TVsSAnZWagAAAUsP/RgDK6b5I5QwTSOe2zAw\nAJcMVsou+muW+4Sl5jSpk3NlCoWOf9zenqPbYgEeYRM2jo6f5bIRBFkR/LZp\nR4wB5CV0w9mDKI82PrfLbOF7P3K88O1fARMcCo04PCg5tDzdo2cGWs38h+6y\nM5KB+K+C1x421+ry7aSMeANl2TPIgQWBe1a4wIAjQZHzsZRyw8ApFPKRjIud\nD8zWggNNC8q/kOu9o/MlESVGsN1DOWGiEKhKSjPEygQ8bVLFFiBVbjCGWNuZ\nHJt0TrnC+7WFKU5/KQ5L6Ac02cflThpjmJUxHQT8aY3rZG+HufwWRiDxuE5s\nwaRJPuaIFopZEcfHFjXoMhpFHIy5AMWA79Z3/54L8sMiJLBPn7rECRNE/WVy\naO3HGKnU6P81hlG/vIDiFbw+d/QCXUzkaU8WEPWIVLfWedmyOInTxe+Kpsjk\njLnWjm4zqCKSm9N79uMfO80ot+mF+6gwpet3kmqT+xl9p95dIF2qzq0U2LKD\nATssFWfRXo5nKO24bQXu5xtQ/a8muc8pgvMn1MRkV1hrHrw4WfIbYku6EV7/\nxIViwg5pDHH2cO2cHOffHFQ3Qtkzyx97wSoAejzabJGPkv1tCJVoBBnFUVta\ngX9RbAAoqPh1snrSRjEtaEpXFS6AlMUYM26gua7GMVqtn0nlZLT8bslDhy/w\n7k5U\r\n=GPVk\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIEcSId6Yj4XZr8fLuOzZDPOEPMt2EoO/XmsDzlhOKaJEAiEAuWHwmgPL/LEfl4wmw8EoL8iFgIwva9mqZQ0YjLdSr2Q="}]},"maintainers":[{"name":"relief.melone","email":"relief.melone@gmail.com"}],"_npmUser":{"name":"relief.melone","email":"relief.melone@gmail.com"},"directories":{},"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/query-bouncer-mongoose-plugin_1.5.0_1603357589367_0.7584045407988391"},"_hasShrinkwrap":false},"1.5.1":{"name":"query-bouncer-mongoose-plugin","version":"1.5.1","description":"Mongoose Plugin for Query Bouncer","main":"./dist/index.js","scripts":{"start":"node ./dist/index.js","test":"nyc mocha","build":"tsc --watch false --declaration","lint":"eslint --ignore-path .gitignore .","tsc":"tsc"},"repository":{"type":"git","url":"git+https://github.com/relief-melone/query-bouncer-mongoose-plugin.git"},"author":{"name":"Relief.Melone"},"license":"MIT","dependencies":{"axios":"^0.19.1","express":"^4.17.1","mongodb":"^3.5.0","mongoose":"^5.8.7"},"devDependencies":{"@types/chai":"latest","@types/express":"^4.17.2","@types/mocha":"latest","@types/mongodb":"^3.3.14","@types/mongoose":"^5.5.41","@types/moxios":"^0.4.9","@types/node":"latest","@typescript-eslint/eslint-plugin":"latest","@typescript-eslint/parser":"latest","axios-mock-adapter":"^1.17.0","chai":"latest","chai-exclude":"^2.0.2","eslint":"latest","eslint-import-resolver-alias":"latest","eslint-plugin-import":"latest","mocha":"^7.1.1","mongodb-memory-server":"^6.5.0","nyc":"latest","sinon":"^8.0.4","typescript":"latest"},"gitHead":"32427e42d270a014f2eabb4fc9e104a636f94c5d","bugs":{"url":"https://github.com/relief-melone/query-bouncer-mongoose-plugin/issues"},"homepage":"https://github.com/relief-melone/query-bouncer-mongoose-plugin#readme","_id":"query-bouncer-mongoose-plugin@1.5.1","_nodeVersion":"14.13.1","_npmVersion":"6.14.8","dist":{"integrity":"sha512-9K3ADsOw4fEee8vMpoYvKXyrLW6KyUkjuMoJWEkY/zH0XHeRdR2tfJAk6/RXKQvQbneRN9h+6/1rON40CC1lkw==","shasum":"65eed81b7261d332a0c41aded15c431af0baa67f","tarball":"https://registry.npmjs.org/query-bouncer-mongoose-plugin/-/query-bouncer-mongoose-plugin-1.5.1.tgz","fileCount":144,"unpackedSize":193871,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.13\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJfnAmNCRA9TVsSAnZWagAA8rgP/0OSpY/SgGncsfHk4qvY\nMgUOg5vx3ra+IJ+SsbDy0JISn44oVwd7YvHM6W1GABpF2BWTUvG/P5Q5rusl\neUfBMLh8KK/rwqi2wDTskkZvvjV97UStPXnaruWZ71nnFt/fQ9M39vDArUvJ\nnsFshdZpnSCeKMnDAtq+oHAqP/ygDzemFF/PcSAxuJzxqEGiGLdaGVAe7w1t\nORKj4WgCCIcO3MCndGrcg79dr10uRig7et4Yel1+hpMwdWbo2jnsOWH5AtB0\nae56kp4Nw/8VJUubqolUSTh+K4gCKhLAv0xXFhM0uM1EJgX55sEgDj8/QnAB\nHKl8oZE4BCvFHRc1u2DaSv+yWFbehCx3sI7lFtb7gPJ52jGd0N3mcqL6+3WJ\np46jr1eNdB3Pbh452j1KKpTIEQFZRYtTxbdQN1mfPSrvGbiA4aIs9WEhv3m7\n46vRRhh4dAorRNV1E50GRLMNRY786vVCfeL1zhplJvWF18CV/lZGQnD9x2r3\nHBJbOfT2HQq8A720ayPeqlArBxApWcZkr4asjZVmyk2WvEuZP6t86OOQGiH0\n6rYTk0wTAby0ncUZQbjqZON7t9kJqOfQp97dRGXK/ym9lnzmtmB+3Ui3gqLU\nZSPzPuWBCpF9Rv4X9RFLpvcR09nxxDPRukKlKxjBC7J2QLdQLGR3Nb3lPzB0\nlQt8\r\n=qbq+\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIQC3GOD+3uPJHKWGGsel59eXGNaY/lGPVBPpFNjuKrklngIgDJ7LJmw0z2GlRYyIua541bi1cLevTrCUWgo52JOYjTs="}]},"maintainers":[{"name":"relief.melone","email":"relief.melone@gmail.com"}],"_npmUser":{"name":"relief.melone","email":"relief.melone@gmail.com"},"directories":{},"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/query-bouncer-mongoose-plugin_1.5.1_1604061581155_0.17967237336983866"},"_hasShrinkwrap":false},"1.5.2-beta.0":{"name":"query-bouncer-mongoose-plugin","version":"1.5.2-beta.0","description":"Mongoose Plugin for Query Bouncer","main":"./dist/index.js","scripts":{"start":"node ./dist/index.js","test":"nyc mocha","build":"tsc --watch false --declaration","lint":"eslint --ignore-path .gitignore .","tsc":"tsc"},"repository":{"type":"git","url":"git+https://github.com/relief-melone/query-bouncer-mongoose-plugin.git"},"author":{"name":"Relief.Melone"},"license":"MIT","dependencies":{"axios":"^0.19.1","express":"^4.17.1","mongodb":"^3.5.0","mongoose":"^5.8.7"},"devDependencies":{"@types/chai":"latest","@types/express":"^4.17.2","@types/mocha":"latest","@types/mongodb":"^3.3.14","@types/mongoose":"^5.5.41","@types/moxios":"^0.4.9","@types/node":"latest","@typescript-eslint/eslint-plugin":"latest","@typescript-eslint/parser":"latest","axios-mock-adapter":"^1.17.0","chai":"latest","chai-exclude":"^2.0.2","eslint":"latest","eslint-import-resolver-alias":"latest","eslint-plugin-import":"latest","mocha":"^7.1.1","mongodb-memory-server":"^6.5.0","nyc":"latest","sinon":"^8.0.4","typescript":"latest"},"readme":"# MongoBouncer - A Mongoose Plugin for Query Bouncer\n\nThe Mongoose Plugin for Query Bouncer (MongoBouncer) integrates with rm-authenticator, Query Bouncer and rm-session-populate. It's goal is to integrate the Role Based Access Control System you define in Query Bouncer easily in your Backend without having to worry about making the correct http requests and modify queries by yourself. The tasks of these components are\n\n1. **rm-authenticator:** Easy way to authenticate your user with just a Docker Container. Works with different OAuth providers like facebook, linkedin and google+. \n   - [GitHub](https://github.com/relief-melone/rm-authenticator)\n   - [Docker](https://hub.docker.com/repository/docker/reliefmelone/rm-authenticator)\n2. **rm-session-populator:** Middleware for Express. It will automatically communicate with the Authenticator and add a user object to your Express **req** with all the information you need\n   - [GitHub](https://github.com/relief-melone/rm-session-populator)\n   - [NPM](https://www.npmjs.com/package/rm-session-populator)\n3. **Query Bouncer:** Set up your Role Based Access System with a comfortable REST-API and use it to automatically modify queries and payloads based on your users permissions. \n   - [GitHub](https://github.com/relief-melone/query-bouncer)\n   - [Docker](https://hub.docker.com/r/reliefmelone/query-bouncer)\n4. **Query Bouncer Mongoose Plugin:** A Plugin that handles all the communication with the authorizer automatically so you can focus on writing your application.\n\nThis Overview illustrates a possible architecture for your application and the integration of those 4 components.\n\n![architecture](https://raw.githubusercontent.com/relief-melone/query-bouncer-mongoose-plugin/master/documentation/architectureOverview.png \"Architecture Overview\")\n\n## Instalation\n\nJust install with npm\n\n```sh\nnpm i --save query-bouncer-mongoose-plugin\n```\n\n## Usage\n\n### Prerequisites\n\nYou need a running instance of Query Bouncer to connect to. The Query Bouncer supplies the plugin with the correct queries accordingly to the users permissions. you can see how to set it up [here](https://github.com/relief-melone/query-bouncer)\n\n### How it Works\n\nQuery Bouncer will be used to easily set up your roles, permissions and roleAssignments for your Application. It supplies endpoints to send your query and payload to. The Query Bouncer will then validate the information based on your users permissions and will e.g. send back an adjusted query based on the users permissions. So what does that mean. Lets assume we have a collection called blogposts. Each BlogPost has a Title, Description and a Category. The user only has access to BlogPosts of the Category \"Cars\". So when a request to the Query Bouncer is made with the query to get all BlogPosts The Query \n\n```js\n{}\n```\nwill be returned as\n\n```js\n{ \n  $or: [ \n    {Category: \"Cars\"} \n  ] \n}\n```\n\nIn order to not having to utilize the API of rm-authorizer directly mongo-bouncer will handle all that for you. The following paragraphs will show you how to use it.\n\n\n### Initialize\n\nAs this is a mongoose plugin simply initialize the plugin like this. You only need the endpoint of your authorizer. That's it\n\n```ts\nimport mongoBouncer from \"query-bouncer-mongoose-plugin\"\n\nmongoose.plugin(mongoBouncer, {\n  baseUrl: \"https://your-authorizer.com\"\n});\n```\n\nNow with the nature of mongoose plugins this has to be made before any schemas are initialized (which most of time will be done already). So either wrap your schemas so you make sure that the plugin gets initialized first or set the plugin for each schema you want to use (**recommended**)\n\n```ts\nconst blogPostSchema = new mongoose.Schema({\n  Title: \"My new Blog Post\",\n  // ...\n});\n\nblogPostSchema.plugin(mongoBouncer, {\n  baseUrl: \"https://your-authorizer.com\"\n});\n```\n\n#### Additional Options\n**baseUrl:** The URL the MongoBouncer that you want to connect to is hosted\n**apiVersion:** The Version of the API you want to use. Defaults to v1\n**axios:** You can force the Plugin to use another Axios Instance. This is mainly for testing purposes and not recommended\n**cookieName:** By default the Authenticator is set up to give you a cookie named connect.sid. If however you changed that you can also adjust the cookieName here\n\n### Useage\n\nMongoBouncer will run all the validation before your operations are being executed. As this middleware is currently not available in mongoose plugins for all methods, we currentyl support the following\n\n- create **(See Important Information about create)**\n- find\n- findOne\n- findOneAndDelete\n- findOneAndRemove\n- findOneAndUpdate\n- findById\n- findByIdAndDelete\n- findByIdAndRemove\n- findByIdAndUpdate\n- insertMany\n- remove \n- update\n- updateOne\n- updateMany\n- deleteOne\n- deleteMany\n\nThis is an example on how to enalbe MongoBouncer on your model. req refers to the express Request here. The MongoBouncer property needs to be added to the Options Object of your method. Let's take a look at some of those methods\n\nFirst let's set up a model.\n```ts\nconst BlogPostSchema = new Schema({\n  Title: { type: String, required: true } ,\n  Description: { type: String },\n  Category: { type: String, required: true }\n});\nconst BlogPost = mongoose.model('blogpost', BlogPostSchema);\n```\n#### Create\nNow to create a Document with respect to the permissions you just add the MongoBouncer to the options. \n\nAs the Options Object in mongoose is only available if the Document is passed in array please make sure you that even of you just add a single Document you use it in an Array. If you use a single Object the Options Object will be empty internally and as a result **Permissions will not be checked!!!**\n\nAs we stated earlier our authorizer has been set up to\nallow the user to create BlogPosts only if the category is \"Cars\". So while this will work just fine.\n```ts\nconst post = await BlogPost.create([{\n  Title: \"MyBlogPost\",\n  Category: \"Cars\",\n  Description: \"Some cool information about my favourite car\"\n}], { \n  MongoBouncer : {\n    Request: req \n  }\n});\n```\nthis\n```ts\nconst post = await BlogPost.create({\n  Title: \"MyBlogPost\",\n  Category: \"Food\",\n  Description: \"Some cool information about my favourite car\"\n}, { \n  MongoBouncer : {\n    Request: req \n  }\n});\n```\nwill throw an Error as the user is not allowed to create Blog Posts in that Category\n\n#### Find\n\nLet's assume we will now try to find that document again. Again as our fictive setup is that our user will only receive BlogPosts if the Category\nCars in this case\n```ts\nBlogPost.find({ Title: \"MyBlogPost\" }, null, {\n  MongoBouncer: {\n    Request: req\n  }\n});\n```\nwe will be returned an array with the Document we added in the Create section\n\n\n#### Update\nIf we now want to update the document we created we do it just the same way. A working update call would look like this\n```ts\nBlogPost.updateOne(\n  { Title: \"MyBlogPost\", Category: \"Cars\" }, \n  { Title: \"A changed Title\"}, \n  {\n    MongoBouncer: {\n      Request: req\n    }\n  }\n);\n```\nInternally both the Payload and the QueryRestrictions will be checked. So if we use any other Category than Cars nothing will be updated. However in this case no error will be returned but the returned Object by mongoose will just state that nothing matched our Query and nothing was updated. But if we try this e.g.\n```ts\nBlogPost.updateOne(\n  { Title: \"MyBlogPost\", Category: \"Cars\" }, \n  { Title: \"A changed Title\", Category: \"Food\" }, \n  {\n    MongoBouncer: {\n      Request: req\n    }\n  }\n);\n```\nan error will be thrown as a Document will be returned but we are not allowed to invoke the changes we are trying to make.\n\n","readmeFilename":"README.md","gitHead":"32427e42d270a014f2eabb4fc9e104a636f94c5d","bugs":{"url":"https://github.com/relief-melone/query-bouncer-mongoose-plugin/issues"},"homepage":"https://github.com/relief-melone/query-bouncer-mongoose-plugin#readme","_id":"query-bouncer-mongoose-plugin@1.5.2-beta.0","_nodeVersion":"14.13.1","_npmVersion":"6.14.8","dist":{"integrity":"sha512-BfFBoER/j2/YNniOXc/ph/rmMtg/0aMulMCjzSDMaDXIXtUDbCT8h3StEuL53sXpZotvIMYIF6h4hB2t8WcOwg==","shasum":"7836bc2949e72fe0a9dde8526c17e3931793c1d0","tarball":"https://registry.npmjs.org/query-bouncer-mongoose-plugin/-/query-bouncer-mongoose-plugin-1.5.2-beta.0.tgz","fileCount":144,"unpackedSize":193904,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.13\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJfoUvsCRA9TVsSAnZWagAAFIQP/il68qX6TqTJwc+qrO5n\nszJHcMAqWC9BB30hdM4aNSPa/qVr6o0aCWe/EOwAkrtJpFA3G19ftsyJniqB\n2KWlH62ubwGO596fVFUIzEXSgTp551YRBchk/7HMv9vxyBht1K1N8QTFIX4c\nCD1+aHbz4UcaNMe8QpZB70rqXNZfaNbsXi48jrV3b4LjYKWE4GvfkHOqR60A\njtEh/Ma+YNSH0B+6mRzTdvr93iOy1zfXvx5AVh384xq/a+H7akX+pwMrHSkc\n6gbAFDd8HJYTmcGFPodVaFOykKCZcatwZRA48tPTOfQ+pajEPZIWq13qxbHK\n3MmEfecI9Eb7pKg3pGaR+dUrRWd/1CuCDg1K1h8UHKQmjwLlV3NTUf46Iji5\n+5PsEO8zEfFFNce1F9phHZLxJUSVT4W6hnaxkzQFUj4T0S2A0mZRS7IpMkVb\nPinositVxbcU1t2rlqPufRxTFtHoZzMGef6VdH7CVsZ7MaPQGHYZTYnol4XT\nK6mKxlu2nj2wMb8Ron0uGOfxN/jvzRjZ8Q59L1/KNVoIFT+eB0Mejv0uG9FZ\nfHaJMPAM68+r1wVH24gPbw3VQjNUB6nGPLXVCytclWk9t065e2MUdBTN9l1E\np+pdF+usro9qenivVhxvJEQ1imA4/AokJb3N4eS4EWxGSkd5ZZHg7GY1VXca\ni5qr\r\n=DLDW\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIBV5STFxlJcEVKKS24dm9DkTQgEr92aibJkzHeXSTxk3AiEAmOFjRRY+etjbKhdmTw3mPizFtdFaBL62nPFrn0aVrJI="}]},"maintainers":[{"name":"relief.melone","email":"relief.melone@gmail.com"}],"_npmUser":{"name":"relief.melone","email":"relief.melone@gmail.com"},"directories":{},"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/query-bouncer-mongoose-plugin_1.5.2-beta.0_1604406252259_0.882667856672092"},"_hasShrinkwrap":false},"1.5.2-beta.1":{"name":"query-bouncer-mongoose-plugin","version":"1.5.2-beta.1","description":"Mongoose Plugin for Query Bouncer","main":"./dist/index.js","scripts":{"start":"node ./dist/index.js","test":"nyc mocha","build":"tsc --watch false --declaration","lint":"eslint --ignore-path .gitignore .","tsc":"tsc"},"repository":{"type":"git","url":"git+https://github.com/relief-melone/query-bouncer-mongoose-plugin.git"},"author":{"name":"Relief.Melone"},"license":"MIT","dependencies":{"axios":"^0.19.1","express":"^4.17.1","mongodb":"^3.5.0","mongoose":"^5.8.7"},"devDependencies":{"@types/chai":"latest","@types/express":"^4.17.2","@types/mocha":"latest","@types/mongodb":"^3.3.14","@types/mongoose":"^5.5.41","@types/moxios":"^0.4.9","@types/node":"latest","@typescript-eslint/eslint-plugin":"latest","@typescript-eslint/parser":"latest","axios-mock-adapter":"^1.17.0","chai":"latest","chai-exclude":"^2.0.2","eslint":"latest","eslint-import-resolver-alias":"latest","eslint-plugin-import":"latest","mocha":"^7.1.1","mongodb-memory-server":"^6.5.0","nyc":"latest","sinon":"^8.0.4","typescript":"latest"},"readme":"# MongoBouncer - A Mongoose Plugin for Query Bouncer\n\nThe Mongoose Plugin for Query Bouncer (MongoBouncer) integrates with rm-authenticator, Query Bouncer and rm-session-populate. It's goal is to integrate the Role Based Access Control System you define in Query Bouncer easily in your Backend without having to worry about making the correct http requests and modify queries by yourself. The tasks of these components are\n\n1. **rm-authenticator:** Easy way to authenticate your user with just a Docker Container. Works with different OAuth providers like facebook, linkedin and google+. \n   - [GitHub](https://github.com/relief-melone/rm-authenticator)\n   - [Docker](https://hub.docker.com/repository/docker/reliefmelone/rm-authenticator)\n2. **rm-session-populator:** Middleware for Express. It will automatically communicate with the Authenticator and add a user object to your Express **req** with all the information you need\n   - [GitHub](https://github.com/relief-melone/rm-session-populator)\n   - [NPM](https://www.npmjs.com/package/rm-session-populator)\n3. **Query Bouncer:** Set up your Role Based Access System with a comfortable REST-API and use it to automatically modify queries and payloads based on your users permissions. \n   - [GitHub](https://github.com/relief-melone/query-bouncer)\n   - [Docker](https://hub.docker.com/r/reliefmelone/query-bouncer)\n4. **Query Bouncer Mongoose Plugin:** A Plugin that handles all the communication with the authorizer automatically so you can focus on writing your application.\n\nThis Overview illustrates a possible architecture for your application and the integration of those 4 components.\n\n![architecture](https://raw.githubusercontent.com/relief-melone/query-bouncer-mongoose-plugin/master/documentation/architectureOverview.png \"Architecture Overview\")\n\n## Instalation\n\nJust install with npm\n\n```sh\nnpm i --save query-bouncer-mongoose-plugin\n```\n\n## Usage\n\n### Prerequisites\n\nYou need a running instance of Query Bouncer to connect to. The Query Bouncer supplies the plugin with the correct queries accordingly to the users permissions. you can see how to set it up [here](https://github.com/relief-melone/query-bouncer)\n\n### How it Works\n\nQuery Bouncer will be used to easily set up your roles, permissions and roleAssignments for your Application. It supplies endpoints to send your query and payload to. The Query Bouncer will then validate the information based on your users permissions and will e.g. send back an adjusted query based on the users permissions. So what does that mean. Lets assume we have a collection called blogposts. Each BlogPost has a Title, Description and a Category. The user only has access to BlogPosts of the Category \"Cars\". So when a request to the Query Bouncer is made with the query to get all BlogPosts The Query \n\n```js\n{}\n```\nwill be returned as\n\n```js\n{ \n  $or: [ \n    {Category: \"Cars\"} \n  ] \n}\n```\n\nIn order to not having to utilize the API of rm-authorizer directly mongo-bouncer will handle all that for you. The following paragraphs will show you how to use it.\n\n\n### Initialize\n\nAs this is a mongoose plugin simply initialize the plugin like this. You only need the endpoint of your authorizer. That's it\n\n```ts\nimport mongoBouncer from \"query-bouncer-mongoose-plugin\"\n\nmongoose.plugin(mongoBouncer, {\n  baseUrl: \"https://your-authorizer.com\"\n});\n```\n\nNow with the nature of mongoose plugins this has to be made before any schemas are initialized (which most of time will be done already). So either wrap your schemas so you make sure that the plugin gets initialized first or set the plugin for each schema you want to use (**recommended**)\n\n```ts\nconst blogPostSchema = new mongoose.Schema({\n  Title: \"My new Blog Post\",\n  // ...\n});\n\nblogPostSchema.plugin(mongoBouncer, {\n  baseUrl: \"https://your-authorizer.com\"\n});\n```\n\n#### Additional Options\n**baseUrl:** The URL the MongoBouncer that you want to connect to is hosted\n**apiVersion:** The Version of the API you want to use. Defaults to v1\n**axios:** You can force the Plugin to use another Axios Instance. This is mainly for testing purposes and not recommended\n**cookieName:** By default the Authenticator is set up to give you a cookie named connect.sid. If however you changed that you can also adjust the cookieName here\n\n### Useage\n\nMongoBouncer will run all the validation before your operations are being executed. As this middleware is currently not available in mongoose plugins for all methods, we currentyl support the following\n\n- create **(See Important Information about create)**\n- find\n- findOne\n- findOneAndDelete\n- findOneAndRemove\n- findOneAndUpdate\n- findById\n- findByIdAndDelete\n- findByIdAndRemove\n- findByIdAndUpdate\n- insertMany\n- remove \n- update\n- updateOne\n- updateMany\n- deleteOne\n- deleteMany\n\nThis is an example on how to enalbe MongoBouncer on your model. req refers to the express Request here. The MongoBouncer property needs to be added to the Options Object of your method. Let's take a look at some of those methods\n\nFirst let's set up a model.\n```ts\nconst BlogPostSchema = new Schema({\n  Title: { type: String, required: true } ,\n  Description: { type: String },\n  Category: { type: String, required: true }\n});\nconst BlogPost = mongoose.model('blogpost', BlogPostSchema);\n```\n#### Create\nNow to create a Document with respect to the permissions you just add the MongoBouncer to the options. \n\nAs the Options Object in mongoose is only available if the Document is passed in array please make sure you that even of you just add a single Document you use it in an Array. If you use a single Object the Options Object will be empty internally and as a result **Permissions will not be checked!!!**\n\nAs we stated earlier our authorizer has been set up to\nallow the user to create BlogPosts only if the category is \"Cars\". So while this will work just fine.\n```ts\nconst post = await BlogPost.create([{\n  Title: \"MyBlogPost\",\n  Category: \"Cars\",\n  Description: \"Some cool information about my favourite car\"\n}], { \n  MongoBouncer : {\n    Request: req \n  }\n});\n```\nthis\n```ts\nconst post = await BlogPost.create({\n  Title: \"MyBlogPost\",\n  Category: \"Food\",\n  Description: \"Some cool information about my favourite car\"\n}, { \n  MongoBouncer : {\n    Request: req \n  }\n});\n```\nwill throw an Error as the user is not allowed to create Blog Posts in that Category\n\n#### Find\n\nLet's assume we will now try to find that document again. Again as our fictive setup is that our user will only receive BlogPosts if the Category\nCars in this case\n```ts\nBlogPost.find({ Title: \"MyBlogPost\" }, null, {\n  MongoBouncer: {\n    Request: req\n  }\n});\n```\nwe will be returned an array with the Document we added in the Create section\n\n\n#### Update\nIf we now want to update the document we created we do it just the same way. A working update call would look like this\n```ts\nBlogPost.updateOne(\n  { Title: \"MyBlogPost\", Category: \"Cars\" }, \n  { Title: \"A changed Title\"}, \n  {\n    MongoBouncer: {\n      Request: req\n    }\n  }\n);\n```\nInternally both the Payload and the QueryRestrictions will be checked. So if we use any other Category than Cars nothing will be updated. However in this case no error will be returned but the returned Object by mongoose will just state that nothing matched our Query and nothing was updated. But if we try this e.g.\n```ts\nBlogPost.updateOne(\n  { Title: \"MyBlogPost\", Category: \"Cars\" }, \n  { Title: \"A changed Title\", Category: \"Food\" }, \n  {\n    MongoBouncer: {\n      Request: req\n    }\n  }\n);\n```\nan error will be thrown as a Document will be returned but we are not allowed to invoke the changes we are trying to make.\n\n","readmeFilename":"README.md","gitHead":"32427e42d270a014f2eabb4fc9e104a636f94c5d","bugs":{"url":"https://github.com/relief-melone/query-bouncer-mongoose-plugin/issues"},"homepage":"https://github.com/relief-melone/query-bouncer-mongoose-plugin#readme","_id":"query-bouncer-mongoose-plugin@1.5.2-beta.1","_nodeVersion":"14.13.1","_npmVersion":"6.14.8","dist":{"integrity":"sha512-LSgV8/YV1GdDiImR5/Q259iCitVTKSpDPUWbKXCQMotjeGLAxEEqesc6qxaqo0B9diWsXZNrz9KoKMvlXhzIsA==","shasum":"e46ac244bfa9019fe0c1b2dc18388e8a9ac09e52","tarball":"https://registry.npmjs.org/query-bouncer-mongoose-plugin/-/query-bouncer-mongoose-plugin-1.5.2-beta.1.tgz","fileCount":144,"unpackedSize":193987,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.13\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJfoUyZCRA9TVsSAnZWagAAmSMP/3SBVO9440/ZGqeypXGR\nrYVUd3ERRkXwsFD8ImcfVYnKNU3PNenQomkW99z/lOy5zuUZS2xW0h7llxbG\nv//O0281EctLNSGv5AhxDy1KzOK19c31YZoTbBIbEf5TFhVJ02nAPlqUvw7r\nN5ihouyJsRxluFLhGaWsg3NPs90B0UXVdR1g/rODZR7Aaor0bNrBnHa3sW1V\nvn+4plx5gXrOcp2MPU2MpeeSJQAAscJhfM9v3NI87yHuTlIXVG6RvvZA1r5c\ncJheejh6VnQadtNAIH9SzuzqurjOI33enq1cVLUraVBrLu8NsDl3HNVvYNGm\nnstK6wz5Cl5BXcYd/LptC6ZSwDtxdhg2CGArZRojn742NtRnQl4V3L9fKCo6\nMxzGedajCZze2CFF8QeLHCuPspK+UCciTGV0vrjKenNHe5BgAS3BptA49Dy8\nmAavX+h14hQS3IjBXglMg1uiF3E20UKKafB518DYFBqTq3Dgl7hOMwL/dKpX\nuVlP6vx+o8p5/XHcADgMl4N2rLzCISRJKX+oi1P0bIaxfwV4AluZpHAeTa1J\nSrLVWaL4vjL2EeYiDGzJIMiohDCHLxwNyeZVWUXvZisjgAcsD/hFt2syD59M\np5ueqVVQl+XLb9L3SdP7ODFLjIy32vAD87z7VDfbiEa98lDqv5rmsOgTPnwT\nckJL\r\n=nl3N\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEYCIQCUHF0Uge8cFazb61HOGOfz2ridLtdknU+9J6q/FpbuqwIhAJ/kQqWVUHN0CHsG9y06d/dBfZEDHC3yzfRjZ+OwXQhh"}]},"maintainers":[{"name":"relief.melone","email":"relief.melone@gmail.com"}],"_npmUser":{"name":"relief.melone","email":"relief.melone@gmail.com"},"directories":{},"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/query-bouncer-mongoose-plugin_1.5.2-beta.1_1604406425369_0.5144119633586901"},"_hasShrinkwrap":false},"1.5.2-beta.2":{"name":"query-bouncer-mongoose-plugin","version":"1.5.2-beta.2","description":"Mongoose Plugin for Query Bouncer","main":"./dist/index.js","scripts":{"start":"node ./dist/index.js","test":"nyc mocha","build":"tsc --watch false --declaration","lint":"eslint --ignore-path .gitignore .","tsc":"tsc"},"repository":{"type":"git","url":"git+https://github.com/relief-melone/query-bouncer-mongoose-plugin.git"},"author":{"name":"Relief.Melone"},"license":"MIT","dependencies":{"axios":"^0.21.0","express":"^4.17.1","mongodb":"^3.5.0","mongoose":"^5.8.7"},"devDependencies":{"@types/chai":"latest","@types/express":"^4.17.2","@types/mocha":"latest","@types/mongodb":"^3.3.14","@types/mongoose":"^5.5.41","@types/moxios":"^0.4.9","@types/node":"latest","@typescript-eslint/eslint-plugin":"latest","@typescript-eslint/parser":"latest","axios-mock-adapter":"^1.17.0","chai":"latest","chai-exclude":"^2.0.2","eslint":"latest","eslint-import-resolver-alias":"latest","eslint-plugin-import":"latest","mocha":"^7.1.1","mongodb-memory-server":"^6.5.0","nyc":"latest","sinon":"^8.0.4","typescript":"latest"},"readme":"# MongoBouncer - A Mongoose Plugin for Query Bouncer\n\nThe Mongoose Plugin for Query Bouncer (MongoBouncer) integrates with rm-authenticator, Query Bouncer and rm-session-populate. It's goal is to integrate the Role Based Access Control System you define in Query Bouncer easily in your Backend without having to worry about making the correct http requests and modify queries by yourself. The tasks of these components are\n\n1. **rm-authenticator:** Easy way to authenticate your user with just a Docker Container. Works with different OAuth providers like facebook, linkedin and google+. \n   - [GitHub](https://github.com/relief-melone/rm-authenticator)\n   - [Docker](https://hub.docker.com/repository/docker/reliefmelone/rm-authenticator)\n2. **rm-session-populator:** Middleware for Express. It will automatically communicate with the Authenticator and add a user object to your Express **req** with all the information you need\n   - [GitHub](https://github.com/relief-melone/rm-session-populator)\n   - [NPM](https://www.npmjs.com/package/rm-session-populator)\n3. **Query Bouncer:** Set up your Role Based Access System with a comfortable REST-API and use it to automatically modify queries and payloads based on your users permissions. \n   - [GitHub](https://github.com/relief-melone/query-bouncer)\n   - [Docker](https://hub.docker.com/r/reliefmelone/query-bouncer)\n4. **Query Bouncer Mongoose Plugin:** A Plugin that handles all the communication with the authorizer automatically so you can focus on writing your application.\n\nThis Overview illustrates a possible architecture for your application and the integration of those 4 components.\n\n![architecture](https://raw.githubusercontent.com/relief-melone/query-bouncer-mongoose-plugin/master/documentation/architectureOverview.png \"Architecture Overview\")\n\n## Instalation\n\nJust install with npm\n\n```sh\nnpm i --save query-bouncer-mongoose-plugin\n```\n\n## Usage\n\n### Prerequisites\n\nYou need a running instance of Query Bouncer to connect to. The Query Bouncer supplies the plugin with the correct queries accordingly to the users permissions. you can see how to set it up [here](https://github.com/relief-melone/query-bouncer)\n\n### How it Works\n\nQuery Bouncer will be used to easily set up your roles, permissions and roleAssignments for your Application. It supplies endpoints to send your query and payload to. The Query Bouncer will then validate the information based on your users permissions and will e.g. send back an adjusted query based on the users permissions. So what does that mean. Lets assume we have a collection called blogposts. Each BlogPost has a Title, Description and a Category. The user only has access to BlogPosts of the Category \"Cars\". So when a request to the Query Bouncer is made with the query to get all BlogPosts The Query \n\n```js\n{}\n```\nwill be returned as\n\n```js\n{ \n  $or: [ \n    {Category: \"Cars\"} \n  ] \n}\n```\n\nIn order to not having to utilize the API of rm-authorizer directly mongo-bouncer will handle all that for you. The following paragraphs will show you how to use it.\n\n\n### Initialize\n\nAs this is a mongoose plugin simply initialize the plugin like this. You only need the endpoint of your authorizer. That's it\n\n```ts\nimport mongoBouncer from \"query-bouncer-mongoose-plugin\"\n\nmongoose.plugin(mongoBouncer, {\n  baseUrl: \"https://your-authorizer.com\"\n});\n```\n\nNow with the nature of mongoose plugins this has to be made before any schemas are initialized (which most of time will be done already). So either wrap your schemas so you make sure that the plugin gets initialized first or set the plugin for each schema you want to use (**recommended**)\n\n```ts\nconst blogPostSchema = new mongoose.Schema({\n  Title: \"My new Blog Post\",\n  // ...\n});\n\nblogPostSchema.plugin(mongoBouncer, {\n  baseUrl: \"https://your-authorizer.com\"\n});\n```\n\n#### Additional Options\n**baseUrl:** The URL the MongoBouncer that you want to connect to is hosted\n**apiVersion:** The Version of the API you want to use. Defaults to v1\n**axios:** You can force the Plugin to use another Axios Instance. This is mainly for testing purposes and not recommended\n**cookieName:** By default the Authenticator is set up to give you a cookie named connect.sid. If however you changed that you can also adjust the cookieName here\n\n### Useage\n\nMongoBouncer will run all the validation before your operations are being executed. As this middleware is currently not available in mongoose plugins for all methods, we currentyl support the following\n\n- create **(See Important Information about create)**\n- find\n- findOne\n- findOneAndDelete\n- findOneAndRemove\n- findOneAndUpdate\n- findById\n- findByIdAndDelete\n- findByIdAndRemove\n- findByIdAndUpdate\n- insertMany\n- remove \n- update\n- updateOne\n- updateMany\n- deleteOne\n- deleteMany\n\nThis is an example on how to enalbe MongoBouncer on your model. req refers to the express Request here. The MongoBouncer property needs to be added to the Options Object of your method. Let's take a look at some of those methods\n\nFirst let's set up a model.\n```ts\nconst BlogPostSchema = new Schema({\n  Title: { type: String, required: true } ,\n  Description: { type: String },\n  Category: { type: String, required: true }\n});\nconst BlogPost = mongoose.model('blogpost', BlogPostSchema);\n```\n#### Create\nNow to create a Document with respect to the permissions you just add the MongoBouncer to the options. \n\nAs the Options Object in mongoose is only available if the Document is passed in array please make sure you that even of you just add a single Document you use it in an Array. If you use a single Object the Options Object will be empty internally and as a result **Permissions will not be checked!!!**\n\nAs we stated earlier our authorizer has been set up to\nallow the user to create BlogPosts only if the category is \"Cars\". So while this will work just fine.\n```ts\nconst post = await BlogPost.create([{\n  Title: \"MyBlogPost\",\n  Category: \"Cars\",\n  Description: \"Some cool information about my favourite car\"\n}], { \n  MongoBouncer : {\n    Request: req \n  }\n});\n```\nthis\n```ts\nconst post = await BlogPost.create({\n  Title: \"MyBlogPost\",\n  Category: \"Food\",\n  Description: \"Some cool information about my favourite car\"\n}, { \n  MongoBouncer : {\n    Request: req \n  }\n});\n```\nwill throw an Error as the user is not allowed to create Blog Posts in that Category\n\n#### Find\n\nLet's assume we will now try to find that document again. Again as our fictive setup is that our user will only receive BlogPosts if the Category\nCars in this case\n```ts\nBlogPost.find({ Title: \"MyBlogPost\" }, null, {\n  MongoBouncer: {\n    Request: req\n  }\n});\n```\nwe will be returned an array with the Document we added in the Create section\n\n\n#### Update\nIf we now want to update the document we created we do it just the same way. A working update call would look like this\n```ts\nBlogPost.updateOne(\n  { Title: \"MyBlogPost\", Category: \"Cars\" }, \n  { Title: \"A changed Title\"}, \n  {\n    MongoBouncer: {\n      Request: req\n    }\n  }\n);\n```\nInternally both the Payload and the QueryRestrictions will be checked. So if we use any other Category than Cars nothing will be updated. However in this case no error will be returned but the returned Object by mongoose will just state that nothing matched our Query and nothing was updated. But if we try this e.g.\n```ts\nBlogPost.updateOne(\n  { Title: \"MyBlogPost\", Category: \"Cars\" }, \n  { Title: \"A changed Title\", Category: \"Food\" }, \n  {\n    MongoBouncer: {\n      Request: req\n    }\n  }\n);\n```\nan error will be thrown as a Document will be returned but we are not allowed to invoke the changes we are trying to make.\n\n","readmeFilename":"README.md","gitHead":"32427e42d270a014f2eabb4fc9e104a636f94c5d","bugs":{"url":"https://github.com/relief-melone/query-bouncer-mongoose-plugin/issues"},"homepage":"https://github.com/relief-melone/query-bouncer-mongoose-plugin#readme","_id":"query-bouncer-mongoose-plugin@1.5.2-beta.2","_nodeVersion":"14.13.1","_npmVersion":"6.14.8","dist":{"integrity":"sha512-KQnDbrt8o5C2htCDn3YFzIGyXNj1pEW4SWojp282qxbymbSRZyqMizyQ8Hke+BlvS2S21VacySzHkhqLQsUMWw==","shasum":"4212d68131b16f1f202c7322e23258fd228802d9","tarball":"https://registry.npmjs.org/query-bouncer-mongoose-plugin/-/query-bouncer-mongoose-plugin-1.5.2-beta.2.tgz","fileCount":144,"unpackedSize":193987,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.13\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJfoW1FCRA9TVsSAnZWagAAhIYP/1GWfrth2AE8IcouFWNJ\ntVDUNvw4q5vi+jhX9WyAVQK/opr0fVB/PMGOqMUL9QzuuNGcC3QQKBILAyAA\nGZt9zSeIHZQw1YXHEOL6eR+4fsS4Ycwo1GfE/XDmL5+mdiqv/Cdb77T/bW3g\n6LFb86c+x8asMlYhWS3PgI57nbdvmzUL1WMEIlbZ5feIjVQVnJx8rZG7j1k6\noarqbiSREch2vGeXaxDdGt33KlXCtDWlNzCFyELjPkk/jugTlcxjBFF8tH6G\nUUwQFzX8yDNwH5aTElKizF7eOTI8wedN1srdE/rlIJHxK1XJxgu3/a/QUR5Y\n7N/Ln0q8+Yhm6FVtcChyCkZgi8qzoUDthu/u2x1cAKjqxU1dNXRUbh5/hTwa\nXd42NwHUz9WP7eih+2+fTx1MvJUPpB2mNaf+0S93Vr2V6Cc8qgCI/Pd+P0hF\nKIa9blJedXS9Jh/knV9gDEjcYCMGWE/gZZM6g05dTrwdJUcwk+NFhzyUNHUl\nLc/DLJtTphRewFJzPqYQHsuAEuIbxjray1TjhijOzo4GaqhbhoEGE9DEtjaq\n32TcVstkKwykxEDtyBRhpMYFgt3Bj4IOVL1hAoDPDDn8SnJFZ7QO+6H5BMxP\nezEH8B8aJWbiPA07QlguU8BOrRZnUFbR8TWVBjcw/65xUvx9elBFBFc7jzPL\nhvw6\r\n=BdvU\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIBAXWyb3LlquX7Vlu+ToFIrLzSRUSMN2xrvk7Gcnsr2uAiEA32MwwnW3m6qZX+r1j+ENgxEhcyOEctvTSIDBQ6LK9PE="}]},"_npmUser":{"name":"relief.melone","email":"relief.melone@gmail.com"},"directories":{},"maintainers":[{"name":"relief.melone","email":"relief.melone@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/query-bouncer-mongoose-plugin_1.5.2-beta.2_1604414789318_0.26711740960065167"},"_hasShrinkwrap":false},"1.5.2-beta.3":{"name":"query-bouncer-mongoose-plugin","version":"1.5.2-beta.3","description":"Mongoose Plugin for Query Bouncer","main":"./dist/index.js","scripts":{"start":"node ./dist/index.js","test":"nyc mocha","build":"tsc --watch false --declaration","lint":"eslint --ignore-path .gitignore .","tsc":"tsc"},"repository":{"type":"git","url":"git+https://github.com/relief-melone/query-bouncer-mongoose-plugin.git"},"author":{"name":"Relief.Melone"},"license":"MIT","dependencies":{"axios":"^0.21.0","express":"^4.17.1","mongodb":"^3.5.0","mongoose":"^5.8.7"},"devDependencies":{"@types/chai":"latest","@types/express":"^4.17.2","@types/mocha":"latest","@types/mongodb":"^3.3.14","@types/mongoose":"^5.5.41","@types/moxios":"^0.4.9","@types/node":"latest","@typescript-eslint/eslint-plugin":"latest","@typescript-eslint/parser":"latest","axios-mock-adapter":"^1.17.0","chai":"latest","chai-exclude":"^2.0.2","eslint":"latest","eslint-import-resolver-alias":"latest","eslint-plugin-import":"latest","mocha":"^7.1.1","mongodb-memory-server":"^6.5.0","nyc":"latest","sinon":"^8.0.4","typescript":"latest"},"readme":"# MongoBouncer - A Mongoose Plugin for Query Bouncer\n\nThe Mongoose Plugin for Query Bouncer (MongoBouncer) integrates with rm-authenticator, Query Bouncer and rm-session-populate. It's goal is to integrate the Role Based Access Control System you define in Query Bouncer easily in your Backend without having to worry about making the correct http requests and modify queries by yourself. The tasks of these components are\n\n1. **rm-authenticator:** Easy way to authenticate your user with just a Docker Container. Works with different OAuth providers like facebook, linkedin and google+. \n   - [GitHub](https://github.com/relief-melone/rm-authenticator)\n   - [Docker](https://hub.docker.com/repository/docker/reliefmelone/rm-authenticator)\n2. **rm-session-populator:** Middleware for Express. It will automatically communicate with the Authenticator and add a user object to your Express **req** with all the information you need\n   - [GitHub](https://github.com/relief-melone/rm-session-populator)\n   - [NPM](https://www.npmjs.com/package/rm-session-populator)\n3. **Query Bouncer:** Set up your Role Based Access System with a comfortable REST-API and use it to automatically modify queries and payloads based on your users permissions. \n   - [GitHub](https://github.com/relief-melone/query-bouncer)\n   - [Docker](https://hub.docker.com/r/reliefmelone/query-bouncer)\n4. **Query Bouncer Mongoose Plugin:** A Plugin that handles all the communication with the authorizer automatically so you can focus on writing your application.\n\nThis Overview illustrates a possible architecture for your application and the integration of those 4 components.\n\n![architecture](https://raw.githubusercontent.com/relief-melone/query-bouncer-mongoose-plugin/master/documentation/architectureOverview.png \"Architecture Overview\")\n\n## Instalation\n\nJust install with npm\n\n```sh\nnpm i --save query-bouncer-mongoose-plugin\n```\n\n## Usage\n\n### Prerequisites\n\nYou need a running instance of Query Bouncer to connect to. The Query Bouncer supplies the plugin with the correct queries accordingly to the users permissions. you can see how to set it up [here](https://github.com/relief-melone/query-bouncer)\n\n### How it Works\n\nQuery Bouncer will be used to easily set up your roles, permissions and roleAssignments for your Application. It supplies endpoints to send your query and payload to. The Query Bouncer will then validate the information based on your users permissions and will e.g. send back an adjusted query based on the users permissions. So what does that mean. Lets assume we have a collection called blogposts. Each BlogPost has a Title, Description and a Category. The user only has access to BlogPosts of the Category \"Cars\". So when a request to the Query Bouncer is made with the query to get all BlogPosts The Query \n\n```js\n{}\n```\nwill be returned as\n\n```js\n{ \n  $or: [ \n    {Category: \"Cars\"} \n  ] \n}\n```\n\nIn order to not having to utilize the API of rm-authorizer directly mongo-bouncer will handle all that for you. The following paragraphs will show you how to use it.\n\n\n### Initialize\n\nAs this is a mongoose plugin simply initialize the plugin like this. You only need the endpoint of your authorizer. That's it\n\n```ts\nimport mongoBouncer from \"query-bouncer-mongoose-plugin\"\n\nmongoose.plugin(mongoBouncer, {\n  baseUrl: \"https://your-authorizer.com\"\n});\n```\n\nNow with the nature of mongoose plugins this has to be made before any schemas are initialized (which most of time will be done already). So either wrap your schemas so you make sure that the plugin gets initialized first or set the plugin for each schema you want to use (**recommended**)\n\n```ts\nconst blogPostSchema = new mongoose.Schema({\n  Title: \"My new Blog Post\",\n  // ...\n});\n\nblogPostSchema.plugin(mongoBouncer, {\n  baseUrl: \"https://your-authorizer.com\"\n});\n```\n\n#### Additional Options\n**baseUrl:** The URL the MongoBouncer that you want to connect to is hosted\n**apiVersion:** The Version of the API you want to use. Defaults to v1\n**axios:** You can force the Plugin to use another Axios Instance. This is mainly for testing purposes and not recommended\n**cookieName:** By default the Authenticator is set up to give you a cookie named connect.sid. If however you changed that you can also adjust the cookieName here\n\n### Useage\n\nMongoBouncer will run all the validation before your operations are being executed. As this middleware is currently not available in mongoose plugins for all methods, we currentyl support the following\n\n- create **(See Important Information about create)**\n- find\n- findOne\n- findOneAndDelete\n- findOneAndRemove\n- findOneAndUpdate\n- findById\n- findByIdAndDelete\n- findByIdAndRemove\n- findByIdAndUpdate\n- insertMany\n- remove \n- update\n- updateOne\n- updateMany\n- deleteOne\n- deleteMany\n\nThis is an example on how to enalbe MongoBouncer on your model. req refers to the express Request here. The MongoBouncer property needs to be added to the Options Object of your method. Let's take a look at some of those methods\n\nFirst let's set up a model.\n```ts\nconst BlogPostSchema = new Schema({\n  Title: { type: String, required: true } ,\n  Description: { type: String },\n  Category: { type: String, required: true }\n});\nconst BlogPost = mongoose.model('blogpost', BlogPostSchema);\n```\n#### Create\nNow to create a Document with respect to the permissions you just add the MongoBouncer to the options. \n\nAs the Options Object in mongoose is only available if the Document is passed in array please make sure you that even of you just add a single Document you use it in an Array. If you use a single Object the Options Object will be empty internally and as a result **Permissions will not be checked!!!**\n\nAs we stated earlier our authorizer has been set up to\nallow the user to create BlogPosts only if the category is \"Cars\". So while this will work just fine.\n```ts\nconst post = await BlogPost.create([{\n  Title: \"MyBlogPost\",\n  Category: \"Cars\",\n  Description: \"Some cool information about my favourite car\"\n}], { \n  MongoBouncer : {\n    Request: req \n  }\n});\n```\nthis\n```ts\nconst post = await BlogPost.create({\n  Title: \"MyBlogPost\",\n  Category: \"Food\",\n  Description: \"Some cool information about my favourite car\"\n}, { \n  MongoBouncer : {\n    Request: req \n  }\n});\n```\nwill throw an Error as the user is not allowed to create Blog Posts in that Category\n\n#### Find\n\nLet's assume we will now try to find that document again. Again as our fictive setup is that our user will only receive BlogPosts if the Category\nCars in this case\n```ts\nBlogPost.find({ Title: \"MyBlogPost\" }, null, {\n  MongoBouncer: {\n    Request: req\n  }\n});\n```\nwe will be returned an array with the Document we added in the Create section\n\n\n#### Update\nIf we now want to update the document we created we do it just the same way. A working update call would look like this\n```ts\nBlogPost.updateOne(\n  { Title: \"MyBlogPost\", Category: \"Cars\" }, \n  { Title: \"A changed Title\"}, \n  {\n    MongoBouncer: {\n      Request: req\n    }\n  }\n);\n```\nInternally both the Payload and the QueryRestrictions will be checked. So if we use any other Category than Cars nothing will be updated. However in this case no error will be returned but the returned Object by mongoose will just state that nothing matched our Query and nothing was updated. But if we try this e.g.\n```ts\nBlogPost.updateOne(\n  { Title: \"MyBlogPost\", Category: \"Cars\" }, \n  { Title: \"A changed Title\", Category: \"Food\" }, \n  {\n    MongoBouncer: {\n      Request: req\n    }\n  }\n);\n```\nan error will be thrown as a Document will be returned but we are not allowed to invoke the changes we are trying to make.\n\n","readmeFilename":"README.md","gitHead":"32427e42d270a014f2eabb4fc9e104a636f94c5d","bugs":{"url":"https://github.com/relief-melone/query-bouncer-mongoose-plugin/issues"},"homepage":"https://github.com/relief-melone/query-bouncer-mongoose-plugin#readme","_id":"query-bouncer-mongoose-plugin@1.5.2-beta.3","_nodeVersion":"14.13.1","_npmVersion":"6.14.8","dist":{"integrity":"sha512-oXU05IV36Ho2+I8DZT2VRMoL1YZCKm3cr4vMUl7dPu+akJh6/NFxudForCGyOj0aEOI9FehJGVA+vTsc8EocJA==","shasum":"3d68c97ea29ba34cef43908ebbeeaecab5ee3669","tarball":"https://registry.npmjs.org/query-bouncer-mongoose-plugin/-/query-bouncer-mongoose-plugin-1.5.2-beta.3.tgz","fileCount":144,"unpackedSize":194163,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.13\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJfoYCICRA9TVsSAnZWagAAoxAP/3mnFXMzQWPyaip+w5II\n0jp0Jm3Rh6T/tU9kd/QRScm5cyUzaqHpwbVCJnAaPXsBHkCmZ//bzX3LyK8/\ny8rikWwyiOI7O02cd5gKvhxmzuO84IYrIFZ1E1W0dAPzSWuKgGuvEmlDO6ZS\ngceieWHD/PcH3/BC2lz1rUFFWa0chkY98PqoBRuYJerUhWmmDbc1ifgfbOGm\nDMMYEmKH31t122QPC7ZVQJ4sn/4ZfP4UpxnGYCByIEoFWRE5Vyh5yyX61PrU\n8gFHHz8EVCKbXc3p4VzhgyAO1ev7R54h87yHXKkeshxJ8V+ld/GFQ3eKBTV7\nB0SJCcF+0++9LdHsythsrlsfjghv5GZQTm2AfLXcCUJZfJFMfeScrIHqoEhK\n+IjVjDz7wxmgaAOatDHjjY5kb0q3I7wYB7VcLWI35lvuQCqRF0mo+klJxfSb\n6F3pYm9sz3rF+vi71knIJBIlR55a9g0Oxghg4PpWCUqnFTiIzpW5+M6fyFau\nmZ1SrsZ6Tocgew07fW91y0OWstXrJKz8H+czfiFcWfz+IwikgNcxxcOubQWg\nVW+LwYUErUOWxz1RkzKJZmVQquZ9DiWmGKB6upAlgCEZjWWwYONIr7Zmxwmy\ndlA5WsnutAgzC2A6MYdet9bRV9TkawPIe7x0882i48nYYBFDSgE+KsJaV2NO\nF4mw\r\n=jxNK\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIF4w3RqClqL+wywXv2+AWSMs4fUxthFVjbLuOXAXO522AiEAx0hgp6qxRL4BYQt2hkzfqWdJtywVLyELmwLcan4Hce8="}]},"_npmUser":{"name":"relief.melone","email":"relief.melone@gmail.com"},"directories":{},"maintainers":[{"name":"relief.melone","email":"relief.melone@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/query-bouncer-mongoose-plugin_1.5.2-beta.3_1604419719657_0.10945222389318365"},"_hasShrinkwrap":false},"1.5.2-beta.4":{"name":"query-bouncer-mongoose-plugin","version":"1.5.2-beta.4","description":"Mongoose Plugin for Query Bouncer","main":"./dist/index.js","scripts":{"start":"node ./dist/index.js","test":"nyc mocha","build":"tsc --watch false --declaration","lint":"eslint --ignore-path .gitignore .","tsc":"tsc"},"repository":{"type":"git","url":"git+https://github.com/relief-melone/query-bouncer-mongoose-plugin.git"},"author":{"name":"Relief.Melone"},"license":"MIT","dependencies":{"axios":"^0.21.0","express":"^4.17.1","mongodb":"^3.5.0","mongoose":"^5.8.7"},"devDependencies":{"@types/chai":"latest","@types/express":"^4.17.2","@types/mocha":"latest","@types/mongodb":"^3.3.14","@types/mongoose":"^5.5.41","@types/moxios":"^0.4.9","@types/node":"latest","@typescript-eslint/eslint-plugin":"latest","@typescript-eslint/parser":"latest","axios-mock-adapter":"^1.17.0","chai":"latest","chai-exclude":"^2.0.2","eslint":"latest","eslint-import-resolver-alias":"latest","eslint-plugin-import":"latest","mocha":"^7.1.1","mongodb-memory-server":"^6.5.0","nyc":"latest","sinon":"^8.0.4","typescript":"latest"},"readme":"# MongoBouncer - A Mongoose Plugin for Query Bouncer\n\nThe Mongoose Plugin for Query Bouncer (MongoBouncer) integrates with rm-authenticator, Query Bouncer and rm-session-populate. It's goal is to integrate the Role Based Access Control System you define in Query Bouncer easily in your Backend without having to worry about making the correct http requests and modify queries by yourself. The tasks of these components are\n\n1. **rm-authenticator:** Easy way to authenticate your user with just a Docker Container. Works with different OAuth providers like facebook, linkedin and google+. \n   - [GitHub](https://github.com/relief-melone/rm-authenticator)\n   - [Docker](https://hub.docker.com/repository/docker/reliefmelone/rm-authenticator)\n2. **rm-session-populator:** Middleware for Express. It will automatically communicate with the Authenticator and add a user object to your Express **req** with all the information you need\n   - [GitHub](https://github.com/relief-melone/rm-session-populator)\n   - [NPM](https://www.npmjs.com/package/rm-session-populator)\n3. **Query Bouncer:** Set up your Role Based Access System with a comfortable REST-API and use it to automatically modify queries and payloads based on your users permissions. \n   - [GitHub](https://github.com/relief-melone/query-bouncer)\n   - [Docker](https://hub.docker.com/r/reliefmelone/query-bouncer)\n4. **Query Bouncer Mongoose Plugin:** A Plugin that handles all the communication with the authorizer automatically so you can focus on writing your application.\n\nThis Overview illustrates a possible architecture for your application and the integration of those 4 components.\n\n![architecture](https://raw.githubusercontent.com/relief-melone/query-bouncer-mongoose-plugin/master/documentation/architectureOverview.png \"Architecture Overview\")\n\n## Instalation\n\nJust install with npm\n\n```sh\nnpm i --save query-bouncer-mongoose-plugin\n```\n\n## Usage\n\n### Prerequisites\n\nYou need a running instance of Query Bouncer to connect to. The Query Bouncer supplies the plugin with the correct queries accordingly to the users permissions. you can see how to set it up [here](https://github.com/relief-melone/query-bouncer)\n\n### How it Works\n\nQuery Bouncer will be used to easily set up your roles, permissions and roleAssignments for your Application. It supplies endpoints to send your query and payload to. The Query Bouncer will then validate the information based on your users permissions and will e.g. send back an adjusted query based on the users permissions. So what does that mean. Lets assume we have a collection called blogposts. Each BlogPost has a Title, Description and a Category. The user only has access to BlogPosts of the Category \"Cars\". So when a request to the Query Bouncer is made with the query to get all BlogPosts The Query \n\n```js\n{}\n```\nwill be returned as\n\n```js\n{ \n  $or: [ \n    {Category: \"Cars\"} \n  ] \n}\n```\n\nIn order to not having to utilize the API of rm-authorizer directly mongo-bouncer will handle all that for you. The following paragraphs will show you how to use it.\n\n\n### Initialize\n\nAs this is a mongoose plugin simply initialize the plugin like this. You only need the endpoint of your authorizer. That's it\n\n```ts\nimport mongoBouncer from \"query-bouncer-mongoose-plugin\"\n\nmongoose.plugin(mongoBouncer, {\n  baseUrl: \"https://your-authorizer.com\"\n});\n```\n\nNow with the nature of mongoose plugins this has to be made before any schemas are initialized (which most of time will be done already). So either wrap your schemas so you make sure that the plugin gets initialized first or set the plugin for each schema you want to use (**recommended**)\n\n```ts\nconst blogPostSchema = new mongoose.Schema({\n  Title: \"My new Blog Post\",\n  // ...\n});\n\nblogPostSchema.plugin(mongoBouncer, {\n  baseUrl: \"https://your-authorizer.com\"\n});\n```\n\n#### Additional Options\n**baseUrl:** The URL the MongoBouncer that you want to connect to is hosted\n**apiVersion:** The Version of the API you want to use. Defaults to v1\n**axios:** You can force the Plugin to use another Axios Instance. This is mainly for testing purposes and not recommended\n**cookieName:** By default the Authenticator is set up to give you a cookie named connect.sid. If however you changed that you can also adjust the cookieName here\n\n### Useage\n\nMongoBouncer will run all the validation before your operations are being executed. As this middleware is currently not available in mongoose plugins for all methods, we currentyl support the following\n\n- create **(See Important Information about create)**\n- find\n- findOne\n- findOneAndDelete\n- findOneAndRemove\n- findOneAndUpdate\n- findById\n- findByIdAndDelete\n- findByIdAndRemove\n- findByIdAndUpdate\n- insertMany\n- remove \n- update\n- updateOne\n- updateMany\n- deleteOne\n- deleteMany\n\nThis is an example on how to enalbe MongoBouncer on your model. req refers to the express Request here. The MongoBouncer property needs to be added to the Options Object of your method. Let's take a look at some of those methods\n\nFirst let's set up a model.\n```ts\nconst BlogPostSchema = new Schema({\n  Title: { type: String, required: true } ,\n  Description: { type: String },\n  Category: { type: String, required: true }\n});\nconst BlogPost = mongoose.model('blogpost', BlogPostSchema);\n```\n#### Create\nNow to create a Document with respect to the permissions you just add the MongoBouncer to the options. \n\nAs the Options Object in mongoose is only available if the Document is passed in array please make sure you that even of you just add a single Document you use it in an Array. If you use a single Object the Options Object will be empty internally and as a result **Permissions will not be checked!!!**\n\nAs we stated earlier our authorizer has been set up to\nallow the user to create BlogPosts only if the category is \"Cars\". So while this will work just fine.\n```ts\nconst post = await BlogPost.create([{\n  Title: \"MyBlogPost\",\n  Category: \"Cars\",\n  Description: \"Some cool information about my favourite car\"\n}], { \n  MongoBouncer : {\n    Request: req \n  }\n});\n```\nthis\n```ts\nconst post = await BlogPost.create({\n  Title: \"MyBlogPost\",\n  Category: \"Food\",\n  Description: \"Some cool information about my favourite car\"\n}, { \n  MongoBouncer : {\n    Request: req \n  }\n});\n```\nwill throw an Error as the user is not allowed to create Blog Posts in that Category\n\n#### Find\n\nLet's assume we will now try to find that document again. Again as our fictive setup is that our user will only receive BlogPosts if the Category\nCars in this case\n```ts\nBlogPost.find({ Title: \"MyBlogPost\" }, null, {\n  MongoBouncer: {\n    Request: req\n  }\n});\n```\nwe will be returned an array with the Document we added in the Create section\n\n\n#### Update\nIf we now want to update the document we created we do it just the same way. A working update call would look like this\n```ts\nBlogPost.updateOne(\n  { Title: \"MyBlogPost\", Category: \"Cars\" }, \n  { Title: \"A changed Title\"}, \n  {\n    MongoBouncer: {\n      Request: req\n    }\n  }\n);\n```\nInternally both the Payload and the QueryRestrictions will be checked. So if we use any other Category than Cars nothing will be updated. However in this case no error will be returned but the returned Object by mongoose will just state that nothing matched our Query and nothing was updated. But if we try this e.g.\n```ts\nBlogPost.updateOne(\n  { Title: \"MyBlogPost\", Category: \"Cars\" }, \n  { Title: \"A changed Title\", Category: \"Food\" }, \n  {\n    MongoBouncer: {\n      Request: req\n    }\n  }\n);\n```\nan error will be thrown as a Document will be returned but we are not allowed to invoke the changes we are trying to make.\n\n","readmeFilename":"README.md","gitHead":"32427e42d270a014f2eabb4fc9e104a636f94c5d","bugs":{"url":"https://github.com/relief-melone/query-bouncer-mongoose-plugin/issues"},"homepage":"https://github.com/relief-melone/query-bouncer-mongoose-plugin#readme","_id":"query-bouncer-mongoose-plugin@1.5.2-beta.4","_nodeVersion":"14.13.1","_npmVersion":"6.14.8","dist":{"integrity":"sha512-rDCh1LTw5yKKI5gMHI7UFRcvTsiXMOZ3nJnTpS8METy/zc/Gm09GDgrgfuKWzUsWIRinWZ4b2yG7aHFUSKsh+Q==","shasum":"8f2b4b5c87e59314af8021faddfe0677446ad273","tarball":"https://registry.npmjs.org/query-bouncer-mongoose-plugin/-/query-bouncer-mongoose-plugin-1.5.2-beta.4.tgz","fileCount":144,"unpackedSize":194330,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.13\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJfoYMTCRA9TVsSAnZWagAAzi8QAIgeXSR9pi15RgX/KWlf\nmVzgA0E3boVZ+0DpK9PhMInh/xB5LEhEnwF7G78rQ1rrYO361OmsOUXHiNA2\nfbs5VGVR49BMUim9P420yI+/+I3h3weaCp9YvBWerPZJjgaDm5O/tKyumiP0\nWfbD1w1D/SoL6FjXl8aRKrF2f+ryVUf9qh/FFh93UNxq3h0/6QGiLN943MIh\nDnG1e0qrS+3zgy5Y/EV2Vl9bBYyqz1bpMokBQljeZ4ivC8N6/tFuVCqq2tFB\n4FSfnuVF11e4eaWqKCW+k9tHzd/Mv4LykM4YpiI2eC+lVeGdn4me9IgGnG1F\nsk0vENRY57XEjRMDfGLBbcrnR0gZeRlFYlWW1QbgTbZUeeM/SoPXaL5GOP4o\nVxsP60wZH97VqpuM8ujLJpqKACJqbfRBRIrGae+rze8fVDZ88lhbXPJGCEsK\nWdz6UhIl2/O35NjgW5nOof0CYbT5c1BP7M307yjJJlGDRpktgA36yBBPNaCP\nszZdLXfowm4Q6AUDXXaPObU5E9Qj1YpRQGUpVevCGuuks0PqbIQah7lJDzPB\n8K8hj4ypFoxwZC0vxonlF++nQPJyl5jnVaebs9qpx7K0ngUX88lbOVY8jm2U\nBXazdOjfTd+ATuP6j75wT7u0IXG1PEArS8tcElfdyCrQMgZVb1AuBpdn0eAI\n6cM+\r\n=XEek\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEYCIQDg7WGjU8I5QuvWlZapv6pt3M3DsHJX8aLp56tWreKntwIhAOg11jvHHWTUCC4FSE7QwrVOI0Dmp4W2n0bujlpHLf7X"}]},"_npmUser":{"name":"relief.melone","email":"relief.melone@gmail.com"},"directories":{},"maintainers":[{"name":"relief.melone","email":"relief.melone@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/query-bouncer-mongoose-plugin_1.5.2-beta.4_1604420370778_0.9679180128335205"},"_hasShrinkwrap":false},"1.5.2-beta.5":{"name":"query-bouncer-mongoose-plugin","version":"1.5.2-beta.5","description":"Mongoose Plugin for Query Bouncer","main":"./dist/index.js","scripts":{"start":"node ./dist/index.js","test":"nyc mocha","build":"tsc --watch false --declaration","lint":"eslint --ignore-path .gitignore .","tsc":"tsc"},"repository":{"type":"git","url":"git+https://github.com/relief-melone/query-bouncer-mongoose-plugin.git"},"author":{"name":"Relief.Melone"},"license":"MIT","dependencies":{"axios":"^0.21.0","express":"^4.17.1","mongodb":"^3.5.0","mongoose":"^5.8.7"},"devDependencies":{"@types/chai":"latest","@types/express":"^4.17.2","@types/mocha":"latest","@types/mongodb":"^3.3.14","@types/mongoose":"^5.5.41","@types/moxios":"^0.4.9","@types/node":"latest","@typescript-eslint/eslint-plugin":"latest","@typescript-eslint/parser":"latest","axios-mock-adapter":"^1.17.0","chai":"latest","chai-exclude":"^2.0.2","eslint":"latest","eslint-import-resolver-alias":"latest","eslint-plugin-import":"latest","mocha":"^7.1.1","mongodb-memory-server":"^6.5.0","nyc":"latest","sinon":"^8.0.4","typescript":"latest"},"readme":"# MongoBouncer - A Mongoose Plugin for Query Bouncer\n\nThe Mongoose Plugin for Query Bouncer (MongoBouncer) integrates with rm-authenticator, Query Bouncer and rm-session-populate. It's goal is to integrate the Role Based Access Control System you define in Query Bouncer easily in your Backend without having to worry about making the correct http requests and modify queries by yourself. The tasks of these components are\n\n1. **rm-authenticator:** Easy way to authenticate your user with just a Docker Container. Works with different OAuth providers like facebook, linkedin and google+. \n   - [GitHub](https://github.com/relief-melone/rm-authenticator)\n   - [Docker](https://hub.docker.com/repository/docker/reliefmelone/rm-authenticator)\n2. **rm-session-populator:** Middleware for Express. It will automatically communicate with the Authenticator and add a user object to your Express **req** with all the information you need\n   - [GitHub](https://github.com/relief-melone/rm-session-populator)\n   - [NPM](https://www.npmjs.com/package/rm-session-populator)\n3. **Query Bouncer:** Set up your Role Based Access System with a comfortable REST-API and use it to automatically modify queries and payloads based on your users permissions. \n   - [GitHub](https://github.com/relief-melone/query-bouncer)\n   - [Docker](https://hub.docker.com/r/reliefmelone/query-bouncer)\n4. **Query Bouncer Mongoose Plugin:** A Plugin that handles all the communication with the authorizer automatically so you can focus on writing your application.\n\nThis Overview illustrates a possible architecture for your application and the integration of those 4 components.\n\n![architecture](https://raw.githubusercontent.com/relief-melone/query-bouncer-mongoose-plugin/master/documentation/architectureOverview.png \"Architecture Overview\")\n\n## Instalation\n\nJust install with npm\n\n```sh\nnpm i --save query-bouncer-mongoose-plugin\n```\n\n## Usage\n\n### Prerequisites\n\nYou need a running instance of Query Bouncer to connect to. The Query Bouncer supplies the plugin with the correct queries accordingly to the users permissions. you can see how to set it up [here](https://github.com/relief-melone/query-bouncer)\n\n### How it Works\n\nQuery Bouncer will be used to easily set up your roles, permissions and roleAssignments for your Application. It supplies endpoints to send your query and payload to. The Query Bouncer will then validate the information based on your users permissions and will e.g. send back an adjusted query based on the users permissions. So what does that mean. Lets assume we have a collection called blogposts. Each BlogPost has a Title, Description and a Category. The user only has access to BlogPosts of the Category \"Cars\". So when a request to the Query Bouncer is made with the query to get all BlogPosts The Query \n\n```js\n{}\n```\nwill be returned as\n\n```js\n{ \n  $or: [ \n    {Category: \"Cars\"} \n  ] \n}\n```\n\nIn order to not having to utilize the API of rm-authorizer directly mongo-bouncer will handle all that for you. The following paragraphs will show you how to use it.\n\n\n### Initialize\n\nAs this is a mongoose plugin simply initialize the plugin like this. You only need the endpoint of your authorizer. That's it\n\n```ts\nimport mongoBouncer from \"query-bouncer-mongoose-plugin\"\n\nmongoose.plugin(mongoBouncer, {\n  baseUrl: \"https://your-authorizer.com\"\n});\n```\n\nNow with the nature of mongoose plugins this has to be made before any schemas are initialized (which most of time will be done already). So either wrap your schemas so you make sure that the plugin gets initialized first or set the plugin for each schema you want to use (**recommended**)\n\n```ts\nconst blogPostSchema = new mongoose.Schema({\n  Title: \"My new Blog Post\",\n  // ...\n});\n\nblogPostSchema.plugin(mongoBouncer, {\n  baseUrl: \"https://your-authorizer.com\"\n});\n```\n\n#### Additional Options\n**baseUrl:** The URL the MongoBouncer that you want to connect to is hosted\n**apiVersion:** The Version of the API you want to use. Defaults to v1\n**axios:** You can force the Plugin to use another Axios Instance. This is mainly for testing purposes and not recommended\n**cookieName:** By default the Authenticator is set up to give you a cookie named connect.sid. If however you changed that you can also adjust the cookieName here\n\n### Useage\n\nMongoBouncer will run all the validation before your operations are being executed. As this middleware is currently not available in mongoose plugins for all methods, we currentyl support the following\n\n- create **(See Important Information about create)**\n- find\n- findOne\n- findOneAndDelete\n- findOneAndRemove\n- findOneAndUpdate\n- findById\n- findByIdAndDelete\n- findByIdAndRemove\n- findByIdAndUpdate\n- insertMany\n- remove \n- update\n- updateOne\n- updateMany\n- deleteOne\n- deleteMany\n\nThis is an example on how to enalbe MongoBouncer on your model. req refers to the express Request here. The MongoBouncer property needs to be added to the Options Object of your method. Let's take a look at some of those methods\n\nFirst let's set up a model.\n```ts\nconst BlogPostSchema = new Schema({\n  Title: { type: String, required: true } ,\n  Description: { type: String },\n  Category: { type: String, required: true }\n});\nconst BlogPost = mongoose.model('blogpost', BlogPostSchema);\n```\n#### Create\nNow to create a Document with respect to the permissions you just add the MongoBouncer to the options. \n\nAs the Options Object in mongoose is only available if the Document is passed in array please make sure you that even of you just add a single Document you use it in an Array. If you use a single Object the Options Object will be empty internally and as a result **Permissions will not be checked!!!**\n\nAs we stated earlier our authorizer has been set up to\nallow the user to create BlogPosts only if the category is \"Cars\". So while this will work just fine.\n```ts\nconst post = await BlogPost.create([{\n  Title: \"MyBlogPost\",\n  Category: \"Cars\",\n  Description: \"Some cool information about my favourite car\"\n}], { \n  MongoBouncer : {\n    Request: req \n  }\n});\n```\nthis\n```ts\nconst post = await BlogPost.create({\n  Title: \"MyBlogPost\",\n  Category: \"Food\",\n  Description: \"Some cool information about my favourite car\"\n}, { \n  MongoBouncer : {\n    Request: req \n  }\n});\n```\nwill throw an Error as the user is not allowed to create Blog Posts in that Category\n\n#### Find\n\nLet's assume we will now try to find that document again. Again as our fictive setup is that our user will only receive BlogPosts if the Category\nCars in this case\n```ts\nBlogPost.find({ Title: \"MyBlogPost\" }, null, {\n  MongoBouncer: {\n    Request: req\n  }\n});\n```\nwe will be returned an array with the Document we added in the Create section\n\n\n#### Update\nIf we now want to update the document we created we do it just the same way. A working update call would look like this\n```ts\nBlogPost.updateOne(\n  { Title: \"MyBlogPost\", Category: \"Cars\" }, \n  { Title: \"A changed Title\"}, \n  {\n    MongoBouncer: {\n      Request: req\n    }\n  }\n);\n```\nInternally both the Payload and the QueryRestrictions will be checked. So if we use any other Category than Cars nothing will be updated. However in this case no error will be returned but the returned Object by mongoose will just state that nothing matched our Query and nothing was updated. But if we try this e.g.\n```ts\nBlogPost.updateOne(\n  { Title: \"MyBlogPost\", Category: \"Cars\" }, \n  { Title: \"A changed Title\", Category: \"Food\" }, \n  {\n    MongoBouncer: {\n      Request: req\n    }\n  }\n);\n```\nan error will be thrown as a Document will be returned but we are not allowed to invoke the changes we are trying to make.\n\n","readmeFilename":"README.md","gitHead":"32427e42d270a014f2eabb4fc9e104a636f94c5d","bugs":{"url":"https://github.com/relief-melone/query-bouncer-mongoose-plugin/issues"},"homepage":"https://github.com/relief-melone/query-bouncer-mongoose-plugin#readme","_id":"query-bouncer-mongoose-plugin@1.5.2-beta.5","_nodeVersion":"14.13.1","_npmVersion":"6.14.8","dist":{"integrity":"sha512-XNyt+jSree7Nw/TAAKEeMiYwh5ZGRbvS5JIm1UA5eQh7vhuyX5UEm1RPiO3sZ/siZ9lZu73Jl9s4zDe+o3hWOw==","shasum":"e2a96a1eddfa1b1681434615ae3f9aed8ed04755","tarball":"https://registry.npmjs.org/query-bouncer-mongoose-plugin/-/query-bouncer-mongoose-plugin-1.5.2-beta.5.tgz","fileCount":144,"unpackedSize":194641,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.13\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJfoYVmCRA9TVsSAnZWagAA23kP/2Sqxa6NECPLq5YSIrii\nsJwKVT8s7lv0K22vtaBpeZmxqrn0tm8i0/WZ9Zkn/P25RKh2WqxzuAyo1vcs\nuJV7kWbYKZlYRJkpjJgHk8VweoeJRjQI9DuakG//rlPzBKL2EiafHDJ+HmaN\na75v2uSUUfZfUfrox2Ika4jQYiyU8v/5uuLYqSZ7gcwOFLq+T75dZrCcCaXq\nVzbFMWFsarLRJGUdt6mMLxwszgzafV40YDLFxtyUEUPjK7kwtJaj9txB9rZp\n1WJ9cUP+W6sebw5HNBPLHMrGCeuiu+ZR4KIL7EOkIU54saqcYvrVe7KabctP\nSWt+AqxrB2+B8f4lHdkjlE527Etv1n7D9/wMjBivK4rVX+H8PYXLtDwnHTx9\nI0zX/EwFPQNbXYGnKuiNzRiCiMC7r4pFLuDbGr7QKbtVUS0pH6s2H5wHDeVD\n3KdvJKyBuLNlgIoFBcYJCTNuh0cC1WWInR+vdl4EzrkFVEwMYGq4ETyONjdK\noy6JQk4FCDp0i0g84Yvac58uWZvcDl13aaa/RKtCj+7rt+XEl7vX2TCblevY\nGjCFR7j3Mu87+lXl7036+ON3s+g7dtVjwX0N87uuVu1SsEKIxSVomlNxCeeR\nl1DzWhwG/u4i1i3GE/OV5vFA9k7sBGV3A+eWoKfgMcWLWX+OfFfp0lshiIGK\nlWWr\r\n=LuXK\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIQDFc0Xfhw9ig3ONT314GlGawkE0d41Fiyz0s1zgv4WcTgIgUAgQkVIDk8UHen3lFiAzGeuIaSGTWKP7Q1Vf3HiAMW8="}]},"_npmUser":{"name":"relief.melone","email":"relief.melone@gmail.com"},"directories":{},"maintainers":[{"name":"relief.melone","email":"relief.melone@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/query-bouncer-mongoose-plugin_1.5.2-beta.5_1604420966467_0.43320804049388917"},"_hasShrinkwrap":false},"1.5.2-beta.6":{"name":"query-bouncer-mongoose-plugin","version":"1.5.2-beta.6","description":"Mongoose Plugin for Query Bouncer","main":"./dist/index.js","scripts":{"start":"node ./dist/index.js","test":"nyc mocha","build":"tsc --watch false --declaration","lint":"eslint --ignore-path .gitignore .","tsc":"tsc"},"repository":{"type":"git","url":"git+https://github.com/relief-melone/query-bouncer-mongoose-plugin.git"},"author":{"name":"Relief.Melone"},"license":"MIT","dependencies":{"axios":"^0.21.0","express":"^4.17.1","mongodb":"^3.5.0","mongoose":"^5.8.7"},"devDependencies":{"@types/chai":"latest","@types/express":"^4.17.2","@types/mocha":"latest","@types/mongodb":"^3.3.14","@types/mongoose":"^5.5.41","@types/moxios":"^0.4.9","@types/node":"latest","@typescript-eslint/eslint-plugin":"latest","@typescript-eslint/parser":"latest","axios-mock-adapter":"^1.17.0","chai":"latest","chai-exclude":"^2.0.2","eslint":"latest","eslint-import-resolver-alias":"latest","eslint-plugin-import":"latest","mocha":"^7.1.1","mongodb-memory-server":"^6.5.0","nyc":"latest","sinon":"^8.0.4","typescript":"latest"},"readme":"# MongoBouncer - A Mongoose Plugin for Query Bouncer\n\nThe Mongoose Plugin for Query Bouncer (MongoBouncer) integrates with rm-authenticator, Query Bouncer and rm-session-populate. It's goal is to integrate the Role Based Access Control System you define in Query Bouncer easily in your Backend without having to worry about making the correct http requests and modify queries by yourself. The tasks of these components are\n\n1. **rm-authenticator:** Easy way to authenticate your user with just a Docker Container. Works with different OAuth providers like facebook, linkedin and google+. \n   - [GitHub](https://github.com/relief-melone/rm-authenticator)\n   - [Docker](https://hub.docker.com/repository/docker/reliefmelone/rm-authenticator)\n2. **rm-session-populator:** Middleware for Express. It will automatically communicate with the Authenticator and add a user object to your Express **req** with all the information you need\n   - [GitHub](https://github.com/relief-melone/rm-session-populator)\n   - [NPM](https://www.npmjs.com/package/rm-session-populator)\n3. **Query Bouncer:** Set up your Role Based Access System with a comfortable REST-API and use it to automatically modify queries and payloads based on your users permissions. \n   - [GitHub](https://github.com/relief-melone/query-bouncer)\n   - [Docker](https://hub.docker.com/r/reliefmelone/query-bouncer)\n4. **Query Bouncer Mongoose Plugin:** A Plugin that handles all the communication with the authorizer automatically so you can focus on writing your application.\n\nThis Overview illustrates a possible architecture for your application and the integration of those 4 components.\n\n![architecture](https://raw.githubusercontent.com/relief-melone/query-bouncer-mongoose-plugin/master/documentation/architectureOverview.png \"Architecture Overview\")\n\n## Instalation\n\nJust install with npm\n\n```sh\nnpm i --save query-bouncer-mongoose-plugin\n```\n\n## Usage\n\n### Prerequisites\n\nYou need a running instance of Query Bouncer to connect to. The Query Bouncer supplies the plugin with the correct queries accordingly to the users permissions. you can see how to set it up [here](https://github.com/relief-melone/query-bouncer)\n\n### How it Works\n\nQuery Bouncer will be used to easily set up your roles, permissions and roleAssignments for your Application. It supplies endpoints to send your query and payload to. The Query Bouncer will then validate the information based on your users permissions and will e.g. send back an adjusted query based on the users permissions. So what does that mean. Lets assume we have a collection called blogposts. Each BlogPost has a Title, Description and a Category. The user only has access to BlogPosts of the Category \"Cars\". So when a request to the Query Bouncer is made with the query to get all BlogPosts The Query \n\n```js\n{}\n```\nwill be returned as\n\n```js\n{ \n  $or: [ \n    {Category: \"Cars\"} \n  ] \n}\n```\n\nIn order to not having to utilize the API of rm-authorizer directly mongo-bouncer will handle all that for you. The following paragraphs will show you how to use it.\n\n\n### Initialize\n\nAs this is a mongoose plugin simply initialize the plugin like this. You only need the endpoint of your authorizer. That's it\n\n```ts\nimport mongoBouncer from \"query-bouncer-mongoose-plugin\"\n\nmongoose.plugin(mongoBouncer, {\n  baseUrl: \"https://your-authorizer.com\"\n});\n```\n\nNow with the nature of mongoose plugins this has to be made before any schemas are initialized (which most of time will be done already). So either wrap your schemas so you make sure that the plugin gets initialized first or set the plugin for each schema you want to use (**recommended**)\n\n```ts\nconst blogPostSchema = new mongoose.Schema({\n  Title: \"My new Blog Post\",\n  // ...\n});\n\nblogPostSchema.plugin(mongoBouncer, {\n  baseUrl: \"https://your-authorizer.com\"\n});\n```\n\n#### Additional Options\n**baseUrl:** The URL the MongoBouncer that you want to connect to is hosted\n**apiVersion:** The Version of the API you want to use. Defaults to v1\n**axios:** You can force the Plugin to use another Axios Instance. This is mainly for testing purposes and not recommended\n**cookieName:** By default the Authenticator is set up to give you a cookie named connect.sid. If however you changed that you can also adjust the cookieName here\n\n### Useage\n\nMongoBouncer will run all the validation before your operations are being executed. As this middleware is currently not available in mongoose plugins for all methods, we currentyl support the following\n\n- create **(See Important Information about create)**\n- find\n- findOne\n- findOneAndDelete\n- findOneAndRemove\n- findOneAndUpdate\n- findById\n- findByIdAndDelete\n- findByIdAndRemove\n- findByIdAndUpdate\n- insertMany\n- remove \n- update\n- updateOne\n- updateMany\n- deleteOne\n- deleteMany\n\nThis is an example on how to enalbe MongoBouncer on your model. req refers to the express Request here. The MongoBouncer property needs to be added to the Options Object of your method. Let's take a look at some of those methods\n\nFirst let's set up a model.\n```ts\nconst BlogPostSchema = new Schema({\n  Title: { type: String, required: true } ,\n  Description: { type: String },\n  Category: { type: String, required: true }\n});\nconst BlogPost = mongoose.model('blogpost', BlogPostSchema);\n```\n#### Create\nNow to create a Document with respect to the permissions you just add the MongoBouncer to the options. \n\nAs the Options Object in mongoose is only available if the Document is passed in array please make sure you that even of you just add a single Document you use it in an Array. If you use a single Object the Options Object will be empty internally and as a result **Permissions will not be checked!!!**\n\nAs we stated earlier our authorizer has been set up to\nallow the user to create BlogPosts only if the category is \"Cars\". So while this will work just fine.\n```ts\nconst post = await BlogPost.create([{\n  Title: \"MyBlogPost\",\n  Category: \"Cars\",\n  Description: \"Some cool information about my favourite car\"\n}], { \n  MongoBouncer : {\n    Request: req \n  }\n});\n```\nthis\n```ts\nconst post = await BlogPost.create({\n  Title: \"MyBlogPost\",\n  Category: \"Food\",\n  Description: \"Some cool information about my favourite car\"\n}, { \n  MongoBouncer : {\n    Request: req \n  }\n});\n```\nwill throw an Error as the user is not allowed to create Blog Posts in that Category\n\n#### Find\n\nLet's assume we will now try to find that document again. Again as our fictive setup is that our user will only receive BlogPosts if the Category\nCars in this case\n```ts\nBlogPost.find({ Title: \"MyBlogPost\" }, null, {\n  MongoBouncer: {\n    Request: req\n  }\n});\n```\nwe will be returned an array with the Document we added in the Create section\n\n\n#### Update\nIf we now want to update the document we created we do it just the same way. A working update call would look like this\n```ts\nBlogPost.updateOne(\n  { Title: \"MyBlogPost\", Category: \"Cars\" }, \n  { Title: \"A changed Title\"}, \n  {\n    MongoBouncer: {\n      Request: req\n    }\n  }\n);\n```\nInternally both the Payload and the QueryRestrictions will be checked. So if we use any other Category than Cars nothing will be updated. However in this case no error will be returned but the returned Object by mongoose will just state that nothing matched our Query and nothing was updated. But if we try this e.g.\n```ts\nBlogPost.updateOne(\n  { Title: \"MyBlogPost\", Category: \"Cars\" }, \n  { Title: \"A changed Title\", Category: \"Food\" }, \n  {\n    MongoBouncer: {\n      Request: req\n    }\n  }\n);\n```\nan error will be thrown as a Document will be returned but we are not allowed to invoke the changes we are trying to make.\n\n","readmeFilename":"README.md","gitHead":"32427e42d270a014f2eabb4fc9e104a636f94c5d","bugs":{"url":"https://github.com/relief-melone/query-bouncer-mongoose-plugin/issues"},"homepage":"https://github.com/relief-melone/query-bouncer-mongoose-plugin#readme","_id":"query-bouncer-mongoose-plugin@1.5.2-beta.6","_nodeVersion":"14.13.1","_npmVersion":"6.14.8","dist":{"integrity":"sha512-yWuZeVvyEcbM3TbBQcK8+h2CeVlYvZnyItRLgYqF1wzD5PfSvH4JRjTAiEsaI4v7F12wQcD9aIp9DfQ3tJxr8A==","shasum":"ebf44d028b2d480dffb8d3235b8448711152907f","tarball":"https://registry.npmjs.org/query-bouncer-mongoose-plugin/-/query-bouncer-mongoose-plugin-1.5.2-beta.6.tgz","fileCount":144,"unpackedSize":194805,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.13\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJfoYiJCRA9TVsSAnZWagAA8j8P/iL1BJ51ohEWRrvM6pko\n7JtatEpSTkpdzFxwInPXpNJRTqMO/LpvkNs/+4A/H17hkBqr1oD3/WKCqOnF\nLgaEYJ0nwp+/Vtsj/WL2bhr4UlrwG9pjvZ/kfjtZqOnrVPDCt12wNQIEdLGW\nqmN2sUG582KjkD5/cj+mt3DeQTtAtV/Cvi2Nvj+xL6/l0kV6lpIh6GnRqVOz\n89YpDD3IfbxZFENkQV3TyepUd+YQvEWGFVm9V9+cusmyoMIMKsbG2xwGT3Do\nm0hsghN3wSwTS+4jMr3VPHgptNTgrXioqQAq3cGVArEnm0WNy+S0xrwhgMXA\n7c5qr+Gg/z7go+b9oF1e80mGXkj9WRsGZNhl8XHXlzthBHpClgwxDIuOOI2a\ny4ddiChppVtK/OKXLZRNM0r/Sl3ErKleqVUc8EWhcX7u2ogFsJMX++m1kBZP\nH1UpAt+uhLARU0Pl2/YLaiJYYjWA7A7XG8PsCStvRlw7VzCV0Awvm31ubCXH\nzi8p/H0h3XcSBWtQSGGU3U+/ooDXRureuRbFMfpUSAE70yDbAKe049Z43m+S\nNGtFBSMR++oZPkIx+Z+uPqQFeuKh7JslK9BXddLNyuPuL8K8r0dam00Gq0T2\n7o8ZIp23IGHSLewlw5/XiF0LVr9iCZ0XLySj7NCA3gOUiKMiaXr05fhYQM3H\nW1OS\r\n=hYft\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEQCIDKXJNdQproJAey9Z+Zve4JglTLDrXTrWmZz0AoB9iuSAiBn6sk8Dl0juEPj6C3AIZHIlkZVrAVKFAlN6V+FRtIvgA=="}]},"_npmUser":{"name":"relief.melone","email":"relief.melone@gmail.com"},"directories":{},"maintainers":[{"name":"relief.melone","email":"relief.melone@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/query-bouncer-mongoose-plugin_1.5.2-beta.6_1604421769453_0.26440136359711053"},"_hasShrinkwrap":false},"1.5.2-beta.7":{"name":"query-bouncer-mongoose-plugin","version":"1.5.2-beta.7","description":"Mongoose Plugin for Query Bouncer","main":"./dist/index.js","scripts":{"start":"node ./dist/index.js","test":"nyc mocha","build":"tsc --watch false --declaration","lint":"eslint --ignore-path .gitignore .","tsc":"tsc"},"repository":{"type":"git","url":"git+https://github.com/relief-melone/query-bouncer-mongoose-plugin.git"},"author":{"name":"Relief.Melone"},"license":"MIT","dependencies":{"axios":"^0.21.0","express":"^4.17.1","mongodb":"^3.5.0","mongoose":"^5.8.7"},"devDependencies":{"@types/chai":"latest","@types/express":"^4.17.2","@types/mocha":"latest","@types/mongodb":"^3.3.14","@types/mongoose":"^5.5.41","@types/moxios":"^0.4.9","@types/node":"latest","@typescript-eslint/eslint-plugin":"latest","@typescript-eslint/parser":"latest","axios-mock-adapter":"^1.17.0","chai":"latest","chai-exclude":"^2.0.2","eslint":"latest","eslint-import-resolver-alias":"latest","eslint-plugin-import":"latest","mocha":"^7.1.1","mongodb-memory-server":"^6.5.0","nyc":"latest","sinon":"^8.0.4","typescript":"latest"},"readme":"# MongoBouncer - A Mongoose Plugin for Query Bouncer\n\nThe Mongoose Plugin for Query Bouncer (MongoBouncer) integrates with rm-authenticator, Query Bouncer and rm-session-populate. It's goal is to integrate the Role Based Access Control System you define in Query Bouncer easily in your Backend without having to worry about making the correct http requests and modify queries by yourself. The tasks of these components are\n\n1. **rm-authenticator:** Easy way to authenticate your user with just a Docker Container. Works with different OAuth providers like facebook, linkedin and google+. \n   - [GitHub](https://github.com/relief-melone/rm-authenticator)\n   - [Docker](https://hub.docker.com/repository/docker/reliefmelone/rm-authenticator)\n2. **rm-session-populator:** Middleware for Express. It will automatically communicate with the Authenticator and add a user object to your Express **req** with all the information you need\n   - [GitHub](https://github.com/relief-melone/rm-session-populator)\n   - [NPM](https://www.npmjs.com/package/rm-session-populator)\n3. **Query Bouncer:** Set up your Role Based Access System with a comfortable REST-API and use it to automatically modify queries and payloads based on your users permissions. \n   - [GitHub](https://github.com/relief-melone/query-bouncer)\n   - [Docker](https://hub.docker.com/r/reliefmelone/query-bouncer)\n4. **Query Bouncer Mongoose Plugin:** A Plugin that handles all the communication with the authorizer automatically so you can focus on writing your application.\n\nThis Overview illustrates a possible architecture for your application and the integration of those 4 components.\n\n![architecture](https://raw.githubusercontent.com/relief-melone/query-bouncer-mongoose-plugin/master/documentation/architectureOverview.png \"Architecture Overview\")\n\n## Instalation\n\nJust install with npm\n\n```sh\nnpm i --save query-bouncer-mongoose-plugin\n```\n\n## Usage\n\n### Prerequisites\n\nYou need a running instance of Query Bouncer to connect to. The Query Bouncer supplies the plugin with the correct queries accordingly to the users permissions. you can see how to set it up [here](https://github.com/relief-melone/query-bouncer)\n\n### How it Works\n\nQuery Bouncer will be used to easily set up your roles, permissions and roleAssignments for your Application. It supplies endpoints to send your query and payload to. The Query Bouncer will then validate the information based on your users permissions and will e.g. send back an adjusted query based on the users permissions. So what does that mean. Lets assume we have a collection called blogposts. Each BlogPost has a Title, Description and a Category. The user only has access to BlogPosts of the Category \"Cars\". So when a request to the Query Bouncer is made with the query to get all BlogPosts The Query \n\n```js\n{}\n```\nwill be returned as\n\n```js\n{ \n  $or: [ \n    {Category: \"Cars\"} \n  ] \n}\n```\n\nIn order to not having to utilize the API of rm-authorizer directly mongo-bouncer will handle all that for you. The following paragraphs will show you how to use it.\n\n\n### Initialize\n\nAs this is a mongoose plugin simply initialize the plugin like this. You only need the endpoint of your authorizer. That's it\n\n```ts\nimport mongoBouncer from \"query-bouncer-mongoose-plugin\"\n\nmongoose.plugin(mongoBouncer, {\n  baseUrl: \"https://your-authorizer.com\"\n});\n```\n\nNow with the nature of mongoose plugins this has to be made before any schemas are initialized (which most of time will be done already). So either wrap your schemas so you make sure that the plugin gets initialized first or set the plugin for each schema you want to use (**recommended**)\n\n```ts\nconst blogPostSchema = new mongoose.Schema({\n  Title: \"My new Blog Post\",\n  // ...\n});\n\nblogPostSchema.plugin(mongoBouncer, {\n  baseUrl: \"https://your-authorizer.com\"\n});\n```\n\n#### Additional Options\n**baseUrl:** The URL the MongoBouncer that you want to connect to is hosted\n**apiVersion:** The Version of the API you want to use. Defaults to v1\n**axios:** You can force the Plugin to use another Axios Instance. This is mainly for testing purposes and not recommended\n**cookieName:** By default the Authenticator is set up to give you a cookie named connect.sid. If however you changed that you can also adjust the cookieName here\n\n### Useage\n\nMongoBouncer will run all the validation before your operations are being executed. As this middleware is currently not available in mongoose plugins for all methods, we currentyl support the following\n\n- create **(See Important Information about create)**\n- find\n- findOne\n- findOneAndDelete\n- findOneAndRemove\n- findOneAndUpdate\n- findById\n- findByIdAndDelete\n- findByIdAndRemove\n- findByIdAndUpdate\n- insertMany\n- remove \n- update\n- updateOne\n- updateMany\n- deleteOne\n- deleteMany\n\nThis is an example on how to enalbe MongoBouncer on your model. req refers to the express Request here. The MongoBouncer property needs to be added to the Options Object of your method. Let's take a look at some of those methods\n\nFirst let's set up a model.\n```ts\nconst BlogPostSchema = new Schema({\n  Title: { type: String, required: true } ,\n  Description: { type: String },\n  Category: { type: String, required: true }\n});\nconst BlogPost = mongoose.model('blogpost', BlogPostSchema);\n```\n#### Create\nNow to create a Document with respect to the permissions you just add the MongoBouncer to the options. \n\nAs the Options Object in mongoose is only available if the Document is passed in array please make sure you that even of you just add a single Document you use it in an Array. If you use a single Object the Options Object will be empty internally and as a result **Permissions will not be checked!!!**\n\nAs we stated earlier our authorizer has been set up to\nallow the user to create BlogPosts only if the category is \"Cars\". So while this will work just fine.\n```ts\nconst post = await BlogPost.create([{\n  Title: \"MyBlogPost\",\n  Category: \"Cars\",\n  Description: \"Some cool information about my favourite car\"\n}], { \n  MongoBouncer : {\n    Request: req \n  }\n});\n```\nthis\n```ts\nconst post = await BlogPost.create({\n  Title: \"MyBlogPost\",\n  Category: \"Food\",\n  Description: \"Some cool information about my favourite car\"\n}, { \n  MongoBouncer : {\n    Request: req \n  }\n});\n```\nwill throw an Error as the user is not allowed to create Blog Posts in that Category\n\n#### Find\n\nLet's assume we will now try to find that document again. Again as our fictive setup is that our user will only receive BlogPosts if the Category\nCars in this case\n```ts\nBlogPost.find({ Title: \"MyBlogPost\" }, null, {\n  MongoBouncer: {\n    Request: req\n  }\n});\n```\nwe will be returned an array with the Document we added in the Create section\n\n\n#### Update\nIf we now want to update the document we created we do it just the same way. A working update call would look like this\n```ts\nBlogPost.updateOne(\n  { Title: \"MyBlogPost\", Category: \"Cars\" }, \n  { Title: \"A changed Title\"}, \n  {\n    MongoBouncer: {\n      Request: req\n    }\n  }\n);\n```\nInternally both the Payload and the QueryRestrictions will be checked. So if we use any other Category than Cars nothing will be updated. However in this case no error will be returned but the returned Object by mongoose will just state that nothing matched our Query and nothing was updated. But if we try this e.g.\n```ts\nBlogPost.updateOne(\n  { Title: \"MyBlogPost\", Category: \"Cars\" }, \n  { Title: \"A changed Title\", Category: \"Food\" }, \n  {\n    MongoBouncer: {\n      Request: req\n    }\n  }\n);\n```\nan error will be thrown as a Document will be returned but we are not allowed to invoke the changes we are trying to make.\n\n","readmeFilename":"README.md","gitHead":"32427e42d270a014f2eabb4fc9e104a636f94c5d","bugs":{"url":"https://github.com/relief-melone/query-bouncer-mongoose-plugin/issues"},"homepage":"https://github.com/relief-melone/query-bouncer-mongoose-plugin#readme","_id":"query-bouncer-mongoose-plugin@1.5.2-beta.7","_nodeVersion":"14.13.1","_npmVersion":"6.14.8","dist":{"integrity":"sha512-pzrtIpKvakNiKHPlCjkhRHplZeFer8NduMRAxWx7Wui77Je1Czei0f0zhI5+n/Hgk87qeOuvgfIS4yZGHrD89Q==","shasum":"48392dc4a906f00afa4b909ebfc35dd7d42a9135","tarball":"https://registry.npmjs.org/query-bouncer-mongoose-plugin/-/query-bouncer-mongoose-plugin-1.5.2-beta.7.tgz","fileCount":144,"unpackedSize":195093,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.13\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJfoYzeCRA9TVsSAnZWagAAgXcP/RICFStkkH75neaW1i8M\ndGX+chpD323jDG+vRZnTArJCKl9xrhy0JbWEhN8a/BpqHbLYAEg6nKukhI3j\nOaZBDfGLguim7DDAF13V2DoduAMPuQFiaBUsXp7b57iMG+5ExiyLM5atHH6C\n+eIcAP24evhVm5G1mfB/eKPSZOl4o4Xzqh+9Uq1RKWIAX7i1I7bJ+Jvr3tfL\nw8BqdRJ86MNCqNH4Nwb9dpLtK+6Yv6Yko6A8waNLVy3e8/P+I8FnGqxnS+JH\n4pMAERBTQrylLDEnioaWr2DbBeJJHPry9Gz1/zwk+DSKczGU1CbVCVq8mfxd\nqeld2Scli4cLz/uG/mUB9qscYiuowzWw25+kbkD3e+iMlzKIbe427SCDc8gO\nN28TXu5e5pKtsHEpbiPxP3gQ+pmhfZe5DJGCK1wFtU/+P2V8zNnVY18puzEz\nm/yT74w8MJ06UMZJjwoE8F9pBvhywSmnjugoATTbTOaIu5qSEbTUJcmiSbAJ\nXMD5uU20FmJax8XZkpfWcCGkJ/vhvr4QhVPRTjE4Cka57RcLHmdFQU8URRee\nJh5xBN3MoKVq3mkTEjawMPZPkwrnX/gO/p93fgRW21tXK/FQ8grBAgnL24w/\ndF9XF0Wy8UcQ7za/glFXtokZ1JuDiAqXgkgccV4No6ZGe2W9nxGOqKCMw5c4\n3VJr\r\n=Pf/R\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEQCIGIJOB6Q+gF9GMP3VEtyalQkA1KpQd5tRfVSDwvhI3ZxAiAwhYncjj4YGG1AS86KqKGI+zKR4NKDuG/pbCjXq0mYzg=="}]},"_npmUser":{"name":"relief.melone","email":"relief.melone@gmail.com"},"directories":{},"maintainers":[{"name":"relief.melone","email":"relief.melone@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/query-bouncer-mongoose-plugin_1.5.2-beta.7_1604422878381_0.1322675634653807"},"_hasShrinkwrap":false},"1.6.0":{"name":"query-bouncer-mongoose-plugin","version":"1.6.0","description":"Mongoose Plugin for Query Bouncer","main":"./dist/index.js","scripts":{"start":"node ./dist/index.js","test":"nyc mocha","build":"tsc --watch false --declaration","lint":"eslint --ignore-path .gitignore .","tsc":"tsc"},"repository":{"type":"git","url":"git+https://github.com/relief-melone/query-bouncer-mongoose-plugin.git"},"author":{"name":"Relief.Melone"},"license":"MIT","dependencies":{"axios":"^0.21.0","express":"^4.17.1","mongodb":"^3.5.0","mongoose":"^5.8.7"},"devDependencies":{"@types/chai":"latest","@types/express":"^4.17.2","@types/mocha":"latest","@types/mongodb":"^3.3.14","@types/mongoose":"^5.5.41","@types/moxios":"^0.4.9","@types/node":"latest","@typescript-eslint/eslint-plugin":"latest","@typescript-eslint/parser":"latest","axios-mock-adapter":"^1.17.0","chai":"latest","chai-exclude":"^2.0.2","eslint":"latest","eslint-import-resolver-alias":"latest","eslint-plugin-import":"latest","mocha":"^7.1.1","mongodb-memory-server":"^6.5.0","nyc":"latest","sinon":"^8.0.4","typescript":"latest"},"gitHead":"745f75c0a97ce72c73a54277ac51b7ee588d1582","bugs":{"url":"https://github.com/relief-melone/query-bouncer-mongoose-plugin/issues"},"homepage":"https://github.com/relief-melone/query-bouncer-mongoose-plugin#readme","_id":"query-bouncer-mongoose-plugin@1.6.0","_nodeVersion":"14.13.1","_npmVersion":"6.14.8","dist":{"integrity":"sha512-h/CLrLgEe5Oh4ZVAbxTJHv8zGYXlTnNyYMCjMEW+4SEe68ScX8dwGdhuKhBexlEc1csfM9VSOmscE0mZFwUEgQ==","shasum":"388f8d926f736b989c92a1353fb9de33a66b83eb","tarball":"https://registry.npmjs.org/query-bouncer-mongoose-plugin/-/query-bouncer-mongoose-plugin-1.6.0.tgz","fileCount":144,"unpackedSize":195640,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.13\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJfodEcCRA9TVsSAnZWagAAfkMQAI8jXyeRGi3CAM9SgPpm\n0kcxQPi6tusMv8sF+4UqwduOX8ntLt4piEyYrYSg60vdZWg5LjWOMZ6KHCPm\n9GjFopeHul8gDCzvwQWBDHqRPieAUPxiRsdVvJaVGnNM8rfXKLSgLGySWq88\nZx4cphbhQPw5z9dxMo3VLTuyFIa5TMRhM12bpQhppE58TLKSCEYTq5a0DT9Y\nSCoSL9YYXsdzDEmbQs/o2QsrMXglk5jS2pPS8/uY1iwf2RTEt5wsxIB4TY+7\n57IQmocaFNK6nxADvJmnxP1upv5nxhG4xBU6zAXPXpf1TyvxDD0rnFknVf3k\nklechHrXWCueGLbk45o6Sw80kgHfdItDCcptsBSrBiJBJcZrB9JjuoMcakRr\n1QG3hrsZHIwOe7wdqLT8Cz8pcvR6Y2SVLWUsd4C82Atr+SkvGI8wQoR7PBng\nheT95og6gtr1vEjRMYxIpiw3TSZSSkjxVctNO9y8rs9mI5JjUs/U1PVFraCQ\nWW5UJ/ucYeLKmfhvMcIDQ8XUDo7AX4I06Fa+zggiJM6mfFvR0McltDb05KIO\numD1/aMOikJId5RrMj4gteo2OmdymGhFUuQWY0F1KUZa/I4J1/jiuAXksV2w\nglYX8rRbk7gd1NkiS8ZquTuMfTkNQTdakqLftqIQ2Xc/8bTUQgmGsgxk/PGw\nyaOB\r\n=JYfd\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIQDYXiI/KDXxlOz5a3rJaDNa4NtsjzdJzhZlkW5wx5t5qAIgIshqgbMKH7gu8iN9Mstse2hj6CBBSIGSgvM36ifLQhE="}]},"_npmUser":{"name":"relief.melone","email":"relief.melone@gmail.com"},"directories":{},"maintainers":[{"name":"relief.melone","email":"relief.melone@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/query-bouncer-mongoose-plugin_1.6.0_1604440348470_0.7277120693156189"},"_hasShrinkwrap":false},"1.7.0":{"name":"query-bouncer-mongoose-plugin","version":"1.7.0","description":"Mongoose Plugin for Query Bouncer","main":"./dist/index.js","scripts":{"start":"node ./dist/index.js","test":"nyc mocha","build":"tsc --watch false --declaration","lint":"eslint --ignore-path .gitignore .","tsc":"tsc"},"repository":{"type":"git","url":"git+https://github.com/relief-melone/query-bouncer-mongoose-plugin.git"},"author":{"name":"Relief.Melone"},"license":"MIT","dependencies":{"axios":"^0.21.0","express":"^4.17.1","mongodb":"^3.5.0","mongoose":"^5.8.7"},"devDependencies":{"@types/chai":"latest","@types/express":"^4.17.2","@types/mocha":"latest","@types/mongodb":"^3.3.14","@types/mongoose":"^5.5.41","@types/moxios":"^0.4.9","@types/node":"latest","@typescript-eslint/eslint-plugin":"latest","@typescript-eslint/parser":"latest","axios-mock-adapter":"^1.17.0","chai":"latest","chai-exclude":"^2.0.2","eslint":"latest","eslint-import-resolver-alias":"latest","eslint-plugin-import":"latest","mocha":"^7.1.1","mongodb-memory-server":"^6.5.0","nyc":"latest","sinon":"^8.0.4","typescript":"latest"},"gitHead":"651d08da8ab54b92a836528ac4e89db14f11b9d8","bugs":{"url":"https://github.com/relief-melone/query-bouncer-mongoose-plugin/issues"},"homepage":"https://github.com/relief-melone/query-bouncer-mongoose-plugin#readme","_id":"query-bouncer-mongoose-plugin@1.7.0","_nodeVersion":"14.13.1","_npmVersion":"6.14.9","dist":{"integrity":"sha512-WUSRZAjh2IhRB2cLxrW/IpTgCjMWE3wXMn31fKdGnjgCkL4MAjR2hoWFGyO0BuURkYeW5ORJ0gI07RGyh41ytg==","shasum":"4ea32cb7c5ce0d9629a79bd70383a14dcdf7db0b","tarball":"https://registry.npmjs.org/query-bouncer-mongoose-plugin/-/query-bouncer-mongoose-plugin-1.7.0.tgz","fileCount":147,"unpackedSize":206208,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.13\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJfwif0CRA9TVsSAnZWagAAZc8P/05gmClaf42ftTjiMNnB\nhYObJVa29QVCamU4h+HQzzsenobE0UNEdePn+F2MDRnv+z2zzS1bWMXvrc3Y\nIHSu806V+1v0G4IQNsV5tcKwxpVpa8iHI6MAvH8zP55XuI8zlCxTR9ifZCo4\n8bXDRyOYDms4ibaak/hFkSH8ZO75v0VB+9+T6It1SXT/lvyhz76btBiZLtNz\nkJklxPcNcMzUQqfIZwLl4tg+ceSixVvxcveR9ZbNXFt64kAHAmrQMOtMvTbH\nPpT8j2XfY0mvm51e52fk/Iwl7FLXUNdIlAADksHrheWXLP40Nvi9xxd31hSb\nkVDPcooPj7pZdlDPmcWlfVaeZkBrIZsI95sZ7rU35o+hbhq5bRvdRfj8kX10\naZ5k3eZkAiN45idu8XWAq1Th4+0QWw+X7BoGozqKegnm/F1F7bKF8dfRU3N7\nxq2ICJXqvKNMElStiEKToqdSbKEAHU4QZoobCs5kl8sALX+Jq76zQR/82dMV\nwnvMVuJEizDHfsUnf50C9fogFh7to5hhT6vqoTzJds8K9NpU66gOWEuEMVXc\n44dZ+MPB+1jPx8yK0Q/JnZqm3j/HbBP8/7Fke+idLaaiLGYP5gQSa+MJ2R+X\nPEnDMkweQMEoKe8U/hzTAsxBYCGr3N07VjFTQTxhLiRzMkFnmPHPZ6S6DAaj\n/ZJR\r\n=HmIG\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIQDn6Cx2RUCsg95u5KIYHFRCndCqewzzsaoq2FY7MONDqgIgbRoi1WzYlCJErp46wFGwl4Sdh1UR0abNO/ZE7Nd8ykQ="}]},"_npmUser":{"name":"relief.melone","email":"relief.melone@gmail.com"},"directories":{},"maintainers":[{"name":"relief.melone","email":"relief.melone@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/query-bouncer-mongoose-plugin_1.7.0_1606559731725_0.365530372361772"},"_hasShrinkwrap":false},"1.8.0":{"name":"query-bouncer-mongoose-plugin","version":"1.8.0","description":"Mongoose Plugin for Query Bouncer","main":"./dist/index.js","scripts":{"start":"node ./dist/index.js","test":"mocha","coverage":"nyc mocha","build":"tsc --watch false --declaration","lint":"eslint --ignore-path .gitignore .","tsc":"tsc"},"repository":{"type":"git","url":"git+https://github.com/relief-melone/query-bouncer-mongoose-plugin.git"},"author":{"name":"Relief.Melone"},"license":"MIT","dependencies":{"axios":"^0.21.0","express":"^4.17.1","mongodb":"^3.5.0","mongoose":"^5.8.7"},"devDependencies":{"@sinonjs/referee-sinon":"^8.0.0","@types/chai":"latest","@types/express":"^4.17.2","@types/mocha":"latest","@types/mongodb":"^3.3.14","@types/mongoose":"^5.5.41","@types/moxios":"^0.4.9","@types/node":"latest","@types/sinon":"^9.0.9","@typescript-eslint/eslint-plugin":"latest","@typescript-eslint/parser":"latest","axios-mock-adapter":"^1.17.0","chai":"latest","chai-exclude":"^2.0.2","eslint":"latest","eslint-import-resolver-alias":"latest","eslint-plugin-import":"latest","mocha":"^7.1.1","mongodb-memory-server":"^6.5.0","nyc":"latest","sinon":"^8.1.1","typescript":"latest"},"gitHead":"24d5604d713574a9a167b9ac78739a5ac019dceb","bugs":{"url":"https://github.com/relief-melone/query-bouncer-mongoose-plugin/issues"},"homepage":"https://github.com/relief-melone/query-bouncer-mongoose-plugin#readme","_id":"query-bouncer-mongoose-plugin@1.8.0","_nodeVersion":"14.13.1","_npmVersion":"6.14.9","dist":{"integrity":"sha512-B4wX5xLP47y3NbLCQiQ79yT3ZLSRHa0azq5xNb6UGOFqisR0yATHc8ghdSV0O1XA8lyW1SpN54Kf8beBxWZsNA==","shasum":"4f889149837bfe0cbfc048fd69ed10a291ec0525","tarball":"https://registry.npmjs.org/query-bouncer-mongoose-plugin/-/query-bouncer-mongoose-plugin-1.8.0.tgz","fileCount":153,"unpackedSize":218769,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.13\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJfwlQ+CRA9TVsSAnZWagAANTQP/0EiSpwRg3hmck6fDmbY\nyTgt5IakrVdUkmAStl6VIwg2q4fHwWfP4rx4pxTveeOFj1BnORRRjCeD6P+P\n6SCIpdRhSYxe0XBoT33VTum9QHCv+h8AofsasD0anw17VVsoYCyCd3hVh/ZZ\nhIPnKD4IixhmQxG31CHxwG8GHStYsH9R2M2yD3kA54XIm40y2VdT0f6TnGca\nDMos+KEUZYY8jTYFwFxsUQPjLL+kAjcWYfPaOELYWV2y2B/iAvI+ocAg3Hte\n1f7Zi2TSGlYYcSMBAO86VfoKN+KF5EQQVmlALrq2cFTRbGk4oLRhQI1ou//f\n7TK2K8ycD2OVGV5F5GjIIUktnk/6xUkzVni3vkywuZzrcT65N1p8lMs8I6QW\nIMp3RJh92X99FlvHxKb4AD8Rs78rZzhScd9mnNIz8Rv4qwQv8iJQ3mt3cPsa\naCmDHbr8G10L0vx2CVNaEEtiX06qpns6p/q5A1SSE+FTg1EibT6w2LJL/pg0\nZOEuPFsciPrifU6HXz3u+sIN/x4dan64ebjG/XfINCric2sETYWYUUKAApZE\npF43+v9c5ygRxLKHJxEBleM0P/eqPsE9bghk1rfDJF1Il4pz24/B8Se/GBe/\nYI8hwDdZVzzfIh4Vk6lPtX9+60Dw5UbXKzaNQc6/h8HsRFSN/hOOf9EqmMNw\nkY9S\r\n=M40a\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIH+UQZuRrB9Ov7W6ilVBQm1mgT9pVsCoqbDgRR8iK0hIAiEA8v2TkfEEzJw78M+oXjw3JwPvh2K+DU/x/+VkzU7Gkbc="}]},"_npmUser":{"name":"relief.melone","email":"relief.melone@gmail.com"},"directories":{},"maintainers":[{"name":"relief.melone","email":"relief.melone@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/query-bouncer-mongoose-plugin_1.8.0_1606571069505_0.10114866905395026"},"_hasShrinkwrap":false},"1.8.1":{"name":"query-bouncer-mongoose-plugin","version":"1.8.1","description":"Mongoose Plugin for Query Bouncer","main":"./dist/index.js","scripts":{"start":"node ./dist/index.js","test":"mocha","coverage":"nyc mocha","build":"tsc --watch false --declaration","lint":"eslint --ignore-path .gitignore .","tsc":"tsc"},"repository":{"type":"git","url":"git+https://github.com/relief-melone/query-bouncer-mongoose-plugin.git"},"author":{"name":"Relief.Melone"},"license":"MIT","dependencies":{"axios":"^0.21.0","express":"^4.17.1","mongodb":"^3.5.0","mongoose":"^5.8.7"},"devDependencies":{"@sinonjs/referee-sinon":"^8.0.0","@types/chai":"latest","@types/express":"^4.17.2","@types/mocha":"latest","@types/mongodb":"^3.3.14","@types/mongoose":"^5.5.41","@types/moxios":"^0.4.9","@types/node":"latest","@types/sinon":"^9.0.9","@typescript-eslint/eslint-plugin":"latest","@typescript-eslint/parser":"latest","axios-mock-adapter":"^1.17.0","chai":"latest","chai-exclude":"^2.0.2","eslint":"latest","eslint-import-resolver-alias":"latest","eslint-plugin-import":"latest","mocha":"^7.1.1","mongodb-memory-server":"^6.5.0","nyc":"latest","sinon":"^8.1.1","typescript":"latest"},"gitHead":"c66dc5525e19cc85800bb443a3eaec0e698455b2","bugs":{"url":"https://github.com/relief-melone/query-bouncer-mongoose-plugin/issues"},"homepage":"https://github.com/relief-melone/query-bouncer-mongoose-plugin#readme","_id":"query-bouncer-mongoose-plugin@1.8.1","_nodeVersion":"14.13.1","_npmVersion":"6.14.9","dist":{"integrity":"sha512-Gy7DyTSaLgi3AHmlpOiE/Pv2X4zGYx4ktczeLBXWkGMesl1runtxAR9SQ7OfPR/Kn0FCuDTD8KUh+EdbzKlZ8Q==","shasum":"3b7b2191e0e1a00aad7151b204f71a327a22be19","tarball":"https://registry.npmjs.org/query-bouncer-mongoose-plugin/-/query-bouncer-mongoose-plugin-1.8.1.tgz","fileCount":150,"unpackedSize":217813,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.13\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJfw8UOCRA9TVsSAnZWagAAFX4QAIsdbMo30n/qkDAftG1y\nRQ5u/+tvJpY2TgIfvA9vSOBiiNhZoE0/hdo0TTpFD55WgeSobq+Yan7SD+EH\nTCzhiYv5ckbSKnaaApIemo59+eY1dMME6uWo+kGrHaBs8y6TWk5DPhWRU3CI\natzE4btlhIs7aoHBVslCJyRpt71Ms7UifwdFNSOt0cghLIbVYOy5/RoUeluY\nLu4gZzo6Oa/tlickab4A/DYI9yxsnss+krpXhYfLBEgmpQIZ3339FeF9bua+\nT4hj39tDjM+vJc0IvyN+t8D8W+XbizZP6Zn2tiHZc1IeWpeyD6PMdfKTg20t\namDoEWqbV72iUmMqgI2Vge3H2toC2q95BM8Qde6zQy8VWFWddnW3eii7aJAF\nXSukN+4IeUQ1eT8OH9oXNfDpQMeC4d0JGHMway+gMaPynWPdwa2kFcLV+2ke\niGLnuzH6OQO2gdp6JRsFuH36zej56TIl+a5AYlWkMBq5VvMnpSA4hGVEtxxu\nU3/Q2vjGEkU0NdOkqED0cH3uFpnS+ESiP7UPcRvmIOgozh5fUeA4RsNL5OY6\nzMm/GvCjOU9S4RW38mUq6sL1cRb1dAUchy1GkOdJkh2TZ+G/aHns6T/7HBg6\nOgud55J91OazyCs55pNySg+8JOxUMzLCaUYyd6Doed52mOX3aaVmmhI7xP2+\nxDlO\r\n=i7Go\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIQCl7w2lw4aVCR7TdnCJbVaB9z7I18dOhgKBmAvlKWNfMAIgPUiUYFNVtsxEuzjGXQLYmWZ6MBndIH8sMk33avlJQoM="}]},"_npmUser":{"name":"relief.melone","email":"relief.melone@gmail.com"},"directories":{},"maintainers":[{"name":"relief.melone","email":"relief.melone@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/query-bouncer-mongoose-plugin_1.8.1_1606665485844_0.5172236970707516"},"_hasShrinkwrap":false},"1.9.0":{"name":"query-bouncer-mongoose-plugin","version":"1.9.0","description":"Mongoose Plugin for Query Bouncer","main":"./dist/index.js","scripts":{"start":"node ./dist/index.js","test":"mocha","coverage":"nyc mocha","build":"tsc --watch false --declaration","lint":"eslint --ignore-path .gitignore .","tsc":"tsc"},"repository":{"type":"git","url":"git+https://github.com/relief-melone/query-bouncer-mongoose-plugin.git"},"author":{"name":"Relief.Melone"},"license":"MIT","dependencies":{"axios":"^0.21.0","express":"^4.17.1","mongodb":"^3.5.0","mongoose":"^5.8.7"},"devDependencies":{"@sinonjs/referee-sinon":"^8.0.0","@types/chai":"latest","@types/express":"^4.17.2","@types/mocha":"latest","@types/mongodb":"^3.3.14","@types/mongoose":"^5.5.41","@types/moxios":"^0.4.9","@types/node":"latest","@types/sinon":"^9.0.9","@typescript-eslint/eslint-plugin":"latest","@typescript-eslint/parser":"latest","axios-mock-adapter":"^1.17.0","chai":"latest","chai-exclude":"^2.0.2","eslint":"latest","eslint-import-resolver-alias":"latest","eslint-plugin-import":"latest","mocha":"^7.1.1","mongodb-memory-server":"^6.5.0","nyc":"latest","sinon":"^8.1.1","typescript":"latest"},"gitHead":"721fb3173d37d1d5246ae35f8ca34cac348ed2de","bugs":{"url":"https://github.com/relief-melone/query-bouncer-mongoose-plugin/issues"},"homepage":"https://github.com/relief-melone/query-bouncer-mongoose-plugin#readme","_id":"query-bouncer-mongoose-plugin@1.9.0","_nodeVersion":"14.13.1","_npmVersion":"6.14.9","dist":{"integrity":"sha512-RYMDyeizrywhH1qvRczqLKrjsJ5KmOBzajdTV1SUWlVC7zA6CsGx9qzP68CGoknktQioxHNLVg59W2PuuS49IA==","shasum":"dab00eb4759d61d88388c56d6de356e4f797980f","tarball":"https://registry.npmjs.org/query-bouncer-mongoose-plugin/-/query-bouncer-mongoose-plugin-1.9.0.tgz","fileCount":150,"unpackedSize":217702,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.13\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJfxBahCRA9TVsSAnZWagAAj9oQAJIII7apefODBEMkalnB\nFqz2NXHAMNTtPqWgl+QhRrZBmuY3pMZgz53knzS5Z78rDIKYxyRrL5CMLN5G\nsgv3tnxMRUhT+Fq1zVwbn5utsIf4KNkfkbM7jBZll3OjeqiRhZ6zrxzffZie\ncrJ+FTW+2Amkd0+/4Eec6wnweM90jM09nzxvwIN2GlbgVwZUoc0QKf8guZdY\n/kjnTnsHj5vRPktcKScDueHwtvIsgWOgbh1mhZVsjqW2TLLcJ37lxtabn/rE\nWPnuTvRd81VULw/EeXnPqabh3ua9WzJqCccQOmYEc7On9+lmtSM5LeNm3/e5\nOGWmfBJp5HyFXo1q2r8ZWIKxrvYI4bDct0GB+pLuGFuTzE50rmrXZ0PaQWch\nMyzGcJJXG1Mq88LFiH7ES5o4QrMJwshFoT2r8ZPW4n3f665yDCKCq8dQjmiR\nCDdH/nwRSRbpZRqr+2If6d/poCft1qgWZoX2P1oPzb/ep7x2cB2BD0R6Toau\nmMlNOLc2/ZrtITZrk5H/ntT/pjVGf6+VhoMmorq//TVt0JTilSWLZlXi+Wvg\nqcT3AjlUnQ1PWWOaQyljQ5xCrdbRCMgVARyLDJAyZI1/FBQtci+nC+4lhwDV\nAVV86H8yR8r3Qw3dRHRM4MNajtJAfh4JAP2hPzEaTYIaGQbHBkMOBTHeF5Of\ng/v0\r\n=bYHc\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEQCIA52SZyWVZyt0tbWPKJfmTXaQW17VTaDPFiSLGz9dnyaAiAOSNYtcrK0nQOsQ12/R3sC9Kpo/pAjmfO5U8d+qgBEug=="}]},"_npmUser":{"name":"relief.melone","email":"relief.melone@gmail.com"},"directories":{},"maintainers":[{"name":"relief.melone","email":"relief.melone@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/query-bouncer-mongoose-plugin_1.9.0_1606686369339_0.9606970274193742"},"_hasShrinkwrap":false},"1.9.1":{"name":"query-bouncer-mongoose-plugin","version":"1.9.1","description":"Mongoose Plugin for Query Bouncer","main":"./dist/index.js","scripts":{"start":"node ./dist/index.js","test":"mocha","coverage":"nyc mocha","build":"tsc --watch false --declaration","lint":"eslint --ignore-path .gitignore .","tsc":"tsc"},"repository":{"type":"git","url":"git+https://github.com/relief-melone/query-bouncer-mongoose-plugin.git"},"author":{"name":"Relief.Melone"},"license":"MIT","dependencies":{"axios":"^0.21.0","express":"^4.17.1","mongodb":"^3.5.0","mongoose":"^5.8.7"},"devDependencies":{"@sinonjs/referee-sinon":"^8.0.0","@types/chai":"latest","@types/express":"^4.17.2","@types/mocha":"latest","@types/mongodb":"^3.3.14","@types/mongoose":"^5.5.41","@types/moxios":"^0.4.9","@types/node":"latest","@types/sinon":"^9.0.9","@typescript-eslint/eslint-plugin":"latest","@typescript-eslint/parser":"latest","axios-mock-adapter":"^1.17.0","chai":"latest","chai-exclude":"^2.0.2","eslint":"latest","eslint-import-resolver-alias":"latest","eslint-plugin-import":"latest","mocha":"^7.1.1","mongodb-memory-server":"^6.5.0","nyc":"latest","sinon":"^8.1.1","typescript":"latest"},"gitHead":"9ec3081238cfa956216778cf99c351d6422be3c2","bugs":{"url":"https://github.com/relief-melone/query-bouncer-mongoose-plugin/issues"},"homepage":"https://github.com/relief-melone/query-bouncer-mongoose-plugin#readme","_id":"query-bouncer-mongoose-plugin@1.9.1","_nodeVersion":"14.13.1","_npmVersion":"6.14.9","dist":{"integrity":"sha512-PEGLQskJZo1OPjr797vVbZ47IPbAR98guh0k26t8CDcsu+dNXaBe7stTEW8xwqZzGy/Afl1EryFVMF9sQ7RQlA==","shasum":"cddfeb5327c84bcc10ead62b098d05ade721661b","tarball":"https://registry.npmjs.org/query-bouncer-mongoose-plugin/-/query-bouncer-mongoose-plugin-1.9.1.tgz","fileCount":150,"unpackedSize":217726,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.13\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJfxB3eCRA9TVsSAnZWagAAh2sP/RCU7UgaxkNpMpe6gVOv\nOTwqxqr4UkJ24uuwUTBz6Xfta/1ihGR2czYKFzrE1KiwijwZy5fAGakUl+So\n7C5tmYMaSv9AZjUQAYVOiobPqXSLivyjeXGgBHo6E3n29Pw0vBSiW7i1x+1j\ndY6CU5z0XSZIzoxf2vvUx6wAcwchTdn7HaO0aD7UeM0etoR517sBqb0orFXy\njS/9t6QARx0ntOE1mvISEfhVT+ZxUSobYxoQG4uF3UYjL4hTsY4JaPfaCMnr\nHc22OXB1sjMVIHyFcs03tAwZDJxbONLimj6O2puCmtox5Fdf8KDyObtqIky7\n6EY6pHuuHBVWT21PQgR7yglzwtxwYaARbCFXY2fUpzHCvGnc6Q2VSHANQ0kf\nLDOIt+VRAj1JTAe5VEZjqDE3aIhZ7QdPITUI9Y/rhlF/Iv9PjrwjG5vyzTsC\nOQQ0L9xZrvOiQgtmvpbkgt5zusKurBjcwAY1HB9YLhZWU0QGkEUuRJ5DlNqT\nVpZaYHcltIPyCN7zVtJh1cFm3L6KXeefT2ksp66glwrnZ1WPTLZVkUofxKd4\n3BbWUkCo9pi2OVtTuu2cjlIXboiZZ/j+O9Uxjq+5illnzgHcElyF3cztHhfB\nk0DGbXaHP+wx7Hl5KBgiFCE7XrOtvowd+QtJTnDF7r9G8uIVrVOKDbb7S4/0\nCAlO\r\n=5bO4\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIQCLQ2G3yZ9w3DnDq8jOxIifHxOSLUdLezU62HphRtg+agIgTxl7T/WNe7MM1GD/rFJCJjFUm70zK7OVv8IgKC5Ji6k="}]},"_npmUser":{"name":"relief.melone","email":"relief.melone@gmail.com"},"directories":{},"maintainers":[{"name":"relief.melone","email":"relief.melone@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/query-bouncer-mongoose-plugin_1.9.1_1606688221675_0.2351446928292662"},"_hasShrinkwrap":false},"2.0.0-0":{"name":"query-bouncer-mongoose-plugin","version":"2.0.0-0","description":"Mongoose Plugin for Query Bouncer","main":"./dist/index.js","scripts":{"start":"node ./dist/index.js","test":"mocha","coverage":"nyc npm run test","build":"rm -rf ./dist && ./node_modules/.bin/tsc --watch false -d","lint":"eslint --ignore-path .gitignore .","tsc":"tsc"},"repository":{"type":"git","url":"git+https://github.com/relief-melone/query-bouncer-mongoose-plugin.git"},"author":{"name":"Relief.Melone"},"license":"MIT","dependencies":{"axios":"^0.21.0","express":"^4.17.2","mongodb":"^3.5.0","mongoose":"^6.1.8"},"devDependencies":{"@sinonjs/referee-sinon":"^10.1.0","@types/chai":"latest","@types/express":"^4.17.13","@types/mocha":"^9.1.0","@types/moxios":"^0.4.9","@types/node":"latest","@types/sinon":"^9.0.9","@typescript-eslint/eslint-plugin":"latest","@typescript-eslint/parser":"latest","axios-mock-adapter":"^1.17.0","chai":"latest","chai-exclude":"^2.0.2","eslint":"latest","eslint-import-resolver-alias":"latest","eslint-plugin-import":"latest","mocha":"^9.2.0","mongodb-memory-server":"^6.5.0","nyc":"latest","sinon":"^8.1.1","typescript":"latest"},"gitHead":"f521e6baad369bf579e360d105b3f3d81826c979","readme":"# MongoBouncer - A Mongoose Plugin for Query Bouncer\n\nThe Mongoose Plugin for Query Bouncer (MongoBouncer) integrates with rm-authenticator, Query Bouncer and rm-session-populate. It's goal is to integrate the Role Based Access Control System you define in Query Bouncer easily in your Backend without having to worry about making the correct http requests and modify queries by yourself. The tasks of these components are\n\n1. **rm-authenticator:** Easy way to authenticate your user with just a Docker Container. Works with different OAuth providers like facebook, linkedin and google+. \n   - [GitHub](https://github.com/relief-melone/rm-authenticator)\n   - [Docker](https://hub.docker.com/repository/docker/reliefmelone/rm-authenticator)\n2. **rm-session-populator:** Middleware for Express. It will automatically communicate with the Authenticator and add a user object to your Express **req** with all the information you need\n   - [GitHub](https://github.com/relief-melone/rm-session-populator)\n   - [NPM](https://www.npmjs.com/package/rm-session-populator)\n3. **Query Bouncer:** Set up your Role Based Access System with a comfortable REST-API and use it to automatically modify queries and payloads based on your users permissions. \n   - [GitHub](https://github.com/relief-melone/query-bouncer)\n   - [Docker](https://hub.docker.com/r/reliefmelone/query-bouncer)\n4. **Query Bouncer Mongoose Plugin:** A Plugin that handles all the communication with the authorizer automatically so you can focus on writing your application.\n\nThis Overview illustrates a possible architecture for your application and the integration of those 4 components.\n\n![architecture](https://raw.githubusercontent.com/relief-melone/query-bouncer-mongoose-plugin/master/documentation/architectureOverview.png \"Architecture Overview\")\n\n## Instalation\n\nJust install with npm\n\n```sh\nnpm i --save query-bouncer-mongoose-plugin\n```\n\n## Usage\n\n### Prerequisites\n\nYou need a running instance of Query Bouncer to connect to. The Query Bouncer supplies the plugin with the correct queries accordingly to the users permissions. you can see how to set it up [here](https://github.com/relief-melone/query-bouncer)\n\n### How it Works\n\nQuery Bouncer will be used to easily set up your roles, permissions and roleAssignments for your Application. It supplies endpoints to send your query and payload to. The Query Bouncer will then validate the information based on your users permissions and will e.g. send back an adjusted query based on the users permissions. So what does that mean. Lets assume we have a collection called blogposts. Each BlogPost has a Title, Description and a Category. The user only has access to BlogPosts of the Category \"Cars\". So when a request to the Query Bouncer is made with the query to get all BlogPosts The Query \n\n```js\n{}\n```\nwill be returned as\n\n```js\n{ \n  $or: [ \n    {Category: \"Cars\"} \n  ] \n}\n```\n\nIn order to not having to utilize the API of rm-authorizer directly mongo-bouncer will handle all that for you. The following paragraphs will show you how to use it.\n\n\n### Initialize\n\nAs this is a mongoose plugin simply initialize the plugin like this. You only need the endpoint of your authorizer. That's it. Now there are two ways of handling your config\n\n#### Basic\n```ts\nimport mongoBouncer from \"query-bouncer-mongoose-plugin\"\n\nmongoose.plugin(mongoBouncer, {\n  baseUrl: \"https://your-authorizer.com\"\n});\n```\n\n#### Advanced\n\nMongoose will only keep the object we set in the basic setup stored and the complete config will be generated automatically on the fly. If you want to have more control and to be able to switch out components like axios we recommend you instantiate your config like this. This is also necessary if you want to use the [MockAdapter](#testing)\n\n```ts\nimport mongoBouncer, { QbConfig } from \"query-bouncer-mongoose-plugin\"\n\nconst config = new QbConfig({\n  baseUrl: \"https://your-authorizer.com\"\n})\n\nmongoose.plugin(mongoBouncer, config);\n\n```\n\n\nNow with the nature of mongoose plugins this has to be made before any schemas are initialized (which most of time will be done already). So either wrap your schemas so you make sure that the plugin gets initialized first or set the plugin for each schema you want to use (**recommended**)\n\n```ts\nconst blogPostSchema = new mongoose.Schema({\n  Title: \"My new Blog Post\",\n  // ...\n});\n\nblogPostSchema.plugin(mongoBouncer, {\n  baseUrl: \"https://your-authorizer.com\"\n});\n```\n\n#### Additional Options\n**baseUrl:** The URL the MongoBouncer that you want to connect to is hosted\n**apiVersion:** The Version of the API you want to use. Defaults to v1\n**axios:** You can force the Plugin to use another Axios Instance. This is mainly for testing purposes and not recommended\n**cookieName:** By default the Authenticator is set up to give you a cookie named connect.sid. If however you changed that you can also adjust the cookieName here\n\n### Useage\n\nMongoBouncer will run all the validation before your operations are being executed. As this middleware is currently not available in mongoose plugins for all methods, we currentyl support the following\n\n- create **(See Important Information about create)**\n- find\n- findOne\n- findOneAndDelete\n- findOneAndRemove\n- findOneAndUpdate\n- findById\n- findByIdAndDelete\n- findByIdAndRemove\n- findByIdAndUpdate\n- insertMany\n- remove \n- update\n- updateOne\n- updateMany\n- deleteOne\n- deleteMany\n\nThis is an example on how to enalbe MongoBouncer on your model. req refers to the express Request here. The MongoBouncer property needs to be added to the Options Object of your method. Let's take a look at some of those methods\n\nFirst let's set up a model.\n```ts\nconst BlogPostSchema = new Schema({\n  Title: { type: String, required: true } ,\n  Description: { type: String },\n  Category: { type: String, required: true }\n});\nconst BlogPost = mongoose.model('blogpost', BlogPostSchema);\n```\n#### Create\nNow to create a Document with respect to the permissions you just add the MongoBouncer to the options. \n\nAs the Options Object in mongoose is only available if the Document is passed in array please make sure you that even of you just add a single Document you use it in an Array. If you use a single Object the Options Object will be empty internally and as a result **Permissions will not be checked!!!**\n\nAs we stated earlier our authorizer has been set up to\nallow the user to create BlogPosts only if the category is \"Cars\". So while this will work just fine.\n```ts\nconst post = await BlogPost.create([{\n  Title: \"MyBlogPost\",\n  Category: \"Cars\",\n  Description: \"Some cool information about my favourite car\"\n}], { \n  MongoBouncer : {\n    Request: req \n  }\n});\n```\nthis\n```ts\nconst post = await BlogPost.create({\n  Title: \"MyBlogPost\",\n  Category: \"Food\",\n  Description: \"Some cool information about my favourite car\"\n}, { \n  MongoBouncer : {\n    Request: req \n  }\n});\n```\nwill throw an Error as the user is not allowed to create Blog Posts in that Category\n\n#### Find\n\nLet's assume we will now try to find that document again. Again as our fictive setup is that our user will only receive BlogPosts if the Category\nCars in this case\n```ts\nBlogPost.find({ Title: \"MyBlogPost\" }, null, {\n  MongoBouncer: {\n    Request: req\n  }\n});\n```\nwe will be returned an array with the Document we added in the Create section\n\n\n#### Update\nIf we now want to update the document we created we do it just the same way. A working update call would look like this\n```ts\nBlogPost.updateOne(\n  { Title: \"MyBlogPost\", Category: \"Cars\" }, \n  { Title: \"A changed Title\"}, \n  {\n    MongoBouncer: {\n      Request: req\n    }\n  }\n);\n```\nInternally both the Payload and the QueryRestrictions will be checked. So if we use any other Category than Cars nothing will be updated. However in this case no error will be returned but the returned Object by mongoose will just state that nothing matched our Query and nothing was updated. But if we try this e.g.\n```ts\nBlogPost.updateOne(\n  { Title: \"MyBlogPost\", Category: \"Cars\" }, \n  { Title: \"A changed Title\", Category: \"Food\" }, \n  {\n    MongoBouncer: {\n      Request: req\n    }\n  }\n);\n```\nan error will be thrown as a Document will be returned but we are not allowed to invoke the changes we are trying to make.\n\n### More Options\n\n#### Override Disable\nNow if you just add a Request MongoBouncer will run. To stop that from happening later down the road, even if you have already injected the Request into the options you can still disable MongoBouncer by setting the *Disabled* field to true. So a request like this will not run MongoBouncer\n\n```ts\nimport { OperationOptionsInput } from \"query-bouncer-mongoose-plugin\"\n\nconst myService = (opts:OperationOptionsInput) => {\n  // opts is already filled with MongoBouncer: { Request }\n\n  if(someConditionApplies()){\n    bouncerOpts.MongoBouncer.Disable = true;\n  }\n\n  BlogPost.updateOne(\n    { Title: \"MyBlogPost\", Category: \"Cars\" }, \n    { Title: \"A changed Title\", Category: \"Food\" }, \n    opts\n  );\n}\n```\n\n### Testing\n\nWhen you test you don't want to have a query bouncer running, so you could manually switch out the axios instance with a mock. However we provide our own MockAdapter for the QueryBouncer. If you want to mock a schmema with an existing config please make sure you instantiated this config as described under [advanced](#advanced)\n\n\n**my-model.ts**\n```ts\nimport { Model, Schema } from 'mongoose'\nimport MongoBouncer, { QbConfig } from 'query-bouncer-mongoose-plugin'\n\nconst schema = new Schema({\n  Title: String,\n  Category: String\n});\n// It is important that you instantiate as a new class or the tests will not work\n\nconst config = new QbConfig({\n  baseUrl: 'http://some-where.com/'\n})\nschema.plugin(MongoBouncer, config);\n\nconst model = Model('test', schema)\nexport default model;\nexport { config };\n```\n\n\n**my-model.spec.ts**\n```ts\nimport { MockAdapter, QbConfig,  } from 'query-bouncer-mongoose-plugin';\nimport mymodel, { config } from './my-model.ts';\n\nit('should do something', async () => {\n  // Prepare\n  const qBouncer = new MockAdapter(config);\n  qBouncer.mock({\n    collection: mymodel.collection.collectionName,\n    right: 'read',\n    response: {\n      query: { $or: { Category: 'Food' } }\n    }\n  });\n\n  // Execute\n  /// Your Test Code\n})\n```\n\n","readmeFilename":"README.md","bugs":{"url":"https://github.com/relief-melone/query-bouncer-mongoose-plugin/issues"},"homepage":"https://github.com/relief-melone/query-bouncer-mongoose-plugin#readme","_id":"query-bouncer-mongoose-plugin@2.0.0-0","_nodeVersion":"14.18.3","_npmVersion":"6.14.15","dist":{"integrity":"sha512-F3S/NF7cJduiM/nzGhjlyC71YQO/NhifrEjbRziL7lofRV2apDWuanPV/jMr8LOMVrwEPL5ZDtc6r7quWBIXSw==","shasum":"3ef5e333daea7f6bce472e4390222a56620b1d7e","tarball":"https://registry.npmjs.org/query-bouncer-mongoose-plugin/-/query-bouncer-mongoose-plugin-2.0.0-0.tgz","fileCount":3,"unpackedSize":12738,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.13\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJh8P7kCRA9TVsSAnZWagAAOiwP/2NUEweWbkeESl46/npS\nL3dKZfzNOCKdvkAnJ2UaCLxcJvh2kZs12apzbryOc/+Z6cRFbXwTELffsYxK\nnWvqi/IlSJzxvpLLIvq5hj2bjm+6UFNqTTPgUYvH22h/lDBCD4nVo3z8eild\ny063j8eTDJnVNcEnYm21y827iV3qBTGU9MV4o1S1liLtXYe1TB6vP1YL4HCo\nbPhf1gzE9U9jwrlEyKd7XuX3KcO0eXaw0A1wGdmMulomNUsjfPrUaEPjqcYU\nTykJP54HKGXhO3fkSjnawzrab94LMWqLuNKzRA7PiPGvCfFii1v/KpgWOpHo\n5YfFM6V1yorgHZP3RKBe06AuyK+0jHyV2XqTLT6ZUU5pK6Tx4pfTwva4ljb8\n776TXK5MqmpV+qcqp33RG5hesfVZcIKFL7OO2xfNAnqLat0O9HL7PLsEm7Qa\nmCDBLXpnS6Ts0I0S87rZSqH/PRKc1dymMp9tPurkxo3kFwvS0dzJ72rC5a1G\n0sBdzM6XKGru2VZVTEaHHMM3ctnEuGfHrQpQoq+3H8EKSl77gWoejLsaPTLb\nF27ChsVWPzKJ7TFKyse6ZNdWySuRy4tX8Q4fKcJVMzogmkX6d5/2uHG0b3Hc\nu/8VjAPq7cMZUXl/CrQyAEEsxgRKpUluJlQtEOvn2R3mYGTS0KsbYmK5DSEr\nihwj\r\n=nFei\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIBsDJrTA2fMXKLrr6sWZy99SGp+aJsApevQ5yQucxqUeAiEA2jkbLWQz8YE6wmyFQfPN6CpHxFyFOtjXAzIlLajUbFQ="}]},"_npmUser":{"name":"relief.melone","email":"relief.melone@gmail.com"},"directories":{},"maintainers":[{"name":"relief.melone","email":"relief.melone@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/query-bouncer-mongoose-plugin_2.0.0-0_1643183844220_0.9971487569370454"},"_hasShrinkwrap":false},"2.0.0-1":{"name":"query-bouncer-mongoose-plugin","version":"2.0.0-1","description":"Mongoose Plugin for Query Bouncer","main":"./dist/index.js","scripts":{"start":"node ./dist/index.js","test":"mocha","coverage":"nyc npm run test","build":"rm -rf ./dist && ./node_modules/.bin/tsc --watch false -d","lint":"eslint --ignore-path .gitignore .","tsc":"tsc"},"repository":{"type":"git","url":"git+https://github.com/relief-melone/query-bouncer-mongoose-plugin.git"},"author":{"name":"Relief.Melone"},"license":"MIT","dependencies":{"axios":"^0.21.0","express":"^4.17.2","mongodb":"^3.5.0","mongoose":"^6.1.8"},"devDependencies":{"@sinonjs/referee-sinon":"^10.1.0","@types/chai":"latest","@types/express":"^4.17.13","@types/mocha":"^9.1.0","@types/moxios":"^0.4.9","@types/node":"latest","@types/sinon":"^9.0.9","@typescript-eslint/eslint-plugin":"latest","@typescript-eslint/parser":"latest","axios-mock-adapter":"^1.17.0","chai":"latest","chai-exclude":"^2.0.2","eslint":"latest","eslint-import-resolver-alias":"latest","eslint-plugin-import":"latest","mocha":"^9.2.0","mongodb-memory-server":"^6.5.0","nyc":"latest","sinon":"^8.1.1","typescript":"latest"},"gitHead":"3bd8d99d8fc3ce6e340f2da1b7339710644e9892","readme":"# MongoBouncer - A Mongoose Plugin for Query Bouncer\n\nThe Mongoose Plugin for Query Bouncer (MongoBouncer) integrates with rm-authenticator, Query Bouncer and rm-session-populate. It's goal is to integrate the Role Based Access Control System you define in Query Bouncer easily in your Backend without having to worry about making the correct http requests and modify queries by yourself. The tasks of these components are\n\n1. **rm-authenticator:** Easy way to authenticate your user with just a Docker Container. Works with different OAuth providers like facebook, linkedin and google+. \n   - [GitHub](https://github.com/relief-melone/rm-authenticator)\n   - [Docker](https://hub.docker.com/repository/docker/reliefmelone/rm-authenticator)\n2. **rm-session-populator:** Middleware for Express. It will automatically communicate with the Authenticator and add a user object to your Express **req** with all the information you need\n   - [GitHub](https://github.com/relief-melone/rm-session-populator)\n   - [NPM](https://www.npmjs.com/package/rm-session-populator)\n3. **Query Bouncer:** Set up your Role Based Access System with a comfortable REST-API and use it to automatically modify queries and payloads based on your users permissions. \n   - [GitHub](https://github.com/relief-melone/query-bouncer)\n   - [Docker](https://hub.docker.com/r/reliefmelone/query-bouncer)\n4. **Query Bouncer Mongoose Plugin:** A Plugin that handles all the communication with the authorizer automatically so you can focus on writing your application.\n\nThis Overview illustrates a possible architecture for your application and the integration of those 4 components.\n\n![architecture](https://raw.githubusercontent.com/relief-melone/query-bouncer-mongoose-plugin/master/documentation/architectureOverview.png \"Architecture Overview\")\n\n## Instalation\n\nJust install with npm\n\n```sh\nnpm i --save query-bouncer-mongoose-plugin\n```\n\n## Usage\n\n### Prerequisites\n\nYou need a running instance of Query Bouncer to connect to. The Query Bouncer supplies the plugin with the correct queries accordingly to the users permissions. you can see how to set it up [here](https://github.com/relief-melone/query-bouncer)\n\n### How it Works\n\nQuery Bouncer will be used to easily set up your roles, permissions and roleAssignments for your Application. It supplies endpoints to send your query and payload to. The Query Bouncer will then validate the information based on your users permissions and will e.g. send back an adjusted query based on the users permissions. So what does that mean. Lets assume we have a collection called blogposts. Each BlogPost has a Title, Description and a Category. The user only has access to BlogPosts of the Category \"Cars\". So when a request to the Query Bouncer is made with the query to get all BlogPosts The Query \n\n```js\n{}\n```\nwill be returned as\n\n```js\n{ \n  $or: [ \n    {Category: \"Cars\"} \n  ] \n}\n```\n\nIn order to not having to utilize the API of rm-authorizer directly mongo-bouncer will handle all that for you. The following paragraphs will show you how to use it.\n\n\n### Initialize\n\nAs this is a mongoose plugin simply initialize the plugin like this. You only need the endpoint of your authorizer. That's it. Now there are two ways of handling your config\n\n#### Basic\n```ts\nimport mongoBouncer from \"query-bouncer-mongoose-plugin\"\n\nmongoose.plugin(mongoBouncer, {\n  baseUrl: \"https://your-authorizer.com\"\n});\n```\n\n#### Advanced\n\nMongoose will only keep the object we set in the basic setup stored and the complete config will be generated automatically on the fly. If you want to have more control and to be able to switch out components like axios we recommend you instantiate your config like this. This is also necessary if you want to use the [MockAdapter](#testing)\n\n```ts\nimport mongoBouncer, { QbConfig } from \"query-bouncer-mongoose-plugin\"\n\nconst config = new QbConfig({\n  baseUrl: \"https://your-authorizer.com\"\n})\n\nmongoose.plugin(mongoBouncer, config);\n\n```\n\n\nNow with the nature of mongoose plugins this has to be made before any schemas are initialized (which most of time will be done already). So either wrap your schemas so you make sure that the plugin gets initialized first or set the plugin for each schema you want to use (**recommended**)\n\n```ts\nconst blogPostSchema = new mongoose.Schema({\n  Title: \"My new Blog Post\",\n  // ...\n});\n\nblogPostSchema.plugin(mongoBouncer, {\n  baseUrl: \"https://your-authorizer.com\"\n});\n```\n\n#### Additional Options\n**baseUrl:** The URL the MongoBouncer that you want to connect to is hosted\n**apiVersion:** The Version of the API you want to use. Defaults to v1\n**axios:** You can force the Plugin to use another Axios Instance. This is mainly for testing purposes and not recommended\n**cookieName:** By default the Authenticator is set up to give you a cookie named connect.sid. If however you changed that you can also adjust the cookieName here\n\n### Useage\n\nMongoBouncer will run all the validation before your operations are being executed. As this middleware is currently not available in mongoose plugins for all methods, we currentyl support the following\n\n- create **(See Important Information about create)**\n- find\n- findOne\n- findOneAndDelete\n- findOneAndRemove\n- findOneAndUpdate\n- findById\n- findByIdAndDelete\n- findByIdAndRemove\n- findByIdAndUpdate\n- insertMany\n- remove \n- update\n- updateOne\n- updateMany\n- deleteOne\n- deleteMany\n\nThis is an example on how to enalbe MongoBouncer on your model. req refers to the express Request here. The MongoBouncer property needs to be added to the Options Object of your method. Let's take a look at some of those methods\n\nFirst let's set up a model.\n```ts\nconst BlogPostSchema = new Schema({\n  Title: { type: String, required: true } ,\n  Description: { type: String },\n  Category: { type: String, required: true }\n});\nconst BlogPost = mongoose.model('blogpost', BlogPostSchema);\n```\n#### Create\nNow to create a Document with respect to the permissions you just add the MongoBouncer to the options. \n\nAs the Options Object in mongoose is only available if the Document is passed in array please make sure you that even of you just add a single Document you use it in an Array. If you use a single Object the Options Object will be empty internally and as a result **Permissions will not be checked!!!**\n\nAs we stated earlier our authorizer has been set up to\nallow the user to create BlogPosts only if the category is \"Cars\". So while this will work just fine.\n```ts\nconst post = await BlogPost.create([{\n  Title: \"MyBlogPost\",\n  Category: \"Cars\",\n  Description: \"Some cool information about my favourite car\"\n}], { \n  MongoBouncer : {\n    Request: req \n  }\n});\n```\nthis\n```ts\nconst post = await BlogPost.create({\n  Title: \"MyBlogPost\",\n  Category: \"Food\",\n  Description: \"Some cool information about my favourite car\"\n}, { \n  MongoBouncer : {\n    Request: req \n  }\n});\n```\nwill throw an Error as the user is not allowed to create Blog Posts in that Category\n\n#### Find\n\nLet's assume we will now try to find that document again. Again as our fictive setup is that our user will only receive BlogPosts if the Category\nCars in this case\n```ts\nBlogPost.find({ Title: \"MyBlogPost\" }, null, {\n  MongoBouncer: {\n    Request: req\n  }\n});\n```\nwe will be returned an array with the Document we added in the Create section\n\n\n#### Update\nIf we now want to update the document we created we do it just the same way. A working update call would look like this\n```ts\nBlogPost.updateOne(\n  { Title: \"MyBlogPost\", Category: \"Cars\" }, \n  { Title: \"A changed Title\"}, \n  {\n    MongoBouncer: {\n      Request: req\n    }\n  }\n);\n```\nInternally both the Payload and the QueryRestrictions will be checked. So if we use any other Category than Cars nothing will be updated. However in this case no error will be returned but the returned Object by mongoose will just state that nothing matched our Query and nothing was updated. But if we try this e.g.\n```ts\nBlogPost.updateOne(\n  { Title: \"MyBlogPost\", Category: \"Cars\" }, \n  { Title: \"A changed Title\", Category: \"Food\" }, \n  {\n    MongoBouncer: {\n      Request: req\n    }\n  }\n);\n```\nan error will be thrown as a Document will be returned but we are not allowed to invoke the changes we are trying to make.\n\n### More Options\n\n#### Override Disable\nNow if you just add a Request MongoBouncer will run. To stop that from happening later down the road, even if you have already injected the Request into the options you can still disable MongoBouncer by setting the *Disabled* field to true. So a request like this will not run MongoBouncer\n\n```ts\nimport { OperationOptionsInput } from \"query-bouncer-mongoose-plugin\"\n\nconst myService = (opts:OperationOptionsInput) => {\n  // opts is already filled with MongoBouncer: { Request }\n\n  if(someConditionApplies()){\n    bouncerOpts.MongoBouncer.Disable = true;\n  }\n\n  BlogPost.updateOne(\n    { Title: \"MyBlogPost\", Category: \"Cars\" }, \n    { Title: \"A changed Title\", Category: \"Food\" }, \n    opts\n  );\n}\n```\n\n### Testing\n\nWhen you test you don't want to have a query bouncer running, so you could manually switch out the axios instance with a mock. However we provide our own MockAdapter for the QueryBouncer. If you want to mock a schmema with an existing config please make sure you instantiated this config as described under [advanced](#advanced)\n\n\n**my-model.ts**\n```ts\nimport { Model, Schema } from 'mongoose'\nimport MongoBouncer, { QbConfig } from 'query-bouncer-mongoose-plugin'\n\nconst schema = new Schema({\n  Title: String,\n  Category: String\n});\n// It is important that you instantiate as a new class or the tests will not work\n\nconst config = new QbConfig({\n  baseUrl: 'http://some-where.com/'\n})\nschema.plugin(MongoBouncer, config);\n\nconst model = Model('test', schema)\nexport default model;\nexport { config };\n```\n\n\n**my-model.spec.ts**\n```ts\nimport { MockAdapter, QbConfig,  } from 'query-bouncer-mongoose-plugin';\nimport mymodel, { config } from './my-model.ts';\n\nit('should do something', async () => {\n  // Prepare\n  const qBouncer = new MockAdapter(config);\n  qBouncer.mock({\n    collection: mymodel.collection.collectionName,\n    right: 'read',\n    response: {\n      query: { $or: { Category: 'Food' } }\n    }\n  });\n\n  // Execute\n  /// Your Test Code\n})\n```\n\n","readmeFilename":"README.md","bugs":{"url":"https://github.com/relief-melone/query-bouncer-mongoose-plugin/issues"},"homepage":"https://github.com/relief-melone/query-bouncer-mongoose-plugin#readme","_id":"query-bouncer-mongoose-plugin@2.0.0-1","_nodeVersion":"14.18.3","_npmVersion":"6.14.15","dist":{"integrity":"sha512-5MHk2b8V40sKdn+8J6Rt2KuVR8K8TgzfLC+/aNJmz+mP1CKEBZlnOeSXsqTzqNCXK3s51B9KkidPl2t5RWxhJw==","shasum":"fccafc8081c9f8e5c021c31a8022cf70dd8d9806","tarball":"https://registry.npmjs.org/query-bouncer-mongoose-plugin/-/query-bouncer-mongoose-plugin-2.0.0-1.tgz","fileCount":3,"unpackedSize":12738,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.13\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJh8SJxCRA9TVsSAnZWagAAyKcP/1a2/ZM8dO01LyXnUFiH\nLM5a9UoUT3aMNc3MHkIoxq/AKNBnTolhSFus9GFPR3xk07hhYzy5WetsfMrP\nieKiVTWGgt4O9sV9KBUuxLJmGYwqCynmxK/sx7+HhPrHw5hBKvmkWFUC2T5d\nJOXmP03cUlIVFdtbA/0k5xB2ze0VblziaU2oH/59MmJugg5Mvd3YWnhgO4tw\nGGnIyEMAlsBwDo7mNg4V7j7pADMPkIMYVMAHhRNveT96aseVxuuz/6BsjKzX\nw0DlOGak17LnM79xBY+zu11bYb52nbXAPsA1BHas0bltSYhMguqMIaGz2t1y\noJ+bRUnlHj0vZj2ZR04pYiQZ2xvd0iHfG6C5Bpuf+WHCTdSV9tsk8ATwZ3Zu\nWOgMkf0tnvxfd9WwTl1SlXo8lVljc+O2OgFMJWEb1tK9tdA9t2X6shRlUONF\ntIJSfuxEb4C4qTinhWRczfWfCIC3975bs9khyLD4jN4Vvk2Eptm10yMTBKKo\nErrZ9Xqk5A+/FcmGKHRM3HABQohoV5zkjqqERnkjgcWIYCz/uxWMNfkQz9Or\nQTtTX8uCcwTJuwJJxrN5pWmhyVpCn/LWJ9furOz6KXBh2TlLFBQV659ToPzY\nnYZrSMB44Z9MH1IGd6nGXZqT016XFctFDsWtlmlvbb9/mTvi4+3ew8OGfvg2\nvYdm\r\n=0hbl\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEYCIQDJBljIjDX8anT9CV7e65rLbBLcXHz2WdrJybpwWqEmLAIhAOMtTwWhyqPVyztnGLUoXsp/cSVkaXjEPCxFbVfq4Fx9"}]},"_npmUser":{"name":"relief.melone","email":"relief.melone@gmail.com"},"directories":{},"maintainers":[{"name":"relief.melone","email":"relief.melone@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/query-bouncer-mongoose-plugin_2.0.0-1_1643192945747_0.9496877025618347"},"_hasShrinkwrap":false},"2.0.0-2":{"name":"query-bouncer-mongoose-plugin","version":"2.0.0-2","description":"Mongoose Plugin for Query Bouncer","main":"./dist/index.js","scripts":{"start":"node ./dist/index.js","test":"mocha","coverage":"nyc npm run test","build":"rm -rf ./dist && ./node_modules/.bin/tsc --watch false -d","lint":"eslint --ignore-path .gitignore .","tsc":"tsc"},"repository":{"type":"git","url":"git+https://github.com/relief-melone/query-bouncer-mongoose-plugin.git"},"author":{"name":"Relief.Melone"},"license":"MIT","dependencies":{"axios":"^0.21.0","express":"^4.17.2","mongodb":"^3.5.0","mongoose":"^6.1.8"},"devDependencies":{"@sinonjs/referee-sinon":"^10.1.0","@types/chai":"latest","@types/express":"^4.17.13","@types/mocha":"^9.1.0","@types/moxios":"^0.4.9","@types/node":"latest","@types/sinon":"^9.0.9","@typescript-eslint/eslint-plugin":"latest","@typescript-eslint/parser":"latest","axios-mock-adapter":"^1.17.0","chai":"latest","chai-exclude":"^2.0.2","eslint":"latest","eslint-import-resolver-alias":"latest","eslint-plugin-import":"latest","mocha":"^9.2.0","mongodb-memory-server":"^6.5.0","nyc":"latest","sinon":"^8.1.1","typescript":"latest"},"gitHead":"080dfcffd83d541e51fc96e87ed39fe965ebb9c0","bugs":{"url":"https://github.com/relief-melone/query-bouncer-mongoose-plugin/issues"},"homepage":"https://github.com/relief-melone/query-bouncer-mongoose-plugin#readme","_id":"query-bouncer-mongoose-plugin@2.0.0-2","_nodeVersion":"14.18.3","_npmVersion":"6.14.15","dist":{"integrity":"sha512-tNYX/IkZeOu5CHEh21uWkiz8N8sm9gfWt0qRD2evqoPqLYJ1LDDAK0CIkcSZDNC8RBEEOkNQRiu64FBRvSdI4A==","shasum":"bfbcfbb9a85ac0ba23fa89143b7343b3e3e1faae","tarball":"https://registry.npmjs.org/query-bouncer-mongoose-plugin/-/query-bouncer-mongoose-plugin-2.0.0-2.tgz","fileCount":3,"unpackedSize":12738,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.13\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJh8SN+CRA9TVsSAnZWagAAWRcP/20vE+/fW8BQYqPvFEWH\nIOTESGP5i7PVNkY8ocU2JAtlz0RrL9VfpAkRCeUjiMugxvsfwXoOHLXQGQLt\n61prRQBDYN3L7W7YLSt5Os7OHWju1fuCt3b0T4GQ/QZPY/LX4OiCQ2666wWr\nivEpPcFFckQlnqmDwXKYPCl1FL/MiTcWSd2zYPy++HEi1d44xUtY51lpVvEL\nKQGwrOL3aR7q1Vu7K3ZicsVy/xwdMI1Sl7+fyMlg95zdyqI/61WyE7Ay7RbQ\ni+bHn30afsCxHz6MwLeVxGwkWLLMKgFxP0Iq0pjue0EoanlxO9zopSWTbjnh\n8+ujK8L2YI0kdI0qakfuZUs9cBSYpyK529tVZgVzsZ6LUeHAEHlpLgghNmuV\nCQzXdpM9Jf7MAAJhq3LMAwzHVzl2yaoj892UQFSET9QdERndBie7nL4KGxvk\nhAEPY/BYkm7LhrUNIhqYvxfNTSxP71ZCqX0435q1mltASWNt4nOxwVawu3Ao\n6jKpFpdk9Q1ihliMK0zfpsMggs5to9YMq4klKmx3h5TpTQAhdRD+ecN7YtQw\nP7lU+0Q1NmDiuIe8dj+xOQqY7tw0EaBvdjgGweSxgf49t4B3gmt1laUnN/7k\nRfVoudVqUNRer6ygqWtdowX9HOfrIFfNlZzIOc56QW1DF3TjabFN5rYGCllz\nsYO5\r\n=q7Nf\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIQCXKDsum2kKgkTh6h8i02j6f8WQTnBUI3PYrfZVvSu3QwIgfzr+LTJ93zKnmwuBx0YvWLeD2/V/QTMWLdNYPG4fMv8="}]},"_npmUser":{"name":"relief.melone","email":"relief.melone@gmail.com"},"directories":{},"maintainers":[{"name":"relief.melone","email":"relief.melone@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/query-bouncer-mongoose-plugin_2.0.0-2_1643193214689_0.4270416520705367"},"_hasShrinkwrap":false},"2.0.1-0":{"name":"query-bouncer-mongoose-plugin","version":"2.0.1-0","description":"Mongoose Plugin for Query Bouncer","main":"./dist/index.js","scripts":{"start":"node ./dist/index.js","test":"mocha","coverage":"nyc npm run test","build":"rm -rf ./dist && ./node_modules/.bin/tsc --watch false -d","lint":"eslint --ignore-path .gitignore .","tsc":"tsc"},"repository":{"type":"git","url":"git+https://github.com/relief-melone/query-bouncer-mongoose-plugin.git"},"author":{"name":"Relief.Melone"},"license":"MIT","dependencies":{"axios":"^0.21.0","express":"^4.17.2","mongodb":"^3.5.0","mongoose":"^6.1.8"},"devDependencies":{"@sinonjs/referee-sinon":"^10.1.0","@types/chai":"latest","@types/express":"^4.17.13","@types/mocha":"^9.1.0","@types/moxios":"^0.4.9","@types/node":"latest","@types/sinon":"^9.0.9","@typescript-eslint/eslint-plugin":"latest","@typescript-eslint/parser":"latest","axios-mock-adapter":"^1.17.0","chai":"latest","chai-exclude":"^2.0.2","eslint":"latest","eslint-import-resolver-alias":"latest","eslint-plugin-import":"latest","mocha":"^9.2.0","mongodb-memory-server":"^6.5.0","nyc":"latest","sinon":"^8.1.1","typescript":"latest"},"gitHead":"ab3d037bd417c5fc75dbec15c286842c06fdc0f8","readme":"# MongoBouncer - A Mongoose Plugin for Query Bouncer\n\nThe Mongoose Plugin for Query Bouncer (MongoBouncer) integrates with rm-authenticator, Query Bouncer and rm-session-populate. It's goal is to integrate the Role Based Access Control System you define in Query Bouncer easily in your Backend without having to worry about making the correct http requests and modify queries by yourself. The tasks of these components are\n\n1. **rm-authenticator:** Easy way to authenticate your user with just a Docker Container. Works with different OAuth providers like facebook, linkedin and google+. \n   - [GitHub](https://github.com/relief-melone/rm-authenticator)\n   - [Docker](https://hub.docker.com/repository/docker/reliefmelone/rm-authenticator)\n2. **rm-session-populator:** Middleware for Express. It will automatically communicate with the Authenticator and add a user object to your Express **req** with all the information you need\n   - [GitHub](https://github.com/relief-melone/rm-session-populator)\n   - [NPM](https://www.npmjs.com/package/rm-session-populator)\n3. **Query Bouncer:** Set up your Role Based Access System with a comfortable REST-API and use it to automatically modify queries and payloads based on your users permissions. \n   - [GitHub](https://github.com/relief-melone/query-bouncer)\n   - [Docker](https://hub.docker.com/r/reliefmelone/query-bouncer)\n4. **Query Bouncer Mongoose Plugin:** A Plugin that handles all the communication with the authorizer automatically so you can focus on writing your application.\n\nThis Overview illustrates a possible architecture for your application and the integration of those 4 components.\n\n![architecture](https://raw.githubusercontent.com/relief-melone/query-bouncer-mongoose-plugin/master/documentation/architectureOverview.png \"Architecture Overview\")\n\n## Instalation\n\nJust install with npm\n\n```sh\nnpm i --save query-bouncer-mongoose-plugin\n```\n\n## Usage\n\n### Prerequisites\n\nYou need a running instance of Query Bouncer to connect to. The Query Bouncer supplies the plugin with the correct queries accordingly to the users permissions. you can see how to set it up [here](https://github.com/relief-melone/query-bouncer)\n\n### How it Works\n\nQuery Bouncer will be used to easily set up your roles, permissions and roleAssignments for your Application. It supplies endpoints to send your query and payload to. The Query Bouncer will then validate the information based on your users permissions and will e.g. send back an adjusted query based on the users permissions. So what does that mean. Lets assume we have a collection called blogposts. Each BlogPost has a Title, Description and a Category. The user only has access to BlogPosts of the Category \"Cars\". So when a request to the Query Bouncer is made with the query to get all BlogPosts The Query \n\n```js\n{}\n```\nwill be returned as\n\n```js\n{ \n  $or: [ \n    {Category: \"Cars\"} \n  ] \n}\n```\n\nIn order to not having to utilize the API of rm-authorizer directly mongo-bouncer will handle all that for you. The following paragraphs will show you how to use it.\n\n\n### Initialize\n\nAs this is a mongoose plugin simply initialize the plugin like this. You only need the endpoint of your authorizer. That's it. Now there are two ways of handling your config\n\n#### Basic\n```ts\nimport mongoBouncer from \"query-bouncer-mongoose-plugin\"\n\nmongoose.plugin(mongoBouncer, {\n  baseUrl: \"https://your-authorizer.com\"\n});\n```\n\n#### Advanced\n\nMongoose will only keep the object we set in the basic setup stored and the complete config will be generated automatically on the fly. If you want to have more control and to be able to switch out components like axios we recommend you instantiate your config like this. This is also necessary if you want to use the [MockAdapter](#testing)\n\n```ts\nimport mongoBouncer, { QbConfig } from \"query-bouncer-mongoose-plugin\"\n\nconst config = new QbConfig({\n  baseUrl: \"https://your-authorizer.com\"\n})\n\nmongoose.plugin(mongoBouncer, config);\n\n```\n\n\nNow with the nature of mongoose plugins this has to be made before any schemas are initialized (which most of time will be done already). So either wrap your schemas so you make sure that the plugin gets initialized first or set the plugin for each schema you want to use (**recommended**)\n\n```ts\nconst blogPostSchema = new mongoose.Schema({\n  Title: \"My new Blog Post\",\n  // ...\n});\n\nblogPostSchema.plugin(mongoBouncer, {\n  baseUrl: \"https://your-authorizer.com\"\n});\n```\n\n#### Additional Options\n**baseUrl:** The URL the MongoBouncer that you want to connect to is hosted\n**apiVersion:** The Version of the API you want to use. Defaults to v1\n**axios:** You can force the Plugin to use another Axios Instance. This is mainly for testing purposes and not recommended\n**cookieName:** By default the Authenticator is set up to give you a cookie named connect.sid. If however you changed that you can also adjust the cookieName here\n\n### Useage\n\nMongoBouncer will run all the validation before your operations are being executed. As this middleware is currently not available in mongoose plugins for all methods, we currentyl support the following\n\n- create **(See Important Information about create)**\n- find\n- findOne\n- findOneAndDelete\n- findOneAndRemove\n- findOneAndUpdate\n- findById\n- findByIdAndDelete\n- findByIdAndRemove\n- findByIdAndUpdate\n- insertMany\n- remove \n- update\n- updateOne\n- updateMany\n- deleteOne\n- deleteMany\n\nThis is an example on how to enalbe MongoBouncer on your model. req refers to the express Request here. The MongoBouncer property needs to be added to the Options Object of your method. Let's take a look at some of those methods\n\nFirst let's set up a model.\n```ts\nconst BlogPostSchema = new Schema({\n  Title: { type: String, required: true } ,\n  Description: { type: String },\n  Category: { type: String, required: true }\n});\nconst BlogPost = mongoose.model('blogpost', BlogPostSchema);\n```\n#### Create\nNow to create a Document with respect to the permissions you just add the MongoBouncer to the options. \n\nAs the Options Object in mongoose is only available if the Document is passed in array please make sure you that even of you just add a single Document you use it in an Array. If you use a single Object the Options Object will be empty internally and as a result **Permissions will not be checked!!!**\n\nAs we stated earlier our authorizer has been set up to\nallow the user to create BlogPosts only if the category is \"Cars\". So while this will work just fine.\n```ts\nconst post = await BlogPost.create([{\n  Title: \"MyBlogPost\",\n  Category: \"Cars\",\n  Description: \"Some cool information about my favourite car\"\n}], { \n  MongoBouncer : {\n    Request: req \n  }\n});\n```\nthis\n```ts\nconst post = await BlogPost.create({\n  Title: \"MyBlogPost\",\n  Category: \"Food\",\n  Description: \"Some cool information about my favourite car\"\n}, { \n  MongoBouncer : {\n    Request: req \n  }\n});\n```\nwill throw an Error as the user is not allowed to create Blog Posts in that Category\n\n#### Find\n\nLet's assume we will now try to find that document again. Again as our fictive setup is that our user will only receive BlogPosts if the Category\nCars in this case\n```ts\nBlogPost.find({ Title: \"MyBlogPost\" }, null, {\n  MongoBouncer: {\n    Request: req\n  }\n});\n```\nwe will be returned an array with the Document we added in the Create section\n\n\n#### Update\nIf we now want to update the document we created we do it just the same way. A working update call would look like this\n```ts\nBlogPost.updateOne(\n  { Title: \"MyBlogPost\", Category: \"Cars\" }, \n  { Title: \"A changed Title\"}, \n  {\n    MongoBouncer: {\n      Request: req\n    }\n  }\n);\n```\nInternally both the Payload and the QueryRestrictions will be checked. So if we use any other Category than Cars nothing will be updated. However in this case no error will be returned but the returned Object by mongoose will just state that nothing matched our Query and nothing was updated. But if we try this e.g.\n```ts\nBlogPost.updateOne(\n  { Title: \"MyBlogPost\", Category: \"Cars\" }, \n  { Title: \"A changed Title\", Category: \"Food\" }, \n  {\n    MongoBouncer: {\n      Request: req\n    }\n  }\n);\n```\nan error will be thrown as a Document will be returned but we are not allowed to invoke the changes we are trying to make.\n\n### More Options\n\n#### Override Disable\nNow if you just add a Request MongoBouncer will run. To stop that from happening later down the road, even if you have already injected the Request into the options you can still disable MongoBouncer by setting the *Disabled* field to true. So a request like this will not run MongoBouncer\n\n```ts\nimport { OperationOptionsInput } from \"query-bouncer-mongoose-plugin\"\n\nconst myService = (opts:OperationOptionsInput) => {\n  // opts is already filled with MongoBouncer: { Request }\n\n  if(someConditionApplies()){\n    bouncerOpts.MongoBouncer.Disable = true;\n  }\n\n  BlogPost.updateOne(\n    { Title: \"MyBlogPost\", Category: \"Cars\" }, \n    { Title: \"A changed Title\", Category: \"Food\" }, \n    opts\n  );\n}\n```\n\n### Testing\n\nWhen you test you don't want to have a query bouncer running, so you could manually switch out the axios instance with a mock. However we provide our own MockAdapter for the QueryBouncer. If you want to mock a schmema with an existing config please make sure you instantiated this config as described under [advanced](#advanced)\n\n\n**my-model.ts**\n```ts\nimport { Model, Schema } from 'mongoose'\nimport MongoBouncer, { QbConfig } from 'query-bouncer-mongoose-plugin'\n\nconst schema = new Schema({\n  Title: String,\n  Category: String\n});\n// It is important that you instantiate as a new class or the tests will not work\n\nconst config = new QbConfig({\n  baseUrl: 'http://some-where.com/'\n})\nschema.plugin(MongoBouncer, config);\n\nconst model = Model('test', schema)\nexport default model;\nexport { config };\n```\n\n\n**my-model.spec.ts**\n```ts\nimport { MockAdapter, QbConfig,  } from 'query-bouncer-mongoose-plugin';\nimport mymodel, { config } from './my-model.ts';\n\nit('should do something', async () => {\n  // Prepare\n  const qBouncer = new MockAdapter(config);\n  qBouncer.mock({\n    collection: mymodel.collection.collectionName,\n    right: 'read',\n    response: {\n      query: { $or: { Category: 'Food' } }\n    }\n  });\n\n  // Execute\n  /// Your Test Code\n})\n```\n\n","readmeFilename":"README.md","bugs":{"url":"https://github.com/relief-melone/query-bouncer-mongoose-plugin/issues"},"homepage":"https://github.com/relief-melone/query-bouncer-mongoose-plugin#readme","_id":"query-bouncer-mongoose-plugin@2.0.1-0","_nodeVersion":"14.18.3","_npmVersion":"6.14.15","dist":{"integrity":"sha512-K8ljaHRzkcKK9Mk0/dM2WbbF2xyTXTdHVYtW7YeOH6b08x8dowQbFwvR0H5sUCPyavFoZhJ+2H9KSn4ReOYMDg==","shasum":"fccd80b1e623c7df682ab9adc326025f3f7921b7","tarball":"https://registry.npmjs.org/query-bouncer-mongoose-plugin/-/query-bouncer-mongoose-plugin-2.0.1-0.tgz","fileCount":150,"unpackedSize":216204,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.13\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJh8WlZCRA9TVsSAnZWagAA8SgP/jeoHrVTBOULbGbj0/lV\n3aTkwvq+b1VLHLQk0L2NfDsygfOnD+6+gr4+5OGD9/SrVOg0l+H1krVVOT6a\n9y0m64+YHyCqt0E9AU0HjfQWho0nDbbvCUdTkOGXSL2ps3di/Sps2vf/0x23\nDPCjEOv8tplTUaTg6r63+L9cCagfk03vd2F2yftu/lg8rGbOfTe3hetww5hq\n2+t7KiT/Fp8kDiU6hoHkdSFV4DCp0SVJ/0/u6hhoXvsIclcTVXnCUB67rlMK\nmcbYPowM1fKpJjAYKWu0g27pS3Hyr+yrZrMHWnBk2aSCfpPOC9E14ZuEtQNP\nD7TA+z6PxvLI7w6HpCTzeZO9JyOPL3Hb/Ymmv5ypBU40r8cA/Ddz7jVHPf8f\nYN19MMMoli0q72lvKkYobwK2YNftbSNrR24ratINu2KKH4Hrvzdl7e3oAy5Z\nxr4Km3nOJv2LE/hwNGMLbdeyP77Mbg0sPdt3R9lbGt7HgFqqGyX6XYQoqqUW\n/PWLj9STT+y0lVmRZA1gffLzc9nA8xV03hKE487e2k6huMB/iSK/fL/kL0Y0\n99UZXEmS/Rz3HuQgu94TJdchGPZoUlgkIp7rwIDd5UHS5Y6G5TFSI254M8Dc\nr8JOW/3dHDoKeIvgyvcm4/Bmoh0vnSXNUHqTHWXvohOhWE+8owEMSDw0sH3m\nsmLt\r\n=q98n\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEQCIBLhPPwh4LHKBC5iY8PybyzBP4OiIiCADCRHLiQd7kKGAiB7GCElQk/fFrQL/G0i60jyLT9B/K/BWEbPx3OHOnGPDg=="}]},"_npmUser":{"name":"relief.melone","email":"relief.melone@gmail.com"},"directories":{},"maintainers":[{"name":"relief.melone","email":"relief.melone@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/query-bouncer-mongoose-plugin_2.0.1-0_1643211097105_0.6224935086076078"},"_hasShrinkwrap":false},"2.0.1-1":{"name":"query-bouncer-mongoose-plugin","version":"2.0.1-1","description":"Mongoose Plugin for Query Bouncer","main":"./dist/index.js","scripts":{"start":"node ./dist/index.js","test":"mocha","coverage":"nyc npm run test","build":"rm -rf ./dist && ./node_modules/.bin/tsc --watch false -d","lint":"eslint --ignore-path .gitignore .","tsc":"tsc"},"repository":{"type":"git","url":"git+https://github.com/relief-melone/query-bouncer-mongoose-plugin.git"},"author":{"name":"Relief.Melone"},"license":"MIT","dependencies":{"axios":"^0.21.0","express":"^4.17.2","mongodb":"^3.5.0","mongoose":"^6.1.8","axios-mock-adapter":"^1.17.0"},"devDependencies":{"@sinonjs/referee-sinon":"^10.1.0","@types/chai":"latest","@types/express":"^4.17.13","@types/mocha":"^9.1.0","@types/moxios":"^0.4.9","@types/node":"latest","@types/sinon":"^9.0.9","@typescript-eslint/eslint-plugin":"latest","@typescript-eslint/parser":"latest","chai":"latest","chai-exclude":"^2.0.2","eslint":"latest","eslint-import-resolver-alias":"latest","eslint-plugin-import":"latest","mocha":"^9.2.0","mongodb-memory-server":"^6.5.0","nyc":"latest","sinon":"^8.1.1","typescript":"latest"},"gitHead":"ce05d49d23632d3dee59d0c55e2825eba1922a9d","readme":"# MongoBouncer - A Mongoose Plugin for Query Bouncer\n\nThe Mongoose Plugin for Query Bouncer (MongoBouncer) integrates with rm-authenticator, Query Bouncer and rm-session-populate. It's goal is to integrate the Role Based Access Control System you define in Query Bouncer easily in your Backend without having to worry about making the correct http requests and modify queries by yourself. The tasks of these components are\n\n1. **rm-authenticator:** Easy way to authenticate your user with just a Docker Container. Works with different OAuth providers like facebook, linkedin and google+. \n   - [GitHub](https://github.com/relief-melone/rm-authenticator)\n   - [Docker](https://hub.docker.com/repository/docker/reliefmelone/rm-authenticator)\n2. **rm-session-populator:** Middleware for Express. It will automatically communicate with the Authenticator and add a user object to your Express **req** with all the information you need\n   - [GitHub](https://github.com/relief-melone/rm-session-populator)\n   - [NPM](https://www.npmjs.com/package/rm-session-populator)\n3. **Query Bouncer:** Set up your Role Based Access System with a comfortable REST-API and use it to automatically modify queries and payloads based on your users permissions. \n   - [GitHub](https://github.com/relief-melone/query-bouncer)\n   - [Docker](https://hub.docker.com/r/reliefmelone/query-bouncer)\n4. **Query Bouncer Mongoose Plugin:** A Plugin that handles all the communication with the authorizer automatically so you can focus on writing your application.\n\nThis Overview illustrates a possible architecture for your application and the integration of those 4 components.\n\n![architecture](https://raw.githubusercontent.com/relief-melone/query-bouncer-mongoose-plugin/master/documentation/architectureOverview.png \"Architecture Overview\")\n\n## Instalation\n\nJust install with npm\n\n```sh\nnpm i --save query-bouncer-mongoose-plugin\n```\n\n## Usage\n\n### Prerequisites\n\nYou need a running instance of Query Bouncer to connect to. The Query Bouncer supplies the plugin with the correct queries accordingly to the users permissions. you can see how to set it up [here](https://github.com/relief-melone/query-bouncer)\n\n### How it Works\n\nQuery Bouncer will be used to easily set up your roles, permissions and roleAssignments for your Application. It supplies endpoints to send your query and payload to. The Query Bouncer will then validate the information based on your users permissions and will e.g. send back an adjusted query based on the users permissions. So what does that mean. Lets assume we have a collection called blogposts. Each BlogPost has a Title, Description and a Category. The user only has access to BlogPosts of the Category \"Cars\". So when a request to the Query Bouncer is made with the query to get all BlogPosts The Query \n\n```js\n{}\n```\nwill be returned as\n\n```js\n{ \n  $or: [ \n    {Category: \"Cars\"} \n  ] \n}\n```\n\nIn order to not having to utilize the API of rm-authorizer directly mongo-bouncer will handle all that for you. The following paragraphs will show you how to use it.\n\n\n### Initialize\n\nAs this is a mongoose plugin simply initialize the plugin like this. You only need the endpoint of your authorizer. That's it. Now there are two ways of handling your config\n\n#### Basic\n```ts\nimport mongoBouncer from \"query-bouncer-mongoose-plugin\"\n\nmongoose.plugin(mongoBouncer, {\n  baseUrl: \"https://your-authorizer.com\"\n});\n```\n\n#### Advanced\n\nMongoose will only keep the object we set in the basic setup stored and the complete config will be generated automatically on the fly. If you want to have more control and to be able to switch out components like axios we recommend you instantiate your config like this. This is also necessary if you want to use the [MockAdapter](#testing)\n\n```ts\nimport mongoBouncer, { QbConfig } from \"query-bouncer-mongoose-plugin\"\n\nconst config = new QbConfig({\n  baseUrl: \"https://your-authorizer.com\"\n})\n\nmongoose.plugin(mongoBouncer, config);\n\n```\n\n\nNow with the nature of mongoose plugins this has to be made before any schemas are initialized (which most of time will be done already). So either wrap your schemas so you make sure that the plugin gets initialized first or set the plugin for each schema you want to use (**recommended**)\n\n```ts\nconst blogPostSchema = new mongoose.Schema({\n  Title: \"My new Blog Post\",\n  // ...\n});\n\nblogPostSchema.plugin(mongoBouncer, {\n  baseUrl: \"https://your-authorizer.com\"\n});\n```\n\n#### Additional Options\n**baseUrl:** The URL the MongoBouncer that you want to connect to is hosted\n**apiVersion:** The Version of the API you want to use. Defaults to v1\n**axios:** You can force the Plugin to use another Axios Instance. This is mainly for testing purposes and not recommended\n**cookieName:** By default the Authenticator is set up to give you a cookie named connect.sid. If however you changed that you can also adjust the cookieName here\n\n### Useage\n\nMongoBouncer will run all the validation before your operations are being executed. As this middleware is currently not available in mongoose plugins for all methods, we currentyl support the following\n\n- create **(See Important Information about create)**\n- find\n- findOne\n- findOneAndDelete\n- findOneAndRemove\n- findOneAndUpdate\n- findById\n- findByIdAndDelete\n- findByIdAndRemove\n- findByIdAndUpdate\n- insertMany\n- remove \n- update\n- updateOne\n- updateMany\n- deleteOne\n- deleteMany\n\nThis is an example on how to enalbe MongoBouncer on your model. req refers to the express Request here. The MongoBouncer property needs to be added to the Options Object of your method. Let's take a look at some of those methods\n\nFirst let's set up a model.\n```ts\nconst BlogPostSchema = new Schema({\n  Title: { type: String, required: true } ,\n  Description: { type: String },\n  Category: { type: String, required: true }\n});\nconst BlogPost = mongoose.model('blogpost', BlogPostSchema);\n```\n#### Create\nNow to create a Document with respect to the permissions you just add the MongoBouncer to the options. \n\nAs the Options Object in mongoose is only available if the Document is passed in array please make sure you that even of you just add a single Document you use it in an Array. If you use a single Object the Options Object will be empty internally and as a result **Permissions will not be checked!!!**\n\nAs we stated earlier our authorizer has been set up to\nallow the user to create BlogPosts only if the category is \"Cars\". So while this will work just fine.\n```ts\nconst post = await BlogPost.create([{\n  Title: \"MyBlogPost\",\n  Category: \"Cars\",\n  Description: \"Some cool information about my favourite car\"\n}], { \n  MongoBouncer : {\n    Request: req \n  }\n});\n```\nthis\n```ts\nconst post = await BlogPost.create({\n  Title: \"MyBlogPost\",\n  Category: \"Food\",\n  Description: \"Some cool information about my favourite car\"\n}, { \n  MongoBouncer : {\n    Request: req \n  }\n});\n```\nwill throw an Error as the user is not allowed to create Blog Posts in that Category\n\n#### Find\n\nLet's assume we will now try to find that document again. Again as our fictive setup is that our user will only receive BlogPosts if the Category\nCars in this case\n```ts\nBlogPost.find({ Title: \"MyBlogPost\" }, null, {\n  MongoBouncer: {\n    Request: req\n  }\n});\n```\nwe will be returned an array with the Document we added in the Create section\n\n\n#### Update\nIf we now want to update the document we created we do it just the same way. A working update call would look like this\n```ts\nBlogPost.updateOne(\n  { Title: \"MyBlogPost\", Category: \"Cars\" }, \n  { Title: \"A changed Title\"}, \n  {\n    MongoBouncer: {\n      Request: req\n    }\n  }\n);\n```\nInternally both the Payload and the QueryRestrictions will be checked. So if we use any other Category than Cars nothing will be updated. However in this case no error will be returned but the returned Object by mongoose will just state that nothing matched our Query and nothing was updated. But if we try this e.g.\n```ts\nBlogPost.updateOne(\n  { Title: \"MyBlogPost\", Category: \"Cars\" }, \n  { Title: \"A changed Title\", Category: \"Food\" }, \n  {\n    MongoBouncer: {\n      Request: req\n    }\n  }\n);\n```\nan error will be thrown as a Document will be returned but we are not allowed to invoke the changes we are trying to make.\n\n### More Options\n\n#### Override Disable\nNow if you just add a Request MongoBouncer will run. To stop that from happening later down the road, even if you have already injected the Request into the options you can still disable MongoBouncer by setting the *Disabled* field to true. So a request like this will not run MongoBouncer\n\n```ts\nimport { OperationOptionsInput } from \"query-bouncer-mongoose-plugin\"\n\nconst myService = (opts:OperationOptionsInput) => {\n  // opts is already filled with MongoBouncer: { Request }\n\n  if(someConditionApplies()){\n    bouncerOpts.MongoBouncer.Disable = true;\n  }\n\n  BlogPost.updateOne(\n    { Title: \"MyBlogPost\", Category: \"Cars\" }, \n    { Title: \"A changed Title\", Category: \"Food\" }, \n    opts\n  );\n}\n```\n\n### Testing\n\nWhen you test you don't want to have a query bouncer running, so you could manually switch out the axios instance with a mock. However we provide our own MockAdapter for the QueryBouncer. If you want to mock a schmema with an existing config please make sure you instantiated this config as described under [advanced](#advanced)\n\n\n**my-model.ts**\n```ts\nimport { Model, Schema } from 'mongoose'\nimport MongoBouncer, { QbConfig } from 'query-bouncer-mongoose-plugin'\n\nconst schema = new Schema({\n  Title: String,\n  Category: String\n});\n// It is important that you instantiate as a new class or the tests will not work\n\nconst config = new QbConfig({\n  baseUrl: 'http://some-where.com/'\n})\nschema.plugin(MongoBouncer, config);\n\nconst model = Model('test', schema)\nexport default model;\nexport { config };\n```\n\n\n**my-model.spec.ts**\n```ts\nimport { MockAdapter, QbConfig,  } from 'query-bouncer-mongoose-plugin';\nimport mymodel, { config } from './my-model.ts';\n\nit('should do something', async () => {\n  // Prepare\n  const qBouncer = new MockAdapter(config);\n  qBouncer.mock({\n    collection: mymodel.collection.collectionName,\n    right: 'read',\n    response: {\n      query: { $or: { Category: 'Food' } }\n    }\n  });\n\n  // Execute\n  /// Your Test Code\n})\n```\n\n","readmeFilename":"README.md","bugs":{"url":"https://github.com/relief-melone/query-bouncer-mongoose-plugin/issues"},"homepage":"https://github.com/relief-melone/query-bouncer-mongoose-plugin#readme","_id":"query-bouncer-mongoose-plugin@2.0.1-1","_nodeVersion":"14.18.3","_npmVersion":"6.14.15","dist":{"integrity":"sha512-czfrRohIrixQbrLPHYlUZzGOs9P8O2D3lcS6gScerIyA9XDKhJCgZr/fuiFEBaER+4/yYvSV6Pe3y6MXhUhYCg==","shasum":"dcba98899b2123ceb99888d9f9fc56950afd2bb1","tarball":"https://registry.npmjs.org/query-bouncer-mongoose-plugin/-/query-bouncer-mongoose-plugin-2.0.1-1.tgz","fileCount":150,"unpackedSize":216204,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.13\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJh8WyVCRA9TVsSAnZWagAA6R0P+weXiS3hE8CTlkyCxNBQ\nT0fy5JssTA3zdpUdkrMRufugidqavVGhRIRnDRObxWvkakKmLd3CaLy7mo1J\nCnNxI5NDMD7s7F0Uv1Wm5MuyKVhmD2K/zlzqIIbFaXdWcLtEFIECcPchfuyJ\n43JlvgDwbPGkF2rZbA/cg3f08HzHD5qlUhc5bIMBwKTmlqf57Cu2JLwkJ5LV\n/EkUrwszEytR9p3pfk/Ia/WdRpK3f8dA/7fa5//sNhx/k39JfuzlYn2fcLBi\nWaXG+QNH+pKWEkD+zEEPSBBRcboLOFA56ISk8j8qlp5QQvu/3iVtZxwjQLQv\nF5A65d67BsqYkvH0yDj6Y6A+ZF76yvO8noKFgza5SWkxP1rh1hYXwq5iGjYe\n4dZphyzT47rdYj8yZMsVsPvIvVKdAX8zEHrMc73t4iAgUxr/OYcyaW2HIYfE\nQbyvzq9o4PYzH5KhTh9Qkd26ZiHoMmtooyjumG1lvrkanFbrK3L0ptazSXJg\nwHSON5WvMEJ0h/BRh9s5ooQmGCvnU6af/80yD4HQ2GrE8JmNiMiD40RBdnNT\nQr7C8U1VHuZti8dZEqGST0PylV7vAo0X4TxhQGxGy9zMW2cEhocU9vx0Ih/H\n+D60jKUsSKkED0WnWvY3qLAl5ppcb8DcxvPgENywf5RoGRmj6Q3xtBV/sCz1\n4xr+\r\n=F8Kb\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEQCIAulQb34VCFj3+JNFjW/tDMfuoxKMl63CM2ddkvmJD9dAiA42S76KiXQ2Mb5Rryj694JI59xbTtx2R36KwR65iRV6A=="}]},"_npmUser":{"name":"relief.melone","email":"relief.melone@gmail.com"},"directories":{},"maintainers":[{"name":"relief.melone","email":"relief.melone@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/query-bouncer-mongoose-plugin_2.0.1-1_1643211925399_0.047614672740159625"},"_hasShrinkwrap":false},"2.0.1-2":{"name":"query-bouncer-mongoose-plugin","version":"2.0.1-2","description":"Mongoose Plugin for Query Bouncer","main":"./dist/index.js","scripts":{"start":"node ./dist/index.js","test":"mocha","coverage":"nyc npm run test","build":"rm -rf ./dist && ./node_modules/.bin/tsc --watch false -d","lint":"eslint --ignore-path .gitignore .","tsc":"tsc"},"repository":{"type":"git","url":"git+https://github.com/relief-melone/query-bouncer-mongoose-plugin.git"},"author":{"name":"Relief.Melone"},"license":"MIT","dependencies":{"axios":"^0.21.0","express":"^4.17.2","mongodb":"^3.5.0","mongoose":"^6.1.8","axios-mock-adapter":"^1.17.0"},"devDependencies":{"@sinonjs/referee-sinon":"^10.1.0","@types/chai":"latest","@types/express":"^4.17.13","@types/mocha":"^9.1.0","@types/moxios":"^0.4.9","@types/node":"latest","@types/sinon":"^9.0.9","@typescript-eslint/eslint-plugin":"latest","@typescript-eslint/parser":"latest","chai":"latest","chai-exclude":"^2.0.2","eslint":"latest","eslint-import-resolver-alias":"latest","eslint-plugin-import":"latest","mocha":"^9.2.0","mongodb-memory-server":"^6.5.0","nyc":"latest","sinon":"^8.1.1","typescript":"latest"},"gitHead":"34a2942bca4f4bc24f5165478812d31add81cf8d","readme":"# MongoBouncer - A Mongoose Plugin for Query Bouncer\n\nThe Mongoose Plugin for Query Bouncer (MongoBouncer) integrates with rm-authenticator, Query Bouncer and rm-session-populate. It's goal is to integrate the Role Based Access Control System you define in Query Bouncer easily in your Backend without having to worry about making the correct http requests and modify queries by yourself. The tasks of these components are\n\n1. **rm-authenticator:** Easy way to authenticate your user with just a Docker Container. Works with different OAuth providers like facebook, linkedin and google+. \n   - [GitHub](https://github.com/relief-melone/rm-authenticator)\n   - [Docker](https://hub.docker.com/repository/docker/reliefmelone/rm-authenticator)\n2. **rm-session-populator:** Middleware for Express. It will automatically communicate with the Authenticator and add a user object to your Express **req** with all the information you need\n   - [GitHub](https://github.com/relief-melone/rm-session-populator)\n   - [NPM](https://www.npmjs.com/package/rm-session-populator)\n3. **Query Bouncer:** Set up your Role Based Access System with a comfortable REST-API and use it to automatically modify queries and payloads based on your users permissions. \n   - [GitHub](https://github.com/relief-melone/query-bouncer)\n   - [Docker](https://hub.docker.com/r/reliefmelone/query-bouncer)\n4. **Query Bouncer Mongoose Plugin:** A Plugin that handles all the communication with the authorizer automatically so you can focus on writing your application.\n\nThis Overview illustrates a possible architecture for your application and the integration of those 4 components.\n\n![architecture](https://raw.githubusercontent.com/relief-melone/query-bouncer-mongoose-plugin/master/documentation/architectureOverview.png \"Architecture Overview\")\n\n## Instalation\n\nJust install with npm\n\n```sh\nnpm i --save query-bouncer-mongoose-plugin\n```\n\n## Usage\n\n### Prerequisites\n\nYou need a running instance of Query Bouncer to connect to. The Query Bouncer supplies the plugin with the correct queries accordingly to the users permissions. you can see how to set it up [here](https://github.com/relief-melone/query-bouncer)\n\n### How it Works\n\nQuery Bouncer will be used to easily set up your roles, permissions and roleAssignments for your Application. It supplies endpoints to send your query and payload to. The Query Bouncer will then validate the information based on your users permissions and will e.g. send back an adjusted query based on the users permissions. So what does that mean. Lets assume we have a collection called blogposts. Each BlogPost has a Title, Description and a Category. The user only has access to BlogPosts of the Category \"Cars\". So when a request to the Query Bouncer is made with the query to get all BlogPosts The Query \n\n```js\n{}\n```\nwill be returned as\n\n```js\n{ \n  $or: [ \n    {Category: \"Cars\"} \n  ] \n}\n```\n\nIn order to not having to utilize the API of rm-authorizer directly mongo-bouncer will handle all that for you. The following paragraphs will show you how to use it.\n\n\n### Initialize\n\nAs this is a mongoose plugin simply initialize the plugin like this. You only need the endpoint of your authorizer. That's it. Now there are two ways of handling your config\n\n#### Basic\n```ts\nimport mongoBouncer from \"query-bouncer-mongoose-plugin\"\n\nmongoose.plugin(mongoBouncer, {\n  baseUrl: \"https://your-authorizer.com\"\n});\n```\n\n#### Advanced\n\nMongoose will only keep the object we set in the basic setup stored and the complete config will be generated automatically on the fly. If you want to have more control and to be able to switch out components like axios we recommend you instantiate your config like this. This is also necessary if you want to use the [MockAdapter](#testing)\n\n```ts\nimport mongoBouncer, { QbConfig } from \"query-bouncer-mongoose-plugin\"\n\nconst config = new QbConfig({\n  baseUrl: \"https://your-authorizer.com\"\n})\n\nmongoose.plugin(mongoBouncer, config);\n\n```\n\n\nNow with the nature of mongoose plugins this has to be made before any schemas are initialized (which most of time will be done already). So either wrap your schemas so you make sure that the plugin gets initialized first or set the plugin for each schema you want to use (**recommended**)\n\n```ts\nconst blogPostSchema = new mongoose.Schema({\n  Title: \"My new Blog Post\",\n  // ...\n});\n\nblogPostSchema.plugin(mongoBouncer, {\n  baseUrl: \"https://your-authorizer.com\"\n});\n```\n\n#### Additional Options\n**baseUrl:** The URL the MongoBouncer that you want to connect to is hosted\n**apiVersion:** The Version of the API you want to use. Defaults to v1\n**axios:** You can force the Plugin to use another Axios Instance. This is mainly for testing purposes and not recommended\n**cookieName:** By default the Authenticator is set up to give you a cookie named connect.sid. If however you changed that you can also adjust the cookieName here\n\n### Useage\n\nMongoBouncer will run all the validation before your operations are being executed. As this middleware is currently not available in mongoose plugins for all methods, we currentyl support the following\n\n- create **(See Important Information about create)**\n- find\n- findOne\n- findOneAndDelete\n- findOneAndRemove\n- findOneAndUpdate\n- findById\n- findByIdAndDelete\n- findByIdAndRemove\n- findByIdAndUpdate\n- insertMany\n- remove \n- update\n- updateOne\n- updateMany\n- deleteOne\n- deleteMany\n\nThis is an example on how to enalbe MongoBouncer on your model. req refers to the express Request here. The MongoBouncer property needs to be added to the Options Object of your method. Let's take a look at some of those methods\n\nFirst let's set up a model.\n```ts\nconst BlogPostSchema = new Schema({\n  Title: { type: String, required: true } ,\n  Description: { type: String },\n  Category: { type: String, required: true }\n});\nconst BlogPost = mongoose.model('blogpost', BlogPostSchema);\n```\n#### Create\nNow to create a Document with respect to the permissions you just add the MongoBouncer to the options. \n\nAs the Options Object in mongoose is only available if the Document is passed in array please make sure you that even of you just add a single Document you use it in an Array. If you use a single Object the Options Object will be empty internally and as a result **Permissions will not be checked!!!**\n\nAs we stated earlier our authorizer has been set up to\nallow the user to create BlogPosts only if the category is \"Cars\". So while this will work just fine.\n```ts\nconst post = await BlogPost.create([{\n  Title: \"MyBlogPost\",\n  Category: \"Cars\",\n  Description: \"Some cool information about my favourite car\"\n}], { \n  MongoBouncer : {\n    Request: req \n  }\n});\n```\nthis\n```ts\nconst post = await BlogPost.create({\n  Title: \"MyBlogPost\",\n  Category: \"Food\",\n  Description: \"Some cool information about my favourite car\"\n}, { \n  MongoBouncer : {\n    Request: req \n  }\n});\n```\nwill throw an Error as the user is not allowed to create Blog Posts in that Category\n\n#### Find\n\nLet's assume we will now try to find that document again. Again as our fictive setup is that our user will only receive BlogPosts if the Category\nCars in this case\n```ts\nBlogPost.find({ Title: \"MyBlogPost\" }, null, {\n  MongoBouncer: {\n    Request: req\n  }\n});\n```\nwe will be returned an array with the Document we added in the Create section\n\n\n#### Update\nIf we now want to update the document we created we do it just the same way. A working update call would look like this\n```ts\nBlogPost.updateOne(\n  { Title: \"MyBlogPost\", Category: \"Cars\" }, \n  { Title: \"A changed Title\"}, \n  {\n    MongoBouncer: {\n      Request: req\n    }\n  }\n);\n```\nInternally both the Payload and the QueryRestrictions will be checked. So if we use any other Category than Cars nothing will be updated. However in this case no error will be returned but the returned Object by mongoose will just state that nothing matched our Query and nothing was updated. But if we try this e.g.\n```ts\nBlogPost.updateOne(\n  { Title: \"MyBlogPost\", Category: \"Cars\" }, \n  { Title: \"A changed Title\", Category: \"Food\" }, \n  {\n    MongoBouncer: {\n      Request: req\n    }\n  }\n);\n```\nan error will be thrown as a Document will be returned but we are not allowed to invoke the changes we are trying to make.\n\n### More Options\n\n#### Override Disable\nNow if you just add a Request MongoBouncer will run. To stop that from happening later down the road, even if you have already injected the Request into the options you can still disable MongoBouncer by setting the *Disabled* field to true. So a request like this will not run MongoBouncer\n\n```ts\nimport { OperationOptionsInput } from \"query-bouncer-mongoose-plugin\"\n\nconst myService = (opts:OperationOptionsInput) => {\n  // opts is already filled with MongoBouncer: { Request }\n\n  if(someConditionApplies()){\n    bouncerOpts.MongoBouncer.Disable = true;\n  }\n\n  BlogPost.updateOne(\n    { Title: \"MyBlogPost\", Category: \"Cars\" }, \n    { Title: \"A changed Title\", Category: \"Food\" }, \n    opts\n  );\n}\n```\n\n### Testing\n\nWhen you test you don't want to have a query bouncer running, so you could manually switch out the axios instance with a mock. However we provide our own MockAdapter for the QueryBouncer. If you want to mock a schmema with an existing config please make sure you instantiated this config as described under [advanced](#advanced)\n\n\n**my-model.ts**\n```ts\nimport { Model, Schema } from 'mongoose'\nimport MongoBouncer, { QbConfig } from 'query-bouncer-mongoose-plugin'\n\nconst schema = new Schema({\n  Title: String,\n  Category: String\n});\n// It is important that you instantiate as a new class or the tests will not work\n\nconst config = new QbConfig({\n  baseUrl: 'http://some-where.com/'\n})\nschema.plugin(MongoBouncer, config);\n\nconst model = Model('test', schema)\nexport default model;\nexport { config };\n```\n\n\n**my-model.spec.ts**\n```ts\nimport { MockAdapter, QbConfig,  } from 'query-bouncer-mongoose-plugin';\nimport mymodel, { config } from './my-model.ts';\n\nit('should do something', async () => {\n  // Prepare\n  const qBouncer = new MockAdapter(config);\n  qBouncer.mock({\n    collection: mymodel.collection.collectionName,\n    right: 'read',\n    response: {\n      query: { $or: { Category: 'Food' } }\n    }\n  });\n\n  // Execute\n  /// Your Test Code\n})\n```\n\n","readmeFilename":"README.md","bugs":{"url":"https://github.com/relief-melone/query-bouncer-mongoose-plugin/issues"},"homepage":"https://github.com/relief-melone/query-bouncer-mongoose-plugin#readme","_id":"query-bouncer-mongoose-plugin@2.0.1-2","_nodeVersion":"14.18.3","_npmVersion":"6.14.15","dist":{"integrity":"sha512-a/459oQ3iJEo1JYo9wIYMHKFzp9tRs47NDPDTtmqeKyCx0ma4zpxsaRs8/4MyYfQ6gPqOixFhHr3fJtouu5Qlw==","shasum":"962c9fba59859d8c3698a353c32b9da850dfa172","tarball":"https://registry.npmjs.org/query-bouncer-mongoose-plugin/-/query-bouncer-mongoose-plugin-2.0.1-2.tgz","fileCount":150,"unpackedSize":215040,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.13\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJh8XA0CRA9TVsSAnZWagAANowP/j1PAikj1h+Baa7KgVuC\nOwYPFGCO4JJpeiWM4hfMwl7jGO9gK2d4UFTqJzBHVPZoBge4Lp6eM5HC3k2V\nQwxK4dj+UinueZxyA7PQE4HIAZ2wVACsgu+mZ9TNvF0DA0Ia8k7jMURg0S2o\nSdXDIfB/IcIm5WUOPawjlhRjr2boeMy1213sMY6V8QebFoWJu4gANsm+Lrf6\nqAMwDHEhqHAW3vFtwLMhC1ESCH1adiPrT4NNuJlwAwEIdRvDSpr4rjjJ3+mb\nWZdDMdHruzXPPzjETwVGsqY2pDblHdALpcLjIUtDzrULxtw6DrUMk5AZm7zp\nIGcfl1slp52vY+563ZaxSXRqbzQZXEj38FgNuIAmRftI/6w27tPqvPVT//7Y\nTcSyxbe4acCH0TofcSPFVhRWu+3/y7ivG+97uWW+iFtHehh/PGlWzUDaJqX6\nXW+peYGJfahpDea46YLaS+B4Mo2T/XcRiLpnnuHdXw3+XLnY1Xs46H+lXx1z\n34Cd91Gk/UwQPvMiUOOCByI5//K63IAoCvJ0NTjdCZcP2WBSm0mhIKUarm8P\n1ixnJJ1yhk3q5p9pPo5jFcLPknJP6qkNpT6U/HEurIUS2Qr7T9QSJbiBzhXI\nqUr50tEmLpO6RABAHROgxAew88ONm9oUanbBFGP/XVrZ00/2LVdZMXTNUX5f\nGLlG\r\n=BD5j\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIQDa3mfAAdKNinxIQ+JBcufycK+a5BphwP0Mwofiq1gLwwIgUUsbYwndhF3c8B5ctPCRaJTkUGLQ2GGe3HR/ETNdA70="}]},"_npmUser":{"name":"relief.melone","email":"relief.melone@gmail.com"},"directories":{},"maintainers":[{"name":"relief.melone","email":"relief.melone@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/query-bouncer-mongoose-plugin_2.0.1-2_1643212851943_0.9661598812308274"},"_hasShrinkwrap":false},"2.0.1-3":{"name":"query-bouncer-mongoose-plugin","version":"2.0.1-3","description":"Mongoose Plugin for Query Bouncer","main":"./dist/index.js","scripts":{"start":"node ./dist/index.js","test":"mocha","coverage":"nyc npm run test","build":"rm -rf ./dist && ./node_modules/.bin/tsc --watch false -d","lint":"eslint --ignore-path .gitignore .","tsc":"tsc"},"repository":{"type":"git","url":"git+https://github.com/relief-melone/query-bouncer-mongoose-plugin.git"},"author":{"name":"Relief.Melone"},"license":"MIT","dependencies":{"axios":"^0.21.0","express":"^4.17.2","mongodb":"^3.5.0","mongoose":"^6.1.8","axios-mock-adapter":"^1.17.0"},"devDependencies":{"@sinonjs/referee-sinon":"^10.1.0","@types/chai":"latest","@types/express":"^4.17.13","@types/mocha":"^9.1.0","@types/moxios":"^0.4.9","@types/node":"latest","@types/sinon":"^9.0.9","@typescript-eslint/eslint-plugin":"latest","@typescript-eslint/parser":"latest","chai":"latest","chai-exclude":"^2.0.2","eslint":"latest","eslint-import-resolver-alias":"latest","eslint-plugin-import":"latest","mocha":"^9.2.0","mongodb-memory-server":"^6.5.0","nyc":"latest","sinon":"^8.1.1","typescript":"latest"},"gitHead":"9c3c7ed3ecb3572acd4e4378bf6c84c125d85e92","readme":"# MongoBouncer - A Mongoose Plugin for Query Bouncer\n\nThe Mongoose Plugin for Query Bouncer (MongoBouncer) integrates with rm-authenticator, Query Bouncer and rm-session-populate. It's goal is to integrate the Role Based Access Control System you define in Query Bouncer easily in your Backend without having to worry about making the correct http requests and modify queries by yourself. The tasks of these components are\n\n1. **rm-authenticator:** Easy way to authenticate your user with just a Docker Container. Works with different OAuth providers like facebook, linkedin and google+. \n   - [GitHub](https://github.com/relief-melone/rm-authenticator)\n   - [Docker](https://hub.docker.com/repository/docker/reliefmelone/rm-authenticator)\n2. **rm-session-populator:** Middleware for Express. It will automatically communicate with the Authenticator and add a user object to your Express **req** with all the information you need\n   - [GitHub](https://github.com/relief-melone/rm-session-populator)\n   - [NPM](https://www.npmjs.com/package/rm-session-populator)\n3. **Query Bouncer:** Set up your Role Based Access System with a comfortable REST-API and use it to automatically modify queries and payloads based on your users permissions. \n   - [GitHub](https://github.com/relief-melone/query-bouncer)\n   - [Docker](https://hub.docker.com/r/reliefmelone/query-bouncer)\n4. **Query Bouncer Mongoose Plugin:** A Plugin that handles all the communication with the authorizer automatically so you can focus on writing your application.\n\nThis Overview illustrates a possible architecture for your application and the integration of those 4 components.\n\n![architecture](https://raw.githubusercontent.com/relief-melone/query-bouncer-mongoose-plugin/master/documentation/architectureOverview.png \"Architecture Overview\")\n\n## Instalation\n\nJust install with npm\n\n```sh\nnpm i --save query-bouncer-mongoose-plugin\n```\n\n## Usage\n\n### Prerequisites\n\nYou need a running instance of Query Bouncer to connect to. The Query Bouncer supplies the plugin with the correct queries accordingly to the users permissions. you can see how to set it up [here](https://github.com/relief-melone/query-bouncer)\n\n### How it Works\n\nQuery Bouncer will be used to easily set up your roles, permissions and roleAssignments for your Application. It supplies endpoints to send your query and payload to. The Query Bouncer will then validate the information based on your users permissions and will e.g. send back an adjusted query based on the users permissions. So what does that mean. Lets assume we have a collection called blogposts. Each BlogPost has a Title, Description and a Category. The user only has access to BlogPosts of the Category \"Cars\". So when a request to the Query Bouncer is made with the query to get all BlogPosts The Query \n\n```js\n{}\n```\nwill be returned as\n\n```js\n{ \n  $or: [ \n    {Category: \"Cars\"} \n  ] \n}\n```\n\nIn order to not having to utilize the API of rm-authorizer directly mongo-bouncer will handle all that for you. The following paragraphs will show you how to use it.\n\n\n### Initialize\n\nAs this is a mongoose plugin simply initialize the plugin like this. You only need the endpoint of your authorizer. That's it. Now there are two ways of handling your config\n\n#### Basic\n```ts\nimport mongoBouncer from \"query-bouncer-mongoose-plugin\"\n\nmongoose.plugin(mongoBouncer, {\n  baseUrl: \"https://your-authorizer.com\"\n});\n```\n\n#### Advanced\n\nMongoose will only keep the object we set in the basic setup stored and the complete config will be generated automatically on the fly. If you want to have more control and to be able to switch out components like axios we recommend you instantiate your config like this. This is also necessary if you want to use the [MockAdapter](#testing)\n\n```ts\nimport mongoBouncer, { QbConfig } from \"query-bouncer-mongoose-plugin\"\n\nconst config = new QbConfig({\n  baseUrl: \"https://your-authorizer.com\"\n})\n\nmongoose.plugin(mongoBouncer, config);\n\n```\n\n\nNow with the nature of mongoose plugins this has to be made before any schemas are initialized (which most of time will be done already). So either wrap your schemas so you make sure that the plugin gets initialized first or set the plugin for each schema you want to use (**recommended**)\n\n```ts\nconst blogPostSchema = new mongoose.Schema({\n  Title: \"My new Blog Post\",\n  // ...\n});\n\nblogPostSchema.plugin(mongoBouncer, {\n  baseUrl: \"https://your-authorizer.com\"\n});\n```\n\n#### Additional Options\n**baseUrl:** The URL the MongoBouncer that you want to connect to is hosted\n**apiVersion:** The Version of the API you want to use. Defaults to v1\n**axios:** You can force the Plugin to use another Axios Instance. This is mainly for testing purposes and not recommended\n**cookieName:** By default the Authenticator is set up to give you a cookie named connect.sid. If however you changed that you can also adjust the cookieName here\n\n### Useage\n\nMongoBouncer will run all the validation before your operations are being executed. As this middleware is currently not available in mongoose plugins for all methods, we currentyl support the following\n\n- create **(See Important Information about create)**\n- find\n- findOne\n- findOneAndDelete\n- findOneAndRemove\n- findOneAndUpdate\n- findById\n- findByIdAndDelete\n- findByIdAndRemove\n- findByIdAndUpdate\n- insertMany\n- remove \n- update\n- updateOne\n- updateMany\n- deleteOne\n- deleteMany\n\nThis is an example on how to enalbe MongoBouncer on your model. req refers to the express Request here. The MongoBouncer property needs to be added to the Options Object of your method. Let's take a look at some of those methods\n\nFirst let's set up a model.\n```ts\nconst BlogPostSchema = new Schema({\n  Title: { type: String, required: true } ,\n  Description: { type: String },\n  Category: { type: String, required: true }\n});\nconst BlogPost = mongoose.model('blogpost', BlogPostSchema);\n```\n#### Create\nNow to create a Document with respect to the permissions you just add the MongoBouncer to the options. \n\nAs the Options Object in mongoose is only available if the Document is passed in array please make sure you that even of you just add a single Document you use it in an Array. If you use a single Object the Options Object will be empty internally and as a result **Permissions will not be checked!!!**\n\nAs we stated earlier our authorizer has been set up to\nallow the user to create BlogPosts only if the category is \"Cars\". So while this will work just fine.\n```ts\nconst post = await BlogPost.create([{\n  Title: \"MyBlogPost\",\n  Category: \"Cars\",\n  Description: \"Some cool information about my favourite car\"\n}], { \n  MongoBouncer : {\n    Request: req \n  }\n});\n```\nthis\n```ts\nconst post = await BlogPost.create({\n  Title: \"MyBlogPost\",\n  Category: \"Food\",\n  Description: \"Some cool information about my favourite car\"\n}, { \n  MongoBouncer : {\n    Request: req \n  }\n});\n```\nwill throw an Error as the user is not allowed to create Blog Posts in that Category\n\n#### Find\n\nLet's assume we will now try to find that document again. Again as our fictive setup is that our user will only receive BlogPosts if the Category\nCars in this case\n```ts\nBlogPost.find({ Title: \"MyBlogPost\" }, null, {\n  MongoBouncer: {\n    Request: req\n  }\n});\n```\nwe will be returned an array with the Document we added in the Create section\n\n\n#### Update\nIf we now want to update the document we created we do it just the same way. A working update call would look like this\n```ts\nBlogPost.updateOne(\n  { Title: \"MyBlogPost\", Category: \"Cars\" }, \n  { Title: \"A changed Title\"}, \n  {\n    MongoBouncer: {\n      Request: req\n    }\n  }\n);\n```\nInternally both the Payload and the QueryRestrictions will be checked. So if we use any other Category than Cars nothing will be updated. However in this case no error will be returned but the returned Object by mongoose will just state that nothing matched our Query and nothing was updated. But if we try this e.g.\n```ts\nBlogPost.updateOne(\n  { Title: \"MyBlogPost\", Category: \"Cars\" }, \n  { Title: \"A changed Title\", Category: \"Food\" }, \n  {\n    MongoBouncer: {\n      Request: req\n    }\n  }\n);\n```\nan error will be thrown as a Document will be returned but we are not allowed to invoke the changes we are trying to make.\n\n### More Options\n\n#### Override Disable\nNow if you just add a Request MongoBouncer will run. To stop that from happening later down the road, even if you have already injected the Request into the options you can still disable MongoBouncer by setting the *Disabled* field to true. So a request like this will not run MongoBouncer\n\n```ts\nimport { OperationOptionsInput } from \"query-bouncer-mongoose-plugin\"\n\nconst myService = (opts:OperationOptionsInput) => {\n  // opts is already filled with MongoBouncer: { Request }\n\n  if(someConditionApplies()){\n    bouncerOpts.MongoBouncer.Disable = true;\n  }\n\n  BlogPost.updateOne(\n    { Title: \"MyBlogPost\", Category: \"Cars\" }, \n    { Title: \"A changed Title\", Category: \"Food\" }, \n    opts\n  );\n}\n```\n\n### Testing\n\nWhen you test you don't want to have a query bouncer running, so you could manually switch out the axios instance with a mock. However we provide our own MockAdapter for the QueryBouncer. If you want to mock a schmema with an existing config please make sure you instantiated this config as described under [advanced](#advanced)\n\n\n**my-model.ts**\n```ts\nimport { Model, Schema } from 'mongoose'\nimport MongoBouncer, { QbConfig } from 'query-bouncer-mongoose-plugin'\n\nconst schema = new Schema({\n  Title: String,\n  Category: String\n});\n// It is important that you instantiate as a new class or the tests will not work\n\nconst config = new QbConfig({\n  baseUrl: 'http://some-where.com/'\n})\nschema.plugin(MongoBouncer, config);\n\nconst model = Model('test', schema)\nexport default model;\nexport { config };\n```\n\n\n**my-model.spec.ts**\n```ts\nimport { MockAdapter, QbConfig,  } from 'query-bouncer-mongoose-plugin';\nimport mymodel, { config } from './my-model.ts';\n\nit('should do something', async () => {\n  // Prepare\n  const qBouncer = new MockAdapter(config);\n  qBouncer.mock({\n    collection: mymodel.collection.collectionName,\n    right: 'read',\n    response: {\n      query: { $or: { Category: 'Food' } }\n    }\n  });\n\n  // Execute\n  /// Your Test Code\n})\n```\n\n","readmeFilename":"README.md","bugs":{"url":"https://github.com/relief-melone/query-bouncer-mongoose-plugin/issues"},"homepage":"https://github.com/relief-melone/query-bouncer-mongoose-plugin#readme","_id":"query-bouncer-mongoose-plugin@2.0.1-3","_nodeVersion":"14.18.3","_npmVersion":"6.14.15","dist":{"integrity":"sha512-CBDBS2Il+KISCKk8+IQD+quyRghpl8IFMNGkfahxpLtsutv6f8+a5ygvEe0A7xEkCEHl0mnXH+fXqXxAJYT4qw==","shasum":"817fd0acbf2d834317ea14c0e058217cf07b0a62","tarball":"https://registry.npmjs.org/query-bouncer-mongoose-plugin/-/query-bouncer-mongoose-plugin-2.0.1-3.tgz","fileCount":150,"unpackedSize":215040,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.13\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJh8X5ICRA9TVsSAnZWagAAdq0P/29coWAMV8Mruh0ym9yM\n2eAYjBKr7DtTIKw2AFkG4AvoX+T7zGrRlaDQAZh1qD1kMh73xJknu7DjRZvB\nJslIiZwEDViJQIWDDI7/I2fWZM0oaOscTwne+u+3JV+gvA6gib4afmj21D1n\n0ypNgSQ8ZfQusY7ck76e3TSrOJFYdyeZljXiqG8YSwQ8G0OV8Ce/dtPC17WM\n6w+wagF2cn0w5LEckICaAEZp85/dvvCAR/rSmVdU5tDPiFRWcac9eDQ267qO\nvBGKHYAVlecdI9fPax+C5J4ioOJ98Pn/GCeTCh33bQMt4/cLnSsQR5uTxffI\nk69WuznLUVPgZqTAYuOqNOmtnxSLJvnCva2Ol4DSscdNAezey3kTlk6hd4pP\nsdQqiwBIRSJuXOru6Och1jVN3tQeCa17ZSnLC0LZXeQuvXm+xKMTONXtzRej\ntkiX4FXvuEMYLmg7DuaIHcr0HAitf1yG2DzrDciYslLd916T5Bw8/6fHeUOR\np4yTekIdFWIaL8+tBcXSIzBvwvKSZgLcGcOtuNBF165/QdyFRXn6nlcf/DgH\nrh/Lj/+i0XVol0V6X2dKLLk55Mi1LYNQRagP/g1kfA1l9LP13YFGV4J0gyGP\nNmVyENLZ7K+U6OTR3wmj4RGp+a1c1heMyOZY3NhOkaA0xvQu9frckwqWyplv\nJFEB\r\n=6WvD\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIE5aOpj88cCxAFht/Cq82H4/to1dEFcA+Pq+Vvh85craAiEA7yDHX13ZtqrMKALzZlDMuzBzQtIGy/LGTthc+LOF6/g="}]},"_npmUser":{"name":"relief.melone","email":"relief.melone@gmail.com"},"directories":{},"maintainers":[{"name":"relief.melone","email":"relief.melone@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/query-bouncer-mongoose-plugin_2.0.1-3_1643216456566_0.2804985049380415"},"_hasShrinkwrap":false},"2.0.1":{"name":"query-bouncer-mongoose-plugin","version":"2.0.1","description":"Mongoose Plugin for Query Bouncer","main":"./dist/index.js","scripts":{"start":"node ./dist/index.js","test":"mocha","coverage":"nyc npm run test","build":"rm -rf ./dist && ./node_modules/.bin/tsc --watch false -d","lint":"eslint --ignore-path .gitignore .","tsc":"tsc"},"repository":{"type":"git","url":"git+https://github.com/relief-melone/query-bouncer-mongoose-plugin.git"},"author":{"name":"Relief.Melone"},"license":"MIT","dependencies":{"axios":"^0.21.0","express":"^4.17.2","mongodb":"^3.5.0","mongoose":"^6.1.8","axios-mock-adapter":"^1.17.0"},"devDependencies":{"@sinonjs/referee-sinon":"^10.1.0","@types/chai":"latest","@types/express":"^4.17.13","@types/mocha":"^9.1.0","@types/moxios":"^0.4.9","@types/node":"latest","@types/sinon":"^9.0.9","@typescript-eslint/eslint-plugin":"latest","@typescript-eslint/parser":"latest","chai":"latest","chai-exclude":"^2.0.2","eslint":"latest","eslint-import-resolver-alias":"latest","eslint-plugin-import":"latest","mocha":"^9.2.0","mongodb-memory-server":"^6.5.0","nyc":"latest","sinon":"^8.1.1","typescript":"latest"},"gitHead":"6600c1890c90c22f3726bd0eaeeae7f135f8c9e0","bugs":{"url":"https://github.com/relief-melone/query-bouncer-mongoose-plugin/issues"},"homepage":"https://github.com/relief-melone/query-bouncer-mongoose-plugin#readme","_id":"query-bouncer-mongoose-plugin@2.0.1","_nodeVersion":"14.18.3","_npmVersion":"6.14.15","dist":{"integrity":"sha512-+O2OSvUClbo30M0/n2jXK4woyYMWAxr3OFwx3sJ6e4++slLIXg7gNC8xcRjb3FbIvvmlhhujAjaJpbh6sicJpw==","shasum":"0fd04471481c7e81bb6a0f0d838e706882a2deaa","tarball":"https://registry.npmjs.org/query-bouncer-mongoose-plugin/-/query-bouncer-mongoose-plugin-2.0.1.tgz","fileCount":150,"unpackedSize":215038,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.13\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJh8cNqCRA9TVsSAnZWagAAL/oP/37oCl4DKkZHry7tsHVV\ndb+KS+YMEcIk1LkPPpVLOQNbXlU3+OozvgAGicoAGQgl9J2m+j8wJntOovum\nNqsOUOgLMfswoII3prrzfA3JmFP2RcIo9ju7hnAyfV5U7ztnwmVun2aJpAtS\nZGT6B4bsk4iw9kzGiCqyJBr5Jn5m/lA6STFFov+xf42KByULtmHbDGCqNF1M\nbKbcTrU8xpqRGfxeNxUNUbc70jN9h17iyFkZigG+LAEn4sKOS5QSkdLCBBsm\nxghzlXUGuwBofKHn8ZqoOD3M3u5oPZeTe8huARAQC7IMmc4Lw7o1xorBdY1r\nvmkIiqMUvk+7KEVJiPYZpGUfP8uH5ayz4EVkRfQA8hFKCUBPsfyxu6hq/3EX\nh+I68ntXWSSPWGcOnK2a5jc1/JVcSmmi9tpV2PmapOxWT5pIZHm6Ia4GCbxw\ncz1wyYbcqTFfNFY6g0LCQq5lktSpu/655Ovjs16iM4uTUCyV167O5dRMGjav\nTRaJ0w3pBHs8u8qW3rOR+TUyHIfA/EtHN99OiU6KooSaYvTXJdfTQK0Ju3gv\nkqltWS1koe3qxMLdNaJQBWOad/2kI2kxYFuc1oR+Y2MUWldzX7VRKtwe+Vbi\nCVHzlyDofNsmLgRiegCYao7ZzWzc9wWz/1ycfy9CYhztHzGYwpu0tERl7Lib\nJkpH\r\n=exdM\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEYCIQD1bocqWyFBWUOYZc7mqyu2XerLkVOivog4sB54hOwp3AIhAM6VM5kMk6fz0FEKNB3JNWVe7hVV/GjNzrG57xOrYux/"}]},"_npmUser":{"name":"relief.melone","email":"relief.melone@gmail.com"},"directories":{},"maintainers":[{"name":"relief.melone","email":"relief.melone@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/query-bouncer-mongoose-plugin_2.0.1_1643234153874_0.19921581571978497"},"_hasShrinkwrap":false},"2.0.2-0":{"name":"query-bouncer-mongoose-plugin","version":"2.0.2-0","description":"Mongoose Plugin for Query Bouncer","main":"./dist/index.js","scripts":{"start":"node ./dist/index.js","test":"mocha","coverage":"nyc npm run test","build":"rm -rf ./dist && ./node_modules/.bin/tsc --watch false -d","lint":"eslint --ignore-path .gitignore .","tsc":"tsc"},"repository":{"type":"git","url":"git+https://gitlab.com/rm-npm-packages/query-bouncer-mongoose-plugin.git"},"author":{"name":"Relief.Melone"},"license":"MIT","dependencies":{"axios":"^0.26.0","axios-mock-adapter":"^1.20.0","mongodb":"^4.4.0","mongoose":"^6.2.2","express":"^4.17.2"},"devDependencies":{"@sinonjs/referee-sinon":"^10.1.0","@types/chai":"latest","@types/express":"^4.17.13","@types/mocha":"^9.1.0","@types/moxios":"^0.4.9","@types/node":"latest","@types/sinon":"^9.0.9","@typescript-eslint/eslint-plugin":"latest","@typescript-eslint/parser":"latest","chai":"latest","chai-exclude":"^2.0.2","eslint":"latest","eslint-import-resolver-alias":"latest","eslint-plugin-import":"latest","mongodb-memory-server":"^6.9.6","mocha":"^9.2.0","nyc":"latest","sinon":"^8.1.1","typescript":"latest"},"gitHead":"2d32562c0344c7a89c0500fa3bf312a92026619b","readme":"# MongoBouncer - A Mongoose Plugin for Query Bouncer\n\nThe Mongoose Plugin for Query Bouncer (MongoBouncer) integrates with rm-authenticator, Query Bouncer and rm-session-populate. It's goal is to integrate the Role Based Access Control System you define in Query Bouncer easily in your Backend without having to worry about making the correct http requests and modify queries by yourself. The tasks of these components are\n\n1. **rm-authenticator:** Easy way to authenticate your user with just a Docker Container. Works with different OAuth providers like facebook, linkedin and google+. \n   - [GitHub](https://github.com/relief-melone/rm-authenticator)\n   - [Docker](https://hub.docker.com/repository/docker/reliefmelone/rm-authenticator)\n2. **rm-session-populator:** Middleware for Express. It will automatically communicate with the Authenticator and add a user object to your Express **req** with all the information you need\n   - [GitHub](https://github.com/relief-melone/rm-session-populator)\n   - [NPM](https://www.npmjs.com/package/rm-session-populator)\n3. **Query Bouncer:** Set up your Role Based Access System with a comfortable REST-API and use it to automatically modify queries and payloads based on your users permissions. \n   - [GitHub](https://github.com/relief-melone/query-bouncer)\n   - [Docker](https://hub.docker.com/r/reliefmelone/query-bouncer)\n4. **Query Bouncer Mongoose Plugin:** A Plugin that handles all the communication with the authorizer automatically so you can focus on writing your application.\n\nThis Overview illustrates a possible architecture for your application and the integration of those 4 components.\n\n![architecture](https://raw.githubusercontent.com/relief-melone/query-bouncer-mongoose-plugin/master/documentation/architectureOverview.png \"Architecture Overview\")\n\n## Instalation\n\nJust install with npm\n\n```sh\nnpm i --save query-bouncer-mongoose-plugin\n```\n\n## Usage\n\n### Prerequisites\n\nYou need a running instance of Query Bouncer to connect to. The Query Bouncer supplies the plugin with the correct queries accordingly to the users permissions. you can see how to set it up [here](https://github.com/relief-melone/query-bouncer)\n\n### How it Works\n\nQuery Bouncer will be used to easily set up your roles, permissions and roleAssignments for your Application. It supplies endpoints to send your query and payload to. The Query Bouncer will then validate the information based on your users permissions and will e.g. send back an adjusted query based on the users permissions. So what does that mean. Lets assume we have a collection called blogposts. Each BlogPost has a Title, Description and a Category. The user only has access to BlogPosts of the Category \"Cars\". So when a request to the Query Bouncer is made with the query to get all BlogPosts The Query \n\n```js\n{}\n```\nwill be returned as\n\n```js\n{ \n  $or: [ \n    {Category: \"Cars\"} \n  ] \n}\n```\n\nIn order to not having to utilize the API of rm-authorizer directly mongo-bouncer will handle all that for you. The following paragraphs will show you how to use it.\n\n\n### Initialize\n\nAs this is a mongoose plugin simply initialize the plugin like this. You only need the endpoint of your authorizer. That's it. Now there are two ways of handling your config\n\n#### Basic\n```ts\nimport mongoBouncer from \"query-bouncer-mongoose-plugin\"\n\nmongoose.plugin(mongoBouncer, {\n  baseUrl: \"https://your-authorizer.com\"\n});\n```\n\n#### Advanced\n\nMongoose will only keep the object we set in the basic setup stored and the complete config will be generated automatically on the fly. If you want to have more control and to be able to switch out components like axios we recommend you instantiate your config like this. This is also necessary if you want to use the [MockAdapter](#testing)\n\n```ts\nimport mongoBouncer, { QbConfig } from \"query-bouncer-mongoose-plugin\"\n\nconst config = new QbConfig({\n  baseUrl: \"https://your-authorizer.com\"\n})\n\nmongoose.plugin(mongoBouncer, config);\n\n```\n\n\nNow with the nature of mongoose plugins this has to be made before any schemas are initialized (which most of time will be done already). So either wrap your schemas so you make sure that the plugin gets initialized first or set the plugin for each schema you want to use (**recommended**)\n\n```ts\nconst blogPostSchema = new mongoose.Schema({\n  Title: \"My new Blog Post\",\n  // ...\n});\n\nblogPostSchema.plugin(mongoBouncer, {\n  baseUrl: \"https://your-authorizer.com\"\n});\n```\n\n#### Additional Options\n**baseUrl:** The URL the MongoBouncer that you want to connect to is hosted\n**apiVersion:** The Version of the API you want to use. Defaults to v1\n**axios:** You can force the Plugin to use another Axios Instance. This is mainly for testing purposes and not recommended\n**cookieName:** By default the Authenticator is set up to give you a cookie named connect.sid. If however you changed that you can also adjust the cookieName here\n\n### Useage\n\nMongoBouncer will run all the validation before your operations are being executed. As this middleware is currently not available in mongoose plugins for all methods, we currentyl support the following\n\n- create **(See Important Information about create)**\n- find\n- findOne\n- findOneAndDelete\n- findOneAndRemove\n- findOneAndUpdate\n- findById\n- findByIdAndDelete\n- findByIdAndRemove\n- findByIdAndUpdate\n- insertMany\n- remove \n- update\n- updateOne\n- updateMany\n- deleteOne\n- deleteMany\n\nThis is an example on how to enalbe MongoBouncer on your model. req refers to the express Request here. The MongoBouncer property needs to be added to the Options Object of your method. Let's take a look at some of those methods\n\nFirst let's set up a model.\n```ts\nconst BlogPostSchema = new Schema({\n  Title: { type: String, required: true } ,\n  Description: { type: String },\n  Category: { type: String, required: true }\n});\nconst BlogPost = mongoose.model('blogpost', BlogPostSchema);\n```\n#### Create\nNow to create a Document with respect to the permissions you just add the MongoBouncer to the options. \n\nAs the Options Object in mongoose is only available if the Document is passed in array please make sure you that even of you just add a single Document you use it in an Array. If you use a single Object the Options Object will be empty internally and as a result **Permissions will not be checked!!!**\n\nAs we stated earlier our authorizer has been set up to\nallow the user to create BlogPosts only if the category is \"Cars\". So while this will work just fine.\n```ts\nconst post = await BlogPost.create([{\n  Title: \"MyBlogPost\",\n  Category: \"Cars\",\n  Description: \"Some cool information about my favourite car\"\n}], { \n  MongoBouncer : {\n    Request: req \n  }\n});\n```\nthis\n```ts\nconst post = await BlogPost.create({\n  Title: \"MyBlogPost\",\n  Category: \"Food\",\n  Description: \"Some cool information about my favourite car\"\n}, { \n  MongoBouncer : {\n    Request: req \n  }\n});\n```\nwill throw an Error as the user is not allowed to create Blog Posts in that Category\n\n#### Find\n\nLet's assume we will now try to find that document again. Again as our fictive setup is that our user will only receive BlogPosts if the Category\nCars in this case\n```ts\nBlogPost.find({ Title: \"MyBlogPost\" }, null, {\n  MongoBouncer: {\n    Request: req\n  }\n});\n```\nwe will be returned an array with the Document we added in the Create section\n\n\n#### Update\nIf we now want to update the document we created we do it just the same way. A working update call would look like this\n```ts\nBlogPost.updateOne(\n  { Title: \"MyBlogPost\", Category: \"Cars\" }, \n  { Title: \"A changed Title\"}, \n  {\n    MongoBouncer: {\n      Request: req\n    }\n  }\n);\n```\nInternally both the Payload and the QueryRestrictions will be checked. So if we use any other Category than Cars nothing will be updated. However in this case no error will be returned but the returned Object by mongoose will just state that nothing matched our Query and nothing was updated. But if we try this e.g.\n```ts\nBlogPost.updateOne(\n  { Title: \"MyBlogPost\", Category: \"Cars\" }, \n  { Title: \"A changed Title\", Category: \"Food\" }, \n  {\n    MongoBouncer: {\n      Request: req\n    }\n  }\n);\n```\nan error will be thrown as a Document will be returned but we are not allowed to invoke the changes we are trying to make.\n\n### More Options\n\n#### Override Disable\nNow if you just add a Request MongoBouncer will run. To stop that from happening later down the road, even if you have already injected the Request into the options you can still disable MongoBouncer by setting the *Disabled* field to true. So a request like this will not run MongoBouncer\n\n```ts\nimport { OperationOptionsInput } from \"query-bouncer-mongoose-plugin\"\n\nconst myService = (opts:OperationOptionsInput) => {\n  // opts is already filled with MongoBouncer: { Request }\n\n  if(someConditionApplies()){\n    bouncerOpts.MongoBouncer.Disable = true;\n  }\n\n  BlogPost.updateOne(\n    { Title: \"MyBlogPost\", Category: \"Cars\" }, \n    { Title: \"A changed Title\", Category: \"Food\" }, \n    opts\n  );\n}\n```\n\n### Testing\n\nWhen you test you don't want to have a query bouncer running, so you could manually switch out the axios instance with a mock. However we provide our own MockAdapter for the QueryBouncer. If you want to mock a schmema with an existing config please make sure you instantiated this config as described under [advanced](#advanced)\n\n\n**my-model.ts**\n```ts\nimport { Model, Schema } from 'mongoose'\nimport MongoBouncer, { QbConfig } from 'query-bouncer-mongoose-plugin'\n\nconst schema = new Schema({\n  Title: String,\n  Category: String\n});\n// It is important that you instantiate as a new class or the tests will not work\n\nconst config = new QbConfig({\n  baseUrl: 'http://some-where.com/'\n})\nschema.plugin(MongoBouncer, config);\n\nconst model = Model('test', schema)\nexport default model;\nexport { config };\n```\n\n\n**my-model.spec.ts**\n```ts\nimport { MockAdapter, QbConfig,  } from 'query-bouncer-mongoose-plugin';\nimport mymodel, { config } from './my-model.ts';\n\nit('should do something', async () => {\n  // Prepare\n  const qBouncer = new MockAdapter(config);\n  qBouncer.mock({\n    collection: mymodel.collection.collectionName,\n    right: 'read',\n    response: {\n      query: { $or: { Category: 'Food' } }\n    }\n  });\n\n  // Execute\n  /// Your Test Code\n})\n```\n\n","readmeFilename":"README.md","bugs":{"url":"https://gitlab.com/rm-npm-packages/query-bouncer-mongoose-plugin/issues"},"homepage":"https://gitlab.com/rm-npm-packages/query-bouncer-mongoose-plugin#readme","_id":"query-bouncer-mongoose-plugin@2.0.2-0","_nodeVersion":"14.19.0","_npmVersion":"6.14.16","dist":{"integrity":"sha512-m+DX9FB3wr2oOFKDXa5wYduReWCO/OWc1DuSEPyJq1lHM/3tCHrFS8OLF6UrFAilUIJldfr13oxU8ZVN+JJDkA==","shasum":"3a5111f6906033c78fc37e6f43755fef149fb79e","tarball":"https://registry.npmjs.org/query-bouncer-mongoose-plugin/-/query-bouncer-mongoose-plugin-2.0.2-0.tgz","fileCount":168,"unpackedSize":228683,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v4.10.10\r\nComment: https://openpgpjs.org\r\n\r\nwsFzBAEBCAAGBQJiEqQ5ACEJED1NWxICdlZqFiEECWMYAoorWMhJKdjhPU1b\r\nEgJ2VmqvshAAjbnu9kKRJEA0Qwqql3bHsiaBcDQ/WFze1E/AqYc9n3Npi6Ln\r\n8JL+0thYXMSHpsU4WgLs0+B4NWhDzHO42iVvA/ayjdKBCkMkyZ9qJEbkr9eB\r\nSfm2kgkWjYGIll5yemNG3vTiKefSMhem33xkXiOF9PuJTYC+f62aLU34aWf+\r\nWTEWwWejO/TuxUjd6scRhHPQi+DXJQDJW3beDFeAIT4tE8abS+Lns+qfelgk\r\n/Alub6cx0jeQB7YD3i5Mw1ygXB06roQf/9Xa8xMgIoWGmZhF7FKAvPQgbtXt\r\nryiNvmXK1KijeZQGnlQvegsZ6m3V50xC79S0wrHzG3+roetuVPCFl3VqmORp\r\nME/hPddXRmTSYKQ21tzV3dYY49FMpETXde1vgPWZaY+6bJMCK9T2J0Ko7jTe\r\nm6dYrLg8MsYFAyXCP7w/axDnwsY1lOjRfA59ecIhac7s7ZvgeZjKExxsd3RP\r\nEENw9aem59fVleDw1ln+/p5YbVXzj1OP9wN3Dc0oeaAHdKaRMxn5DNPolO5i\r\n1A+3im7C15k5qrRiUWH13YO04b+ss1GMsUWPtj1LDNTM5HJIuTcqsXn4Fc1E\r\naJJIvIjCTIoRYtvdfW19E0EklPEc+KdAC2RaoG+Ja3vRVl7EPTf8dHGdbwOV\r\nu/f6qT5ET7+bJHy4jwTddhE4k7AX39pgmaw=\r\n=IDhZ\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEQCIF8vukfe5pzo+hziotPRauVioSFglzqXJaixMN/ikqJMAiBz5kXeOpY6sLZ5u4UuOQ0lSV/W6egyqaV+AusgxkLlGA=="}]},"_npmUser":{"name":"relief.melone","email":"relief.melone@gmail.com"},"directories":{},"maintainers":[{"name":"relief.melone","email":"relief.melone@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/query-bouncer-mongoose-plugin_2.0.2-0_1645388857642_0.6865885440946466"},"_hasShrinkwrap":false},"2.0.2":{"name":"query-bouncer-mongoose-plugin","version":"2.0.2","description":"Mongoose Plugin for Query Bouncer","main":"./dist/index.js","scripts":{"start":"node ./dist/index.js","test":"mocha","coverage":"nyc npm run test","build":"rm -rf ./dist && ./node_modules/.bin/tsc --watch false -d","lint":"eslint --ignore-path .gitignore .","tsc":"tsc"},"repository":{"type":"git","url":"git+https://gitlab.com/rm-npm-packages/query-bouncer-mongoose-plugin.git"},"author":{"name":"Relief.Melone"},"license":"MIT","dependencies":{"axios":"^0.26.0","axios-mock-adapter":"^1.20.0","mongodb":"^4.4.0","mongoose":"^6.2.2","express":"^4.17.2"},"devDependencies":{"@sinonjs/referee-sinon":"^10.1.0","@types/chai":"latest","@types/express":"^4.17.13","@types/mocha":"^9.1.0","@types/moxios":"^0.4.9","@types/node":"latest","@types/sinon":"^9.0.9","@typescript-eslint/eslint-plugin":"latest","@typescript-eslint/parser":"latest","chai":"latest","chai-exclude":"^2.0.2","eslint":"latest","eslint-import-resolver-alias":"latest","eslint-plugin-import":"latest","mongodb-memory-server":"^6.9.6","mocha":"^9.2.0","nyc":"latest","sinon":"^8.1.1","typescript":"latest"},"gitHead":"453ba5e70bad016a8708a679c21cec59e5df17ae","bugs":{"url":"https://gitlab.com/rm-npm-packages/query-bouncer-mongoose-plugin/issues"},"homepage":"https://gitlab.com/rm-npm-packages/query-bouncer-mongoose-plugin#readme","_id":"query-bouncer-mongoose-plugin@2.0.2","_nodeVersion":"14.19.0","_npmVersion":"6.14.16","dist":{"integrity":"sha512-9veupC/tDDo1eIBfpUanW2MuwqbScDIrEnKCDGIRpfLgW9Sj1N3ghCAe+oGaHhtMISaWYEsJDXw0ciXXOdugVg==","shasum":"b0a7828d2042e809da93a28c12aaeefd64af0609","tarball":"https://registry.npmjs.org/query-bouncer-mongoose-plugin/-/query-bouncer-mongoose-plugin-2.0.2.tgz","fileCount":168,"unpackedSize":228681,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v4.10.10\r\nComment: https://openpgpjs.org\r\n\r\nwsFzBAEBCAAGBQJiEqUbACEJED1NWxICdlZqFiEECWMYAoorWMhJKdjhPU1b\r\nEgJ2VmoFIg/+KP1YuZ8hUZDPcSfjbnC67dnjst66K5iaFrfz6g4h6nG9Sk26\r\nAtIj4lmZId6w3+ZI7MmigrhLdWj4O00Db3EtaqWGbvx7MnMVSyYBJ+SVNdwL\r\nkhf/YRG9Cpms9BYXRlCX7oCDXc21IJGlTPwJkHTBFhrfconPqYX94NWd53FK\r\nGUwGx4bRCotBLFstV7V4k9o1oscI0c23R5olMPO/1L9D9IlX78WurBBvSG9e\r\nfJi91WKa40ufVLo8+FkbbIpgvqRiV61oQ2IQ1BUnNUU1QYkRF8HFkabCV2Zq\r\nsvnzzr9mOwdkF3RgQz5sB9BfAauGeakocH4i7HFlvzaHRd1DNFwNOOgWTxQj\r\nsSiIBxNjY6e29qc0sPqtqLN6/86jKMxHPVqoMeNAih11bESTIIF48dpWf8yc\r\nHVVPLn+rCRAMi7izUgu2jW+onnoT7w4jCfWBIQLBTRrYTKOpQWk79QpfRs6D\r\nSWp4oKM40Y6+PmlpFcp0q75nO0h3zKrChIFwY+KFLckOO1Zkpwa5Dc9TB0Mi\r\nXUzE/s8OnWgbnn6wcEDiXAMCBE5tG69wC8JCTgm8XzTEGGnyJ1tZ0Z2xEVhP\r\nDRxRW2lvQWRKNFLatuCcCroa3F/d+vPJSzQeuQXfgHqinVyONlSzJHGaSEDO\r\nwC+MukZPlxKKKZmbuE7lZXRadjZJhhhUEwA=\r\n=+1hk\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIFJvLkkDkbv5NtS9MaofCn7qIHMjLBVLOcoZBLVMYImuAiEAkOr6FJi1lfL2/4UIkRu17OUWrqtsemz1I0Gn8JyqdaE="}]},"_npmUser":{"name":"relief.melone","email":"relief.melone@gmail.com"},"directories":{},"maintainers":[{"name":"relief.melone","email":"relief.melone@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/query-bouncer-mongoose-plugin_2.0.2_1645389083303_0.8260863039636508"},"_hasShrinkwrap":false}},"time":{"created":"2020-01-24T15:44:06.694Z","1.0.0":"2020-01-24T15:44:06.825Z","modified":"2022-05-13T22:18:41.549Z","1.0.1":"2020-01-27T11:13:17.061Z","1.0.2":"2020-02-03T08:52:01.527Z","1.0.3":"2020-02-03T08:54:51.647Z","1.2.0":"2020-02-10T13:44:57.397Z","1.3.1":"2020-02-10T18:26:07.532Z","1.3.2":"2020-03-25T20:54:07.682Z","1.3.3-beta.0":"2020-10-12T17:50:39.969Z","1.4.0":"2020-10-19T06:51:46.490Z","1.5.0-beta.0":"2020-10-21T14:53:11.716Z","1.5.0-beta.1":"2020-10-21T15:00:18.269Z","1.5.0":"2020-10-22T09:06:29.544Z","1.5.1":"2020-10-30T12:39:41.271Z","1.5.2-beta.0":"2020-11-03T12:24:12.400Z","1.5.2-beta.1":"2020-11-03T12:27:05.556Z","1.5.2-beta.2":"2020-11-03T14:46:29.464Z","1.5.2-beta.3":"2020-11-03T16:08:39.801Z","1.5.2-beta.4":"2020-11-03T16:19:30.963Z","1.5.2-beta.5":"2020-11-03T16:29:26.619Z","1.5.2-beta.6":"2020-11-03T16:42:49.625Z","1.5.2-beta.7":"2020-11-03T17:01:18.574Z","1.6.0":"2020-11-03T21:52:28.644Z","1.7.0":"2020-11-28T10:35:31.908Z","1.8.0":"2020-11-28T13:44:29.731Z","1.8.1":"2020-11-29T15:58:05.988Z","1.9.0":"2020-11-29T21:46:09.502Z","1.9.1":"2020-11-29T22:17:01.884Z","2.0.0-0":"2022-01-26T07:57:24.337Z","2.0.0-1":"2022-01-26T10:29:05.898Z","2.0.0-2":"2022-01-26T10:33:34.878Z","2.0.1-0":"2022-01-26T15:31:37.239Z","2.0.1-1":"2022-01-26T15:45:25.559Z","2.0.1-2":"2022-01-26T16:00:52.287Z","2.0.1-3":"2022-01-26T17:00:56.692Z","2.0.1":"2022-01-26T21:55:54.045Z","2.0.2-0":"2022-02-20T20:27:37.883Z","2.0.2":"2022-02-20T20:31:23.454Z"},"maintainers":[{"name":"relief.melone","email":"relief.melone@gmail.com"}],"description":"Mongoose Plugin for Query Bouncer","author":{"name":"Relief.Melone"},"license":"MIT","readme":"# MongoBouncer - A Mongoose Plugin for Query Bouncer\n\nThe Mongoose Plugin for Query Bouncer (MongoBouncer) integrates with rm-authenticator, Query Bouncer and rm-session-populate. It's goal is to integrate the Role Based Access Control System you define in Query Bouncer easily in your Backend without having to worry about making the correct http requests and modify queries by yourself. The tasks of these components are\n\n1. **rm-authenticator:** Easy way to authenticate your user with just a Docker Container. Works with different OAuth providers like facebook, linkedin and google+. \n   - [GitHub](https://github.com/relief-melone/rm-authenticator)\n   - [Docker](https://hub.docker.com/repository/docker/reliefmelone/rm-authenticator)\n2. **rm-session-populator:** Middleware for Express. It will automatically communicate with the Authenticator and add a user object to your Express **req** with all the information you need\n   - [GitHub](https://github.com/relief-melone/rm-session-populator)\n   - [NPM](https://www.npmjs.com/package/rm-session-populator)\n3. **Query Bouncer:** Set up your Role Based Access System with a comfortable REST-API and use it to automatically modify queries and payloads based on your users permissions. \n   - [GitHub](https://github.com/relief-melone/query-bouncer)\n   - [Docker](https://hub.docker.com/r/reliefmelone/query-bouncer)\n4. **Query Bouncer Mongoose Plugin:** A Plugin that handles all the communication with the authorizer automatically so you can focus on writing your application.\n\nThis Overview illustrates a possible architecture for your application and the integration of those 4 components.\n\n![architecture](https://raw.githubusercontent.com/relief-melone/query-bouncer-mongoose-plugin/master/documentation/architectureOverview.png \"Architecture Overview\")\n\n## Instalation\n\nJust install with npm\n\n```sh\nnpm i --save query-bouncer-mongoose-plugin\n```\n\n## Usage\n\n### Prerequisites\n\nYou need a running instance of Query Bouncer to connect to. The Query Bouncer supplies the plugin with the correct queries accordingly to the users permissions. you can see how to set it up [here](https://github.com/relief-melone/query-bouncer)\n\n### How it Works\n\nQuery Bouncer will be used to easily set up your roles, permissions and roleAssignments for your Application. It supplies endpoints to send your query and payload to. The Query Bouncer will then validate the information based on your users permissions and will e.g. send back an adjusted query based on the users permissions. So what does that mean. Lets assume we have a collection called blogposts. Each BlogPost has a Title, Description and a Category. The user only has access to BlogPosts of the Category \"Cars\". So when a request to the Query Bouncer is made with the query to get all BlogPosts The Query \n\n```js\n{}\n```\nwill be returned as\n\n```js\n{ \n  $or: [ \n    {Category: \"Cars\"} \n  ] \n}\n```\n\nIn order to not having to utilize the API of rm-authorizer directly mongo-bouncer will handle all that for you. The following paragraphs will show you how to use it.\n\n\n### Initialize\n\nAs this is a mongoose plugin simply initialize the plugin like this. You only need the endpoint of your authorizer. That's it. Now there are two ways of handling your config\n\n#### Basic\n```ts\nimport mongoBouncer from \"query-bouncer-mongoose-plugin\"\n\nmongoose.plugin(mongoBouncer, {\n  baseUrl: \"https://your-authorizer.com\"\n});\n```\n\n#### Advanced\n\nMongoose will only keep the object we set in the basic setup stored and the complete config will be generated automatically on the fly. If you want to have more control and to be able to switch out components like axios we recommend you instantiate your config like this. This is also necessary if you want to use the [MockAdapter](#testing)\n\n```ts\nimport mongoBouncer, { QbConfig } from \"query-bouncer-mongoose-plugin\"\n\nconst config = new QbConfig({\n  baseUrl: \"https://your-authorizer.com\"\n})\n\nmongoose.plugin(mongoBouncer, config);\n\n```\n\n\nNow with the nature of mongoose plugins this has to be made before any schemas are initialized (which most of time will be done already). So either wrap your schemas so you make sure that the plugin gets initialized first or set the plugin for each schema you want to use (**recommended**)\n\n```ts\nconst blogPostSchema = new mongoose.Schema({\n  Title: \"My new Blog Post\",\n  // ...\n});\n\nblogPostSchema.plugin(mongoBouncer, {\n  baseUrl: \"https://your-authorizer.com\"\n});\n```\n\n#### Additional Options\n**baseUrl:** The URL the MongoBouncer that you want to connect to is hosted\n**apiVersion:** The Version of the API you want to use. Defaults to v1\n**axios:** You can force the Plugin to use another Axios Instance. This is mainly for testing purposes and not recommended\n**cookieName:** By default the Authenticator is set up to give you a cookie named connect.sid. If however you changed that you can also adjust the cookieName here\n\n### Useage\n\nMongoBouncer will run all the validation before your operations are being executed. As this middleware is currently not available in mongoose plugins for all methods, we currentyl support the following\n\n- create **(See Important Information about create)**\n- find\n- findOne\n- findOneAndDelete\n- findOneAndRemove\n- findOneAndUpdate\n- findById\n- findByIdAndDelete\n- findByIdAndRemove\n- findByIdAndUpdate\n- insertMany\n- remove \n- update\n- updateOne\n- updateMany\n- deleteOne\n- deleteMany\n\nThis is an example on how to enalbe MongoBouncer on your model. req refers to the express Request here. The MongoBouncer property needs to be added to the Options Object of your method. Let's take a look at some of those methods\n\nFirst let's set up a model.\n```ts\nconst BlogPostSchema = new Schema({\n  Title: { type: String, required: true } ,\n  Description: { type: String },\n  Category: { type: String, required: true }\n});\nconst BlogPost = mongoose.model('blogpost', BlogPostSchema);\n```\n#### Create\nNow to create a Document with respect to the permissions you just add the MongoBouncer to the options. \n\nAs the Options Object in mongoose is only available if the Document is passed in array please make sure you that even of you just add a single Document you use it in an Array. If you use a single Object the Options Object will be empty internally and as a result **Permissions will not be checked!!!**\n\nAs we stated earlier our authorizer has been set up to\nallow the user to create BlogPosts only if the category is \"Cars\". So while this will work just fine.\n```ts\nconst post = await BlogPost.create([{\n  Title: \"MyBlogPost\",\n  Category: \"Cars\",\n  Description: \"Some cool information about my favourite car\"\n}], { \n  MongoBouncer : {\n    Request: req \n  }\n});\n```\nthis\n```ts\nconst post = await BlogPost.create({\n  Title: \"MyBlogPost\",\n  Category: \"Food\",\n  Description: \"Some cool information about my favourite car\"\n}, { \n  MongoBouncer : {\n    Request: req \n  }\n});\n```\nwill throw an Error as the user is not allowed to create Blog Posts in that Category\n\n#### Find\n\nLet's assume we will now try to find that document again. Again as our fictive setup is that our user will only receive BlogPosts if the Category\nCars in this case\n```ts\nBlogPost.find({ Title: \"MyBlogPost\" }, null, {\n  MongoBouncer: {\n    Request: req\n  }\n});\n```\nwe will be returned an array with the Document we added in the Create section\n\n\n#### Update\nIf we now want to update the document we created we do it just the same way. A working update call would look like this\n```ts\nBlogPost.updateOne(\n  { Title: \"MyBlogPost\", Category: \"Cars\" }, \n  { Title: \"A changed Title\"}, \n  {\n    MongoBouncer: {\n      Request: req\n    }\n  }\n);\n```\nInternally both the Payload and the QueryRestrictions will be checked. So if we use any other Category than Cars nothing will be updated. However in this case no error will be returned but the returned Object by mongoose will just state that nothing matched our Query and nothing was updated. But if we try this e.g.\n```ts\nBlogPost.updateOne(\n  { Title: \"MyBlogPost\", Category: \"Cars\" }, \n  { Title: \"A changed Title\", Category: \"Food\" }, \n  {\n    MongoBouncer: {\n      Request: req\n    }\n  }\n);\n```\nan error will be thrown as a Document will be returned but we are not allowed to invoke the changes we are trying to make.\n\n### More Options\n\n#### Override Disable\nNow if you just add a Request MongoBouncer will run. To stop that from happening later down the road, even if you have already injected the Request into the options you can still disable MongoBouncer by setting the *Disabled* field to true. So a request like this will not run MongoBouncer\n\n```ts\nimport { OperationOptionsInput } from \"query-bouncer-mongoose-plugin\"\n\nconst myService = (opts:OperationOptionsInput) => {\n  // opts is already filled with MongoBouncer: { Request }\n\n  if(someConditionApplies()){\n    bouncerOpts.MongoBouncer.Disable = true;\n  }\n\n  BlogPost.updateOne(\n    { Title: \"MyBlogPost\", Category: \"Cars\" }, \n    { Title: \"A changed Title\", Category: \"Food\" }, \n    opts\n  );\n}\n```\n\n### Testing\n\nWhen you test you don't want to have a query bouncer running, so you could manually switch out the axios instance with a mock. However we provide our own MockAdapter for the QueryBouncer. If you want to mock a schmema with an existing config please make sure you instantiated this config as described under [advanced](#advanced)\n\n\n**my-model.ts**\n```ts\nimport { Model, Schema } from 'mongoose'\nimport MongoBouncer, { QbConfig } from 'query-bouncer-mongoose-plugin'\n\nconst schema = new Schema({\n  Title: String,\n  Category: String\n});\n// It is important that you instantiate as a new class or the tests will not work\n\nconst config = new QbConfig({\n  baseUrl: 'http://some-where.com/'\n})\nschema.plugin(MongoBouncer, config);\n\nconst model = Model('test', schema)\nexport default model;\nexport { config };\n```\n\n\n**my-model.spec.ts**\n```ts\nimport { MockAdapter, QbConfig,  } from 'query-bouncer-mongoose-plugin';\nimport mymodel, { config } from './my-model.ts';\n\nit('should do something', async () => {\n  // Prepare\n  const qBouncer = new MockAdapter(config);\n  qBouncer.mock({\n    collection: mymodel.collection.collectionName,\n    right: 'read',\n    response: {\n      query: { $or: { Category: 'Food' } }\n    }\n  });\n\n  // Execute\n  /// Your Test Code\n})\n```\n\n","readmeFilename":"README.md","homepage":"https://gitlab.com/rm-npm-packages/query-bouncer-mongoose-plugin#readme","repository":{"type":"git","url":"git+https://gitlab.com/rm-npm-packages/query-bouncer-mongoose-plugin.git"},"bugs":{"url":"https://gitlab.com/rm-npm-packages/query-bouncer-mongoose-plugin/issues"}}