rxdb-server 15.13.4 → 15.14.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -4,6 +4,7 @@ Object.defineProperty(exports, "__esModule", {
4
4
  value: true
5
5
  });
6
6
  exports.RxServerReplicationEndpoint = void 0;
7
+ exports.blockPreviousReplicationVersionPaths = blockPreviousReplicationVersionPaths;
7
8
  var _core = require("rxdb/plugins/core");
8
9
  var _replicationWebsocket = require("rxdb/plugins/replication-websocket");
9
10
  var _rxjs = require("rxjs");
@@ -18,7 +19,7 @@ var RxServerReplicationEndpoint = exports.RxServerReplicationEndpoint = function
18
19
  this.cors = cors;
19
20
  var adapter = this.server.adapter;
20
21
  (0, _helper.setCors)(this.server, [this.name].join('/'), cors);
21
- (0, _helper.blockPreviousVersionPaths)(this.server, [this.name].join('/'), collection.schema.version);
22
+ blockPreviousReplicationVersionPaths(this.server, [this.name].join('/'), collection.schema.version);
22
23
  this.urlPath = [this.name, collection.schema.version].join('/');
23
24
  var primaryPath = this.collection.schema.primaryPath;
24
25
  var replicationHandler = (0, _replicationWebsocket.getReplicationHandlerByCollection)(this.server.database, collection.name);
@@ -169,4 +170,27 @@ var RxServerReplicationEndpoint = exports.RxServerReplicationEndpoint = function
169
170
  });
170
171
  });
171
172
  };
173
+ /**
174
+ * "block" the previous version urls and send a 426 on them so that
175
+ * the clients know they must update.
176
+ */
177
+ function blockPreviousReplicationVersionPaths(server, path, currentVersion) {
178
+ var v = 0;
179
+ var _loop = function () {
180
+ var version = v;
181
+ /**
182
+ * Some adapters do not allow regex or handle them property (like Koa),
183
+ * so to make it easier, use the hard-coded array of path parts.
184
+ */
185
+ ['', 'pull', 'push', 'pullStream'].forEach(subPath => {
186
+ server.adapter.all(server.serverApp, '/' + path + '/' + version + '/' + subPath, (req, res) => {
187
+ server.adapter.closeConnection(res, 426, 'Outdated version ' + version + ' (newest is ' + currentVersion + ')');
188
+ });
189
+ });
190
+ v++;
191
+ };
192
+ while (v < currentVersion) {
193
+ _loop();
194
+ }
195
+ }
172
196
  //# sourceMappingURL=endpoint-replication.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"endpoint-replication.js","names":["_core","require","_replicationWebsocket","_rxjs","_utils","_helper","RxServerReplicationEndpoint","exports","server","name","collection","queryModifier","changeValidator","serverOnlyFields","cors","type","adapter","setCors","join","blockPreviousVersionPaths","schema","version","urlPath","primaryPath","replicationHandler","getReplicationHandlerByCollection","database","authData","query","doesContainRegexQuerySelector","selector","Error","change","assumedMasterState","docContainsServerOnlyFields","newDocumentState","removeServerOnlyFields","removeServerOnlyFieldsMonad","mergeServerDocumentFields","mergeServerDocumentFieldsMonad","get","serverApp","req","res","getAuthDataByRequest","urlQuery","getRequestQuery","id","lwt","parseInt","limit","plainQuery","getChangedDocumentsSinceQuery","storageInstance","useQueryChanges","ensureNotFalsy","prepared","prepareQuery","jsonSchema","result","newCheckpoint","documents","length","lastOfArray","updatedAt","_meta","responseDocuments","map","d","setResponseHeader","endResponseJson","checkpoint","post","docDataMatcherWrite","getDocAllowedMatcher","rows","getRequestBody","ids","forEach","row","push","nonAllowedRow","find","closeConnection","hasInvalidChange","currentStateDocsArray","findDocumentsById","currentStateDocs","Map","set","useRows","isChangeValid","serverDoc","conflicts","masterWrite","setSSEHeaders","docDataMatcherStream","subscription","masterChangeStream$","pipe","mergeMap","changes","authHandler","getRequestHeaders","err","useDocs","filter","f","subscribe","filteredAndModified","responseWrite","JSON","stringify","onRequestClose","unsubscribe","endResponse"],"sources":["../../../../src/plugins/server/endpoint-replication.ts"],"sourcesContent":["import {\n FilledMangoQuery,\n RxCollection,\n RxReplicationHandler,\n RxReplicationWriteToMasterRow,\n RxStorageDefaultCheckpoint,\n StringKeys,\n prepareQuery,\n getChangedDocumentsSinceQuery,\n RxDocumentData\n} from 'rxdb/plugins/core';\nimport { getReplicationHandlerByCollection } from 'rxdb/plugins/replication-websocket';\nimport type { RxServer } from './rx-server.ts';\nimport type {\n RxServerAuthData,\n RxServerChangeValidator,\n RxServerEndpoint,\n RxServerQueryModifier\n} from './types.ts';\nimport { filter, mergeMap } from 'rxjs';\nimport {\n ensureNotFalsy,\n getFromMapOrThrow,\n lastOfArray\n} from 'rxdb/plugins/utils';\n\nimport {\n blockPreviousVersionPaths,\n docContainsServerOnlyFields,\n doesContainRegexQuerySelector,\n getAuthDataByRequest,\n getDocAllowedMatcher,\n mergeServerDocumentFieldsMonad,\n removeServerOnlyFieldsMonad,\n setCors\n} from './helper.ts';\n\nexport type RxReplicationEndpointMessageType = {\n id: string;\n method: StringKeys<RxReplicationHandler<any, any>> | 'auth';\n params: any[];\n};\n\nexport class RxServerReplicationEndpoint<ServerAppType, AuthType, RxDocType> implements RxServerEndpoint<AuthType, RxDocType> {\n readonly type = 'replication';\n readonly urlPath: string;\n readonly changeValidator: RxServerChangeValidator<AuthType, RxDocType>;\n readonly queryModifier: RxServerQueryModifier<AuthType, RxDocType>;\n constructor(\n public readonly server: RxServer<ServerAppType, AuthType>,\n public readonly name: string,\n public readonly collection: RxCollection<RxDocType>,\n queryModifier: RxServerQueryModifier<AuthType, RxDocType>,\n changeValidator: RxServerChangeValidator<AuthType, RxDocType>,\n public readonly serverOnlyFields: string[],\n public readonly cors?: string,\n ) {\n const adapter = this.server.adapter;\n\n setCors(this.server, [this.name].join('/'), cors);\n blockPreviousVersionPaths(this.server, [this.name].join('/'), collection.schema.version);\n\n this.urlPath = [this.name, collection.schema.version].join('/');\n\n const primaryPath = this.collection.schema.primaryPath;\n const replicationHandler = getReplicationHandlerByCollection(this.server.database, collection.name);\n this.queryModifier = (authData, query) => {\n if (doesContainRegexQuerySelector(query.selector)) {\n throw new Error('$regex queries not allowed because of DOS-attacks');\n }\n return queryModifier(authData, query);\n }\n this.changeValidator = (authData, change) => {\n if (\n (change.assumedMasterState && docContainsServerOnlyFields(serverOnlyFields, change.assumedMasterState)) ||\n docContainsServerOnlyFields(serverOnlyFields, change.newDocumentState)\n ) {\n return false;\n }\n return changeValidator(authData, change);\n }\n const removeServerOnlyFields = removeServerOnlyFieldsMonad<RxDocType>(this.serverOnlyFields);\n const mergeServerDocumentFields = mergeServerDocumentFieldsMonad<RxDocType>(this.serverOnlyFields);\n\n this.server.adapter.get(this.server.serverApp, '/' + this.urlPath + '/pull', async (req: any, res: any) => {\n const authData = await getAuthDataByRequest(this.server, req, res);\n if (!authData) { return; }\n\n const urlQuery = adapter.getRequestQuery(req);\n const id = urlQuery.id ? urlQuery.id as string : '';\n const lwt = urlQuery.lwt ? parseInt(urlQuery.lwt as any, 10) : 0;\n const limit = urlQuery.limit ? parseInt(urlQuery.limit as any, 10) : 1;\n const plainQuery = getChangedDocumentsSinceQuery<RxDocType, RxStorageDefaultCheckpoint>(\n this.collection.storageInstance,\n limit,\n { id, lwt }\n );\n const useQueryChanges: FilledMangoQuery<RxDocType> = this.queryModifier(\n ensureNotFalsy(authData),\n plainQuery\n );\n const prepared = prepareQuery<RxDocType>(\n this.collection.schema.jsonSchema,\n useQueryChanges\n );\n const result = await this.collection.storageInstance.query(prepared);\n\n const newCheckpoint = result.documents.length === 0 ? { id, lwt } : {\n id: ensureNotFalsy(lastOfArray(result.documents))[primaryPath],\n updatedAt: ensureNotFalsy(lastOfArray(result.documents))._meta.lwt\n };\n const responseDocuments = result.documents.map(d => removeServerOnlyFields(d));\n adapter.setResponseHeader(res, 'Content-Type', 'application/json');\n adapter.endResponseJson(res, {\n documents: responseDocuments,\n checkpoint: newCheckpoint\n });\n });\n\n this.server.adapter.post(this.server.serverApp, '/' + this.urlPath + '/push', async (req: any, res: any) => {\n const authData = await getAuthDataByRequest(this.server, req, res);\n if (!authData) { return; }\n\n const docDataMatcherWrite = getDocAllowedMatcher(this, ensureNotFalsy(authData as any));\n const rows: RxReplicationWriteToMasterRow<RxDocType>[] = adapter.getRequestBody(req);\n const ids: string[] = [];\n rows.forEach(row => ids.push((row.newDocumentState as any)[primaryPath]));\n\n for (const row of rows) {\n // TODO remove this check\n if (row.assumedMasterState && (row.assumedMasterState as any)._meta) {\n throw new Error('body document contains meta!');\n }\n }\n\n // ensure all writes are allowed\n const nonAllowedRow = rows.find(row => {\n if (\n !docDataMatcherWrite(row.newDocumentState as any) ||\n (row.assumedMasterState && !docDataMatcherWrite(row.assumedMasterState as any))\n ) {\n return true;\n }\n });\n if (nonAllowedRow) {\n adapter.closeConnection(res, 403, 'Forbidden');\n return;\n }\n let hasInvalidChange = false;\n\n const currentStateDocsArray = await this.collection.storageInstance.findDocumentsById(ids, true);\n const currentStateDocs = new Map<string, RxDocumentData<RxDocType>>();\n currentStateDocsArray.forEach(d => currentStateDocs.set((d as any)[primaryPath], d));\n\n const useRows: typeof rows = rows.map((row) => {\n const id = (row.newDocumentState as any)[primaryPath];\n const isChangeValid = this.changeValidator(ensureNotFalsy(authData), {\n newDocumentState: removeServerOnlyFields(row.newDocumentState),\n assumedMasterState: removeServerOnlyFields(row.assumedMasterState)\n });\n if (!isChangeValid) {\n hasInvalidChange = true;\n }\n\n const serverDoc = currentStateDocs.get(id);\n return {\n newDocumentState: mergeServerDocumentFields(row.newDocumentState, serverDoc),\n assumedMasterState: mergeServerDocumentFields(row.assumedMasterState as any, serverDoc)\n } as typeof row;\n });\n if (hasInvalidChange) {\n adapter.closeConnection(res, 403, 'Forbidden');\n return;\n }\n\n const conflicts = await replicationHandler.masterWrite(useRows);\n\n adapter.setResponseHeader(res, 'Content-Type', 'application/json');\n adapter.endResponseJson(res, conflicts);\n });\n this.server.adapter.get(this.server.serverApp, '/' + this.urlPath + '/pullStream', async (req, res) => {\n \n const authData = await getAuthDataByRequest<AuthType, any, any>(this.server, req, res);\n if (!authData) { return; }\n \n adapter.setSSEHeaders(res);\n const docDataMatcherStream = getDocAllowedMatcher(this, ensureNotFalsy(authData));\n const subscription = replicationHandler.masterChangeStream$.pipe(\n mergeMap(async (changes) => {\n /**\n * The auth-data might be expired\n * so we re-run the auth parsing each time\n * before emitting an event.\n */\n let authData: RxServerAuthData<AuthType>;\n try {\n authData = await server.authHandler(adapter.getRequestHeaders(req));\n } catch (err) {\n adapter.closeConnection(res, 401, 'Unauthorized');\n return null;\n }\n\n if (changes === 'RESYNC') {\n return changes;\n } else {\n const useDocs = changes.documents.filter(d => docDataMatcherStream(d as any));\n return {\n documents: useDocs,\n checkpoint: changes.checkpoint\n };\n }\n }),\n filter(f => f !== null && (f === 'RESYNC' || f.documents.length > 0))\n ).subscribe(filteredAndModified => {\n if (filteredAndModified === 'RESYNC') {\n adapter.responseWrite(res, 'data: ' + JSON.stringify(filteredAndModified) + '\\n\\n');\n } else {\n const responseDocuments = ensureNotFalsy(filteredAndModified).documents.map(d => removeServerOnlyFields(d as any));\n adapter.responseWrite(res, 'data: ' + JSON.stringify({ documents: responseDocuments, checkpoint: ensureNotFalsy(filteredAndModified).checkpoint }) + '\\n\\n');\n }\n\n });\n\n /**\n * @link https://youtu.be/0PcMuYGJPzM?si=AxkczxcMaUwhh8k9&t=363\n */\n adapter.onRequestClose(req, () => {\n subscription.unsubscribe();\n adapter.endResponse(res);\n });\n });\n }\n}\n"],"mappings":"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","ignoreList":[]}
1
+ {"version":3,"file":"endpoint-replication.js","names":["_core","require","_replicationWebsocket","_rxjs","_utils","_helper","RxServerReplicationEndpoint","exports","server","name","collection","queryModifier","changeValidator","serverOnlyFields","cors","type","adapter","setCors","join","blockPreviousReplicationVersionPaths","schema","version","urlPath","primaryPath","replicationHandler","getReplicationHandlerByCollection","database","authData","query","doesContainRegexQuerySelector","selector","Error","change","assumedMasterState","docContainsServerOnlyFields","newDocumentState","removeServerOnlyFields","removeServerOnlyFieldsMonad","mergeServerDocumentFields","mergeServerDocumentFieldsMonad","get","serverApp","req","res","getAuthDataByRequest","urlQuery","getRequestQuery","id","lwt","parseInt","limit","plainQuery","getChangedDocumentsSinceQuery","storageInstance","useQueryChanges","ensureNotFalsy","prepared","prepareQuery","jsonSchema","result","newCheckpoint","documents","length","lastOfArray","updatedAt","_meta","responseDocuments","map","d","setResponseHeader","endResponseJson","checkpoint","post","docDataMatcherWrite","getDocAllowedMatcher","rows","getRequestBody","ids","forEach","row","push","nonAllowedRow","find","closeConnection","hasInvalidChange","currentStateDocsArray","findDocumentsById","currentStateDocs","Map","set","useRows","isChangeValid","serverDoc","conflicts","masterWrite","setSSEHeaders","docDataMatcherStream","subscription","masterChangeStream$","pipe","mergeMap","changes","authHandler","getRequestHeaders","err","useDocs","filter","f","subscribe","filteredAndModified","responseWrite","JSON","stringify","onRequestClose","unsubscribe","endResponse","path","currentVersion","v","_loop","subPath","all"],"sources":["../../../../src/plugins/server/endpoint-replication.ts"],"sourcesContent":["import {\n FilledMangoQuery,\n RxCollection,\n RxReplicationHandler,\n RxReplicationWriteToMasterRow,\n RxStorageDefaultCheckpoint,\n StringKeys,\n prepareQuery,\n getChangedDocumentsSinceQuery,\n RxDocumentData\n} from 'rxdb/plugins/core';\nimport { getReplicationHandlerByCollection } from 'rxdb/plugins/replication-websocket';\nimport type { RxServer } from './rx-server.ts';\nimport type {\n RxServerAuthData,\n RxServerChangeValidator,\n RxServerEndpoint,\n RxServerQueryModifier\n} from './types.ts';\nimport { filter, mergeMap } from 'rxjs';\nimport {\n ensureNotFalsy,\n lastOfArray\n} from 'rxdb/plugins/utils';\n\nimport {\n docContainsServerOnlyFields,\n doesContainRegexQuerySelector,\n getAuthDataByRequest,\n getDocAllowedMatcher,\n mergeServerDocumentFieldsMonad,\n removeServerOnlyFieldsMonad,\n setCors\n} from './helper.ts';\n\nexport type RxReplicationEndpointMessageType = {\n id: string;\n method: StringKeys<RxReplicationHandler<any, any>> | 'auth';\n params: any[];\n};\n\nexport class RxServerReplicationEndpoint<ServerAppType, AuthType, RxDocType> implements RxServerEndpoint<AuthType, RxDocType> {\n readonly type = 'replication';\n readonly urlPath: string;\n readonly changeValidator: RxServerChangeValidator<AuthType, RxDocType>;\n readonly queryModifier: RxServerQueryModifier<AuthType, RxDocType>;\n constructor(\n public readonly server: RxServer<ServerAppType, AuthType>,\n public readonly name: string,\n public readonly collection: RxCollection<RxDocType>,\n queryModifier: RxServerQueryModifier<AuthType, RxDocType>,\n changeValidator: RxServerChangeValidator<AuthType, RxDocType>,\n public readonly serverOnlyFields: string[],\n public readonly cors?: string,\n ) {\n const adapter = this.server.adapter;\n\n setCors(this.server, [this.name].join('/'), cors);\n blockPreviousReplicationVersionPaths(this.server, [this.name].join('/'), collection.schema.version);\n\n this.urlPath = [this.name, collection.schema.version].join('/');\n\n const primaryPath = this.collection.schema.primaryPath;\n const replicationHandler = getReplicationHandlerByCollection(this.server.database, collection.name);\n this.queryModifier = (authData, query) => {\n if (doesContainRegexQuerySelector(query.selector)) {\n throw new Error('$regex queries not allowed because of DOS-attacks');\n }\n return queryModifier(authData, query);\n }\n this.changeValidator = (authData, change) => {\n if (\n (change.assumedMasterState && docContainsServerOnlyFields(serverOnlyFields, change.assumedMasterState)) ||\n docContainsServerOnlyFields(serverOnlyFields, change.newDocumentState)\n ) {\n return false;\n }\n return changeValidator(authData, change);\n }\n const removeServerOnlyFields = removeServerOnlyFieldsMonad<RxDocType>(this.serverOnlyFields);\n const mergeServerDocumentFields = mergeServerDocumentFieldsMonad<RxDocType>(this.serverOnlyFields);\n\n this.server.adapter.get(this.server.serverApp, '/' + this.urlPath + '/pull', async (req: any, res: any) => {\n const authData = await getAuthDataByRequest(this.server, req, res);\n if (!authData) { return; }\n\n const urlQuery = adapter.getRequestQuery(req);\n const id = urlQuery.id ? urlQuery.id as string : '';\n const lwt = urlQuery.lwt ? parseInt(urlQuery.lwt as any, 10) : 0;\n const limit = urlQuery.limit ? parseInt(urlQuery.limit as any, 10) : 1;\n const plainQuery = getChangedDocumentsSinceQuery<RxDocType, RxStorageDefaultCheckpoint>(\n this.collection.storageInstance,\n limit,\n { id, lwt }\n );\n const useQueryChanges: FilledMangoQuery<RxDocType> = this.queryModifier(\n ensureNotFalsy(authData),\n plainQuery\n );\n const prepared = prepareQuery<RxDocType>(\n this.collection.schema.jsonSchema,\n useQueryChanges\n );\n const result = await this.collection.storageInstance.query(prepared);\n\n const newCheckpoint = result.documents.length === 0 ? { id, lwt } : {\n id: ensureNotFalsy(lastOfArray(result.documents))[primaryPath],\n updatedAt: ensureNotFalsy(lastOfArray(result.documents))._meta.lwt\n };\n const responseDocuments = result.documents.map(d => removeServerOnlyFields(d));\n adapter.setResponseHeader(res, 'Content-Type', 'application/json');\n adapter.endResponseJson(res, {\n documents: responseDocuments,\n checkpoint: newCheckpoint\n });\n });\n\n this.server.adapter.post(this.server.serverApp, '/' + this.urlPath + '/push', async (req: any, res: any) => {\n const authData = await getAuthDataByRequest(this.server, req, res);\n if (!authData) { return; }\n\n const docDataMatcherWrite = getDocAllowedMatcher(this, ensureNotFalsy(authData as any));\n const rows: RxReplicationWriteToMasterRow<RxDocType>[] = adapter.getRequestBody(req);\n const ids: string[] = [];\n rows.forEach(row => ids.push((row.newDocumentState as any)[primaryPath]));\n\n for (const row of rows) {\n // TODO remove this check\n if (row.assumedMasterState && (row.assumedMasterState as any)._meta) {\n throw new Error('body document contains meta!');\n }\n }\n\n // ensure all writes are allowed\n const nonAllowedRow = rows.find(row => {\n if (\n !docDataMatcherWrite(row.newDocumentState as any) ||\n (row.assumedMasterState && !docDataMatcherWrite(row.assumedMasterState as any))\n ) {\n return true;\n }\n });\n if (nonAllowedRow) {\n adapter.closeConnection(res, 403, 'Forbidden');\n return;\n }\n let hasInvalidChange = false;\n\n const currentStateDocsArray = await this.collection.storageInstance.findDocumentsById(ids, true);\n const currentStateDocs = new Map<string, RxDocumentData<RxDocType>>();\n currentStateDocsArray.forEach(d => currentStateDocs.set((d as any)[primaryPath], d));\n\n const useRows: typeof rows = rows.map((row) => {\n const id = (row.newDocumentState as any)[primaryPath];\n const isChangeValid = this.changeValidator(ensureNotFalsy(authData), {\n newDocumentState: removeServerOnlyFields(row.newDocumentState),\n assumedMasterState: removeServerOnlyFields(row.assumedMasterState)\n });\n if (!isChangeValid) {\n hasInvalidChange = true;\n }\n\n const serverDoc = currentStateDocs.get(id);\n return {\n newDocumentState: mergeServerDocumentFields(row.newDocumentState, serverDoc),\n assumedMasterState: mergeServerDocumentFields(row.assumedMasterState as any, serverDoc)\n } as typeof row;\n });\n if (hasInvalidChange) {\n adapter.closeConnection(res, 403, 'Forbidden');\n return;\n }\n\n const conflicts = await replicationHandler.masterWrite(useRows);\n\n adapter.setResponseHeader(res, 'Content-Type', 'application/json');\n adapter.endResponseJson(res, conflicts);\n });\n this.server.adapter.get(this.server.serverApp, '/' + this.urlPath + '/pullStream', async (req, res) => {\n\n const authData = await getAuthDataByRequest<AuthType, any, any>(this.server, req, res);\n if (!authData) { return; }\n\n adapter.setSSEHeaders(res);\n const docDataMatcherStream = getDocAllowedMatcher(this, ensureNotFalsy(authData));\n const subscription = replicationHandler.masterChangeStream$.pipe(\n mergeMap(async (changes) => {\n /**\n * The auth-data might be expired\n * so we re-run the auth parsing each time\n * before emitting an event.\n */\n let authData: RxServerAuthData<AuthType>;\n try {\n authData = await server.authHandler(adapter.getRequestHeaders(req));\n } catch (err) {\n adapter.closeConnection(res, 401, 'Unauthorized');\n return null;\n }\n\n if (changes === 'RESYNC') {\n return changes;\n } else {\n const useDocs = changes.documents.filter(d => docDataMatcherStream(d as any));\n return {\n documents: useDocs,\n checkpoint: changes.checkpoint\n };\n }\n }),\n filter(f => f !== null && (f === 'RESYNC' || f.documents.length > 0))\n ).subscribe(filteredAndModified => {\n if (filteredAndModified === 'RESYNC') {\n adapter.responseWrite(res, 'data: ' + JSON.stringify(filteredAndModified) + '\\n\\n');\n } else {\n const responseDocuments = ensureNotFalsy(filteredAndModified).documents.map(d => removeServerOnlyFields(d as any));\n adapter.responseWrite(res, 'data: ' + JSON.stringify({ documents: responseDocuments, checkpoint: ensureNotFalsy(filteredAndModified).checkpoint }) + '\\n\\n');\n }\n\n });\n\n /**\n * @link https://youtu.be/0PcMuYGJPzM?si=AxkczxcMaUwhh8k9&t=363\n */\n adapter.onRequestClose(req, () => {\n subscription.unsubscribe();\n adapter.endResponse(res);\n });\n });\n }\n}\n\n\n/**\n * \"block\" the previous version urls and send a 426 on them so that\n * the clients know they must update.\n */\nexport function blockPreviousReplicationVersionPaths(\n server: RxServer<any, any>,\n path: string,\n currentVersion: number\n\n) {\n let v = 0;\n while (v < currentVersion) {\n const version = v;\n /**\n * Some adapters do not allow regex or handle them property (like Koa),\n * so to make it easier, use the hard-coded array of path parts.\n */\n [\n '',\n 'pull',\n 'push',\n 'pullStream'\n ].forEach(subPath => {\n server.adapter.all(server.serverApp, '/' + path + '/' + version + '/' + subPath, (req, res) => {\n server.adapter.closeConnection(res, 426, 'Outdated version ' + version + ' (newest is ' + currentVersion + ')');\n });\n });\n v++;\n }\n}\n"],"mappings":";;;;;;;AAAA,IAAAA,KAAA,GAAAC,OAAA;AAWA,IAAAC,qBAAA,GAAAD,OAAA;AAQA,IAAAE,KAAA,GAAAF,OAAA;AACA,IAAAG,MAAA,GAAAH,OAAA;AAKA,IAAAI,OAAA,GAAAJ,OAAA;AAQqB,IAQRK,2BAA2B,GAAAC,OAAA,CAAAD,2BAAA,GAKpC,SAAAA,4BACoBE,MAAyC,EACzCC,IAAY,EACZC,UAAmC,EACnDC,aAAyD,EACzDC,eAA6D,EAC7CC,gBAA0B,EAC1BC,IAAa,EAC/B;EAAA,KAZOC,IAAI,GAAG,aAAa;EAAA,KAKTP,MAAyC,GAAzCA,MAAyC;EAAA,KACzCC,IAAY,GAAZA,IAAY;EAAA,KACZC,UAAmC,GAAnCA,UAAmC;EAAA,KAGnCG,gBAA0B,GAA1BA,gBAA0B;EAAA,KAC1BC,IAAa,GAAbA,IAAa;EAE7B,IAAME,OAAO,GAAG,IAAI,CAACR,MAAM,CAACQ,OAAO;EAEnC,IAAAC,eAAO,EAAC,IAAI,CAACT,MAAM,EAAE,CAAC,IAAI,CAACC,IAAI,CAAC,CAACS,IAAI,CAAC,GAAG,CAAC,EAAEJ,IAAI,CAAC;EACjDK,oCAAoC,CAAC,IAAI,CAACX,MAAM,EAAE,CAAC,IAAI,CAACC,IAAI,CAAC,CAACS,IAAI,CAAC,GAAG,CAAC,EAAER,UAAU,CAACU,MAAM,CAACC,OAAO,CAAC;EAEnG,IAAI,CAACC,OAAO,GAAG,CAAC,IAAI,CAACb,IAAI,EAAEC,UAAU,CAACU,MAAM,CAACC,OAAO,CAAC,CAACH,IAAI,CAAC,GAAG,CAAC;EAE/D,IAAMK,WAAW,GAAG,IAAI,CAACb,UAAU,CAACU,MAAM,CAACG,WAAW;EACtD,IAAMC,kBAAkB,GAAG,IAAAC,uDAAiC,EAAC,IAAI,CAACjB,MAAM,CAACkB,QAAQ,EAAEhB,UAAU,CAACD,IAAI,CAAC;EACnG,IAAI,CAACE,aAAa,GAAG,CAACgB,QAAQ,EAAEC,KAAK,KAAK;IACtC,IAAI,IAAAC,qCAA6B,EAACD,KAAK,CAACE,QAAQ,CAAC,EAAE;MAC/C,MAAM,IAAIC,KAAK,CAAC,mDAAmD,CAAC;IACxE;IACA,OAAOpB,aAAa,CAACgB,QAAQ,EAAEC,KAAK,CAAC;EACzC,CAAC;EACD,IAAI,CAAChB,eAAe,GAAG,CAACe,QAAQ,EAAEK,MAAM,KAAK;IACzC,IACKA,MAAM,CAACC,kBAAkB,IAAI,IAAAC,mCAA2B,EAACrB,gBAAgB,EAAEmB,MAAM,CAACC,kBAAkB,CAAC,IACtG,IAAAC,mCAA2B,EAACrB,gBAAgB,EAAEmB,MAAM,CAACG,gBAAgB,CAAC,EACxE;MACE,OAAO,KAAK;IAChB;IACA,OAAOvB,eAAe,CAACe,QAAQ,EAAEK,MAAM,CAAC;EAC5C,CAAC;EACD,IAAMI,sBAAsB,GAAG,IAAAC,mCAA2B,EAAY,IAAI,CAACxB,gBAAgB,CAAC;EAC5F,IAAMyB,yBAAyB,GAAG,IAAAC,sCAA8B,EAAY,IAAI,CAAC1B,gBAAgB,CAAC;EAElG,IAAI,CAACL,MAAM,CAACQ,OAAO,CAACwB,GAAG,CAAC,IAAI,CAAChC,MAAM,CAACiC,SAAS,EAAE,GAAG,GAAG,IAAI,CAACnB,OAAO,GAAG,OAAO,EAAE,OAAOoB,GAAQ,EAAEC,GAAQ,KAAK;IACvG,IAAMhB,QAAQ,GAAG,MAAM,IAAAiB,4BAAoB,EAAC,IAAI,CAACpC,MAAM,EAAEkC,GAAG,EAAEC,GAAG,CAAC;IAClE,IAAI,CAAChB,QAAQ,EAAE;MAAE;IAAQ;IAEzB,IAAMkB,QAAQ,GAAG7B,OAAO,CAAC8B,eAAe,CAACJ,GAAG,CAAC;IAC7C,IAAMK,EAAE,GAAGF,QAAQ,CAACE,EAAE,GAAGF,QAAQ,CAACE,EAAE,GAAa,EAAE;IACnD,IAAMC,GAAG,GAAGH,QAAQ,CAACG,GAAG,GAAGC,QAAQ,CAACJ,QAAQ,CAACG,GAAG,EAAS,EAAE,CAAC,GAAG,CAAC;IAChE,IAAME,KAAK,GAAGL,QAAQ,CAACK,KAAK,GAAGD,QAAQ,CAACJ,QAAQ,CAACK,KAAK,EAAS,EAAE,CAAC,GAAG,CAAC;IACtE,IAAMC,UAAU,GAAG,IAAAC,mCAA6B,EAC5C,IAAI,CAAC1C,UAAU,CAAC2C,eAAe,EAC/BH,KAAK,EACL;MAAEH,EAAE;MAAEC;IAAI,CACd,CAAC;IACD,IAAMM,eAA4C,GAAG,IAAI,CAAC3C,aAAa,CACnE,IAAA4C,qBAAc,EAAC5B,QAAQ,CAAC,EACxBwB,UACJ,CAAC;IACD,IAAMK,QAAQ,GAAG,IAAAC,kBAAY,EACzB,IAAI,CAAC/C,UAAU,CAACU,MAAM,CAACsC,UAAU,EACjCJ,eACJ,CAAC;IACD,IAAMK,MAAM,GAAG,MAAM,IAAI,CAACjD,UAAU,CAAC2C,eAAe,CAACzB,KAAK,CAAC4B,QAAQ,CAAC;IAEpE,IAAMI,aAAa,GAAGD,MAAM,CAACE,SAAS,CAACC,MAAM,KAAK,CAAC,GAAG;MAAEf,EAAE;MAAEC;IAAI,CAAC,GAAG;MAChED,EAAE,EAAE,IAAAQ,qBAAc,EAAC,IAAAQ,kBAAW,EAACJ,MAAM,CAACE,SAAS,CAAC,CAAC,CAACtC,WAAW,CAAC;MAC9DyC,SAAS,EAAE,IAAAT,qBAAc,EAAC,IAAAQ,kBAAW,EAACJ,MAAM,CAACE,SAAS,CAAC,CAAC,CAACI,KAAK,CAACjB;IACnE,CAAC;IACD,IAAMkB,iBAAiB,GAAGP,MAAM,CAACE,SAAS,CAACM,GAAG,CAACC,CAAC,IAAIhC,sBAAsB,CAACgC,CAAC,CAAC,CAAC;IAC9EpD,OAAO,CAACqD,iBAAiB,CAAC1B,GAAG,EAAE,cAAc,EAAE,kBAAkB,CAAC;IAClE3B,OAAO,CAACsD,eAAe,CAAC3B,GAAG,EAAE;MACzBkB,SAAS,EAAEK,iBAAiB;MAC5BK,UAAU,EAAEX;IAChB,CAAC,CAAC;EACN,CAAC,CAAC;EAEF,IAAI,CAACpD,MAAM,CAACQ,OAAO,CAACwD,IAAI,CAAC,IAAI,CAAChE,MAAM,CAACiC,SAAS,EAAE,GAAG,GAAG,IAAI,CAACnB,OAAO,GAAG,OAAO,EAAE,OAAOoB,GAAQ,EAAEC,GAAQ,KAAK;IACxG,IAAMhB,QAAQ,GAAG,MAAM,IAAAiB,4BAAoB,EAAC,IAAI,CAACpC,MAAM,EAAEkC,GAAG,EAAEC,GAAG,CAAC;IAClE,IAAI,CAAChB,QAAQ,EAAE;MAAE;IAAQ;IAEzB,IAAM8C,mBAAmB,GAAG,IAAAC,4BAAoB,EAAC,IAAI,EAAE,IAAAnB,qBAAc,EAAC5B,QAAe,CAAC,CAAC;IACvF,IAAMgD,IAAgD,GAAG3D,OAAO,CAAC4D,cAAc,CAAClC,GAAG,CAAC;IACpF,IAAMmC,GAAa,GAAG,EAAE;IACxBF,IAAI,CAACG,OAAO,CAACC,GAAG,IAAIF,GAAG,CAACG,IAAI,CAAED,GAAG,CAAC5C,gBAAgB,CAASZ,WAAW,CAAC,CAAC,CAAC;IAEzE,KAAK,IAAMwD,GAAG,IAAIJ,IAAI,EAAE;MACpB;MACA,IAAII,GAAG,CAAC9C,kBAAkB,IAAK8C,GAAG,CAAC9C,kBAAkB,CAASgC,KAAK,EAAE;QACjE,MAAM,IAAIlC,KAAK,CAAC,8BAA8B,CAAC;MACnD;IACJ;;IAEA;IACA,IAAMkD,aAAa,GAAGN,IAAI,CAACO,IAAI,CAACH,GAAG,IAAI;MACnC,IACI,CAACN,mBAAmB,CAACM,GAAG,CAAC5C,gBAAuB,CAAC,IAChD4C,GAAG,CAAC9C,kBAAkB,IAAI,CAACwC,mBAAmB,CAACM,GAAG,CAAC9C,kBAAyB,CAAE,EACjF;QACE,OAAO,IAAI;MACf;IACJ,CAAC,CAAC;IACF,IAAIgD,aAAa,EAAE;MACfjE,OAAO,CAACmE,eAAe,CAACxC,GAAG,EAAE,GAAG,EAAE,WAAW,CAAC;MAC9C;IACJ;IACA,IAAIyC,gBAAgB,GAAG,KAAK;IAE5B,IAAMC,qBAAqB,GAAG,MAAM,IAAI,CAAC3E,UAAU,CAAC2C,eAAe,CAACiC,iBAAiB,CAACT,GAAG,EAAE,IAAI,CAAC;IAChG,IAAMU,gBAAgB,GAAG,IAAIC,GAAG,CAAoC,CAAC;IACrEH,qBAAqB,CAACP,OAAO,CAACV,CAAC,IAAImB,gBAAgB,CAACE,GAAG,CAAErB,CAAC,CAAS7C,WAAW,CAAC,EAAE6C,CAAC,CAAC,CAAC;IAEpF,IAAMsB,OAAoB,GAAGf,IAAI,CAACR,GAAG,CAAEY,GAAG,IAAK;MAC3C,IAAMhC,EAAE,GAAIgC,GAAG,CAAC5C,gBAAgB,CAASZ,WAAW,CAAC;MACrD,IAAMoE,aAAa,GAAG,IAAI,CAAC/E,eAAe,CAAC,IAAA2C,qBAAc,EAAC5B,QAAQ,CAAC,EAAE;QACjEQ,gBAAgB,EAAEC,sBAAsB,CAAC2C,GAAG,CAAC5C,gBAAgB,CAAC;QAC9DF,kBAAkB,EAAEG,sBAAsB,CAAC2C,GAAG,CAAC9C,kBAAkB;MACrE,CAAC,CAAC;MACF,IAAI,CAAC0D,aAAa,EAAE;QAChBP,gBAAgB,GAAG,IAAI;MAC3B;MAEA,IAAMQ,SAAS,GAAGL,gBAAgB,CAAC/C,GAAG,CAACO,EAAE,CAAC;MAC1C,OAAO;QACHZ,gBAAgB,EAAEG,yBAAyB,CAACyC,GAAG,CAAC5C,gBAAgB,EAAEyD,SAAS,CAAC;QAC5E3D,kBAAkB,EAAEK,yBAAyB,CAACyC,GAAG,CAAC9C,kBAAkB,EAAS2D,SAAS;MAC1F,CAAC;IACL,CAAC,CAAC;IACF,IAAIR,gBAAgB,EAAE;MAClBpE,OAAO,CAACmE,eAAe,CAACxC,GAAG,EAAE,GAAG,EAAE,WAAW,CAAC;MAC9C;IACJ;IAEA,IAAMkD,SAAS,GAAG,MAAMrE,kBAAkB,CAACsE,WAAW,CAACJ,OAAO,CAAC;IAE/D1E,OAAO,CAACqD,iBAAiB,CAAC1B,GAAG,EAAE,cAAc,EAAE,kBAAkB,CAAC;IAClE3B,OAAO,CAACsD,eAAe,CAAC3B,GAAG,EAAEkD,SAAS,CAAC;EAC3C,CAAC,CAAC;EACF,IAAI,CAACrF,MAAM,CAACQ,OAAO,CAACwB,GAAG,CAAC,IAAI,CAAChC,MAAM,CAACiC,SAAS,EAAE,GAAG,GAAG,IAAI,CAACnB,OAAO,GAAG,aAAa,EAAE,OAAOoB,GAAG,EAAEC,GAAG,KAAK;IAEnG,IAAMhB,QAAQ,GAAG,MAAM,IAAAiB,4BAAoB,EAAqB,IAAI,CAACpC,MAAM,EAAEkC,GAAG,EAAEC,GAAG,CAAC;IACtF,IAAI,CAAChB,QAAQ,EAAE;MAAE;IAAQ;IAEzBX,OAAO,CAAC+E,aAAa,CAACpD,GAAG,CAAC;IAC1B,IAAMqD,oBAAoB,GAAG,IAAAtB,4BAAoB,EAAC,IAAI,EAAE,IAAAnB,qBAAc,EAAC5B,QAAQ,CAAC,CAAC;IACjF,IAAMsE,YAAY,GAAGzE,kBAAkB,CAAC0E,mBAAmB,CAACC,IAAI,CAC5D,IAAAC,cAAQ,EAAC,MAAOC,OAAO,IAAK;MACxB;AACpB;AACA;AACA;AACA;MACoB,IAAI1E,QAAoC;MACxC,IAAI;QACAA,QAAQ,GAAG,MAAMnB,MAAM,CAAC8F,WAAW,CAACtF,OAAO,CAACuF,iBAAiB,CAAC7D,GAAG,CAAC,CAAC;MACvE,CAAC,CAAC,OAAO8D,GAAG,EAAE;QACVxF,OAAO,CAACmE,eAAe,CAACxC,GAAG,EAAE,GAAG,EAAE,cAAc,CAAC;QACjD,OAAO,IAAI;MACf;MAEA,IAAI0D,OAAO,KAAK,QAAQ,EAAE;QACtB,OAAOA,OAAO;MAClB,CAAC,MAAM;QACH,IAAMI,OAAO,GAAGJ,OAAO,CAACxC,SAAS,CAAC6C,MAAM,CAACtC,CAAC,IAAI4B,oBAAoB,CAAC5B,CAAQ,CAAC,CAAC;QAC7E,OAAO;UACHP,SAAS,EAAE4C,OAAO;UAClBlC,UAAU,EAAE8B,OAAO,CAAC9B;QACxB,CAAC;MACL;IACJ,CAAC,CAAC,EACF,IAAAmC,YAAM,EAACC,CAAC,IAAIA,CAAC,KAAK,IAAI,KAAKA,CAAC,KAAK,QAAQ,IAAIA,CAAC,CAAC9C,SAAS,CAACC,MAAM,GAAG,CAAC,CAAC,CACxE,CAAC,CAAC8C,SAAS,CAACC,mBAAmB,IAAI;MAC/B,IAAIA,mBAAmB,KAAK,QAAQ,EAAE;QAClC7F,OAAO,CAAC8F,aAAa,CAACnE,GAAG,EAAE,QAAQ,GAAGoE,IAAI,CAACC,SAAS,CAACH,mBAAmB,CAAC,GAAG,MAAM,CAAC;MACvF,CAAC,MAAM;QACH,IAAM3C,iBAAiB,GAAG,IAAAX,qBAAc,EAACsD,mBAAmB,CAAC,CAAChD,SAAS,CAACM,GAAG,CAACC,CAAC,IAAIhC,sBAAsB,CAACgC,CAAQ,CAAC,CAAC;QAClHpD,OAAO,CAAC8F,aAAa,CAACnE,GAAG,EAAE,QAAQ,GAAGoE,IAAI,CAACC,SAAS,CAAC;UAAEnD,SAAS,EAAEK,iBAAiB;UAAEK,UAAU,EAAE,IAAAhB,qBAAc,EAACsD,mBAAmB,CAAC,CAACtC;QAAW,CAAC,CAAC,GAAG,MAAM,CAAC;MAChK;IAEJ,CAAC,CAAC;;IAEF;AACZ;AACA;IACYvD,OAAO,CAACiG,cAAc,CAACvE,GAAG,EAAE,MAAM;MAC9BuD,YAAY,CAACiB,WAAW,CAAC,CAAC;MAC1BlG,OAAO,CAACmG,WAAW,CAACxE,GAAG,CAAC;IAC5B,CAAC,CAAC;EACN,CAAC,CAAC;AACN,CAAC;AAIL;AACA;AACA;AACA;AACO,SAASxB,oCAAoCA,CAChDX,MAA0B,EAC1B4G,IAAY,EACZC,cAAsB,EAExB;EACE,IAAIC,CAAC,GAAG,CAAC;EAAC,IAAAC,KAAA,YAAAA,CAAA,EACiB;IACvB,IAAMlG,OAAO,GAAGiG,CAAC;IACjB;AACR;AACA;AACA;IACQ,CACI,EAAE,EACF,MAAM,EACN,MAAM,EACN,YAAY,CACf,CAACxC,OAAO,CAAC0C,OAAO,IAAI;MACjBhH,MAAM,CAACQ,OAAO,CAACyG,GAAG,CAACjH,MAAM,CAACiC,SAAS,EAAE,GAAG,GAAG2E,IAAI,GAAG,GAAG,GAAG/F,OAAO,GAAG,GAAG,GAAGmG,OAAO,EAAE,CAAC9E,GAAG,EAAEC,GAAG,KAAK;QAC3FnC,MAAM,CAACQ,OAAO,CAACmE,eAAe,CAACxC,GAAG,EAAE,GAAG,EAAE,mBAAmB,GAAGtB,OAAO,GAAG,cAAc,GAAGgG,cAAc,GAAG,GAAG,CAAC;MACnH,CAAC,CAAC;IACN,CAAC,CAAC;IACFC,CAAC,EAAE;EACP,CAAC;EAjBD,OAAOA,CAAC,GAAGD,cAAc;IAAAE,KAAA;EAAA;AAkB7B","ignoreList":[]}
@@ -4,6 +4,7 @@ Object.defineProperty(exports, "__esModule", {
4
4
  value: true
5
5
  });
6
6
  exports.RxServerRestEndpoint = exports.REST_PATHS = void 0;
7
+ exports.blockPreviousReplicationVersionPathsRest = blockPreviousReplicationVersionPathsRest;
7
8
  var _core = require("rxdb/plugins/core");
8
9
  var _rxjs = require("rxjs");
9
10
  var _utils = require("rxdb/plugins/utils");
@@ -26,7 +27,7 @@ var RxServerRestEndpoint = exports.RxServerRestEndpoint = function RxServerRestE
26
27
  this.cors = cors;
27
28
  var adapter = server.adapter;
28
29
  (0, _helper.setCors)(this.server, [this.name].join('/'), cors);
29
- (0, _helper.blockPreviousVersionPaths)(this.server, [this.name].join('/'), collection.schema.version);
30
+ blockPreviousReplicationVersionPathsRest(this.server, [this.name].join('/'), collection.schema.version);
30
31
  this.urlPath = [this.name, collection.schema.version].join('/');
31
32
  var primaryPath = this.collection.schema.primaryPath;
32
33
  this.queryModifier = (authData, query) => {
@@ -232,4 +233,27 @@ var RxServerRestEndpoint = exports.RxServerRestEndpoint = function RxServerRestE
232
233
  adapter.endResponseJson(res, {});
233
234
  });
234
235
  };
236
+ /**
237
+ * "block" the previous version urls and send a 426 on them so that
238
+ * the clients know they must update.
239
+ */
240
+ function blockPreviousReplicationVersionPathsRest(server, path, currentVersion) {
241
+ var v = 0;
242
+ var _loop3 = function () {
243
+ var version = v;
244
+ /**
245
+ * Some adapters do not allow regex or handle them property (like Koa),
246
+ * so to make it easier, use the hard-coded array of path parts.
247
+ */
248
+ ['', 'query', 'query/observe', 'get', 'set', 'delete'].forEach(subPath => {
249
+ server.adapter.all(server.serverApp, '/' + path + '/' + version + '/' + subPath, (req, res) => {
250
+ server.adapter.closeConnection(res, 426, 'Outdated version ' + version + ' (newest is ' + currentVersion + ')');
251
+ });
252
+ });
253
+ v++;
254
+ };
255
+ while (v < currentVersion) {
256
+ _loop3();
257
+ }
258
+ }
235
259
  //# sourceMappingURL=endpoint-rest.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"endpoint-rest.js","names":["_core","require","_rxjs","_utils","_helper","REST_PATHS","exports","RxServerRestEndpoint","server","name","collection","queryModifier","changeValidator","serverOnlyFields","cors","_this","type","adapter","setCors","join","blockPreviousVersionPaths","schema","version","urlPath","primaryPath","authData","query","doesContainRegexQuerySelector","selector","Error","change","assumedMasterState","docContainsServerOnlyFields","newDocumentState","removeServerOnlyFields","removeServerOnlyFieldsMonad","post","serverApp","req","res","ensureNotFalsy","getRequestBody","getAuthDataByRequest","useQuery","normalizeMangoQuery","jsonSchema","err","closeConnection","rxQuery","find","result","exec","setResponseHeader","endResponseJson","documents","map","d","toJSON","get","setSSEHeaders","JSON","parse","atob","getRequestQuery","subscription","$","pipe","mergeMap","resultData","doc","authHandler","getRequestHeaders","filter","f","subscribe","responseWrite","stringify","onRequestClose","unsubscribe","endResponse","ids","findByIds","resultMap","resultValues","Array","from","values","docMatcher","getDocAllowedMatcher","useDocs","docDataMatcherWrite","docsData","docData","allowed","onWriteError","rxdb","code","push","length","promises","docs","useDocsData","slice","_loop","_docData","id","insert","catch","isAllowed","v","patch","_ret","Promise","all","useIds","docsMap","_loop2","isAllowedDoc","isAllowedChange","remove","_ret2"],"sources":["../../../../src/plugins/server/endpoint-rest.ts"],"sourcesContent":["import {\n FilledMangoQuery,\n RxCollection,\n RxError,\n normalizeMangoQuery\n} from 'rxdb/plugins/core';\nimport type { RxServer } from './rx-server.ts';\nimport type {\n RxServerChangeValidator,\n RxServerEndpoint,\n RxServerQueryModifier\n} from './types.ts';\nimport { filter, mergeMap } from 'rxjs';\nimport {\n ensureNotFalsy,\n getFromMapOrThrow\n} from 'rxdb/plugins/utils';\n\nimport {\n blockPreviousVersionPaths,\n docContainsServerOnlyFields,\n doesContainRegexQuerySelector,\n getAuthDataByRequest,\n getDocAllowedMatcher,\n removeServerOnlyFieldsMonad,\n setCors\n} from './helper.ts';\n\n\nexport const REST_PATHS = [\n 'query',\n 'query/observe',\n 'get',\n 'set',\n 'delete',\n\n // TODO\n /*\n 'attachments/add',\n 'attachments/delete',\n 'events'\n */\n] as const;\n\n\nexport class RxServerRestEndpoint<ServerAppType, AuthType, RxDocType> implements RxServerEndpoint<AuthType, RxDocType> {\n readonly type = 'rest';\n readonly urlPath: string;\n readonly changeValidator: RxServerChangeValidator<AuthType, RxDocType>;\n readonly queryModifier: RxServerQueryModifier<AuthType, RxDocType>;\n constructor(\n public readonly server: RxServer<ServerAppType, AuthType>,\n public readonly name: string,\n public readonly collection: RxCollection<RxDocType>,\n queryModifier: RxServerQueryModifier<AuthType, RxDocType>,\n changeValidator: RxServerChangeValidator<AuthType, RxDocType>,\n public readonly serverOnlyFields: string[],\n public readonly cors?: string\n ) {\n const adapter = server.adapter;\n setCors(this.server, [this.name].join('/'), cors);\n blockPreviousVersionPaths(this.server, [this.name].join('/'), collection.schema.version);\n\n this.urlPath = [this.name, collection.schema.version].join('/');\n const primaryPath = this.collection.schema.primaryPath;\n\n this.queryModifier = (authData, query) => {\n if (doesContainRegexQuerySelector(query.selector)) {\n throw new Error('$regex queries not allowed because of DOS-attacks');\n }\n return queryModifier(authData, query);\n }\n this.changeValidator = (authData, change) => {\n if (\n (\n change.assumedMasterState &&\n docContainsServerOnlyFields(serverOnlyFields, change.assumedMasterState)\n ) ||\n docContainsServerOnlyFields(serverOnlyFields, change.newDocumentState)\n ) {\n return false;\n }\n return changeValidator(authData, change);\n }\n const removeServerOnlyFields = removeServerOnlyFieldsMonad(this.serverOnlyFields);\n\n this.server.adapter.post(this.server.serverApp, '/' + this.urlPath + '/query', async (req, res) => {\n ensureNotFalsy(adapter.getRequestBody(req), 'req body is empty');\n const authData = await getAuthDataByRequest(this.server, req, res);\n if (!authData) { return; }\n\n let useQuery: FilledMangoQuery<RxDocType>\n try {\n useQuery = this.queryModifier(\n ensureNotFalsy(authData),\n normalizeMangoQuery(\n this.collection.schema.jsonSchema,\n adapter.getRequestBody(req)\n )\n );\n } catch (err) {\n adapter.closeConnection(res, 400, 'Bad Request');\n return;\n }\n const rxQuery = this.collection.find(useQuery as any);\n const result = await rxQuery.exec();\n adapter.setResponseHeader(res, 'Content-Type', 'application/json');\n adapter.endResponseJson(res, {\n documents: result.map(d => removeServerOnlyFields(d.toJSON()))\n });\n });\n\n /**\n * It is not possible to send data with server send events,\n * so we send the query as query parameter in base64\n * like ?query=e3NlbGVjdG9yOiB7fX0=\n */\n this.server.adapter.get(this.server.serverApp, '/' + this.urlPath + '/query/observe', async (req, res) => {\n let authData = await getAuthDataByRequest(this.server, req, res);\n if (!authData) { return; }\n\n adapter.setSSEHeaders(res);\n\n const useQuery: FilledMangoQuery<RxDocType> = this.queryModifier(\n ensureNotFalsy(authData),\n normalizeMangoQuery(\n this.collection.schema.jsonSchema,\n JSON.parse(atob(adapter.getRequestQuery(req).query as string))\n )\n );\n\n const rxQuery = this.collection.find(useQuery as any);\n const subscription = rxQuery.$.pipe(\n mergeMap(async (result) => {\n const resultData = result.map(doc => removeServerOnlyFields(doc.toJSON()));\n\n /**\n * The auth-data might be expired\n * so we re-run the auth parsing each time\n * before emitting the new results.\n */\n try {\n authData = await server.authHandler(adapter.getRequestHeaders(req)) as any;\n } catch (err) {\n adapter.closeConnection(res, 401, 'Unauthorized');\n return null;\n }\n\n return resultData;\n }),\n filter(f => f !== null)\n ).subscribe(resultData => {\n adapter.responseWrite(res, 'data: ' + JSON.stringify(resultData) + '\\n\\n');\n });\n\n /**\n * @link https://youtu.be/0PcMuYGJPzM?si=AxkczxcMaUwhh8k9&t=363\n */\n adapter.onRequestClose(req, () => {\n subscription.unsubscribe();\n adapter.endResponse(res);\n });\n });\n\n\n this.server.adapter.post(this.server.serverApp, '/' + this.urlPath + '/get', async (req, res) => {\n const authData = await getAuthDataByRequest(this.server, req, res);\n if (!authData) { return; }\n\n const ids: string[] = adapter.getRequestBody(req);\n\n const rxQuery = this.collection.findByIds(ids);\n const resultMap = await rxQuery.exec();\n const resultValues = Array.from(resultMap.values());\n const docMatcher = getDocAllowedMatcher(this, ensureNotFalsy(authData) as any);\n let useDocs = resultValues.map(d => d.toJSON());\n useDocs = useDocs.filter(d => docMatcher(d as any));\n useDocs = useDocs.map(d => removeServerOnlyFields(d))\n\n adapter.setResponseHeader(res, 'Content-Type', 'application/json');\n adapter.endResponseJson(res, {\n documents: useDocs\n });\n });\n\n this.server.adapter.post(this.server.serverApp, '/' + this.urlPath + '/set', async (req, res) => {\n const authData = await getAuthDataByRequest(this.server, req, res);\n if (!authData) { return; }\n\n const docDataMatcherWrite = getDocAllowedMatcher(this, ensureNotFalsy(authData) as any);\n\n let docsData: RxDocType[] = adapter.getRequestBody(req);\n\n for (const docData of docsData) {\n const allowed = docDataMatcherWrite(docData as any);\n if (!allowed) {\n adapter.closeConnection(res, 403, 'Forbidden');\n return;\n }\n }\n\n function onWriteError(err: RxError, docData: RxDocType) {\n if (err.rxdb && err.code === 'CONFLICT') {\n // just retry on conflicts\n docsData.push(docData);\n } else {\n adapter.closeConnection(res, 500, 'Internal Server Error');\n throw err;\n }\n }\n\n while (docsData.length > 0) {\n const promises: Promise<any>[] = [];\n const docs = await collection.findByIds(docsData.map(d => (d as any)[primaryPath])).exec();\n let useDocsData = docsData.slice();\n docsData = [];\n for (const docData of useDocsData) {\n const id = (docData as any)[primaryPath];\n const doc = docs.get(id);\n if (!doc) {\n promises.push(this.collection.insert(docData).catch(err => onWriteError(err, docData)));\n } else {\n const isAllowed = this.changeValidator(authData, {\n newDocumentState: removeServerOnlyFields(docData as any),\n assumedMasterState: removeServerOnlyFields(doc.toJSON(true))\n });\n if (!isAllowed) {\n adapter.closeConnection(res, 403, 'Forbidden');\n return;\n }\n promises.push(doc.patch(docData).catch(err => onWriteError(err, docData)));\n }\n }\n await Promise.all(promises);\n }\n\n adapter.setResponseHeader(res, 'Content-Type', 'application/json')\n adapter.endResponseJson(res, {});\n });\n\n this.server.adapter.post(this.server.serverApp, '/' + this.urlPath + '/delete', async (req, res) => {\n const authData = await getAuthDataByRequest(this.server, req, res);\n if (!authData) { return; }\n\n const docDataMatcherWrite = getDocAllowedMatcher(this, ensureNotFalsy(authData));\n\n let ids: string[] = adapter.getRequestBody(req);\n while (ids.length > 0) {\n const useIds = ids.slice(0);\n ids = [];\n const promises: Promise<any>[] = [];\n const docsMap = await this.collection.findByIds(useIds).exec();\n for (const id of useIds) {\n const doc = docsMap.get(id);\n if (doc) {\n const isAllowedDoc = docDataMatcherWrite(doc.toJSON(true) as any);\n if (!isAllowedDoc) {\n adapter.closeConnection(res, 403, 'Forbidden');\n return;\n }\n\n const isAllowedChange = this.changeValidator(authData, {\n newDocumentState: doc.toJSON(true) as any,\n assumedMasterState: doc.toJSON(true) as any\n });\n if (!isAllowedChange) {\n adapter.closeConnection(res, 403, 'Forbidden');\n return;\n }\n\n promises.push(doc.remove().catch((err: RxError) => {\n if (err.rxdb && err.code === 'CONFLICT') {\n // just retry on conflicts\n ids.push(id);\n } else {\n adapter.closeConnection(res, 500, 'Internal Server Error');\n throw err;\n }\n }));\n }\n }\n await Promise.all(promises);\n }\n adapter.setResponseHeader(res, 'Content-Type', 'application/json');\n adapter.endResponseJson(res, {});\n });\n }\n}\n"],"mappings":"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","ignoreList":[]}
1
+ {"version":3,"file":"endpoint-rest.js","names":["_core","require","_rxjs","_utils","_helper","REST_PATHS","exports","RxServerRestEndpoint","server","name","collection","queryModifier","changeValidator","serverOnlyFields","cors","_this","type","adapter","setCors","join","blockPreviousReplicationVersionPathsRest","schema","version","urlPath","primaryPath","authData","query","doesContainRegexQuerySelector","selector","Error","change","assumedMasterState","docContainsServerOnlyFields","newDocumentState","removeServerOnlyFields","removeServerOnlyFieldsMonad","post","serverApp","req","res","ensureNotFalsy","getRequestBody","getAuthDataByRequest","useQuery","normalizeMangoQuery","jsonSchema","err","closeConnection","rxQuery","find","result","exec","setResponseHeader","endResponseJson","documents","map","d","toJSON","get","setSSEHeaders","JSON","parse","atob","getRequestQuery","subscription","$","pipe","mergeMap","resultData","doc","authHandler","getRequestHeaders","filter","f","subscribe","responseWrite","stringify","onRequestClose","unsubscribe","endResponse","ids","findByIds","resultMap","resultValues","Array","from","values","docMatcher","getDocAllowedMatcher","useDocs","docDataMatcherWrite","docsData","docData","allowed","onWriteError","rxdb","code","push","length","promises","docs","useDocsData","slice","_loop","_docData","id","insert","catch","isAllowed","v","patch","_ret","Promise","all","useIds","docsMap","_loop2","isAllowedDoc","isAllowedChange","remove","_ret2","path","currentVersion","_loop3","forEach","subPath"],"sources":["../../../../src/plugins/server/endpoint-rest.ts"],"sourcesContent":["import {\n FilledMangoQuery,\n RxCollection,\n RxError,\n normalizeMangoQuery\n} from 'rxdb/plugins/core';\nimport type { RxServer } from './rx-server.ts';\nimport type {\n RxServerChangeValidator,\n RxServerEndpoint,\n RxServerQueryModifier\n} from './types.ts';\nimport { filter, mergeMap } from 'rxjs';\nimport {\n ensureNotFalsy,\n getFromMapOrThrow\n} from 'rxdb/plugins/utils';\n\nimport {\n docContainsServerOnlyFields,\n doesContainRegexQuerySelector,\n getAuthDataByRequest,\n getDocAllowedMatcher,\n removeServerOnlyFieldsMonad,\n setCors\n} from './helper.ts';\n\n\nexport const REST_PATHS = [\n 'query',\n 'query/observe',\n 'get',\n 'set',\n 'delete',\n\n // TODO\n /*\n 'attachments/add',\n 'attachments/delete',\n 'events'\n */\n] as const;\n\n\nexport class RxServerRestEndpoint<ServerAppType, AuthType, RxDocType> implements RxServerEndpoint<AuthType, RxDocType> {\n readonly type = 'rest';\n readonly urlPath: string;\n readonly changeValidator: RxServerChangeValidator<AuthType, RxDocType>;\n readonly queryModifier: RxServerQueryModifier<AuthType, RxDocType>;\n constructor(\n public readonly server: RxServer<ServerAppType, AuthType>,\n public readonly name: string,\n public readonly collection: RxCollection<RxDocType>,\n queryModifier: RxServerQueryModifier<AuthType, RxDocType>,\n changeValidator: RxServerChangeValidator<AuthType, RxDocType>,\n public readonly serverOnlyFields: string[],\n public readonly cors?: string\n ) {\n const adapter = server.adapter;\n setCors(this.server, [this.name].join('/'), cors);\n blockPreviousReplicationVersionPathsRest(this.server, [this.name].join('/'), collection.schema.version);\n\n this.urlPath = [this.name, collection.schema.version].join('/');\n const primaryPath = this.collection.schema.primaryPath;\n\n this.queryModifier = (authData, query) => {\n if (doesContainRegexQuerySelector(query.selector)) {\n throw new Error('$regex queries not allowed because of DOS-attacks');\n }\n return queryModifier(authData, query);\n }\n this.changeValidator = (authData, change) => {\n if (\n (\n change.assumedMasterState &&\n docContainsServerOnlyFields(serverOnlyFields, change.assumedMasterState)\n ) ||\n docContainsServerOnlyFields(serverOnlyFields, change.newDocumentState)\n ) {\n return false;\n }\n return changeValidator(authData, change);\n }\n const removeServerOnlyFields = removeServerOnlyFieldsMonad(this.serverOnlyFields);\n\n this.server.adapter.post(this.server.serverApp, '/' + this.urlPath + '/query', async (req, res) => {\n ensureNotFalsy(adapter.getRequestBody(req), 'req body is empty');\n const authData = await getAuthDataByRequest(this.server, req, res);\n if (!authData) { return; }\n\n let useQuery: FilledMangoQuery<RxDocType>\n try {\n useQuery = this.queryModifier(\n ensureNotFalsy(authData),\n normalizeMangoQuery(\n this.collection.schema.jsonSchema,\n adapter.getRequestBody(req)\n )\n );\n } catch (err) {\n adapter.closeConnection(res, 400, 'Bad Request');\n return;\n }\n const rxQuery = this.collection.find(useQuery as any);\n const result = await rxQuery.exec();\n adapter.setResponseHeader(res, 'Content-Type', 'application/json');\n adapter.endResponseJson(res, {\n documents: result.map(d => removeServerOnlyFields(d.toJSON()))\n });\n });\n\n /**\n * It is not possible to send data with server send events,\n * so we send the query as query parameter in base64\n * like ?query=e3NlbGVjdG9yOiB7fX0=\n */\n this.server.adapter.get(this.server.serverApp, '/' + this.urlPath + '/query/observe', async (req, res) => {\n let authData = await getAuthDataByRequest(this.server, req, res);\n if (!authData) { return; }\n\n adapter.setSSEHeaders(res);\n\n const useQuery: FilledMangoQuery<RxDocType> = this.queryModifier(\n ensureNotFalsy(authData),\n normalizeMangoQuery(\n this.collection.schema.jsonSchema,\n JSON.parse(atob(adapter.getRequestQuery(req).query as string))\n )\n );\n\n const rxQuery = this.collection.find(useQuery as any);\n const subscription = rxQuery.$.pipe(\n mergeMap(async (result) => {\n const resultData = result.map(doc => removeServerOnlyFields(doc.toJSON()));\n\n /**\n * The auth-data might be expired\n * so we re-run the auth parsing each time\n * before emitting the new results.\n */\n try {\n authData = await server.authHandler(adapter.getRequestHeaders(req)) as any;\n } catch (err) {\n adapter.closeConnection(res, 401, 'Unauthorized');\n return null;\n }\n\n return resultData;\n }),\n filter(f => f !== null)\n ).subscribe(resultData => {\n adapter.responseWrite(res, 'data: ' + JSON.stringify(resultData) + '\\n\\n');\n });\n\n /**\n * @link https://youtu.be/0PcMuYGJPzM?si=AxkczxcMaUwhh8k9&t=363\n */\n adapter.onRequestClose(req, () => {\n subscription.unsubscribe();\n adapter.endResponse(res);\n });\n });\n\n\n this.server.adapter.post(this.server.serverApp, '/' + this.urlPath + '/get', async (req, res) => {\n const authData = await getAuthDataByRequest(this.server, req, res);\n if (!authData) { return; }\n\n const ids: string[] = adapter.getRequestBody(req);\n\n const rxQuery = this.collection.findByIds(ids);\n const resultMap = await rxQuery.exec();\n const resultValues = Array.from(resultMap.values());\n const docMatcher = getDocAllowedMatcher(this, ensureNotFalsy(authData) as any);\n let useDocs = resultValues.map(d => d.toJSON());\n useDocs = useDocs.filter(d => docMatcher(d as any));\n useDocs = useDocs.map(d => removeServerOnlyFields(d))\n\n adapter.setResponseHeader(res, 'Content-Type', 'application/json');\n adapter.endResponseJson(res, {\n documents: useDocs\n });\n });\n\n this.server.adapter.post(this.server.serverApp, '/' + this.urlPath + '/set', async (req, res) => {\n const authData = await getAuthDataByRequest(this.server, req, res);\n if (!authData) { return; }\n\n const docDataMatcherWrite = getDocAllowedMatcher(this, ensureNotFalsy(authData) as any);\n\n let docsData: RxDocType[] = adapter.getRequestBody(req);\n\n for (const docData of docsData) {\n const allowed = docDataMatcherWrite(docData as any);\n if (!allowed) {\n adapter.closeConnection(res, 403, 'Forbidden');\n return;\n }\n }\n\n function onWriteError(err: RxError, docData: RxDocType) {\n if (err.rxdb && err.code === 'CONFLICT') {\n // just retry on conflicts\n docsData.push(docData);\n } else {\n adapter.closeConnection(res, 500, 'Internal Server Error');\n throw err;\n }\n }\n\n while (docsData.length > 0) {\n const promises: Promise<any>[] = [];\n const docs = await collection.findByIds(docsData.map(d => (d as any)[primaryPath])).exec();\n let useDocsData = docsData.slice();\n docsData = [];\n for (const docData of useDocsData) {\n const id = (docData as any)[primaryPath];\n const doc = docs.get(id);\n if (!doc) {\n promises.push(this.collection.insert(docData).catch(err => onWriteError(err, docData)));\n } else {\n const isAllowed = this.changeValidator(authData, {\n newDocumentState: removeServerOnlyFields(docData as any),\n assumedMasterState: removeServerOnlyFields(doc.toJSON(true))\n });\n if (!isAllowed) {\n adapter.closeConnection(res, 403, 'Forbidden');\n return;\n }\n promises.push(doc.patch(docData).catch(err => onWriteError(err, docData)));\n }\n }\n await Promise.all(promises);\n }\n\n adapter.setResponseHeader(res, 'Content-Type', 'application/json')\n adapter.endResponseJson(res, {});\n });\n\n this.server.adapter.post(this.server.serverApp, '/' + this.urlPath + '/delete', async (req, res) => {\n const authData = await getAuthDataByRequest(this.server, req, res);\n if (!authData) { return; }\n\n const docDataMatcherWrite = getDocAllowedMatcher(this, ensureNotFalsy(authData));\n\n let ids: string[] = adapter.getRequestBody(req);\n while (ids.length > 0) {\n const useIds = ids.slice(0);\n ids = [];\n const promises: Promise<any>[] = [];\n const docsMap = await this.collection.findByIds(useIds).exec();\n for (const id of useIds) {\n const doc = docsMap.get(id);\n if (doc) {\n const isAllowedDoc = docDataMatcherWrite(doc.toJSON(true) as any);\n if (!isAllowedDoc) {\n adapter.closeConnection(res, 403, 'Forbidden');\n return;\n }\n\n const isAllowedChange = this.changeValidator(authData, {\n newDocumentState: doc.toJSON(true) as any,\n assumedMasterState: doc.toJSON(true) as any\n });\n if (!isAllowedChange) {\n adapter.closeConnection(res, 403, 'Forbidden');\n return;\n }\n\n promises.push(doc.remove().catch((err: RxError) => {\n if (err.rxdb && err.code === 'CONFLICT') {\n // just retry on conflicts\n ids.push(id);\n } else {\n adapter.closeConnection(res, 500, 'Internal Server Error');\n throw err;\n }\n }));\n }\n }\n await Promise.all(promises);\n }\n adapter.setResponseHeader(res, 'Content-Type', 'application/json');\n adapter.endResponseJson(res, {});\n });\n }\n}\n\n\n/**\n * \"block\" the previous version urls and send a 426 on them so that\n * the clients know they must update.\n */\nexport function blockPreviousReplicationVersionPathsRest(\n server: RxServer<any, any>,\n path: string,\n currentVersion: number\n\n) {\n let v = 0;\n while (v < currentVersion) {\n const version = v;\n /**\n * Some adapters do not allow regex or handle them property (like Koa),\n * so to make it easier, use the hard-coded array of path parts.\n */\n [\n '',\n 'query',\n 'query/observe',\n 'get',\n 'set',\n 'delete'\n ].forEach(subPath => {\n server.adapter.all(server.serverApp, '/' + path + '/' + version + '/' + subPath, (req, res) => {\n server.adapter.closeConnection(res, 426, 'Outdated version ' + version + ' (newest is ' + currentVersion + ')');\n });\n });\n v++;\n }\n}\n"],"mappings":"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","ignoreList":[]}
@@ -3,7 +3,6 @@
3
3
  Object.defineProperty(exports, "__esModule", {
4
4
  value: true
5
5
  });
6
- exports.blockPreviousVersionPaths = blockPreviousVersionPaths;
7
6
  exports.docContainsServerOnlyFields = docContainsServerOnlyFields;
8
7
  exports.doesContainRegexQuerySelector = doesContainRegexQuerySelector;
9
8
  exports.getAuthDataByRequest = getAuthDataByRequest;
@@ -21,24 +20,6 @@ function setCors(server, path, cors) {
21
20
  server.adapter.setCors(server.serverApp, path, useCors);
22
21
  }
23
22
  }
24
-
25
- /**
26
- * "block" the previous version urls and send a 426 on them so that
27
- * the clients know they must update.
28
- */
29
- function blockPreviousVersionPaths(server, path, currentVersion) {
30
- var v = 0;
31
- var _loop = function () {
32
- var version = v;
33
- server.adapter.all(server.serverApp, '/' + path + '/' + version + '/*', (req, res) => {
34
- server.adapter.closeConnection(res, 426, 'Outdated version ' + version + ' (newest is ' + currentVersion + ')');
35
- });
36
- v++;
37
- };
38
- while (v < currentVersion) {
39
- _loop();
40
- }
41
- }
42
23
  var AUTH_PER_REQUEST = new WeakMap();
43
24
  async function getAuthDataByRequest(server, request, response) {
44
25
  return (0, _core.getFromMapOrCreate)(AUTH_PER_REQUEST, request, async () => {
@@ -1 +1 @@
1
- {"version":3,"file":"helper.js","names":["_core","require","setCors","server","path","cors","useCors","adapter","serverApp","blockPreviousVersionPaths","currentVersion","v","_loop","version","all","req","res","closeConnection","AUTH_PER_REQUEST","WeakMap","getAuthDataByRequest","request","response","getFromMapOrCreate","headers","getRequestHeaders","authData","authHandler","err","defaultMatchingQuery","selector","skip","sort","getDocAllowedMatcher","endpoint","useQuery","queryModifier","normalizeMangoQuery","collection","schema","jsonSchema","docDataMatcher","getQueryMatcher","docContainsServerOnlyFields","serverOnlyFields","doc","has","find","field","removeServerOnlyFieldsMonad","serverOnlyFieldsStencil","_meta","undefined","_rev","_attachments","forEach","docData","Object","assign","mergeServerDocumentFieldsMonad","useFields","slice","uniqueArray","clientDoc","serverDoc","ret","flatClone","doesContainRegexQuerySelector","Array","isArray","found","item","entries","key","value"],"sources":["../../../../src/plugins/server/helper.ts"],"sourcesContent":["import { RxServer } from './rx-server';\nimport type {\n Request,\n Response,\n NextFunction\n} from 'express';\nimport type { RxServerAdapter, RxServerAuthData, RxServerEndpoint } from './types';\nimport {\n FilledMangoQuery,\n MangoQuerySelector,\n RxDocumentData,\n flatClone,\n getFromMapOrCreate,\n getQueryMatcher,\n normalizeMangoQuery,\n uniqueArray\n} from 'rxdb/plugins/core';\n\nexport function setCors(\n server: RxServer<any, any>,\n path: string,\n cors?: string\n) {\n let useCors = cors;\n if (!useCors) {\n useCors = server.cors;\n }\n if (useCors) {\n server.adapter.setCors(server.serverApp, path, useCors);\n }\n}\n\n/**\n * \"block\" the previous version urls and send a 426 on them so that\n * the clients know they must update.\n */\nexport function blockPreviousVersionPaths(\n server: RxServer<any, any>,\n path: string,\n currentVersion: number\n\n) {\n let v = 0;\n while (v < currentVersion) {\n const version = v;\n server.adapter.all(server.serverApp, '/' + path + '/' + version + '/*', (req, res) => {\n server.adapter.closeConnection(res, 426, 'Outdated version ' + version + ' (newest is ' + currentVersion + ')');\n });\n v++;\n }\n}\n\n\n\nconst AUTH_PER_REQUEST = new WeakMap<any, Promise<any>>();\n\nexport async function getAuthDataByRequest<AuthType, RequestType, ResponseType>(\n server: RxServer<any, AuthType>,\n request: RequestType,\n response: ResponseType\n): Promise<RxServerAuthData<AuthType> | false> {\n return getFromMapOrCreate(\n AUTH_PER_REQUEST,\n request,\n async () => {\n try {\n const headers = server.adapter.getRequestHeaders(request);\n const authData = await server.authHandler(headers);\n return authData;\n } catch (err) {\n server.adapter.closeConnection(response, 401, 'Unauthorized');\n return false;\n }\n }\n );\n};\n\nconst defaultMatchingQuery: FilledMangoQuery<any> = {\n selector: {},\n skip: 0,\n sort: []\n} as const;\n\nexport function getDocAllowedMatcher<RxDocType, AuthType>(\n endpoint: RxServerEndpoint<AuthType, RxDocType>,\n authData: RxServerAuthData<AuthType>\n) {\n const useQuery: FilledMangoQuery<RxDocType> = endpoint.queryModifier ? endpoint.queryModifier(\n authData,\n normalizeMangoQuery(\n endpoint.collection.schema.jsonSchema,\n {}\n )\n ) : defaultMatchingQuery;\n const docDataMatcher = getQueryMatcher(endpoint.collection.schema.jsonSchema, useQuery);\n return docDataMatcher;\n}\n\n\nexport function docContainsServerOnlyFields(\n serverOnlyFields: string[],\n doc: any\n) {\n const has = serverOnlyFields.find(field => {\n return typeof doc[field] !== 'undefined'\n });\n return has;\n}\n\nexport function removeServerOnlyFieldsMonad<RxDocType>(serverOnlyFields: string[]) {\n const serverOnlyFieldsStencil: any = {\n _meta: undefined,\n _rev: undefined,\n _attachments: undefined\n };\n serverOnlyFields.forEach(field => serverOnlyFieldsStencil[field] = undefined);\n return (\n docData?: RxDocType | RxDocumentData<RxDocType>\n ) => {\n if (!docData) {\n return docData;\n }\n return Object.assign({}, docData, serverOnlyFieldsStencil);\n }\n}\n\nexport function mergeServerDocumentFieldsMonad<RxDocType>(serverOnlyFields: string[]) {\n let useFields = serverOnlyFields.slice(0);\n // useFields.push('_rev');\n // useFields.push('_meta');\n // useFields.push('_attachments');\n useFields = uniqueArray(useFields);\n\n return (\n clientDoc: RxDocType | RxDocumentData<RxDocType>,\n serverDoc?: RxDocType | RxDocumentData<RxDocType>\n ) => {\n if (!serverDoc) {\n return clientDoc;\n }\n const ret = flatClone(clientDoc);\n useFields.forEach(field => {\n (ret as any)[field] = (serverDoc as any)[field];\n });\n return ret;\n }\n}\n\n\n/**\n * $regex queries are dangerous because they can dos-attack the server.\n * \n * @param selector \n */\nexport function doesContainRegexQuerySelector(selector: MangoQuerySelector<any> | any): boolean {\n if (!selector) {\n return false;\n }\n if (Array.isArray(selector)) {\n const found = !!selector.find(item => doesContainRegexQuerySelector(item));\n return found;\n }\n\n if (typeof selector !== 'object') {\n return false;\n }\n\n const entries = Object.entries(selector);\n for (const [key, value] of entries) {\n if (key === '$regex') {\n return true;\n } else {\n const has = doesContainRegexQuerySelector(value);\n if (has) {\n return true;\n }\n }\n }\n\n return false;\n}\n"],"mappings":"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","ignoreList":[]}
1
+ {"version":3,"file":"helper.js","names":["_core","require","setCors","server","path","cors","useCors","adapter","serverApp","AUTH_PER_REQUEST","WeakMap","getAuthDataByRequest","request","response","getFromMapOrCreate","headers","getRequestHeaders","authData","authHandler","err","closeConnection","defaultMatchingQuery","selector","skip","sort","getDocAllowedMatcher","endpoint","useQuery","queryModifier","normalizeMangoQuery","collection","schema","jsonSchema","docDataMatcher","getQueryMatcher","docContainsServerOnlyFields","serverOnlyFields","doc","has","find","field","removeServerOnlyFieldsMonad","serverOnlyFieldsStencil","_meta","undefined","_rev","_attachments","forEach","docData","Object","assign","mergeServerDocumentFieldsMonad","useFields","slice","uniqueArray","clientDoc","serverDoc","ret","flatClone","doesContainRegexQuerySelector","Array","isArray","found","item","entries","key","value"],"sources":["../../../../src/plugins/server/helper.ts"],"sourcesContent":["import { RxServer } from './rx-server';\nimport type {\n Request,\n Response,\n NextFunction\n} from 'express';\nimport type { RxServerAdapter, RxServerAuthData, RxServerEndpoint } from './types';\nimport {\n FilledMangoQuery,\n MangoQuerySelector,\n RxDocumentData,\n flatClone,\n getFromMapOrCreate,\n getQueryMatcher,\n normalizeMangoQuery,\n uniqueArray\n} from 'rxdb/plugins/core';\n\nexport function setCors(\n server: RxServer<any, any>,\n path: string,\n cors?: string\n) {\n let useCors = cors;\n if (!useCors) {\n useCors = server.cors;\n }\n if (useCors) {\n server.adapter.setCors(server.serverApp, path, useCors);\n }\n}\n\n\nconst AUTH_PER_REQUEST = new WeakMap<any, Promise<any>>();\n\nexport async function getAuthDataByRequest<AuthType, RequestType, ResponseType>(\n server: RxServer<any, AuthType>,\n request: RequestType,\n response: ResponseType\n): Promise<RxServerAuthData<AuthType> | false> {\n return getFromMapOrCreate(\n AUTH_PER_REQUEST,\n request,\n async () => {\n try {\n const headers = server.adapter.getRequestHeaders(request);\n const authData = await server.authHandler(headers);\n return authData;\n } catch (err) {\n server.adapter.closeConnection(response, 401, 'Unauthorized');\n return false;\n }\n }\n );\n};\n\nconst defaultMatchingQuery: FilledMangoQuery<any> = {\n selector: {},\n skip: 0,\n sort: []\n} as const;\n\nexport function getDocAllowedMatcher<RxDocType, AuthType>(\n endpoint: RxServerEndpoint<AuthType, RxDocType>,\n authData: RxServerAuthData<AuthType>\n) {\n const useQuery: FilledMangoQuery<RxDocType> = endpoint.queryModifier ? endpoint.queryModifier(\n authData,\n normalizeMangoQuery(\n endpoint.collection.schema.jsonSchema,\n {}\n )\n ) : defaultMatchingQuery;\n const docDataMatcher = getQueryMatcher(endpoint.collection.schema.jsonSchema, useQuery);\n return docDataMatcher;\n}\n\n\nexport function docContainsServerOnlyFields(\n serverOnlyFields: string[],\n doc: any\n) {\n const has = serverOnlyFields.find(field => {\n return typeof doc[field] !== 'undefined'\n });\n return has;\n}\n\nexport function removeServerOnlyFieldsMonad<RxDocType>(serverOnlyFields: string[]) {\n const serverOnlyFieldsStencil: any = {\n _meta: undefined,\n _rev: undefined,\n _attachments: undefined\n };\n serverOnlyFields.forEach(field => serverOnlyFieldsStencil[field] = undefined);\n return (\n docData?: RxDocType | RxDocumentData<RxDocType>\n ) => {\n if (!docData) {\n return docData;\n }\n return Object.assign({}, docData, serverOnlyFieldsStencil);\n }\n}\n\nexport function mergeServerDocumentFieldsMonad<RxDocType>(serverOnlyFields: string[]) {\n let useFields = serverOnlyFields.slice(0);\n // useFields.push('_rev');\n // useFields.push('_meta');\n // useFields.push('_attachments');\n useFields = uniqueArray(useFields);\n\n return (\n clientDoc: RxDocType | RxDocumentData<RxDocType>,\n serverDoc?: RxDocType | RxDocumentData<RxDocType>\n ) => {\n if (!serverDoc) {\n return clientDoc;\n }\n const ret = flatClone(clientDoc);\n useFields.forEach(field => {\n (ret as any)[field] = (serverDoc as any)[field];\n });\n return ret;\n }\n}\n\n\n/**\n * $regex queries are dangerous because they can dos-attack the server.\n * \n * @param selector \n */\nexport function doesContainRegexQuerySelector(selector: MangoQuerySelector<any> | any): boolean {\n if (!selector) {\n return false;\n }\n if (Array.isArray(selector)) {\n const found = !!selector.find(item => doesContainRegexQuerySelector(item));\n return found;\n }\n\n if (typeof selector !== 'object') {\n return false;\n }\n\n const entries = Object.entries(selector);\n for (const [key, value] of entries) {\n if (key === '$regex') {\n return true;\n } else {\n const has = doesContainRegexQuerySelector(value);\n if (has) {\n return true;\n }\n }\n }\n\n return false;\n}\n"],"mappings":"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","ignoreList":[]}
@@ -2,7 +2,7 @@ import { prepareQuery, getChangedDocumentsSinceQuery } from 'rxdb/plugins/core';
2
2
  import { getReplicationHandlerByCollection } from 'rxdb/plugins/replication-websocket';
3
3
  import { filter, mergeMap } from 'rxjs';
4
4
  import { ensureNotFalsy, lastOfArray } from 'rxdb/plugins/utils';
5
- import { blockPreviousVersionPaths, docContainsServerOnlyFields, doesContainRegexQuerySelector, getAuthDataByRequest, getDocAllowedMatcher, mergeServerDocumentFieldsMonad, removeServerOnlyFieldsMonad, setCors } from "./helper.js";
5
+ import { docContainsServerOnlyFields, doesContainRegexQuerySelector, getAuthDataByRequest, getDocAllowedMatcher, mergeServerDocumentFieldsMonad, removeServerOnlyFieldsMonad, setCors } from "./helper.js";
6
6
  export var RxServerReplicationEndpoint = function RxServerReplicationEndpoint(server, name, collection, queryModifier, changeValidator, serverOnlyFields, cors) {
7
7
  this.type = 'replication';
8
8
  this.server = server;
@@ -12,7 +12,7 @@ export var RxServerReplicationEndpoint = function RxServerReplicationEndpoint(se
12
12
  this.cors = cors;
13
13
  var adapter = this.server.adapter;
14
14
  setCors(this.server, [this.name].join('/'), cors);
15
- blockPreviousVersionPaths(this.server, [this.name].join('/'), collection.schema.version);
15
+ blockPreviousReplicationVersionPaths(this.server, [this.name].join('/'), collection.schema.version);
16
16
  this.urlPath = [this.name, collection.schema.version].join('/');
17
17
  var primaryPath = this.collection.schema.primaryPath;
18
18
  var replicationHandler = getReplicationHandlerByCollection(this.server.database, collection.name);
@@ -163,4 +163,28 @@ export var RxServerReplicationEndpoint = function RxServerReplicationEndpoint(se
163
163
  });
164
164
  });
165
165
  };
166
+
167
+ /**
168
+ * "block" the previous version urls and send a 426 on them so that
169
+ * the clients know they must update.
170
+ */
171
+ export function blockPreviousReplicationVersionPaths(server, path, currentVersion) {
172
+ var v = 0;
173
+ var _loop = function () {
174
+ var version = v;
175
+ /**
176
+ * Some adapters do not allow regex or handle them property (like Koa),
177
+ * so to make it easier, use the hard-coded array of path parts.
178
+ */
179
+ ['', 'pull', 'push', 'pullStream'].forEach(subPath => {
180
+ server.adapter.all(server.serverApp, '/' + path + '/' + version + '/' + subPath, (req, res) => {
181
+ server.adapter.closeConnection(res, 426, 'Outdated version ' + version + ' (newest is ' + currentVersion + ')');
182
+ });
183
+ });
184
+ v++;
185
+ };
186
+ while (v < currentVersion) {
187
+ _loop();
188
+ }
189
+ }
166
190
  //# sourceMappingURL=endpoint-replication.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"endpoint-replication.js","names":["prepareQuery","getChangedDocumentsSinceQuery","getReplicationHandlerByCollection","filter","mergeMap","ensureNotFalsy","lastOfArray","blockPreviousVersionPaths","docContainsServerOnlyFields","doesContainRegexQuerySelector","getAuthDataByRequest","getDocAllowedMatcher","mergeServerDocumentFieldsMonad","removeServerOnlyFieldsMonad","setCors","RxServerReplicationEndpoint","server","name","collection","queryModifier","changeValidator","serverOnlyFields","cors","type","adapter","join","schema","version","urlPath","primaryPath","replicationHandler","database","authData","query","selector","Error","change","assumedMasterState","newDocumentState","removeServerOnlyFields","mergeServerDocumentFields","get","serverApp","req","res","urlQuery","getRequestQuery","id","lwt","parseInt","limit","plainQuery","storageInstance","useQueryChanges","prepared","jsonSchema","result","newCheckpoint","documents","length","updatedAt","_meta","responseDocuments","map","d","setResponseHeader","endResponseJson","checkpoint","post","docDataMatcherWrite","rows","getRequestBody","ids","forEach","row","push","nonAllowedRow","find","closeConnection","hasInvalidChange","currentStateDocsArray","findDocumentsById","currentStateDocs","Map","set","useRows","isChangeValid","serverDoc","conflicts","masterWrite","setSSEHeaders","docDataMatcherStream","subscription","masterChangeStream$","pipe","changes","authHandler","getRequestHeaders","err","useDocs","f","subscribe","filteredAndModified","responseWrite","JSON","stringify","onRequestClose","unsubscribe","endResponse"],"sources":["../../../../src/plugins/server/endpoint-replication.ts"],"sourcesContent":["import {\n FilledMangoQuery,\n RxCollection,\n RxReplicationHandler,\n RxReplicationWriteToMasterRow,\n RxStorageDefaultCheckpoint,\n StringKeys,\n prepareQuery,\n getChangedDocumentsSinceQuery,\n RxDocumentData\n} from 'rxdb/plugins/core';\nimport { getReplicationHandlerByCollection } from 'rxdb/plugins/replication-websocket';\nimport type { RxServer } from './rx-server.ts';\nimport type {\n RxServerAuthData,\n RxServerChangeValidator,\n RxServerEndpoint,\n RxServerQueryModifier\n} from './types.ts';\nimport { filter, mergeMap } from 'rxjs';\nimport {\n ensureNotFalsy,\n getFromMapOrThrow,\n lastOfArray\n} from 'rxdb/plugins/utils';\n\nimport {\n blockPreviousVersionPaths,\n docContainsServerOnlyFields,\n doesContainRegexQuerySelector,\n getAuthDataByRequest,\n getDocAllowedMatcher,\n mergeServerDocumentFieldsMonad,\n removeServerOnlyFieldsMonad,\n setCors\n} from './helper.ts';\n\nexport type RxReplicationEndpointMessageType = {\n id: string;\n method: StringKeys<RxReplicationHandler<any, any>> | 'auth';\n params: any[];\n};\n\nexport class RxServerReplicationEndpoint<ServerAppType, AuthType, RxDocType> implements RxServerEndpoint<AuthType, RxDocType> {\n readonly type = 'replication';\n readonly urlPath: string;\n readonly changeValidator: RxServerChangeValidator<AuthType, RxDocType>;\n readonly queryModifier: RxServerQueryModifier<AuthType, RxDocType>;\n constructor(\n public readonly server: RxServer<ServerAppType, AuthType>,\n public readonly name: string,\n public readonly collection: RxCollection<RxDocType>,\n queryModifier: RxServerQueryModifier<AuthType, RxDocType>,\n changeValidator: RxServerChangeValidator<AuthType, RxDocType>,\n public readonly serverOnlyFields: string[],\n public readonly cors?: string,\n ) {\n const adapter = this.server.adapter;\n\n setCors(this.server, [this.name].join('/'), cors);\n blockPreviousVersionPaths(this.server, [this.name].join('/'), collection.schema.version);\n\n this.urlPath = [this.name, collection.schema.version].join('/');\n\n const primaryPath = this.collection.schema.primaryPath;\n const replicationHandler = getReplicationHandlerByCollection(this.server.database, collection.name);\n this.queryModifier = (authData, query) => {\n if (doesContainRegexQuerySelector(query.selector)) {\n throw new Error('$regex queries not allowed because of DOS-attacks');\n }\n return queryModifier(authData, query);\n }\n this.changeValidator = (authData, change) => {\n if (\n (change.assumedMasterState && docContainsServerOnlyFields(serverOnlyFields, change.assumedMasterState)) ||\n docContainsServerOnlyFields(serverOnlyFields, change.newDocumentState)\n ) {\n return false;\n }\n return changeValidator(authData, change);\n }\n const removeServerOnlyFields = removeServerOnlyFieldsMonad<RxDocType>(this.serverOnlyFields);\n const mergeServerDocumentFields = mergeServerDocumentFieldsMonad<RxDocType>(this.serverOnlyFields);\n\n this.server.adapter.get(this.server.serverApp, '/' + this.urlPath + '/pull', async (req: any, res: any) => {\n const authData = await getAuthDataByRequest(this.server, req, res);\n if (!authData) { return; }\n\n const urlQuery = adapter.getRequestQuery(req);\n const id = urlQuery.id ? urlQuery.id as string : '';\n const lwt = urlQuery.lwt ? parseInt(urlQuery.lwt as any, 10) : 0;\n const limit = urlQuery.limit ? parseInt(urlQuery.limit as any, 10) : 1;\n const plainQuery = getChangedDocumentsSinceQuery<RxDocType, RxStorageDefaultCheckpoint>(\n this.collection.storageInstance,\n limit,\n { id, lwt }\n );\n const useQueryChanges: FilledMangoQuery<RxDocType> = this.queryModifier(\n ensureNotFalsy(authData),\n plainQuery\n );\n const prepared = prepareQuery<RxDocType>(\n this.collection.schema.jsonSchema,\n useQueryChanges\n );\n const result = await this.collection.storageInstance.query(prepared);\n\n const newCheckpoint = result.documents.length === 0 ? { id, lwt } : {\n id: ensureNotFalsy(lastOfArray(result.documents))[primaryPath],\n updatedAt: ensureNotFalsy(lastOfArray(result.documents))._meta.lwt\n };\n const responseDocuments = result.documents.map(d => removeServerOnlyFields(d));\n adapter.setResponseHeader(res, 'Content-Type', 'application/json');\n adapter.endResponseJson(res, {\n documents: responseDocuments,\n checkpoint: newCheckpoint\n });\n });\n\n this.server.adapter.post(this.server.serverApp, '/' + this.urlPath + '/push', async (req: any, res: any) => {\n const authData = await getAuthDataByRequest(this.server, req, res);\n if (!authData) { return; }\n\n const docDataMatcherWrite = getDocAllowedMatcher(this, ensureNotFalsy(authData as any));\n const rows: RxReplicationWriteToMasterRow<RxDocType>[] = adapter.getRequestBody(req);\n const ids: string[] = [];\n rows.forEach(row => ids.push((row.newDocumentState as any)[primaryPath]));\n\n for (const row of rows) {\n // TODO remove this check\n if (row.assumedMasterState && (row.assumedMasterState as any)._meta) {\n throw new Error('body document contains meta!');\n }\n }\n\n // ensure all writes are allowed\n const nonAllowedRow = rows.find(row => {\n if (\n !docDataMatcherWrite(row.newDocumentState as any) ||\n (row.assumedMasterState && !docDataMatcherWrite(row.assumedMasterState as any))\n ) {\n return true;\n }\n });\n if (nonAllowedRow) {\n adapter.closeConnection(res, 403, 'Forbidden');\n return;\n }\n let hasInvalidChange = false;\n\n const currentStateDocsArray = await this.collection.storageInstance.findDocumentsById(ids, true);\n const currentStateDocs = new Map<string, RxDocumentData<RxDocType>>();\n currentStateDocsArray.forEach(d => currentStateDocs.set((d as any)[primaryPath], d));\n\n const useRows: typeof rows = rows.map((row) => {\n const id = (row.newDocumentState as any)[primaryPath];\n const isChangeValid = this.changeValidator(ensureNotFalsy(authData), {\n newDocumentState: removeServerOnlyFields(row.newDocumentState),\n assumedMasterState: removeServerOnlyFields(row.assumedMasterState)\n });\n if (!isChangeValid) {\n hasInvalidChange = true;\n }\n\n const serverDoc = currentStateDocs.get(id);\n return {\n newDocumentState: mergeServerDocumentFields(row.newDocumentState, serverDoc),\n assumedMasterState: mergeServerDocumentFields(row.assumedMasterState as any, serverDoc)\n } as typeof row;\n });\n if (hasInvalidChange) {\n adapter.closeConnection(res, 403, 'Forbidden');\n return;\n }\n\n const conflicts = await replicationHandler.masterWrite(useRows);\n\n adapter.setResponseHeader(res, 'Content-Type', 'application/json');\n adapter.endResponseJson(res, conflicts);\n });\n this.server.adapter.get(this.server.serverApp, '/' + this.urlPath + '/pullStream', async (req, res) => {\n \n const authData = await getAuthDataByRequest<AuthType, any, any>(this.server, req, res);\n if (!authData) { return; }\n \n adapter.setSSEHeaders(res);\n const docDataMatcherStream = getDocAllowedMatcher(this, ensureNotFalsy(authData));\n const subscription = replicationHandler.masterChangeStream$.pipe(\n mergeMap(async (changes) => {\n /**\n * The auth-data might be expired\n * so we re-run the auth parsing each time\n * before emitting an event.\n */\n let authData: RxServerAuthData<AuthType>;\n try {\n authData = await server.authHandler(adapter.getRequestHeaders(req));\n } catch (err) {\n adapter.closeConnection(res, 401, 'Unauthorized');\n return null;\n }\n\n if (changes === 'RESYNC') {\n return changes;\n } else {\n const useDocs = changes.documents.filter(d => docDataMatcherStream(d as any));\n return {\n documents: useDocs,\n checkpoint: changes.checkpoint\n };\n }\n }),\n filter(f => f !== null && (f === 'RESYNC' || f.documents.length > 0))\n ).subscribe(filteredAndModified => {\n if (filteredAndModified === 'RESYNC') {\n adapter.responseWrite(res, 'data: ' + JSON.stringify(filteredAndModified) + '\\n\\n');\n } else {\n const responseDocuments = ensureNotFalsy(filteredAndModified).documents.map(d => removeServerOnlyFields(d as any));\n adapter.responseWrite(res, 'data: ' + JSON.stringify({ documents: responseDocuments, checkpoint: ensureNotFalsy(filteredAndModified).checkpoint }) + '\\n\\n');\n }\n\n });\n\n /**\n * @link https://youtu.be/0PcMuYGJPzM?si=AxkczxcMaUwhh8k9&t=363\n */\n adapter.onRequestClose(req, () => {\n subscription.unsubscribe();\n adapter.endResponse(res);\n });\n });\n }\n}\n"],"mappings":"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","ignoreList":[]}
1
+ {"version":3,"file":"endpoint-replication.js","names":["prepareQuery","getChangedDocumentsSinceQuery","getReplicationHandlerByCollection","filter","mergeMap","ensureNotFalsy","lastOfArray","docContainsServerOnlyFields","doesContainRegexQuerySelector","getAuthDataByRequest","getDocAllowedMatcher","mergeServerDocumentFieldsMonad","removeServerOnlyFieldsMonad","setCors","RxServerReplicationEndpoint","server","name","collection","queryModifier","changeValidator","serverOnlyFields","cors","type","adapter","join","blockPreviousReplicationVersionPaths","schema","version","urlPath","primaryPath","replicationHandler","database","authData","query","selector","Error","change","assumedMasterState","newDocumentState","removeServerOnlyFields","mergeServerDocumentFields","get","serverApp","req","res","urlQuery","getRequestQuery","id","lwt","parseInt","limit","plainQuery","storageInstance","useQueryChanges","prepared","jsonSchema","result","newCheckpoint","documents","length","updatedAt","_meta","responseDocuments","map","d","setResponseHeader","endResponseJson","checkpoint","post","docDataMatcherWrite","rows","getRequestBody","ids","forEach","row","push","nonAllowedRow","find","closeConnection","hasInvalidChange","currentStateDocsArray","findDocumentsById","currentStateDocs","Map","set","useRows","isChangeValid","serverDoc","conflicts","masterWrite","setSSEHeaders","docDataMatcherStream","subscription","masterChangeStream$","pipe","changes","authHandler","getRequestHeaders","err","useDocs","f","subscribe","filteredAndModified","responseWrite","JSON","stringify","onRequestClose","unsubscribe","endResponse","path","currentVersion","v","_loop","subPath","all"],"sources":["../../../../src/plugins/server/endpoint-replication.ts"],"sourcesContent":["import {\n FilledMangoQuery,\n RxCollection,\n RxReplicationHandler,\n RxReplicationWriteToMasterRow,\n RxStorageDefaultCheckpoint,\n StringKeys,\n prepareQuery,\n getChangedDocumentsSinceQuery,\n RxDocumentData\n} from 'rxdb/plugins/core';\nimport { getReplicationHandlerByCollection } from 'rxdb/plugins/replication-websocket';\nimport type { RxServer } from './rx-server.ts';\nimport type {\n RxServerAuthData,\n RxServerChangeValidator,\n RxServerEndpoint,\n RxServerQueryModifier\n} from './types.ts';\nimport { filter, mergeMap } from 'rxjs';\nimport {\n ensureNotFalsy,\n lastOfArray\n} from 'rxdb/plugins/utils';\n\nimport {\n docContainsServerOnlyFields,\n doesContainRegexQuerySelector,\n getAuthDataByRequest,\n getDocAllowedMatcher,\n mergeServerDocumentFieldsMonad,\n removeServerOnlyFieldsMonad,\n setCors\n} from './helper.ts';\n\nexport type RxReplicationEndpointMessageType = {\n id: string;\n method: StringKeys<RxReplicationHandler<any, any>> | 'auth';\n params: any[];\n};\n\nexport class RxServerReplicationEndpoint<ServerAppType, AuthType, RxDocType> implements RxServerEndpoint<AuthType, RxDocType> {\n readonly type = 'replication';\n readonly urlPath: string;\n readonly changeValidator: RxServerChangeValidator<AuthType, RxDocType>;\n readonly queryModifier: RxServerQueryModifier<AuthType, RxDocType>;\n constructor(\n public readonly server: RxServer<ServerAppType, AuthType>,\n public readonly name: string,\n public readonly collection: RxCollection<RxDocType>,\n queryModifier: RxServerQueryModifier<AuthType, RxDocType>,\n changeValidator: RxServerChangeValidator<AuthType, RxDocType>,\n public readonly serverOnlyFields: string[],\n public readonly cors?: string,\n ) {\n const adapter = this.server.adapter;\n\n setCors(this.server, [this.name].join('/'), cors);\n blockPreviousReplicationVersionPaths(this.server, [this.name].join('/'), collection.schema.version);\n\n this.urlPath = [this.name, collection.schema.version].join('/');\n\n const primaryPath = this.collection.schema.primaryPath;\n const replicationHandler = getReplicationHandlerByCollection(this.server.database, collection.name);\n this.queryModifier = (authData, query) => {\n if (doesContainRegexQuerySelector(query.selector)) {\n throw new Error('$regex queries not allowed because of DOS-attacks');\n }\n return queryModifier(authData, query);\n }\n this.changeValidator = (authData, change) => {\n if (\n (change.assumedMasterState && docContainsServerOnlyFields(serverOnlyFields, change.assumedMasterState)) ||\n docContainsServerOnlyFields(serverOnlyFields, change.newDocumentState)\n ) {\n return false;\n }\n return changeValidator(authData, change);\n }\n const removeServerOnlyFields = removeServerOnlyFieldsMonad<RxDocType>(this.serverOnlyFields);\n const mergeServerDocumentFields = mergeServerDocumentFieldsMonad<RxDocType>(this.serverOnlyFields);\n\n this.server.adapter.get(this.server.serverApp, '/' + this.urlPath + '/pull', async (req: any, res: any) => {\n const authData = await getAuthDataByRequest(this.server, req, res);\n if (!authData) { return; }\n\n const urlQuery = adapter.getRequestQuery(req);\n const id = urlQuery.id ? urlQuery.id as string : '';\n const lwt = urlQuery.lwt ? parseInt(urlQuery.lwt as any, 10) : 0;\n const limit = urlQuery.limit ? parseInt(urlQuery.limit as any, 10) : 1;\n const plainQuery = getChangedDocumentsSinceQuery<RxDocType, RxStorageDefaultCheckpoint>(\n this.collection.storageInstance,\n limit,\n { id, lwt }\n );\n const useQueryChanges: FilledMangoQuery<RxDocType> = this.queryModifier(\n ensureNotFalsy(authData),\n plainQuery\n );\n const prepared = prepareQuery<RxDocType>(\n this.collection.schema.jsonSchema,\n useQueryChanges\n );\n const result = await this.collection.storageInstance.query(prepared);\n\n const newCheckpoint = result.documents.length === 0 ? { id, lwt } : {\n id: ensureNotFalsy(lastOfArray(result.documents))[primaryPath],\n updatedAt: ensureNotFalsy(lastOfArray(result.documents))._meta.lwt\n };\n const responseDocuments = result.documents.map(d => removeServerOnlyFields(d));\n adapter.setResponseHeader(res, 'Content-Type', 'application/json');\n adapter.endResponseJson(res, {\n documents: responseDocuments,\n checkpoint: newCheckpoint\n });\n });\n\n this.server.adapter.post(this.server.serverApp, '/' + this.urlPath + '/push', async (req: any, res: any) => {\n const authData = await getAuthDataByRequest(this.server, req, res);\n if (!authData) { return; }\n\n const docDataMatcherWrite = getDocAllowedMatcher(this, ensureNotFalsy(authData as any));\n const rows: RxReplicationWriteToMasterRow<RxDocType>[] = adapter.getRequestBody(req);\n const ids: string[] = [];\n rows.forEach(row => ids.push((row.newDocumentState as any)[primaryPath]));\n\n for (const row of rows) {\n // TODO remove this check\n if (row.assumedMasterState && (row.assumedMasterState as any)._meta) {\n throw new Error('body document contains meta!');\n }\n }\n\n // ensure all writes are allowed\n const nonAllowedRow = rows.find(row => {\n if (\n !docDataMatcherWrite(row.newDocumentState as any) ||\n (row.assumedMasterState && !docDataMatcherWrite(row.assumedMasterState as any))\n ) {\n return true;\n }\n });\n if (nonAllowedRow) {\n adapter.closeConnection(res, 403, 'Forbidden');\n return;\n }\n let hasInvalidChange = false;\n\n const currentStateDocsArray = await this.collection.storageInstance.findDocumentsById(ids, true);\n const currentStateDocs = new Map<string, RxDocumentData<RxDocType>>();\n currentStateDocsArray.forEach(d => currentStateDocs.set((d as any)[primaryPath], d));\n\n const useRows: typeof rows = rows.map((row) => {\n const id = (row.newDocumentState as any)[primaryPath];\n const isChangeValid = this.changeValidator(ensureNotFalsy(authData), {\n newDocumentState: removeServerOnlyFields(row.newDocumentState),\n assumedMasterState: removeServerOnlyFields(row.assumedMasterState)\n });\n if (!isChangeValid) {\n hasInvalidChange = true;\n }\n\n const serverDoc = currentStateDocs.get(id);\n return {\n newDocumentState: mergeServerDocumentFields(row.newDocumentState, serverDoc),\n assumedMasterState: mergeServerDocumentFields(row.assumedMasterState as any, serverDoc)\n } as typeof row;\n });\n if (hasInvalidChange) {\n adapter.closeConnection(res, 403, 'Forbidden');\n return;\n }\n\n const conflicts = await replicationHandler.masterWrite(useRows);\n\n adapter.setResponseHeader(res, 'Content-Type', 'application/json');\n adapter.endResponseJson(res, conflicts);\n });\n this.server.adapter.get(this.server.serverApp, '/' + this.urlPath + '/pullStream', async (req, res) => {\n\n const authData = await getAuthDataByRequest<AuthType, any, any>(this.server, req, res);\n if (!authData) { return; }\n\n adapter.setSSEHeaders(res);\n const docDataMatcherStream = getDocAllowedMatcher(this, ensureNotFalsy(authData));\n const subscription = replicationHandler.masterChangeStream$.pipe(\n mergeMap(async (changes) => {\n /**\n * The auth-data might be expired\n * so we re-run the auth parsing each time\n * before emitting an event.\n */\n let authData: RxServerAuthData<AuthType>;\n try {\n authData = await server.authHandler(adapter.getRequestHeaders(req));\n } catch (err) {\n adapter.closeConnection(res, 401, 'Unauthorized');\n return null;\n }\n\n if (changes === 'RESYNC') {\n return changes;\n } else {\n const useDocs = changes.documents.filter(d => docDataMatcherStream(d as any));\n return {\n documents: useDocs,\n checkpoint: changes.checkpoint\n };\n }\n }),\n filter(f => f !== null && (f === 'RESYNC' || f.documents.length > 0))\n ).subscribe(filteredAndModified => {\n if (filteredAndModified === 'RESYNC') {\n adapter.responseWrite(res, 'data: ' + JSON.stringify(filteredAndModified) + '\\n\\n');\n } else {\n const responseDocuments = ensureNotFalsy(filteredAndModified).documents.map(d => removeServerOnlyFields(d as any));\n adapter.responseWrite(res, 'data: ' + JSON.stringify({ documents: responseDocuments, checkpoint: ensureNotFalsy(filteredAndModified).checkpoint }) + '\\n\\n');\n }\n\n });\n\n /**\n * @link https://youtu.be/0PcMuYGJPzM?si=AxkczxcMaUwhh8k9&t=363\n */\n adapter.onRequestClose(req, () => {\n subscription.unsubscribe();\n adapter.endResponse(res);\n });\n });\n }\n}\n\n\n/**\n * \"block\" the previous version urls and send a 426 on them so that\n * the clients know they must update.\n */\nexport function blockPreviousReplicationVersionPaths(\n server: RxServer<any, any>,\n path: string,\n currentVersion: number\n\n) {\n let v = 0;\n while (v < currentVersion) {\n const version = v;\n /**\n * Some adapters do not allow regex or handle them property (like Koa),\n * so to make it easier, use the hard-coded array of path parts.\n */\n [\n '',\n 'pull',\n 'push',\n 'pullStream'\n ].forEach(subPath => {\n server.adapter.all(server.serverApp, '/' + path + '/' + version + '/' + subPath, (req, res) => {\n server.adapter.closeConnection(res, 426, 'Outdated version ' + version + ' (newest is ' + currentVersion + ')');\n });\n });\n v++;\n }\n}\n"],"mappings":"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","ignoreList":[]}
@@ -1,7 +1,7 @@
1
1
  import { normalizeMangoQuery } from 'rxdb/plugins/core';
2
2
  import { filter, mergeMap } from 'rxjs';
3
3
  import { ensureNotFalsy } from 'rxdb/plugins/utils';
4
- import { blockPreviousVersionPaths, docContainsServerOnlyFields, doesContainRegexQuerySelector, getAuthDataByRequest, getDocAllowedMatcher, removeServerOnlyFieldsMonad, setCors } from "./helper.js";
4
+ import { docContainsServerOnlyFields, doesContainRegexQuerySelector, getAuthDataByRequest, getDocAllowedMatcher, removeServerOnlyFieldsMonad, setCors } from "./helper.js";
5
5
  export var REST_PATHS = ['query', 'query/observe', 'get', 'set', 'delete'
6
6
 
7
7
  // TODO
@@ -20,7 +20,7 @@ export var RxServerRestEndpoint = function RxServerRestEndpoint(server, name, co
20
20
  this.cors = cors;
21
21
  var adapter = server.adapter;
22
22
  setCors(this.server, [this.name].join('/'), cors);
23
- blockPreviousVersionPaths(this.server, [this.name].join('/'), collection.schema.version);
23
+ blockPreviousReplicationVersionPathsRest(this.server, [this.name].join('/'), collection.schema.version);
24
24
  this.urlPath = [this.name, collection.schema.version].join('/');
25
25
  var primaryPath = this.collection.schema.primaryPath;
26
26
  this.queryModifier = (authData, query) => {
@@ -226,4 +226,28 @@ export var RxServerRestEndpoint = function RxServerRestEndpoint(server, name, co
226
226
  adapter.endResponseJson(res, {});
227
227
  });
228
228
  };
229
+
230
+ /**
231
+ * "block" the previous version urls and send a 426 on them so that
232
+ * the clients know they must update.
233
+ */
234
+ export function blockPreviousReplicationVersionPathsRest(server, path, currentVersion) {
235
+ var v = 0;
236
+ var _loop3 = function () {
237
+ var version = v;
238
+ /**
239
+ * Some adapters do not allow regex or handle them property (like Koa),
240
+ * so to make it easier, use the hard-coded array of path parts.
241
+ */
242
+ ['', 'query', 'query/observe', 'get', 'set', 'delete'].forEach(subPath => {
243
+ server.adapter.all(server.serverApp, '/' + path + '/' + version + '/' + subPath, (req, res) => {
244
+ server.adapter.closeConnection(res, 426, 'Outdated version ' + version + ' (newest is ' + currentVersion + ')');
245
+ });
246
+ });
247
+ v++;
248
+ };
249
+ while (v < currentVersion) {
250
+ _loop3();
251
+ }
252
+ }
229
253
  //# sourceMappingURL=endpoint-rest.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"endpoint-rest.js","names":["normalizeMangoQuery","filter","mergeMap","ensureNotFalsy","blockPreviousVersionPaths","docContainsServerOnlyFields","doesContainRegexQuerySelector","getAuthDataByRequest","getDocAllowedMatcher","removeServerOnlyFieldsMonad","setCors","REST_PATHS","RxServerRestEndpoint","server","name","collection","queryModifier","changeValidator","serverOnlyFields","cors","_this","type","adapter","join","schema","version","urlPath","primaryPath","authData","query","selector","Error","change","assumedMasterState","newDocumentState","removeServerOnlyFields","post","serverApp","req","res","getRequestBody","useQuery","jsonSchema","err","closeConnection","rxQuery","find","result","exec","setResponseHeader","endResponseJson","documents","map","d","toJSON","get","setSSEHeaders","JSON","parse","atob","getRequestQuery","subscription","$","pipe","resultData","doc","authHandler","getRequestHeaders","f","subscribe","responseWrite","stringify","onRequestClose","unsubscribe","endResponse","ids","findByIds","resultMap","resultValues","Array","from","values","docMatcher","useDocs","docDataMatcherWrite","docsData","docData","allowed","onWriteError","rxdb","code","push","length","promises","docs","useDocsData","slice","_loop","_docData","id","insert","catch","isAllowed","v","patch","_ret","Promise","all","useIds","docsMap","_loop2","isAllowedDoc","isAllowedChange","remove","_ret2"],"sources":["../../../../src/plugins/server/endpoint-rest.ts"],"sourcesContent":["import {\n FilledMangoQuery,\n RxCollection,\n RxError,\n normalizeMangoQuery\n} from 'rxdb/plugins/core';\nimport type { RxServer } from './rx-server.ts';\nimport type {\n RxServerChangeValidator,\n RxServerEndpoint,\n RxServerQueryModifier\n} from './types.ts';\nimport { filter, mergeMap } from 'rxjs';\nimport {\n ensureNotFalsy,\n getFromMapOrThrow\n} from 'rxdb/plugins/utils';\n\nimport {\n blockPreviousVersionPaths,\n docContainsServerOnlyFields,\n doesContainRegexQuerySelector,\n getAuthDataByRequest,\n getDocAllowedMatcher,\n removeServerOnlyFieldsMonad,\n setCors\n} from './helper.ts';\n\n\nexport const REST_PATHS = [\n 'query',\n 'query/observe',\n 'get',\n 'set',\n 'delete',\n\n // TODO\n /*\n 'attachments/add',\n 'attachments/delete',\n 'events'\n */\n] as const;\n\n\nexport class RxServerRestEndpoint<ServerAppType, AuthType, RxDocType> implements RxServerEndpoint<AuthType, RxDocType> {\n readonly type = 'rest';\n readonly urlPath: string;\n readonly changeValidator: RxServerChangeValidator<AuthType, RxDocType>;\n readonly queryModifier: RxServerQueryModifier<AuthType, RxDocType>;\n constructor(\n public readonly server: RxServer<ServerAppType, AuthType>,\n public readonly name: string,\n public readonly collection: RxCollection<RxDocType>,\n queryModifier: RxServerQueryModifier<AuthType, RxDocType>,\n changeValidator: RxServerChangeValidator<AuthType, RxDocType>,\n public readonly serverOnlyFields: string[],\n public readonly cors?: string\n ) {\n const adapter = server.adapter;\n setCors(this.server, [this.name].join('/'), cors);\n blockPreviousVersionPaths(this.server, [this.name].join('/'), collection.schema.version);\n\n this.urlPath = [this.name, collection.schema.version].join('/');\n const primaryPath = this.collection.schema.primaryPath;\n\n this.queryModifier = (authData, query) => {\n if (doesContainRegexQuerySelector(query.selector)) {\n throw new Error('$regex queries not allowed because of DOS-attacks');\n }\n return queryModifier(authData, query);\n }\n this.changeValidator = (authData, change) => {\n if (\n (\n change.assumedMasterState &&\n docContainsServerOnlyFields(serverOnlyFields, change.assumedMasterState)\n ) ||\n docContainsServerOnlyFields(serverOnlyFields, change.newDocumentState)\n ) {\n return false;\n }\n return changeValidator(authData, change);\n }\n const removeServerOnlyFields = removeServerOnlyFieldsMonad(this.serverOnlyFields);\n\n this.server.adapter.post(this.server.serverApp, '/' + this.urlPath + '/query', async (req, res) => {\n ensureNotFalsy(adapter.getRequestBody(req), 'req body is empty');\n const authData = await getAuthDataByRequest(this.server, req, res);\n if (!authData) { return; }\n\n let useQuery: FilledMangoQuery<RxDocType>\n try {\n useQuery = this.queryModifier(\n ensureNotFalsy(authData),\n normalizeMangoQuery(\n this.collection.schema.jsonSchema,\n adapter.getRequestBody(req)\n )\n );\n } catch (err) {\n adapter.closeConnection(res, 400, 'Bad Request');\n return;\n }\n const rxQuery = this.collection.find(useQuery as any);\n const result = await rxQuery.exec();\n adapter.setResponseHeader(res, 'Content-Type', 'application/json');\n adapter.endResponseJson(res, {\n documents: result.map(d => removeServerOnlyFields(d.toJSON()))\n });\n });\n\n /**\n * It is not possible to send data with server send events,\n * so we send the query as query parameter in base64\n * like ?query=e3NlbGVjdG9yOiB7fX0=\n */\n this.server.adapter.get(this.server.serverApp, '/' + this.urlPath + '/query/observe', async (req, res) => {\n let authData = await getAuthDataByRequest(this.server, req, res);\n if (!authData) { return; }\n\n adapter.setSSEHeaders(res);\n\n const useQuery: FilledMangoQuery<RxDocType> = this.queryModifier(\n ensureNotFalsy(authData),\n normalizeMangoQuery(\n this.collection.schema.jsonSchema,\n JSON.parse(atob(adapter.getRequestQuery(req).query as string))\n )\n );\n\n const rxQuery = this.collection.find(useQuery as any);\n const subscription = rxQuery.$.pipe(\n mergeMap(async (result) => {\n const resultData = result.map(doc => removeServerOnlyFields(doc.toJSON()));\n\n /**\n * The auth-data might be expired\n * so we re-run the auth parsing each time\n * before emitting the new results.\n */\n try {\n authData = await server.authHandler(adapter.getRequestHeaders(req)) as any;\n } catch (err) {\n adapter.closeConnection(res, 401, 'Unauthorized');\n return null;\n }\n\n return resultData;\n }),\n filter(f => f !== null)\n ).subscribe(resultData => {\n adapter.responseWrite(res, 'data: ' + JSON.stringify(resultData) + '\\n\\n');\n });\n\n /**\n * @link https://youtu.be/0PcMuYGJPzM?si=AxkczxcMaUwhh8k9&t=363\n */\n adapter.onRequestClose(req, () => {\n subscription.unsubscribe();\n adapter.endResponse(res);\n });\n });\n\n\n this.server.adapter.post(this.server.serverApp, '/' + this.urlPath + '/get', async (req, res) => {\n const authData = await getAuthDataByRequest(this.server, req, res);\n if (!authData) { return; }\n\n const ids: string[] = adapter.getRequestBody(req);\n\n const rxQuery = this.collection.findByIds(ids);\n const resultMap = await rxQuery.exec();\n const resultValues = Array.from(resultMap.values());\n const docMatcher = getDocAllowedMatcher(this, ensureNotFalsy(authData) as any);\n let useDocs = resultValues.map(d => d.toJSON());\n useDocs = useDocs.filter(d => docMatcher(d as any));\n useDocs = useDocs.map(d => removeServerOnlyFields(d))\n\n adapter.setResponseHeader(res, 'Content-Type', 'application/json');\n adapter.endResponseJson(res, {\n documents: useDocs\n });\n });\n\n this.server.adapter.post(this.server.serverApp, '/' + this.urlPath + '/set', async (req, res) => {\n const authData = await getAuthDataByRequest(this.server, req, res);\n if (!authData) { return; }\n\n const docDataMatcherWrite = getDocAllowedMatcher(this, ensureNotFalsy(authData) as any);\n\n let docsData: RxDocType[] = adapter.getRequestBody(req);\n\n for (const docData of docsData) {\n const allowed = docDataMatcherWrite(docData as any);\n if (!allowed) {\n adapter.closeConnection(res, 403, 'Forbidden');\n return;\n }\n }\n\n function onWriteError(err: RxError, docData: RxDocType) {\n if (err.rxdb && err.code === 'CONFLICT') {\n // just retry on conflicts\n docsData.push(docData);\n } else {\n adapter.closeConnection(res, 500, 'Internal Server Error');\n throw err;\n }\n }\n\n while (docsData.length > 0) {\n const promises: Promise<any>[] = [];\n const docs = await collection.findByIds(docsData.map(d => (d as any)[primaryPath])).exec();\n let useDocsData = docsData.slice();\n docsData = [];\n for (const docData of useDocsData) {\n const id = (docData as any)[primaryPath];\n const doc = docs.get(id);\n if (!doc) {\n promises.push(this.collection.insert(docData).catch(err => onWriteError(err, docData)));\n } else {\n const isAllowed = this.changeValidator(authData, {\n newDocumentState: removeServerOnlyFields(docData as any),\n assumedMasterState: removeServerOnlyFields(doc.toJSON(true))\n });\n if (!isAllowed) {\n adapter.closeConnection(res, 403, 'Forbidden');\n return;\n }\n promises.push(doc.patch(docData).catch(err => onWriteError(err, docData)));\n }\n }\n await Promise.all(promises);\n }\n\n adapter.setResponseHeader(res, 'Content-Type', 'application/json')\n adapter.endResponseJson(res, {});\n });\n\n this.server.adapter.post(this.server.serverApp, '/' + this.urlPath + '/delete', async (req, res) => {\n const authData = await getAuthDataByRequest(this.server, req, res);\n if (!authData) { return; }\n\n const docDataMatcherWrite = getDocAllowedMatcher(this, ensureNotFalsy(authData));\n\n let ids: string[] = adapter.getRequestBody(req);\n while (ids.length > 0) {\n const useIds = ids.slice(0);\n ids = [];\n const promises: Promise<any>[] = [];\n const docsMap = await this.collection.findByIds(useIds).exec();\n for (const id of useIds) {\n const doc = docsMap.get(id);\n if (doc) {\n const isAllowedDoc = docDataMatcherWrite(doc.toJSON(true) as any);\n if (!isAllowedDoc) {\n adapter.closeConnection(res, 403, 'Forbidden');\n return;\n }\n\n const isAllowedChange = this.changeValidator(authData, {\n newDocumentState: doc.toJSON(true) as any,\n assumedMasterState: doc.toJSON(true) as any\n });\n if (!isAllowedChange) {\n adapter.closeConnection(res, 403, 'Forbidden');\n return;\n }\n\n promises.push(doc.remove().catch((err: RxError) => {\n if (err.rxdb && err.code === 'CONFLICT') {\n // just retry on conflicts\n ids.push(id);\n } else {\n adapter.closeConnection(res, 500, 'Internal Server Error');\n throw err;\n }\n }));\n }\n }\n await Promise.all(promises);\n }\n adapter.setResponseHeader(res, 'Content-Type', 'application/json');\n adapter.endResponseJson(res, {});\n });\n }\n}\n"],"mappings":"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","ignoreList":[]}
1
+ {"version":3,"file":"endpoint-rest.js","names":["normalizeMangoQuery","filter","mergeMap","ensureNotFalsy","docContainsServerOnlyFields","doesContainRegexQuerySelector","getAuthDataByRequest","getDocAllowedMatcher","removeServerOnlyFieldsMonad","setCors","REST_PATHS","RxServerRestEndpoint","server","name","collection","queryModifier","changeValidator","serverOnlyFields","cors","_this","type","adapter","join","blockPreviousReplicationVersionPathsRest","schema","version","urlPath","primaryPath","authData","query","selector","Error","change","assumedMasterState","newDocumentState","removeServerOnlyFields","post","serverApp","req","res","getRequestBody","useQuery","jsonSchema","err","closeConnection","rxQuery","find","result","exec","setResponseHeader","endResponseJson","documents","map","d","toJSON","get","setSSEHeaders","JSON","parse","atob","getRequestQuery","subscription","$","pipe","resultData","doc","authHandler","getRequestHeaders","f","subscribe","responseWrite","stringify","onRequestClose","unsubscribe","endResponse","ids","findByIds","resultMap","resultValues","Array","from","values","docMatcher","useDocs","docDataMatcherWrite","docsData","docData","allowed","onWriteError","rxdb","code","push","length","promises","docs","useDocsData","slice","_loop","_docData","id","insert","catch","isAllowed","v","patch","_ret","Promise","all","useIds","docsMap","_loop2","isAllowedDoc","isAllowedChange","remove","_ret2","path","currentVersion","_loop3","forEach","subPath"],"sources":["../../../../src/plugins/server/endpoint-rest.ts"],"sourcesContent":["import {\n FilledMangoQuery,\n RxCollection,\n RxError,\n normalizeMangoQuery\n} from 'rxdb/plugins/core';\nimport type { RxServer } from './rx-server.ts';\nimport type {\n RxServerChangeValidator,\n RxServerEndpoint,\n RxServerQueryModifier\n} from './types.ts';\nimport { filter, mergeMap } from 'rxjs';\nimport {\n ensureNotFalsy,\n getFromMapOrThrow\n} from 'rxdb/plugins/utils';\n\nimport {\n docContainsServerOnlyFields,\n doesContainRegexQuerySelector,\n getAuthDataByRequest,\n getDocAllowedMatcher,\n removeServerOnlyFieldsMonad,\n setCors\n} from './helper.ts';\n\n\nexport const REST_PATHS = [\n 'query',\n 'query/observe',\n 'get',\n 'set',\n 'delete',\n\n // TODO\n /*\n 'attachments/add',\n 'attachments/delete',\n 'events'\n */\n] as const;\n\n\nexport class RxServerRestEndpoint<ServerAppType, AuthType, RxDocType> implements RxServerEndpoint<AuthType, RxDocType> {\n readonly type = 'rest';\n readonly urlPath: string;\n readonly changeValidator: RxServerChangeValidator<AuthType, RxDocType>;\n readonly queryModifier: RxServerQueryModifier<AuthType, RxDocType>;\n constructor(\n public readonly server: RxServer<ServerAppType, AuthType>,\n public readonly name: string,\n public readonly collection: RxCollection<RxDocType>,\n queryModifier: RxServerQueryModifier<AuthType, RxDocType>,\n changeValidator: RxServerChangeValidator<AuthType, RxDocType>,\n public readonly serverOnlyFields: string[],\n public readonly cors?: string\n ) {\n const adapter = server.adapter;\n setCors(this.server, [this.name].join('/'), cors);\n blockPreviousReplicationVersionPathsRest(this.server, [this.name].join('/'), collection.schema.version);\n\n this.urlPath = [this.name, collection.schema.version].join('/');\n const primaryPath = this.collection.schema.primaryPath;\n\n this.queryModifier = (authData, query) => {\n if (doesContainRegexQuerySelector(query.selector)) {\n throw new Error('$regex queries not allowed because of DOS-attacks');\n }\n return queryModifier(authData, query);\n }\n this.changeValidator = (authData, change) => {\n if (\n (\n change.assumedMasterState &&\n docContainsServerOnlyFields(serverOnlyFields, change.assumedMasterState)\n ) ||\n docContainsServerOnlyFields(serverOnlyFields, change.newDocumentState)\n ) {\n return false;\n }\n return changeValidator(authData, change);\n }\n const removeServerOnlyFields = removeServerOnlyFieldsMonad(this.serverOnlyFields);\n\n this.server.adapter.post(this.server.serverApp, '/' + this.urlPath + '/query', async (req, res) => {\n ensureNotFalsy(adapter.getRequestBody(req), 'req body is empty');\n const authData = await getAuthDataByRequest(this.server, req, res);\n if (!authData) { return; }\n\n let useQuery: FilledMangoQuery<RxDocType>\n try {\n useQuery = this.queryModifier(\n ensureNotFalsy(authData),\n normalizeMangoQuery(\n this.collection.schema.jsonSchema,\n adapter.getRequestBody(req)\n )\n );\n } catch (err) {\n adapter.closeConnection(res, 400, 'Bad Request');\n return;\n }\n const rxQuery = this.collection.find(useQuery as any);\n const result = await rxQuery.exec();\n adapter.setResponseHeader(res, 'Content-Type', 'application/json');\n adapter.endResponseJson(res, {\n documents: result.map(d => removeServerOnlyFields(d.toJSON()))\n });\n });\n\n /**\n * It is not possible to send data with server send events,\n * so we send the query as query parameter in base64\n * like ?query=e3NlbGVjdG9yOiB7fX0=\n */\n this.server.adapter.get(this.server.serverApp, '/' + this.urlPath + '/query/observe', async (req, res) => {\n let authData = await getAuthDataByRequest(this.server, req, res);\n if (!authData) { return; }\n\n adapter.setSSEHeaders(res);\n\n const useQuery: FilledMangoQuery<RxDocType> = this.queryModifier(\n ensureNotFalsy(authData),\n normalizeMangoQuery(\n this.collection.schema.jsonSchema,\n JSON.parse(atob(adapter.getRequestQuery(req).query as string))\n )\n );\n\n const rxQuery = this.collection.find(useQuery as any);\n const subscription = rxQuery.$.pipe(\n mergeMap(async (result) => {\n const resultData = result.map(doc => removeServerOnlyFields(doc.toJSON()));\n\n /**\n * The auth-data might be expired\n * so we re-run the auth parsing each time\n * before emitting the new results.\n */\n try {\n authData = await server.authHandler(adapter.getRequestHeaders(req)) as any;\n } catch (err) {\n adapter.closeConnection(res, 401, 'Unauthorized');\n return null;\n }\n\n return resultData;\n }),\n filter(f => f !== null)\n ).subscribe(resultData => {\n adapter.responseWrite(res, 'data: ' + JSON.stringify(resultData) + '\\n\\n');\n });\n\n /**\n * @link https://youtu.be/0PcMuYGJPzM?si=AxkczxcMaUwhh8k9&t=363\n */\n adapter.onRequestClose(req, () => {\n subscription.unsubscribe();\n adapter.endResponse(res);\n });\n });\n\n\n this.server.adapter.post(this.server.serverApp, '/' + this.urlPath + '/get', async (req, res) => {\n const authData = await getAuthDataByRequest(this.server, req, res);\n if (!authData) { return; }\n\n const ids: string[] = adapter.getRequestBody(req);\n\n const rxQuery = this.collection.findByIds(ids);\n const resultMap = await rxQuery.exec();\n const resultValues = Array.from(resultMap.values());\n const docMatcher = getDocAllowedMatcher(this, ensureNotFalsy(authData) as any);\n let useDocs = resultValues.map(d => d.toJSON());\n useDocs = useDocs.filter(d => docMatcher(d as any));\n useDocs = useDocs.map(d => removeServerOnlyFields(d))\n\n adapter.setResponseHeader(res, 'Content-Type', 'application/json');\n adapter.endResponseJson(res, {\n documents: useDocs\n });\n });\n\n this.server.adapter.post(this.server.serverApp, '/' + this.urlPath + '/set', async (req, res) => {\n const authData = await getAuthDataByRequest(this.server, req, res);\n if (!authData) { return; }\n\n const docDataMatcherWrite = getDocAllowedMatcher(this, ensureNotFalsy(authData) as any);\n\n let docsData: RxDocType[] = adapter.getRequestBody(req);\n\n for (const docData of docsData) {\n const allowed = docDataMatcherWrite(docData as any);\n if (!allowed) {\n adapter.closeConnection(res, 403, 'Forbidden');\n return;\n }\n }\n\n function onWriteError(err: RxError, docData: RxDocType) {\n if (err.rxdb && err.code === 'CONFLICT') {\n // just retry on conflicts\n docsData.push(docData);\n } else {\n adapter.closeConnection(res, 500, 'Internal Server Error');\n throw err;\n }\n }\n\n while (docsData.length > 0) {\n const promises: Promise<any>[] = [];\n const docs = await collection.findByIds(docsData.map(d => (d as any)[primaryPath])).exec();\n let useDocsData = docsData.slice();\n docsData = [];\n for (const docData of useDocsData) {\n const id = (docData as any)[primaryPath];\n const doc = docs.get(id);\n if (!doc) {\n promises.push(this.collection.insert(docData).catch(err => onWriteError(err, docData)));\n } else {\n const isAllowed = this.changeValidator(authData, {\n newDocumentState: removeServerOnlyFields(docData as any),\n assumedMasterState: removeServerOnlyFields(doc.toJSON(true))\n });\n if (!isAllowed) {\n adapter.closeConnection(res, 403, 'Forbidden');\n return;\n }\n promises.push(doc.patch(docData).catch(err => onWriteError(err, docData)));\n }\n }\n await Promise.all(promises);\n }\n\n adapter.setResponseHeader(res, 'Content-Type', 'application/json')\n adapter.endResponseJson(res, {});\n });\n\n this.server.adapter.post(this.server.serverApp, '/' + this.urlPath + '/delete', async (req, res) => {\n const authData = await getAuthDataByRequest(this.server, req, res);\n if (!authData) { return; }\n\n const docDataMatcherWrite = getDocAllowedMatcher(this, ensureNotFalsy(authData));\n\n let ids: string[] = adapter.getRequestBody(req);\n while (ids.length > 0) {\n const useIds = ids.slice(0);\n ids = [];\n const promises: Promise<any>[] = [];\n const docsMap = await this.collection.findByIds(useIds).exec();\n for (const id of useIds) {\n const doc = docsMap.get(id);\n if (doc) {\n const isAllowedDoc = docDataMatcherWrite(doc.toJSON(true) as any);\n if (!isAllowedDoc) {\n adapter.closeConnection(res, 403, 'Forbidden');\n return;\n }\n\n const isAllowedChange = this.changeValidator(authData, {\n newDocumentState: doc.toJSON(true) as any,\n assumedMasterState: doc.toJSON(true) as any\n });\n if (!isAllowedChange) {\n adapter.closeConnection(res, 403, 'Forbidden');\n return;\n }\n\n promises.push(doc.remove().catch((err: RxError) => {\n if (err.rxdb && err.code === 'CONFLICT') {\n // just retry on conflicts\n ids.push(id);\n } else {\n adapter.closeConnection(res, 500, 'Internal Server Error');\n throw err;\n }\n }));\n }\n }\n await Promise.all(promises);\n }\n adapter.setResponseHeader(res, 'Content-Type', 'application/json');\n adapter.endResponseJson(res, {});\n });\n }\n}\n\n\n/**\n * \"block\" the previous version urls and send a 426 on them so that\n * the clients know they must update.\n */\nexport function blockPreviousReplicationVersionPathsRest(\n server: RxServer<any, any>,\n path: string,\n currentVersion: number\n\n) {\n let v = 0;\n while (v < currentVersion) {\n const version = v;\n /**\n * Some adapters do not allow regex or handle them property (like Koa),\n * so to make it easier, use the hard-coded array of path parts.\n */\n [\n '',\n 'query',\n 'query/observe',\n 'get',\n 'set',\n 'delete'\n ].forEach(subPath => {\n server.adapter.all(server.serverApp, '/' + path + '/' + version + '/' + subPath, (req, res) => {\n server.adapter.closeConnection(res, 426, 'Outdated version ' + version + ' (newest is ' + currentVersion + ')');\n });\n });\n v++;\n }\n}\n"],"mappings":"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","ignoreList":[]}
@@ -8,24 +8,6 @@ export function setCors(server, path, cors) {
8
8
  server.adapter.setCors(server.serverApp, path, useCors);
9
9
  }
10
10
  }
11
-
12
- /**
13
- * "block" the previous version urls and send a 426 on them so that
14
- * the clients know they must update.
15
- */
16
- export function blockPreviousVersionPaths(server, path, currentVersion) {
17
- var v = 0;
18
- var _loop = function () {
19
- var version = v;
20
- server.adapter.all(server.serverApp, '/' + path + '/' + version + '/*', (req, res) => {
21
- server.adapter.closeConnection(res, 426, 'Outdated version ' + version + ' (newest is ' + currentVersion + ')');
22
- });
23
- v++;
24
- };
25
- while (v < currentVersion) {
26
- _loop();
27
- }
28
- }
29
11
  var AUTH_PER_REQUEST = new WeakMap();
30
12
  export async function getAuthDataByRequest(server, request, response) {
31
13
  return getFromMapOrCreate(AUTH_PER_REQUEST, request, async () => {
@@ -1 +1 @@
1
- {"version":3,"file":"helper.js","names":["flatClone","getFromMapOrCreate","getQueryMatcher","normalizeMangoQuery","uniqueArray","setCors","server","path","cors","useCors","adapter","serverApp","blockPreviousVersionPaths","currentVersion","v","_loop","version","all","req","res","closeConnection","AUTH_PER_REQUEST","WeakMap","getAuthDataByRequest","request","response","headers","getRequestHeaders","authData","authHandler","err","defaultMatchingQuery","selector","skip","sort","getDocAllowedMatcher","endpoint","useQuery","queryModifier","collection","schema","jsonSchema","docDataMatcher","docContainsServerOnlyFields","serverOnlyFields","doc","has","find","field","removeServerOnlyFieldsMonad","serverOnlyFieldsStencil","_meta","undefined","_rev","_attachments","forEach","docData","Object","assign","mergeServerDocumentFieldsMonad","useFields","slice","clientDoc","serverDoc","ret","doesContainRegexQuerySelector","Array","isArray","found","item","entries","key","value"],"sources":["../../../../src/plugins/server/helper.ts"],"sourcesContent":["import { RxServer } from './rx-server';\nimport type {\n Request,\n Response,\n NextFunction\n} from 'express';\nimport type { RxServerAdapter, RxServerAuthData, RxServerEndpoint } from './types';\nimport {\n FilledMangoQuery,\n MangoQuerySelector,\n RxDocumentData,\n flatClone,\n getFromMapOrCreate,\n getQueryMatcher,\n normalizeMangoQuery,\n uniqueArray\n} from 'rxdb/plugins/core';\n\nexport function setCors(\n server: RxServer<any, any>,\n path: string,\n cors?: string\n) {\n let useCors = cors;\n if (!useCors) {\n useCors = server.cors;\n }\n if (useCors) {\n server.adapter.setCors(server.serverApp, path, useCors);\n }\n}\n\n/**\n * \"block\" the previous version urls and send a 426 on them so that\n * the clients know they must update.\n */\nexport function blockPreviousVersionPaths(\n server: RxServer<any, any>,\n path: string,\n currentVersion: number\n\n) {\n let v = 0;\n while (v < currentVersion) {\n const version = v;\n server.adapter.all(server.serverApp, '/' + path + '/' + version + '/*', (req, res) => {\n server.adapter.closeConnection(res, 426, 'Outdated version ' + version + ' (newest is ' + currentVersion + ')');\n });\n v++;\n }\n}\n\n\n\nconst AUTH_PER_REQUEST = new WeakMap<any, Promise<any>>();\n\nexport async function getAuthDataByRequest<AuthType, RequestType, ResponseType>(\n server: RxServer<any, AuthType>,\n request: RequestType,\n response: ResponseType\n): Promise<RxServerAuthData<AuthType> | false> {\n return getFromMapOrCreate(\n AUTH_PER_REQUEST,\n request,\n async () => {\n try {\n const headers = server.adapter.getRequestHeaders(request);\n const authData = await server.authHandler(headers);\n return authData;\n } catch (err) {\n server.adapter.closeConnection(response, 401, 'Unauthorized');\n return false;\n }\n }\n );\n};\n\nconst defaultMatchingQuery: FilledMangoQuery<any> = {\n selector: {},\n skip: 0,\n sort: []\n} as const;\n\nexport function getDocAllowedMatcher<RxDocType, AuthType>(\n endpoint: RxServerEndpoint<AuthType, RxDocType>,\n authData: RxServerAuthData<AuthType>\n) {\n const useQuery: FilledMangoQuery<RxDocType> = endpoint.queryModifier ? endpoint.queryModifier(\n authData,\n normalizeMangoQuery(\n endpoint.collection.schema.jsonSchema,\n {}\n )\n ) : defaultMatchingQuery;\n const docDataMatcher = getQueryMatcher(endpoint.collection.schema.jsonSchema, useQuery);\n return docDataMatcher;\n}\n\n\nexport function docContainsServerOnlyFields(\n serverOnlyFields: string[],\n doc: any\n) {\n const has = serverOnlyFields.find(field => {\n return typeof doc[field] !== 'undefined'\n });\n return has;\n}\n\nexport function removeServerOnlyFieldsMonad<RxDocType>(serverOnlyFields: string[]) {\n const serverOnlyFieldsStencil: any = {\n _meta: undefined,\n _rev: undefined,\n _attachments: undefined\n };\n serverOnlyFields.forEach(field => serverOnlyFieldsStencil[field] = undefined);\n return (\n docData?: RxDocType | RxDocumentData<RxDocType>\n ) => {\n if (!docData) {\n return docData;\n }\n return Object.assign({}, docData, serverOnlyFieldsStencil);\n }\n}\n\nexport function mergeServerDocumentFieldsMonad<RxDocType>(serverOnlyFields: string[]) {\n let useFields = serverOnlyFields.slice(0);\n // useFields.push('_rev');\n // useFields.push('_meta');\n // useFields.push('_attachments');\n useFields = uniqueArray(useFields);\n\n return (\n clientDoc: RxDocType | RxDocumentData<RxDocType>,\n serverDoc?: RxDocType | RxDocumentData<RxDocType>\n ) => {\n if (!serverDoc) {\n return clientDoc;\n }\n const ret = flatClone(clientDoc);\n useFields.forEach(field => {\n (ret as any)[field] = (serverDoc as any)[field];\n });\n return ret;\n }\n}\n\n\n/**\n * $regex queries are dangerous because they can dos-attack the server.\n * \n * @param selector \n */\nexport function doesContainRegexQuerySelector(selector: MangoQuerySelector<any> | any): boolean {\n if (!selector) {\n return false;\n }\n if (Array.isArray(selector)) {\n const found = !!selector.find(item => doesContainRegexQuerySelector(item));\n return found;\n }\n\n if (typeof selector !== 'object') {\n return false;\n }\n\n const entries = Object.entries(selector);\n for (const [key, value] of entries) {\n if (key === '$regex') {\n return true;\n } else {\n const has = doesContainRegexQuerySelector(value);\n if (has) {\n return true;\n }\n }\n }\n\n return false;\n}\n"],"mappings":"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","ignoreList":[]}
1
+ {"version":3,"file":"helper.js","names":["flatClone","getFromMapOrCreate","getQueryMatcher","normalizeMangoQuery","uniqueArray","setCors","server","path","cors","useCors","adapter","serverApp","AUTH_PER_REQUEST","WeakMap","getAuthDataByRequest","request","response","headers","getRequestHeaders","authData","authHandler","err","closeConnection","defaultMatchingQuery","selector","skip","sort","getDocAllowedMatcher","endpoint","useQuery","queryModifier","collection","schema","jsonSchema","docDataMatcher","docContainsServerOnlyFields","serverOnlyFields","doc","has","find","field","removeServerOnlyFieldsMonad","serverOnlyFieldsStencil","_meta","undefined","_rev","_attachments","forEach","docData","Object","assign","mergeServerDocumentFieldsMonad","useFields","slice","clientDoc","serverDoc","ret","doesContainRegexQuerySelector","Array","isArray","found","item","entries","key","value"],"sources":["../../../../src/plugins/server/helper.ts"],"sourcesContent":["import { RxServer } from './rx-server';\nimport type {\n Request,\n Response,\n NextFunction\n} from 'express';\nimport type { RxServerAdapter, RxServerAuthData, RxServerEndpoint } from './types';\nimport {\n FilledMangoQuery,\n MangoQuerySelector,\n RxDocumentData,\n flatClone,\n getFromMapOrCreate,\n getQueryMatcher,\n normalizeMangoQuery,\n uniqueArray\n} from 'rxdb/plugins/core';\n\nexport function setCors(\n server: RxServer<any, any>,\n path: string,\n cors?: string\n) {\n let useCors = cors;\n if (!useCors) {\n useCors = server.cors;\n }\n if (useCors) {\n server.adapter.setCors(server.serverApp, path, useCors);\n }\n}\n\n\nconst AUTH_PER_REQUEST = new WeakMap<any, Promise<any>>();\n\nexport async function getAuthDataByRequest<AuthType, RequestType, ResponseType>(\n server: RxServer<any, AuthType>,\n request: RequestType,\n response: ResponseType\n): Promise<RxServerAuthData<AuthType> | false> {\n return getFromMapOrCreate(\n AUTH_PER_REQUEST,\n request,\n async () => {\n try {\n const headers = server.adapter.getRequestHeaders(request);\n const authData = await server.authHandler(headers);\n return authData;\n } catch (err) {\n server.adapter.closeConnection(response, 401, 'Unauthorized');\n return false;\n }\n }\n );\n};\n\nconst defaultMatchingQuery: FilledMangoQuery<any> = {\n selector: {},\n skip: 0,\n sort: []\n} as const;\n\nexport function getDocAllowedMatcher<RxDocType, AuthType>(\n endpoint: RxServerEndpoint<AuthType, RxDocType>,\n authData: RxServerAuthData<AuthType>\n) {\n const useQuery: FilledMangoQuery<RxDocType> = endpoint.queryModifier ? endpoint.queryModifier(\n authData,\n normalizeMangoQuery(\n endpoint.collection.schema.jsonSchema,\n {}\n )\n ) : defaultMatchingQuery;\n const docDataMatcher = getQueryMatcher(endpoint.collection.schema.jsonSchema, useQuery);\n return docDataMatcher;\n}\n\n\nexport function docContainsServerOnlyFields(\n serverOnlyFields: string[],\n doc: any\n) {\n const has = serverOnlyFields.find(field => {\n return typeof doc[field] !== 'undefined'\n });\n return has;\n}\n\nexport function removeServerOnlyFieldsMonad<RxDocType>(serverOnlyFields: string[]) {\n const serverOnlyFieldsStencil: any = {\n _meta: undefined,\n _rev: undefined,\n _attachments: undefined\n };\n serverOnlyFields.forEach(field => serverOnlyFieldsStencil[field] = undefined);\n return (\n docData?: RxDocType | RxDocumentData<RxDocType>\n ) => {\n if (!docData) {\n return docData;\n }\n return Object.assign({}, docData, serverOnlyFieldsStencil);\n }\n}\n\nexport function mergeServerDocumentFieldsMonad<RxDocType>(serverOnlyFields: string[]) {\n let useFields = serverOnlyFields.slice(0);\n // useFields.push('_rev');\n // useFields.push('_meta');\n // useFields.push('_attachments');\n useFields = uniqueArray(useFields);\n\n return (\n clientDoc: RxDocType | RxDocumentData<RxDocType>,\n serverDoc?: RxDocType | RxDocumentData<RxDocType>\n ) => {\n if (!serverDoc) {\n return clientDoc;\n }\n const ret = flatClone(clientDoc);\n useFields.forEach(field => {\n (ret as any)[field] = (serverDoc as any)[field];\n });\n return ret;\n }\n}\n\n\n/**\n * $regex queries are dangerous because they can dos-attack the server.\n * \n * @param selector \n */\nexport function doesContainRegexQuerySelector(selector: MangoQuerySelector<any> | any): boolean {\n if (!selector) {\n return false;\n }\n if (Array.isArray(selector)) {\n const found = !!selector.find(item => doesContainRegexQuerySelector(item));\n return found;\n }\n\n if (typeof selector !== 'object') {\n return false;\n }\n\n const entries = Object.entries(selector);\n for (const [key, value] of entries) {\n if (key === '$regex') {\n return true;\n } else {\n const has = doesContainRegexQuerySelector(value);\n if (has) {\n return true;\n }\n }\n }\n\n return false;\n}\n"],"mappings":"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","ignoreList":[]}
@@ -18,3 +18,8 @@ export declare class RxServerReplicationEndpoint<ServerAppType, AuthType, RxDocT
18
18
  readonly queryModifier: RxServerQueryModifier<AuthType, RxDocType>;
19
19
  constructor(server: RxServer<ServerAppType, AuthType>, name: string, collection: RxCollection<RxDocType>, queryModifier: RxServerQueryModifier<AuthType, RxDocType>, changeValidator: RxServerChangeValidator<AuthType, RxDocType>, serverOnlyFields: string[], cors?: string | undefined);
20
20
  }
21
+ /**
22
+ * "block" the previous version urls and send a 426 on them so that
23
+ * the clients know they must update.
24
+ */
25
+ export declare function blockPreviousReplicationVersionPaths(server: RxServer<any, any>, path: string, currentVersion: number): void;
@@ -14,3 +14,8 @@ export declare class RxServerRestEndpoint<ServerAppType, AuthType, RxDocType> im
14
14
  readonly queryModifier: RxServerQueryModifier<AuthType, RxDocType>;
15
15
  constructor(server: RxServer<ServerAppType, AuthType>, name: string, collection: RxCollection<RxDocType>, queryModifier: RxServerQueryModifier<AuthType, RxDocType>, changeValidator: RxServerChangeValidator<AuthType, RxDocType>, serverOnlyFields: string[], cors?: string | undefined);
16
16
  }
17
+ /**
18
+ * "block" the previous version urls and send a 426 on them so that
19
+ * the clients know they must update.
20
+ */
21
+ export declare function blockPreviousReplicationVersionPathsRest(server: RxServer<any, any>, path: string, currentVersion: number): void;
@@ -2,11 +2,6 @@ import { RxServer } from './rx-server';
2
2
  import type { RxServerAuthData, RxServerEndpoint } from './types';
3
3
  import { MangoQuerySelector, RxDocumentData } from 'rxdb/plugins/core';
4
4
  export declare function setCors(server: RxServer<any, any>, path: string, cors?: string): void;
5
- /**
6
- * "block" the previous version urls and send a 426 on them so that
7
- * the clients know they must update.
8
- */
9
- export declare function blockPreviousVersionPaths(server: RxServer<any, any>, path: string, currentVersion: number): void;
10
5
  export declare function getAuthDataByRequest<AuthType, RequestType, ResponseType>(server: RxServer<any, AuthType>, request: RequestType, response: ResponseType): Promise<RxServerAuthData<AuthType> | false>;
11
6
  export declare function getDocAllowedMatcher<RxDocType, AuthType>(endpoint: RxServerEndpoint<AuthType, RxDocType>, authData: RxServerAuthData<AuthType>): import("rxdb/plugins/core").QueryMatcher<RxDocumentData<RxDocType>>;
12
7
  export declare function docContainsServerOnlyFields(serverOnlyFields: string[], doc: any): string | undefined;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "rxdb-server",
3
- "version": "15.13.4",
3
+ "version": "15.14.0",
4
4
  "description": "RxDB Server Plugin",
5
5
  "license": "SSPL",
6
6
  "author": "pubkey",
@@ -131,7 +131,7 @@
131
131
  "minify-all-js": "0.1.9",
132
132
  "mocha": "10.3.0",
133
133
  "rimraf": "5.0.5",
134
- "rxdb": "15.13.4",
134
+ "rxdb": "15.14.0",
135
135
  "rxjs": "7.8.1",
136
136
  "ts-loader": "9.5.1",
137
137
  "ts-mocha": "10.0.0",