UNPKG

@universis/user-storage

Version:

Universis Api Server Extension for managing user remote storage

288 lines (215 loc) 8.84 kB
"use strict"; var _common = require("@themost/common"); var _service = require("./service"); var _mongo = require("@themost/mongo"); var _query = require("@themost/query"); var _ = _interopRequireWildcard(require("lodash")); function _getRequireWildcardCache(nodeInterop) { if (typeof WeakMap !== "function") return null; var cacheBabelInterop = new WeakMap(); var cacheNodeInterop = new WeakMap(); return (_getRequireWildcardCache = function (nodeInterop) { return nodeInterop ? cacheNodeInterop : cacheBabelInterop; })(nodeInterop); } function _interopRequireWildcard(obj, nodeInterop) { if (!nodeInterop && obj && obj.__esModule) { return obj; } if (obj === null || typeof obj !== "object" && typeof obj !== "function") { return { default: obj }; } var cache = _getRequireWildcardCache(nodeInterop); if (cache && cache.has(obj)) { return cache.get(obj); } var newObj = {}; var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var key in obj) { if (key !== "default" && Object.prototype.hasOwnProperty.call(obj, key)) { var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null; if (desc && (desc.get || desc.set)) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } newObj.default = obj; if (cache) { cache.set(obj, newObj); } return newObj; } function escapeKey(key) { let res = key.replace(/\//ig, '.'); if (/^\./.test(res)) { return res.substr(1); } return res; } /** * Tests the given key and returns collection from key * @param key */ function testSelectAttribute(key) { // parse key const keys = escapeKey(key).split('.'); // get collection and property (if any) if (keys.length === 1) { return { collection: keys[0] }; } return { collection: keys[0], property: keys.slice(1).join('.') }; } class MongoUserStorageService extends _service.UserStorageService { /** * @param {IApplication} app */ constructor(app) { super(app); } /** * @name RedisClient#json_set * @param {*} ...args */ /** * @name RedisClient#json_get * @param {*} ...args */ /** * * @param {DataContext} context * @param {string} key * @param {*} value * @param {number=} expiration */ async setItem(context, key, value, expiration) { // parse key const selectAttribute = testSelectAttribute(key); // get collection and property (if any) const collection = selectAttribute.collection; // get property expression let property = selectAttribute.property; // validate user const hasAccess = await context.getConfiguration().getStrategy(_service.UserStorageAccessConfiguration).verify(context, `me/${key}`, 'write'); if (hasAccess == null) { throw new _common.AccessDeniedError('Write access to the specified user storage key is denied'); } // get database connection const db = new _mongo.MongoAdapter(this.options); if (typeof expiration === "number" && expiration > 0) { // call json_set() with expiration return await new Promise((resolve, reject) => { return reject(new Error('This operation is not supported by the specified user storage adapter.')); }); } // split property and get nested object // set item return await new Promise((resolve, reject) => { let query; let finalValue; let property1 = null; let property1value = null; // check if property contains nested properties if (property && /\./ig.test(property)) { property1 = property.split('.')[0]; } // check if item already exists if (property1) { query = new _query.QueryExpression().select('_id', property1).from(collection).where('owner').equal(context.user.name); } else { query = new _query.QueryExpression().select('_id').from(collection).where('owner').equal(context.user.name); } db.execute(query, null, (err, result) => { if (err) { return reject(err); } let _id; // get object id if (result && result.length) { _id = result[0]._id; // set nested property property1value = property1 ? result[0][property1] : null; } // prepare final value if (property) { finalValue = {}; if (property1) { finalValue[property1] = property1value; } // set value _.set(finalValue, property, value); // set owner Object.assign(finalValue, { "owner": context.user.name }); } else { // property does not exist so prepare simple insert statement finalValue = Object.assign(value, { "owner": context.user.name }); } // if object does not exist if (_id == null) { query = new _query.QueryExpression().insert(finalValue).into(collection); } else { // set id Object.assign(finalValue, { "_id": _id }); // prepare update statement query = new _query.QueryExpression().update(collection).set(finalValue).where("_id").equal(_id); } db.execute(query, null, err => { // close database connection db.close(() => { if (err) { return reject(err); } return resolve(value); }); }); }); }); } /** * @param {DataContext} context * @param {string} key */ async getItem(context, key) { // parse key const selectAttribute = testSelectAttribute(key); // validate user access const hasAccess = await context.getConfiguration().getStrategy(_service.UserStorageAccessConfiguration).verify(context, `me/${key}`, 'read'); if (hasAccess == null) { // throw access denied throw new _common.AccessDeniedError('Read access to the specified user storage key is denied'); } // get database connection const db = new _mongo.MongoAdapter(this.options); // set item return await new Promise((resolve, reject) => { // prepare where statement const query = new _query.QueryExpression().select(selectAttribute.property ? selectAttribute.property : '*').from(selectAttribute.collection).where('owner').equal(context.user.name); db.execute(query, null, (err, result) => { // close database connection db.close(() => { if (err) { return reject(err); } if (result && result.length) { // remove identifier delete result[0]._id; // if select contains a nested property if (selectAttribute.property) { //get nested property return resolve(_.get(result[0], selectAttribute.property)); } else { // otherwise get first item return resolve(result[0]); } } return resolve(); }); }); }); } /** * @param {DataContext} context * @param {string} key */ async removeItem(context, key) { // parse key const selectAttribute = testSelectAttribute(key); // validate user access const hasAccess = await context.getConfiguration().getStrategy(_service.UserStorageAccessConfiguration).verify(context, `me/${key}`, 'write'); if (hasAccess == null) { throw new _common.AccessDeniedError('Write access to the specified user storage key is denied'); } if (selectAttribute.property) { // set property to null return this.setItem(context, key, null).then(() => { return Promise.resolve(true); }); } // get database connection const db = new _mongo.MongoAdapter(this.options); return await new Promise((resolve, reject) => { let query; // prepare where statement query = new _query.QueryExpression().delete(selectAttribute.collection).where('owner').equal(context.user.name); db.execute(query, null, err => { // close database connection db.close(() => { if (err) { return reject(err); } return resolve(true); }); }); }); } /** * @param {DataContext} context */ async clear(context) { // validate user access const hasAccess = context.getConfiguration().getStrategy(_service.UserStorageAccessConfiguration).verify(context, `me`, 'write'); if (hasAccess == null) { throw new _common.AccessDeniedError('Write access to the specified user storage key is denied'); } return await new Promise((resolve, reject) => { return reject(new Error('This operation is not supported by the specified user storage adapter.')); }); } } module.exports.MongoUserStorageService = MongoUserStorageService; //# sourceMappingURL=mongo.js.map