/* global ubs_message */
const { Session, Repository, DataStore } = require('@unitybase/ub')
ubs_message.entity.addMethod('getCached')
ubs_message.entity.addMethod('selectAll')
ubs_message.on('select:before', addUserFilters)
/**
* If something changes in ubs_messages from a last call - return a messages.
*
* @function getCached
* @memberOf ubs_message_ns.prototype
* @memberOfModule @unitybase/ubs
* @published
* @param {ubMethodParams} ctx
* @returns {boolean}
*/
ubs_message.getCached = function (ctx) {
if (ctx.mParams.version) {
const expr = 'SELECT MAX(mi_modifyDate) AS "last_number" FROM ubs_message'
const store = DataStore('ubs_message')
store.runSQL(expr, {})
const versionFromDb = store.get('last_number')
store.freeNative()
const version = new Date(versionFromDb).getTime()
const notModified = version === Number(ctx.mParams.version)
ctx.mParams.version = version
if (notModified) {
ctx.mParams.resultData = { notModified: true }
return true
}
}
ctx.dataStore.run('select', ctx.mParams)
}
/**
* Select all ubs_messages (ubs_messages.select returns incomplete messages for current user)
*
* @function selectAll
* @memberOf ubs_message_ns.prototype
* @memberOfModule @unitybase/ubs
* @published
* @param {ubMethodParams} ctx
* @returns {boolean}
*/
ubs_message.selectAll = function (ctx) {
ctx.mParams.__skipAclRls = true
ctx.dataStore.run('select', ctx.mParams)
}
ubs_message.skipAclRls = function () {
return false
}
/**
* Check if user try fetching own message by ID (to create/modify it)
*
* @private
* @param ctx
* @returns {boolean}
*/
function isFetchOwnMessage (ctx) {
const ID = ctx.mParams.ID
if (ID) {
return Repository('ubs_message')
.attrs('mi_owner')
.misc({ __skipAclRls: true })
.where('ID', '=', ID)
.selectScalar() === Session.userID
}
return false
}
/**
* Check if fieldList or whereList contains references to the recipients column
* @param {object} mParams - The parameters object
* @param {string[]} [mParams.fieldList=[]] - List of field names to check
* @param {object} [mParams.whereList={}] - Where conditions to check for recipient restrictions
* @returns {boolean} True if any field or where condition references a recipient column, false otherwise
*/
function hasRecipientRestriction (mParams) {
/**
* Add bracket to fieldName if it is not present
* @param {string} fName
* @returns {string}
*/
function addBracket (fName) {
return fName[0] === '[' ? fName : '[' + fName + ']'
}
const { fieldList = [], whereList = {} } = mParams
const recipientPrefix = '[recipients.'
return fieldList.some(field => addBracket(field).startsWith(recipientPrefix)) ||
Object.values(whereList).some(where => where.expression && addBracket(where.expression).startsWith(recipientPrefix))
}
/**
* Filter only complete(ready for send) up-to-date messages
*
* @private
* @param {ubMethodParams} ctx
* @returns {boolean}
*/
function addUserFilters (ctx) {
const nm = Date.now()
const mParams = ctx.mParams
if (App.els('ubs_message', 'insert') || !ctx.externalCall) {
if (mParams.__skipAclRls || isFetchOwnMessage(ctx)) {
// user can insert messages so can potentially read all and read one message by ID
// usually - SysOps role
mParams.__skipAclRls = true
return true
}
}
if (!mParams.whereList) {
mParams.whereList = {}
}
if (hasRecipientRestriction(mParams)) {
mParams.whereList['user' + nm] = {
expression: '[recipients.userID]',
condition: 'equal',
value: Session.userID
}
mParams.joinAs = ['user' + nm]
}
mParams.whereList['complete' + nm] = {
expression: '[complete]',
condition: 'equal',
value: 1
}
mParams.whereList['startDate' + nm] = {
expression: '[startDate]',
condition: 'less',
value: new Date()
}
return true
}