From c68667be9c33d28412dca7a406592fa8639a8e32 Mon Sep 17 00:00:00 2001 From: Stefan Zermatten Date: Tue, 8 Mar 2022 15:04:51 +0200 Subject: [PATCH] Added data validation diagnostics for offline use --- app/imports/migrations/methods/index.js | 1 + app/imports/migrations/methods/migrateTo.js | 4 +-- .../migrations/methods/validateDatabase.js | 35 +++++++++++++++++++ 3 files changed, 38 insertions(+), 2 deletions(-) create mode 100644 app/imports/migrations/methods/validateDatabase.js diff --git a/app/imports/migrations/methods/index.js b/app/imports/migrations/methods/index.js index 6d5dc8c5..ed6bbb4e 100644 --- a/app/imports/migrations/methods/index.js +++ b/app/imports/migrations/methods/index.js @@ -1,2 +1,3 @@ import './migrateTo.js'; +import './validateDatabase.js'; import './getVersion.js'; diff --git a/app/imports/migrations/methods/migrateTo.js b/app/imports/migrations/methods/migrateTo.js index c5248c9d..f61fb9b3 100644 --- a/app/imports/migrations/methods/migrateTo.js +++ b/app/imports/migrations/methods/migrateTo.js @@ -16,8 +16,8 @@ const migrateTo = new ValidatedMethod({ }).validator(), mixins: [RateLimiterMixin], rateLimit: { - numRequests: 5, - timeInterval: 5000, + numRequests: 1, + timeInterval: 10000, }, run({version}) { if (Meteor.isClient) return; diff --git a/app/imports/migrations/methods/validateDatabase.js b/app/imports/migrations/methods/validateDatabase.js new file mode 100644 index 00000000..c555f3c5 --- /dev/null +++ b/app/imports/migrations/methods/validateDatabase.js @@ -0,0 +1,35 @@ +import { ValidatedMethod } from 'meteor/mdg:validated-method'; +import { RateLimiterMixin } from 'ddp-rate-limiter-mixin'; +import { assertAdmin } from '/imports/api/sharing/sharingPermissions.js'; + +const validateDatabase = new ValidatedMethod({ + name: 'validateDatabase', + validate: null, + mixins: [RateLimiterMixin], + rateLimit: { + numRequests: 1, + timeInterval: 10000, + }, + run() { + assertAdmin(this.userId); + // Very computationally expensive data diagnostics + // Only run in an offline instance you control + return; + if (Meteor.isClient) return; + + Meteor.Collection.getAll().forEach(collection => { + if (!collection.instance._c2?._simpleSchemas) return; + collection.instance.find({}).forEach(doc => { + const schema = collection.instance.simpleSchema(doc); + let cleanDoc = schema.clean(doc); + try { + schema.validate(cleanDoc, {modifier: false}); + } catch (e){ + console.log(collection.name, doc._id, e.message || e.reason || e.toString()); + } + }); + }); + }, +}); + +export default validateDatabase;