backend-plus 2.7.0-beta.3 → 2.7.0-beta.4

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.
@@ -73,7 +73,7 @@ if(dashDashDir>0){
73
73
  console.log('cwd',process.cwd());
74
74
  }
75
75
 
76
- /**
76
+ /**
77
77
  * @param {string} text
78
78
  * @return {string}
79
79
  */
@@ -81,14 +81,14 @@ function md5(text){
81
81
  return crypto.createHash('md5').update(text).digest('hex');
82
82
  }
83
83
 
84
- const DEFAULT_ITERATIONS = 4096;
84
+ const DEFAULT_ITERATIONS = 4096;
85
85
  const HASH_ALGORITHM = 'sha256';
86
86
 
87
87
  // primera version de scram sha 256. El Verifier completo tenía 64 bytes.
88
- const LEGACY_KEY_LENGTH = 64;
88
+ const LEGACY_KEY_LENGTH = 64;
89
89
 
90
90
  // Formato nuevo/PG-Compatible: El Client Key tiene 32 bytes (SHA-256).
91
- const SCRAM_KEY_LENGTH = 32;
91
+ const SCRAM_KEY_LENGTH = 32;
92
92
 
93
93
  const bufferToBase64 = (buffer) => buffer.toString('base64');
94
94
 
@@ -96,31 +96,31 @@ const bufferToBase64 = (buffer) => buffer.toString('base64');
96
96
  * Función central para PBKDF2 (Acepta KEY_LEN para compatibilidad).
97
97
  * Devuelve la clave derivada con la longitud especificada.
98
98
  */
99
- async function deriveKey(password, saltBuffer, iterations, keyLength) {
99
+ async function deriveKey(password, saltBuffer, iterations, keyLength) {
100
100
  return new Promise((resolve, reject) => {
101
101
  crypto.pbkdf2(
102
- password,
102
+ password,
103
103
  saltBuffer,
104
- iterations,
104
+ iterations,
105
105
  keyLength,
106
- HASH_ALGORITHM,
106
+ HASH_ALGORITHM,
107
107
  (err, derivedKey) => {
108
108
  if (err) return reject(err);
109
- resolve(derivedKey);
109
+ resolve(derivedKey);
110
110
  }
111
111
  );
112
112
  });
113
113
  }
114
114
 
115
115
  async function generateScramVerifier(password) {
116
- const saltBuffer = crypto.randomBytes(16);
116
+ const saltBuffer = crypto.randomBytes(16);
117
117
  const saltBase64 = bufferToBase64(saltBuffer);
118
118
 
119
119
  const Hi = await deriveKey(
120
- password,
121
- saltBuffer,
120
+ password,
121
+ saltBuffer,
122
122
  DEFAULT_ITERATIONS,
123
- SCRAM_KEY_LENGTH
123
+ SCRAM_KEY_LENGTH
124
124
  );
125
125
  const clientKey = crypto.createHmac('sha256', Hi).update('Client Key').digest();
126
126
  const serverKey = crypto.createHmac('sha256', Hi).update('Server Key').digest();
@@ -144,27 +144,27 @@ async function verifyScramPG(password, storedScramString) {
144
144
  if (!storedScramString.startsWith('SCRAM-SHA-256$')) {
145
145
  return false;
146
146
  }
147
-
147
+
148
148
  const parts = storedScramString.split('$');
149
149
  if (parts.length !== 3) {
150
150
  return false;
151
151
  }
152
-
152
+
153
153
  const [storedIterations, saltBase64] = parts[1].split(':');
154
154
  const [storedKeyBase64, serverKeyBase64] = parts[2].split(':'); // Asume StoredKey y ServerKey
155
155
 
156
156
  if (!saltBase64 || !storedKeyBase64 || !serverKeyBase64 || isNaN(parseInt(storedIterations))) {
157
157
  return false;
158
158
  }
159
-
159
+
160
160
  const iterations = parseInt(storedIterations);
161
161
  const saltBuffer = Buffer.from(saltBase64, 'base64');
162
162
  const storedKeyBuffer = Buffer.from(storedKeyBase64, 'base64');
163
163
  const serverKeyBuffer = Buffer.from(serverKeyBase64, 'base64');
164
164
 
165
165
  const Hi = await deriveKey(
166
- password,
167
- saltBuffer,
166
+ password,
167
+ saltBuffer,
168
168
  iterations,
169
169
  SCRAM_KEY_LENGTH
170
170
  );
@@ -203,21 +203,21 @@ async function verifyScramLegacy(password, storedScramString) {
203
203
  if (parts.length !== 3) {
204
204
  throw new Error('Formato SCRAM almacenado inválido.');
205
205
  }
206
-
206
+
207
207
  // Obtiene iteraciones y salt de la segunda parte (ej: '4096:SALT_BASE64')
208
208
  const [storedIterations, storedSalt] = parts[1].split(':');
209
209
  const storedVerifier = parts[2];
210
-
210
+
211
211
  if (!storedSalt || !storedVerifier || isNaN(parseInt(storedIterations))) {
212
212
  throw new Error('Datos de SCRAM incompletos o malformados.');
213
213
  }
214
-
214
+
215
215
  const iterations = parseInt(storedIterations);
216
216
 
217
217
  // Deriva la clave de la contraseña ingresada
218
218
  const generatedVerifierBuffer = await deriveKey(
219
- password,
220
- storedSalt,
219
+ password,
220
+ storedSalt,
221
221
  iterations,
222
222
  LEGACY_KEY_LENGTH
223
223
  );
@@ -313,7 +313,7 @@ AppBackend.prototype.configStaticConfig = function configStaticConfig(){
313
313
  min-version: 12
314
314
  fkOnUpdate: cascade
315
315
  max: 50
316
- log:
316
+ log:
317
317
  db:
318
318
  until: 2001-01-01 00:00
319
319
  last-error: false
@@ -326,7 +326,7 @@ AppBackend.prototype.configStaticConfig = function configStaticConfig(){
326
326
  "":
327
327
  local-path: for-client
328
328
  bin: {}
329
- client-setup:
329
+ client-setup:
330
330
  skin: ""
331
331
  lang: en
332
332
  version: 1.0
@@ -589,7 +589,7 @@ function MemoryPerodicallySaved(session){
589
589
  })}
590
590
 
591
591
  /**
592
- * @param {string} text
592
+ * @param {string} text
593
593
  */
594
594
  AppBackend.prototype.jsonPass = function jsonPass(text){
595
595
  return JSON.stringify(text,null,' ').replace(/\n(.*".*(pass|clave|secret).*":\s*").*(",?)\n/gi,'\n$1********$3\n');
@@ -751,7 +751,7 @@ AppBackend.prototype.start = function start(opts){
751
751
  while(iPosDbDump && iPosDbDump<process.argv.length && !process.argv[iPosDbDump].startsWith('--')){
752
752
  dumps.push(process.argv[iPosDbDump]);
753
753
  iPosDbDump++;
754
- }
754
+ }
755
755
  opts["dump-db"]={
756
756
  complete:!dumps.length,
757
757
  tableNames:dumps instanceof Array?dumps:null,
@@ -888,8 +888,8 @@ AppBackend.prototype.start = function start(opts){
888
888
  }
889
889
  be.db = pg;
890
890
  be.dbUserNameExpr="get_app_user()";
891
- be.dbUserRolExpr=`(select ${be.db.quoteIdent(be.config.login.rolFieldName)}
892
- from ${be.config.login.schema?be.db.quoteIdent(be.config.login.schema)+'.':''}${be.db.quoteIdent(be.config.login.table)}
891
+ be.dbUserRolExpr=`(select ${be.db.quoteIdent(be.config.login.rolFieldName)}
892
+ from ${be.config.login.schema?be.db.quoteIdent(be.config.login.schema)+'.':''}${be.db.quoteIdent(be.config.login.table)}
893
893
  where ${be.db.quoteIdent(be.config.login.userFieldName)} = ${be.dbUserNameExpr})`
894
894
  }).then(function(){
895
895
  if(opts["dump-db"]){
@@ -1048,7 +1048,7 @@ AppBackend.prototype.start = function start(opts){
1048
1048
  },function(){ /*OK, login.jade must not be here */ }),
1049
1049
  fs.stat('client/login.jade').then(function(){
1050
1050
  return Path.resolve(be.rootPath,'client/login');
1051
- },function(){
1051
+ },function(){
1052
1052
  return Path.join(__dirname,'../for-client/login');
1053
1053
  }).then(function(loginFile){
1054
1054
  be.config.login.plus.loginPageServe=function(req,res,next){
@@ -1165,7 +1165,7 @@ AppBackend.prototype.start = function start(opts){
1165
1165
  if(verboseStartup){
1166
1166
  console.log('-------------------');
1167
1167
  console.log(
1168
- 'be.config.login',
1168
+ 'be.config.login',
1169
1169
  be.jsonPass(be.config.login)
1170
1170
  );
1171
1171
  }
@@ -1194,7 +1194,7 @@ AppBackend.prototype.start = function start(opts){
1194
1194
  }
1195
1195
  });
1196
1196
  const updatePassword = async ({client, username, password, setUpdateDate, errorIfNoResult}) => {
1197
- const {table, passFieldName, userFieldName, passUpdatedAtFieldName, passAlgorithmFieldName, schema} = be.config.login;
1197
+ const {table, passFieldName, userFieldName, passUpdatedAtFieldName, passAlgorithmFieldName, schema} = be.config.login;
1198
1198
  const hashPass = await generateScramVerifier(password);
1199
1199
  let params = [username, hashPass];
1200
1200
  let setters = [`${be.db.quoteIdent(passFieldName)} = $2`];
@@ -1205,9 +1205,9 @@ AppBackend.prototype.start = function start(opts){
1205
1205
  if(setUpdateDate && passUpdatedAtFieldName){
1206
1206
  setters.push(`${be.db.quoteIdent(passUpdatedAtFieldName)} = current_timestamp`)
1207
1207
  }
1208
-
1208
+
1209
1209
  const result = await client.query(`
1210
- UPDATE ${(schema ? be.db.quoteIdent(schema) + '.' : '') + be.db.quoteIdent(table)}
1210
+ UPDATE ${(schema ? be.db.quoteIdent(schema) + '.' : '') + be.db.quoteIdent(table)}
1211
1211
  SET ${setters.join(', ')}
1212
1212
  WHERE ${be.db.quoteIdent(userFieldName)} = $1
1213
1213
  returning 1 as ok
@@ -1237,7 +1237,7 @@ AppBackend.prototype.start = function start(opts){
1237
1237
  [userFieldName]
1238
1238
  )
1239
1239
  ).concat(passFieldName);
1240
-
1240
+
1241
1241
  const sql = "SELECT "+infoFieldList.map(function(fieldOrPair){ return fieldOrPair.split(' as ').map(function(ident){ return be.db.quoteIdent(ident)}).join(' as '); })+
1242
1242
  ", "+be.config.login.activeClausule+" as active "+
1243
1243
  ", "+be.config.login.lockedClausule+" as locked "+
@@ -1265,7 +1265,7 @@ AppBackend.prototype.start = function start(opts){
1265
1265
  if(await verifyScramPG(password, user[passFieldName])){
1266
1266
  isScramValid = true;
1267
1267
  }
1268
-
1268
+
1269
1269
  // 2. Intento con formato Legacy (64 bytes)
1270
1270
  else if(await verifyScramLegacy(password, user[passFieldName])){
1271
1271
  isScramValid = true;
@@ -1275,7 +1275,7 @@ AppBackend.prototype.start = function start(opts){
1275
1275
  done(null,false,{message:be.messages.unlogged.login.userOrPassFail});
1276
1276
  return
1277
1277
  }
1278
- }else{
1278
+ }else{
1279
1279
  if (md5(password+username.toLowerCase()) === user[passFieldName]){
1280
1280
  needsMigration = true;
1281
1281
  }else{
@@ -1289,7 +1289,7 @@ AppBackend.prototype.start = function start(opts){
1289
1289
  if (be.config.log["pass-migration"]) console.log('Migración completada.');
1290
1290
  }
1291
1291
  }
1292
- //continua validando
1292
+ //continua validando
1293
1293
  if(data.rowCount==1){
1294
1294
  if(!data.row.active){
1295
1295
  done(null,false,{message:be.messages.unlogged.login.inactiveFail});
@@ -1345,7 +1345,7 @@ AppBackend.prototype.start = function start(opts){
1345
1345
  const data = await client.query(
1346
1346
  `SELECT *
1347
1347
  FROM ${(schema ? be.db.quoteIdent(schema) + '.' : '')}${be.db.quoteIdent(table)}
1348
- WHERE ${be.db.quoteIdent(userFieldName)} = $1`,
1348
+ WHERE ${be.db.quoteIdent(userFieldName)} = $1`,
1349
1349
  [username]
1350
1350
  ).fetchOneRowIfExists();
1351
1351
  if (data.rowCount !== 1) {
@@ -1361,7 +1361,7 @@ AppBackend.prototype.start = function start(opts){
1361
1361
  ok = await verifyScramLegacy(oldPassword, storedHash);
1362
1362
  }
1363
1363
  } else { //Intento MD5
1364
- const md5Hash = md5(oldPassword + username.toLowerCase());
1364
+ const md5Hash = md5(oldPassword + username.toLowerCase());
1365
1365
  ok = (md5Hash === storedHash);
1366
1366
  }
1367
1367
  if (!ok) {
@@ -1455,7 +1455,7 @@ AppBackend.prototype.start = function start(opts){
1455
1455
  to: be.config.mailer?.supervise?.to,
1456
1456
  subject: `npm start ${be.config["client-setup"]?.title || packagejson.name} ok ✔️`,
1457
1457
  text:`Inicio del servicio: ${new Date().toJSON()}
1458
-
1458
+
1459
1459
  Contexto: ${os.userInfo().username} ${process.cwd()}
1460
1460
  `
1461
1461
  }, {ignoreNoMailer:true, event:'restart-ok'})
@@ -1463,7 +1463,7 @@ AppBackend.prototype.start = function start(opts){
1463
1463
  if(err.dumping=='ok'){
1464
1464
  console.log('db struct dumped');
1465
1465
  process.exit(0);
1466
- return;
1466
+ return;
1467
1467
  }
1468
1468
  console.log('ERROR',err.stack || err);
1469
1469
  if(err.context){
@@ -1477,11 +1477,11 @@ AppBackend.prototype.start = function start(opts){
1477
1477
  to: be.config.mailer?.supervise?.to,
1478
1478
  subject: `npm start ${be.config["client-setup"]?.title || packagejson.name} fallido 🛑`,
1479
1479
  text:`Falla en el inicio del servicio: ${new Date().toJSON()}
1480
-
1480
+
1481
1481
  Contexto: ${os.userInfo().username} ${process.cwd()}
1482
1482
 
1483
1483
  Mensaje: ${err.message}
1484
-
1484
+
1485
1485
  ${err.stack}
1486
1486
  `
1487
1487
  }, {ignoreNoMailer:true, event:'restart-fail'})
@@ -1550,7 +1550,7 @@ AppBackend.prototype.checkDatabaseStructure = async function checkDatabaseStruct
1550
1550
  throw err;
1551
1551
  }
1552
1552
  try{
1553
- await client.query(`select ${be.db.quoteIdentList(be.config.login.forget.mailFields)}
1553
+ await client.query(`select ${be.db.quoteIdentList(be.config.login.forget.mailFields)}
1554
1554
  from ${be.config.login.schema?be.db.quoteIdent(be.config.login.schema)+'.':''}${be.config.login.table} limit 1`).fetchOneRowIfExists();
1555
1555
  }catch(err){
1556
1556
  var mensaje = `
@@ -1565,7 +1565,7 @@ AppBackend.prototype.checkDatabaseStructure = async function checkDatabaseStruct
1565
1565
  }
1566
1566
  }
1567
1567
  var bitacoraTableName = be.config.server.bitacoraTableName || 'bitacora';
1568
- var bitacoraId = await client.query(`SELECT data_type
1568
+ var bitacoraId = await client.query(`SELECT data_type
1569
1569
  FROM information_schema.columns
1570
1570
  WHERE /*table_schema = 'his' AND*/ table_name = '${bitacoraTableName}' AND column_name = 'id'
1571
1571
  `).fetchOneRowIfExists();
@@ -1610,9 +1610,9 @@ AppBackend.prototype.postConfig = function postConfig(){
1610
1610
  AppBackend.prototype.getContext = function getContext(req){
1611
1611
  var be = this;
1612
1612
  return {
1613
- be, user:req.user, session:req.session,
1614
- username:req.user && req.user[be.config.login.userFieldName],
1615
- machineId:req.machineId,
1613
+ be, user:req.user, session:req.session,
1614
+ username:req.user && req.user[be.config.login.userFieldName],
1615
+ machineId:req.machineId,
1616
1616
  navigator:(req.userAgent||{}).shortDescription||'?'
1617
1617
  };
1618
1618
  }
@@ -1642,7 +1642,7 @@ AppBackend.prototype.generateInsertSQL = function generateInsertSQL(schemaName,
1642
1642
  var cleanValues = [];
1643
1643
  for (var key in insertElement) {
1644
1644
  cleanKeys.push(db.quoteIdent(key));
1645
- cleanValues.push(db.quoteNullable(insertElement[key]));
1645
+ cleanValues.push(db.quoteNullable(insertElement[key]));
1646
1646
  }
1647
1647
  var sql = `INSERT INTO ${db.quoteIdent(schemaName)}.${db.quoteIdent(tableName)}
1648
1648
  (${cleanKeys.join(',')}) VALUES (${cleanValues.join(',')}) returning id`;
@@ -1660,7 +1660,7 @@ AppBackend.prototype.updateUpdateSQL = function updateUpdateSQL(schemaName, tabl
1660
1660
  for (var key in updateConditions) {
1661
1661
  filterPairs.push(be.db.quoteIdent(key) + " = " + be.db.quoteLiteral(updateConditions[key]));
1662
1662
  };
1663
- var sql = `UPDATE ${db.quoteIdent(schemaName)}.${db.quoteIdent(tableName)}
1663
+ var sql = `UPDATE ${db.quoteIdent(schemaName)}.${db.quoteIdent(tableName)}
1664
1664
  SET ${setPairs.join(',')}
1665
1665
  WHERE ${filterPairs.join(' AND ')}`;
1666
1666
  return sql;
@@ -1668,7 +1668,7 @@ AppBackend.prototype.updateUpdateSQL = function updateUpdateSQL(schemaName, tabl
1668
1668
 
1669
1669
 
1670
1670
  /** @param {boolean} forUnlogged */
1671
- AppBackend.prototype.addProcedureServices = function addProcedureServices(forUnlogged){
1671
+ AppBackend.prototype.addProcedureServices = function addProcedureServices(forUnlogged){
1672
1672
  var be = this;
1673
1673
  if(forUnlogged){
1674
1674
  var app = express();
@@ -1686,7 +1686,7 @@ AppBackend.prototype.addProcedureServices = function addProcedureServices(forUnl
1686
1686
  be.procedures = defs;
1687
1687
  be.clientSetup.procedure = be.procedure;
1688
1688
  app.get('/client-setup',async function(req, res, next){
1689
- if(forUnlogged && req.user){
1689
+ if(forUnlogged && req.user){
1690
1690
  // este pedido es para unlogged y está logueado, va al próximo
1691
1691
  next();
1692
1692
  }else{
@@ -1716,12 +1716,12 @@ AppBackend.prototype.addProcedureServices = function addProcedureServices(forUnl
1716
1716
  if(!isLowerIdent(procedureDef.action)){
1717
1717
  console.error('**** DEPRECATED ***** procedureDef action '+JSON.stringify(procedureDef.action)+' must be a Lower Ident');
1718
1718
  }
1719
- app[procedureDef.method]('/'+procedureDef.action,
1719
+ app[procedureDef.method]('/'+procedureDef.action,
1720
1720
  /**
1721
- *
1722
- * @param {Request} req
1723
- * @param {Response} res
1724
- * @param {import('express').NextFunction} next
1721
+ *
1722
+ * @param {Request} req
1723
+ * @param {Response} res
1724
+ * @param {import('express').NextFunction} next
1725
1725
  */
1726
1726
  async function(req, res, next){
1727
1727
  const BITACORA_SCHEMA = be.config.server.bitacoraSchema;
@@ -1774,9 +1774,9 @@ AppBackend.prototype.addProcedureServices = function addProcedureServices(forUnl
1774
1774
  init_date: initDatetimeString,
1775
1775
  };
1776
1776
  var getFinalStatusBitacoraElement = function getFinalStatusBitacoraElement(){
1777
- return {
1778
- end_date: getDatetimeString(),
1779
- end_status: status,
1777
+ return {
1778
+ end_date: getDatetimeString(),
1779
+ end_status: status,
1780
1780
  has_error: hasError
1781
1781
  }
1782
1782
  }
@@ -1806,12 +1806,12 @@ AppBackend.prototype.addProcedureServices = function addProcedureServices(forUnl
1806
1806
  var params = getParams();
1807
1807
  if(status){
1808
1808
  //terminó ejecucion
1809
- updateElement[procedureDef.bitacora.targetTableBitacoraFields.end_date] = getDatetimeString();
1809
+ updateElement[procedureDef.bitacora.targetTableBitacoraFields.end_date] = getDatetimeString();
1810
1810
  updateElement[procedureDef.bitacora.targetTableBitacoraFields.end_status] = status;
1811
1811
  updateElement[procedureDef.bitacora.targetTableBitacoraFields.has_error] = hasError;
1812
1812
  }else{
1813
1813
  //empezó ejecucion
1814
- updateElement[procedureDef.bitacora.targetTableBitacoraFields.init_date] = initDatetimeString;
1814
+ updateElement[procedureDef.bitacora.targetTableBitacoraFields.init_date] = initDatetimeString;
1815
1815
  }
1816
1816
  await be.inTransaction(req,async function(client){
1817
1817
  targetTableUpdateFieldsCondition.forEach(function(field){
@@ -2115,7 +2115,7 @@ AppBackend.prototype.optsGenericForFiles = function optsGenericForFiles(req, opt
2115
2115
  return changing(be.optsGenericForAll||{},{
2116
2116
  allowedExts:be.exts.normal,
2117
2117
  jade:{
2118
- skin:skin,
2118
+ skin:skin,
2119
2119
  skinUrl:skinUrl,
2120
2120
  formTitle:title,
2121
2121
  ...(opts?.withFlash ? {flash:req?.flash?.()} : {}),
@@ -2134,8 +2134,8 @@ AppBackend.prototype.unloggedLandPage = function unloggedLandPage(req){
2134
2134
  html.h2({style:'text-align:center; margin-top:15%; font-family:arial, sans-serif'},[be.messages.server.notLoggedIn]),
2135
2135
  html.h2({style:'text-align:center'},[html.code([
2136
2136
  html.a({
2137
- id:'goto-login',
2138
- style:'border:0.5px solid blue; border-radius: 6px; padding: 6px',
2137
+ id:'goto-login',
2138
+ style:'border:0.5px solid blue; border-radius: 6px; padding: 6px',
2139
2139
  href:Path.posix.join(be.config.server["base-url"],(be.config.login.plus.loginUrlPath||'/login'))
2140
2140
  },'login')
2141
2141
  ])]),
@@ -2158,8 +2158,8 @@ AppBackend.prototype.addUnloggedServices = function addUnloggedServices(mainApp,
2158
2158
  var now = bestGlobals.datetime.now();
2159
2159
  var token = crypto.randomUUID();
2160
2160
  var {rows} = await client.query(`select ${be.db.quoteIdent(be.config.login.userFieldName)} as username
2161
- from ${be.config.login.schema?be.db.quoteIdent(be.config.login.schema)+'.':''}${be.db.quoteIdent(be.config.login.table)}
2162
- where $1 in (${be.db.quoteIdentList(be.config.login.forget.mailFields)})
2161
+ from ${be.config.login.schema?be.db.quoteIdent(be.config.login.schema)+'.':''}${be.db.quoteIdent(be.config.login.table)}
2162
+ where $1 in (${be.db.quoteIdentList(be.config.login.forget.mailFields)})
2163
2163
  and ${be.config.login.activeClausule}
2164
2164
  and ${be.config.login.lockedClausule} is not true
2165
2165
  `, [req.body.email.toLowerCase()]).fetchAll();
@@ -2267,21 +2267,21 @@ AppBackend.prototype.addUnloggedServices = function addUnloggedServices(mainApp,
2267
2267
  // http://localhost:3033/img/login-logo-icon.png
2268
2268
  mainApp.get(Path.posix.join(baseUrl,'/img/login-logo-icon.png'), async function(req,res,next){
2269
2269
  var buscar = [
2270
- 'unlogged/img/login-logo-icon.svg',
2271
- 'dist/unlogged/img/login-logo-icon.svg',
2272
- 'dist/client/unlogged/img/login-logo-icon.svg',
2273
- 'unlogged/img/login-logo-icon.png',
2274
- 'dist/unlogged/img/login-logo-icon.png',
2275
- 'dist/client/unlogged/img/login-logo-icon.png',
2276
- 'unlogged/img/logo.png',
2277
- 'dist/unlogged/img/logo.png',
2278
- 'dist/client/unlogged/img/logo.png',
2279
- 'client/img/logo.png',
2280
- 'dist/client/img/logo.png',
2281
- 'dist/client/client/img/logo.png',
2270
+ 'unlogged/img/login-logo-icon.svg',
2271
+ 'dist/unlogged/img/login-logo-icon.svg',
2272
+ 'dist/client/unlogged/img/login-logo-icon.svg',
2273
+ 'unlogged/img/login-logo-icon.png',
2274
+ 'dist/unlogged/img/login-logo-icon.png',
2275
+ 'dist/client/unlogged/img/login-logo-icon.png',
2276
+ 'unlogged/img/logo.png',
2277
+ 'dist/unlogged/img/logo.png',
2278
+ 'dist/client/unlogged/img/logo.png',
2279
+ 'client/img/logo.png',
2280
+ 'dist/client/img/logo.png',
2281
+ 'dist/client/client/img/logo.png',
2282
2282
  'unlogged/img/logo-128.png',
2283
2283
  'dist/unlogged/img/logo-128.png',
2284
- 'dist/client/unlogged/img/logo-128.png'
2284
+ 'dist/client/unlogged/img/logo-128.png'
2285
2285
  ];
2286
2286
  buscar = buscar.map(n=>be.rootPath+'/'+n);
2287
2287
  buscar.push(__dirname+'/../for-client/img/login-logo-icon.png');
@@ -2296,7 +2296,7 @@ AppBackend.prototype.addUnloggedServices = function addUnloggedServices(mainApp,
2296
2296
  be.clientIncludesCompleted(null).filter(x => x.module).forEach(function (moduleDef) {
2297
2297
  if(baseUrl=='/'){
2298
2298
  baseUrl='';
2299
- }
2299
+ }
2300
2300
  let baseLib = baseUrl + '/' + (moduleDef.path ? moduleDef.path : be.esJavascript(moduleDef.type)? 'lib': 'css');
2301
2301
  resolve_module_dir(moduleDef.module, moduleDef.modPath, moduleDef.file ?? '.')
2302
2302
  try {
@@ -2320,7 +2320,7 @@ AppBackend.prototype.addUnloggedServices = function addUnloggedServices(mainApp,
2320
2320
  // ----------------------------------------------------
2321
2321
  var skin=be.config['client-setup'].skin;
2322
2322
  var skinUrl=(skin?skin+'/':'');
2323
- var optsGenericForFilesUnlogged=be.optsGenericForFiles();
2323
+ var optsGenericForFilesUnlogged=be.optsGenericForFiles();
2324
2324
  var skinPaths=[Path.join(be.rootPath,'skins')];
2325
2325
  if(be.config.server.skins[skin]['local-path']){
2326
2326
  skinPaths=skinPaths.concat(be.config.server.skins[skin]['local-path']).map(function(path){
@@ -2373,7 +2373,7 @@ AppBackend.prototype.getVisibleMenu = function getVisibleMenu(menu, context){
2373
2373
 
2374
2374
  AppBackend.prototype.clientIncludes = function clientIncludes(req, opts) {
2375
2375
  const hideBEPlusInclusions = opts === true || opts && typeof opts == "object" && opts.hideBEPlusInclusions;
2376
- opts = opts === true ? {} : opts || {};
2376
+ opts = opts === true ? {} : opts || {};
2377
2377
  var list = [];
2378
2378
  if (!hideBEPlusInclusions) {
2379
2379
  list = [
@@ -2464,7 +2464,7 @@ AppBackend.prototype.clientModules = function clientModules(req, opts) {
2464
2464
  }
2465
2465
 
2466
2466
  /**
2467
- * @param {string} tableName
2467
+ * @param {string} tableName
2468
2468
  * @param {(tableDef:typesOpe.TableDefinition, context?:TableContext)=>void} appenderFunction
2469
2469
  */
2470
2470
  AppBackend.prototype.appendToTableDefinition = function appendToTableDefinition(tableName, appenderFunction){
@@ -2521,16 +2521,16 @@ AppBackend.prototype.csss = function csss(hideBEPlusInclusions){
2521
2521
  AppBackend.prototype.scanSkinFiles = function scanSkinFiles() {
2522
2522
  var be = this;
2523
2523
  var skinName = be.config['client-setup'].skin;
2524
- be.activeSkinFiles = new Set();
2524
+ be.activeSkinFiles = new Set();
2525
2525
 
2526
2526
  var skinConfig = be.config.server.skins && be.config.server.skins[skinName];
2527
2527
 
2528
2528
  if (skinName && skinConfig && skinConfig['local-path']) {
2529
2529
  try {
2530
2530
  var skinPath = Path.join(Path.resolve(skinConfig['local-path']), skinName);
2531
-
2531
+
2532
2532
  if (fs.existsSync(skinPath)) {
2533
-
2533
+
2534
2534
  const walk = (currentPath) => {
2535
2535
  const entries = fs.readdirSync(currentPath, { withFileTypes: true });
2536
2536
 
@@ -2545,7 +2545,7 @@ AppBackend.prototype.scanSkinFiles = function scanSkinFiles() {
2545
2545
  var relativePath = Path.relative(skinPath, fullPath)
2546
2546
  .replace(/\\/g, '/')
2547
2547
  .replace(/^\//, '');
2548
-
2548
+
2549
2549
  be.activeSkinFiles.add(relativePath);
2550
2550
  }
2551
2551
  }
@@ -2632,7 +2632,7 @@ AppBackend.prototype.mainPage = function mainPage(req, offlineMode, opts){
2632
2632
 
2633
2633
  var lastDotIndex = css.lastIndexOf('.');
2634
2634
  var cssBase = (lastDotIndex !== -1) ? css.substring(0, lastDotIndex) : css;
2635
-
2635
+
2636
2636
  var existsInSkin = EXTENSIONES_SKIN.some(function(ext) {
2637
2637
  return be.activeSkinFiles.has(cssBase + ext);
2638
2638
  });
@@ -2898,7 +2898,7 @@ AppBackend.prototype.validateBitacora = function validateBitacora(procedureDef){
2898
2898
  var tableDefFields = be.tableStructures[procedureDef.bitacora.targetTable](contextForDump).fields;
2899
2899
  var targetTableBitacoraFields = procedureDef.bitacora.targetTableBitacoraFields;
2900
2900
  for (var fieldForSearch in targetTableBitacoraFields) {
2901
- var searchResult = tableDefFields.find(function findByName(field) {
2901
+ var searchResult = tableDefFields.find(function findByName(field) {
2902
2902
  return field.name === targetTableBitacoraFields[fieldForSearch];
2903
2903
  });
2904
2904
  if(!searchResult){
@@ -2906,12 +2906,12 @@ AppBackend.prototype.validateBitacora = function validateBitacora(procedureDef){
2906
2906
  }
2907
2907
  }
2908
2908
  var targetTableUpdateFieldsCondition = procedureDef.bitacora.targetTableUpdateFieldsCondition || ['init_date','end_date','has_error', 'end_status'];
2909
- if(targetTableUpdateFieldsCondition){
2909
+ if(targetTableUpdateFieldsCondition){
2910
2910
  if(targetTableUpdateFieldsCondition.length == 0){
2911
2911
  throw Error("Bitacora bad definition in core function '" + procedureDef.action + "', targetTableUpdateFieldsCondition must to be defined for table '" + procedureDef.bitacora.targetTable + "'.");
2912
2912
  }
2913
2913
  targetTableUpdateFieldsCondition.forEach(function(fieldName){
2914
- var searchResult = tableDefFields.find(function findByName(field) {
2914
+ var searchResult = tableDefFields.find(function findByName(field) {
2915
2915
  return field.name === fieldName;
2916
2916
  });
2917
2917
  if(!searchResult){
@@ -3041,9 +3041,9 @@ AppBackend.prototype.dumpDbTableFields = function dumpDbTableFields(tableDef, op
3041
3041
  (fieldDef.dataDecimals?','+fieldDef.dataDecimals:'')
3042
3042
  +')':fieldType)+
3043
3043
  ( be.specialSqlDefaultExpressions[fieldDef.defaultDbValue] != null ? ' default ' + be.specialSqlDefaultExpressions[fieldDef.defaultDbValue]
3044
- : fieldDef.defaultDbValue != null ? ' default ' + fieldDef.defaultDbValue
3044
+ : fieldDef.defaultDbValue != null ? ' default ' + fieldDef.defaultDbValue
3045
3045
  : be.specialSqlDefaultExpressions[fieldDef.specialDefaultValue] != null ? ' default ' + be.specialSqlDefaultExpressions[fieldDef.specialDefaultValue]
3046
- : fieldDef.defaultValue != null ? ' default ' + db.quoteLiteral(fieldDef.defaultValue)
3046
+ : fieldDef.defaultValue != null ? ' default ' + db.quoteLiteral(fieldDef.defaultValue)
3047
3047
  : ''
3048
3048
  ) +
3049
3049
  (be.isGeneratedSequence(fieldDef.sequence)?' generated always as identity':'')+
@@ -3196,7 +3196,7 @@ AppBackend.prototype.dumpDbSchemaPartial = async function dumpDbSchemaPartial(pa
3196
3196
  lines.push(');');
3197
3197
  //TODO: REFACTOR: Hacerlo mas sencillo
3198
3198
  // este codigo se encarga de convertir a rights de sql nuestros propios rights
3199
- // por ej (import -> [insert, update])
3199
+ // por ej (import -> [insert, update])
3200
3200
  var allows = tableDef.allow;
3201
3201
  var appToSqlRights = {'import': ['insert', 'update'], 'export': ['select'], 'deleteAll': ['delete']};
3202
3202
  [ 'import', 'export', 'deleteAll'].filter(function(right){
@@ -3253,7 +3253,7 @@ AppBackend.prototype.dumpDbSchemaPartial = async function dumpDbSchemaPartial(pa
3253
3253
  var prefix = 'alter table '+cualQuoteTableName+' add '+
3254
3254
  (cons.consName?'constraint '+db.quoteIdent(cons.consName)+' ':'');
3255
3255
  switch(cons.constraintType){
3256
- case 'unique':
3256
+ case 'unique':
3257
3257
  sql='('+cons.fields.map(function(field){ return db.quoteIdent(field); }).join(', ')+')';
3258
3258
  if(cons.where){
3259
3259
  if(cons.consName == null){
@@ -3265,10 +3265,10 @@ AppBackend.prototype.dumpDbSchemaPartial = async function dumpDbSchemaPartial(pa
3265
3265
  prefix += 'unique ';
3266
3266
  }
3267
3267
  break;
3268
- case 'check':
3268
+ case 'check':
3269
3269
  sql='check ('+cons.expr+')';
3270
3270
  break;
3271
- case 'exclude':
3271
+ case 'exclude':
3272
3272
  sql=`exclude using ${cons.using} (${cons.fields.map(f => typeof f == "string"?`${f} WITH =`:`${f.fieldName} WITH ${f.operator}`).join(', ')})${cons.where ? ` WHERE (${cons.where})`:``}`;
3273
3273
  break;
3274
3274
  default:
@@ -3311,7 +3311,7 @@ AppBackend.prototype.dumpDbSchemaPartial = async function dumpDbSchemaPartial(pa
3311
3311
  (polcom.using? ` USING ( ${polcom.using} )`:'')+
3312
3312
  (polcom.check?` WITH CHECK ( ${polcom.check} )`:'')+';'
3313
3313
  );
3314
- }
3314
+ }
3315
3315
  });
3316
3316
  }
3317
3317
  }else{
@@ -3352,7 +3352,7 @@ begin
3352
3352
  else
3353
3353
  select ${be.config.login.infoFieldList.map(fieldName => db.quoteIdent(fieldName)).join(', ')}
3354
3354
  into ${be.config.login.infoFieldList.map(fieldName => db.quoteIdent('v_'+fieldName)).join(', ')}
3355
-
3355
+
3356
3356
  from ${(be.config.login.from ?? (
3357
3357
  (be.config.login.schema?be.db.quoteIdent(be.config.login.schema)+'.':'')+
3358
3358
  be.db.quoteIdent(be.config.login.table)))}
@@ -3363,7 +3363,7 @@ begin
3363
3363
  set backend_plus._mode = normal;
3364
3364
  end if;
3365
3365
  perform set_config('backend_plus._user', p_username, false);
3366
- end;
3366
+ end;
3367
3367
  $body$;
3368
3368
 
3369
3369
  `)
@@ -3377,7 +3377,7 @@ $body$;
3377
3377
  var allTableContent = await fs.readFile('install/local-dump.psql','utf-8');
3378
3378
  var startIndex = allTableContent.indexOf('-- Data for Name: ');
3379
3379
  console.log('startIndex', startIndex);
3380
- var lastUseful = allTableContent.lastIndexOf('\nSELECT pg_catalog.setval')
3380
+ var lastUseful = allTableContent.lastIndexOf('\nSELECT pg_catalog.setval')
3381
3381
  console.log('lastUseful', lastUseful);
3382
3382
  if (lastUseful == -1) lastUseful = allTableContent.lastIndexOf('\n\\.\n');
3383
3383
  console.log('lastUseful', lastUseful);
@@ -3423,6 +3423,7 @@ $body$;
3423
3423
  return {path:Path.relative(process.cwd(),theTableFileName),content};
3424
3424
  });
3425
3425
  }).then(function({path,content}){
3426
+ /* LETRUA DEL ARCHIVO .TAB */
3426
3427
  dataText.push("\n-- table data: "+path);
3427
3428
  var lines;
3428
3429
  var rows;
@@ -3490,7 +3491,7 @@ $body$;
3490
3491
  throw Error("no se encuentra la columna "+filteredFieldDef[i]+" en "+tableName);
3491
3492
  }
3492
3493
  return value==='' ? (
3493
- def.allowEmptyText && ('nullable' in def) && !def.nullable ? "''" : 'null'
3494
+ def.allowEmptyText && ('nullable' in def) && !def.nullable ? "''" : 'null'
3494
3495
  ) : db.quoteNullable(value);
3495
3496
  }).join(', ')+")";
3496
3497
  }).join(',\n')+';\n';
@@ -3525,7 +3526,7 @@ $body$;
3525
3526
  ]
3526
3527
  .map(async function(fileNames){
3527
3528
  if (!fileNames) return '';
3528
- var i = 0;
3529
+ var i = 0;
3529
3530
  return (await Promise.all(fileNames.map(async fileName => {
3530
3531
  var content;
3531
3532
  do {
@@ -3577,7 +3578,7 @@ $body$;
3577
3578
  '\n-- functions\n' + functionLines.join('\n')+
3578
3579
  '\n-- lines \n' + lines.join('\n')+
3579
3580
  (complete? ('\n\n-- pre-ADAPTs\n'+texts[1]+'\n\n') : '' )+
3580
- (complete? ('\n\n-- DATA\n'+ dataText.join('\n')) : '' )+
3581
+ (complete? ('\n\n-- DATA\n'+ dataText.join('\n')) : '' )+
3581
3582
  (complete? ('\n\n-- ADAPTs\n'+ texts[2]+'\n\n') : '' )+
3582
3583
  '\n-- conss\n' + consLines.join('\n')+
3583
3584
  '\n-- FKs\n' + fkLines.join('\n')+
@@ -3607,7 +3608,7 @@ AppBackend.prototype.getDbFunctions = async function (){
3607
3608
  AppBackend.prototype.dumpDbSchema = async function dumpDbSchema(opts){
3608
3609
  var be = this;
3609
3610
  var {mainSql,enancePart} = await be.dumpDbSchemaPartial(
3610
- opts.complete?be.tableStructures:likeAr(be.tableStructures).filter((_, name)=>opts.tableNames.includes(name)),
3611
+ opts.complete?be.tableStructures:likeAr(be.tableStructures).filter((_, name)=>opts.tableNames.includes(name)),
3611
3612
  opts
3612
3613
  )
3613
3614
  mainSql=be.config.install.dump.db.extensions.map(function(extension){
@@ -3690,7 +3691,7 @@ AppBackend.prototype.transformInput = function transformInput(fieldDef, value){
3690
3691
  return value;
3691
3692
  }
3692
3693
 
3693
- /**
3694
+ /**
3694
3695
  * xxxparam {{ action:string, parameters:any, conRegistro:boolean, conPadron:boolean, fileName?:string, csvFileName?:string, csvSeparator?:string, queries:{titulo:string, sql:string, params:string[]}[] }}
3695
3696
  * @param {{title:string, rows:Record<string, any>[]}[]} result
3696
3697
  * @returns {Promise<void>}
@@ -3788,7 +3789,7 @@ AppBackend.prototype.exportacionesGenerico = async function exportacionesGeneric
3788
3789
  ))
3789
3790
  }
3790
3791
  return [
3791
- ...(fileName?[{url:fileName, label:csvFileName?'xlsx de control':fileName}]:[]),
3792
+ ...(fileName?[{url:fileName, label:csvFileName?'xlsx de control':fileName}]:[]),
3792
3793
  ...(csvFileName?[{url:csvFileName, label:fileName?'csv (formato UTF-8)':csvFileName}]:[]),
3793
3794
  ];
3794
3795
  }