UNPKG

rxdb-server

Version:
157 lines (154 loc) 5.08 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.docContainsServerOnlyFields = docContainsServerOnlyFields; exports.doesContainRegexQuerySelector = doesContainRegexQuerySelector; exports.getAuthDataByRequest = getAuthDataByRequest; exports.getDocAllowedMatcher = getDocAllowedMatcher; exports.mergeServerDocumentFieldsMonad = mergeServerDocumentFieldsMonad; exports.removeServerOnlyFieldsMonad = removeServerOnlyFieldsMonad; exports.setCors = setCors; exports.stripServerOnlyFieldsMonad = stripServerOnlyFieldsMonad; var _core = require("rxdb/plugins/core"); function setCors(server, path, cors) { var useCors = cors; if (!useCors) { useCors = server.cors; } if (useCors) { server.adapter.setCors(server.serverApp, path, useCors); } } var AUTH_PER_REQUEST = new WeakMap(); async function getAuthDataByRequest(server, request, response) { return (0, _core.getFromMapOrCreate)(AUTH_PER_REQUEST, request, async () => { try { var headers = server.adapter.getRequestHeaders(request); var authData = await server.authHandler(headers); return authData; } catch (err) { server.adapter.closeConnection(response, 401, 'Unauthorized'); return false; } }); } ; var defaultMatchingQuery = { selector: {}, skip: 0, sort: [] }; function getDocAllowedMatcher(endpoint, authData) { var useQuery = endpoint.queryModifier ? endpoint.queryModifier(authData, (0, _core.normalizeMangoQuery)(endpoint.collection.schema.jsonSchema, {})) : defaultMatchingQuery; var docDataMatcher = (0, _core.getQueryMatcher)(endpoint.collection.schema.jsonSchema, useQuery); return docDataMatcher; } function docContainsServerOnlyFields(serverOnlyFields, doc) { var has = serverOnlyFields.find(field => { return typeof doc[field] !== 'undefined'; }); return has; } /** * Returns a function that strips the given server-only fields from a client * document. This is used when accepting a NEW document from a client write to * make sure that server-only fields cannot be populated by the client. * * Unlike {@link removeServerOnlyFieldsMonad} this does not assign undefined to * RxDB internal meta fields (`_meta`, `_rev`, `_attachments`) so the result can * be safely passed to `RxCollection.insert()`. */ function stripServerOnlyFieldsMonad(serverOnlyFields) { if (serverOnlyFields.length === 0) { return docData => docData; } return docData => { var ret = (0, _core.flatClone)(docData); for (var i = 0; i < serverOnlyFields.length; i++) { delete ret[serverOnlyFields[i]]; } return ret; }; } function removeServerOnlyFieldsMonad(serverOnlyFields) { var serverOnlyFieldsStencil = { _meta: undefined, _rev: undefined, _attachments: undefined }; serverOnlyFields.forEach(field => serverOnlyFieldsStencil[field] = undefined); return docData => { if (!docData) { return docData; } return Object.assign({}, docData, serverOnlyFieldsStencil); }; } function mergeServerDocumentFieldsMonad(serverOnlyFields) { var useFields = serverOnlyFields.slice(0); // useFields.push('_rev'); // useFields.push('_meta'); // useFields.push('_attachments'); useFields = (0, _core.uniqueArray)(useFields); return (clientDoc, serverDoc) => { if (!clientDoc) { return clientDoc; } var ret = (0, _core.flatClone)(clientDoc); if (!serverDoc) { // No prior server-side state exists for this document (new // insert). The client must not be able to populate server-only // fields on creation, so strip them from the merged document. useFields.forEach(field => delete ret[field]); return ret; } useFields.forEach(field => { /** * If the field exists on the serverDoc, copy its value so that * the server-side value always wins over anything the client * sent. If it does not exist on the serverDoc, delete it from * the merged document so the key is truly absent — using `null` * here would make the merged row differ from the stored master * state during the isEqual check inside masterWrite and * produce a false conflict that silently reverts the write. */ if (field in serverDoc) { ret[field] = serverDoc[field]; } else { delete ret[field]; } }); return ret; }; } /** * $regex queries are dangerous because they can dos-attack the server. * * @param selector */ function doesContainRegexQuerySelector(selector) { if (!selector) { return false; } if (Array.isArray(selector)) { var found = !!selector.find(item => doesContainRegexQuerySelector(item)); return found; } if (typeof selector !== 'object') { return false; } var entries = Object.entries(selector); for (var [key, value] of entries) { if (key === '$regex') { return true; } else { var has = doesContainRegexQuerySelector(value); if (has) { return true; } } } return false; } //# sourceMappingURL=helper.js.map