@universis/user-storage
Version:
Universis Api Server Extension for managing user remote storage
288 lines (215 loc) • 8.84 kB
JavaScript
;
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