backend-plus 2.5.0-betha.3 → 2.5.2-betha.10
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.
- package/lib/backend-plus.d.ts +20 -6
- package/lib/backend-plus.js +51 -18
- package/package.json +14 -12
package/lib/backend-plus.d.ts
CHANGED
|
@@ -172,6 +172,10 @@ export type SequenceDefinition = {
|
|
|
172
172
|
name:string
|
|
173
173
|
firstValue:number
|
|
174
174
|
prefix?:string /* Prefix for the generated value */
|
|
175
|
+
}
|
|
176
|
+
export type SequenceMadMaxDefinition = {
|
|
177
|
+
madMax: string[] // grouping of mad max sequences
|
|
178
|
+
firstValue?: number
|
|
175
179
|
}
|
|
176
180
|
export type ExportMetadataDefinition={ /* TODO: define */ }
|
|
177
181
|
export type PostInputOptions='upperSpanish' | 'upperWithoutDiacritics' | 'parseDecimal'
|
|
@@ -218,11 +222,21 @@ export type FieldDefinition = EditableDbDefinition & {
|
|
|
218
222
|
alwaysShow?:boolean /* show when appears in fixed fields */
|
|
219
223
|
suggestingKeys?:string[]
|
|
220
224
|
postInput?:PostInputOptions
|
|
221
|
-
} & (
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
225
|
+
} & (
|
|
226
|
+
{
|
|
227
|
+
sequence?: undefined
|
|
228
|
+
nullable?: boolean
|
|
229
|
+
editable?: boolean
|
|
230
|
+
} | {
|
|
231
|
+
sequence: SequenceDefinition
|
|
232
|
+
nullable: true
|
|
233
|
+
editable: false
|
|
234
|
+
} | {
|
|
235
|
+
sequence: SequenceMadMaxDefinition
|
|
236
|
+
nullable: true
|
|
237
|
+
editable: boolean
|
|
238
|
+
}
|
|
239
|
+
);
|
|
226
240
|
export type EditableDbDefinition = {
|
|
227
241
|
editable?:boolean
|
|
228
242
|
allow?:{
|
|
@@ -395,6 +409,7 @@ export interface AppConfigServer
|
|
|
395
409
|
"kill-9": string // a way to kill from URL with a token
|
|
396
410
|
bitacoraSchema: string
|
|
397
411
|
bitacoraTableName: string
|
|
412
|
+
allowedHosts:string[] //API allowed hosts
|
|
398
413
|
}
|
|
399
414
|
export interface AppConfigDb
|
|
400
415
|
{
|
|
@@ -414,7 +429,6 @@ export interface AppConfigLogin
|
|
|
414
429
|
{
|
|
415
430
|
schema: string // schema of the user table
|
|
416
431
|
table: string // user table
|
|
417
|
-
from: string // complete expression to get table or join where get the user
|
|
418
432
|
userFieldname: string // fieldname in user table that stores the user name
|
|
419
433
|
passFieldname: string // fieldname in user table that stores the password hash
|
|
420
434
|
rolFieldname: string // fieldname in user table that stores the rol
|
package/lib/backend-plus.js
CHANGED
|
@@ -20,6 +20,7 @@ MiniTools.globalOpts.serveErr.propertiesWhiteList=['message','detail','code','ta
|
|
|
20
20
|
var crypto = require('crypto');
|
|
21
21
|
var serveContent = require('serve-content');
|
|
22
22
|
var pg = require('pg-promise-strict');
|
|
23
|
+
var pgTriggers = require('pg-triggers');
|
|
23
24
|
var SessionFileStore = require('session-file-store');
|
|
24
25
|
var memorystore = require('memorystore');
|
|
25
26
|
var jsToHtml=require('js-to-html');
|
|
@@ -30,6 +31,7 @@ var locatePath = require('@upgraded/locate-path');
|
|
|
30
31
|
var jsYaml = require('js-yaml');
|
|
31
32
|
var nodemailer = require('nodemailer');
|
|
32
33
|
var os = require('os');
|
|
34
|
+
const cors = require('cors');
|
|
33
35
|
|
|
34
36
|
var likeAr = require('like-ar');
|
|
35
37
|
|
|
@@ -902,6 +904,18 @@ AppBackend.prototype.start = function start(opts){
|
|
|
902
904
|
}).then(async function(){
|
|
903
905
|
mainApp = express();
|
|
904
906
|
//mainApp.use(cookieParser());
|
|
907
|
+
const whitelist = ['localhost'].concat(be.config.server.allowedHosts||[]); // Agrega aquí los orígenes de tus aplicaciones
|
|
908
|
+
const corsOptions = {
|
|
909
|
+
origin: function (origin, callback) {
|
|
910
|
+
if (whitelist.some((element)=>origin?.includes(element)) || !origin){
|
|
911
|
+
callback(null, true);
|
|
912
|
+
}else{
|
|
913
|
+
callback(new Error('Not allowed by CORS'));
|
|
914
|
+
}
|
|
915
|
+
},
|
|
916
|
+
credentials: true
|
|
917
|
+
};
|
|
918
|
+
mainApp.use(cors(corsOptions));
|
|
905
919
|
mainApp.use(bodyParser.urlencoded({extended:true, limit: '50mb'}));
|
|
906
920
|
mainApp.use(function(req,res,next){
|
|
907
921
|
if((req.headers['content-type']||'').match(/^multipart\/form-data/)){
|
|
@@ -2640,7 +2654,16 @@ AppBackend.prototype.dumpFkConstraint = function dumpFkConstraint(fk, tableDef,
|
|
|
2640
2654
|
return {consName, clause, sourceFieldList};
|
|
2641
2655
|
}
|
|
2642
2656
|
|
|
2657
|
+
AppBackend.prototype.isGeneratedSequence = function isGeneratedSequence(sequence, not){
|
|
2658
|
+
return sequence && ((!sequence.name && !sequence.madMax) == !not)
|
|
2659
|
+
}
|
|
2660
|
+
|
|
2661
|
+
AppBackend.prototype.isSequenceNonGenerated = function isSequenceNonGenerated(sequence){
|
|
2662
|
+
return this.isGeneratedSequence(sequence, true);
|
|
2663
|
+
}
|
|
2664
|
+
|
|
2643
2665
|
AppBackend.prototype.dumpDbTableFields = function dumpDbTableFields(tableDef, opts = {}, complements = null){
|
|
2666
|
+
var be = this;
|
|
2644
2667
|
var db = this.db;
|
|
2645
2668
|
var fields=[];
|
|
2646
2669
|
tableDef.fields.forEach(function(fieldDef){
|
|
@@ -2654,7 +2677,7 @@ AppBackend.prototype.dumpDbTableFields = function dumpDbTableFields(tableDef, op
|
|
|
2654
2677
|
' '+(fieldDef.dataLength?(fieldType=='text'?'varchar':fieldType)+'('+fieldDef.dataLength+')':fieldType)+
|
|
2655
2678
|
(fieldDef.defaultValue!=null?' default '+db.quoteLiteral(fieldDef.defaultValue):'')+
|
|
2656
2679
|
(fieldDef.defaultDbValue!=null?' default '+fieldDef.defaultDbValue:'')+
|
|
2657
|
-
(
|
|
2680
|
+
(be.isGeneratedSequence(fieldDef.sequence)?' generated always as identity':'')+
|
|
2658
2681
|
(fieldDef.generatedAs!=null?` generated always as (${fieldDef.generatedAs}) stored`:'')
|
|
2659
2682
|
);
|
|
2660
2683
|
if(complements){
|
|
@@ -2761,7 +2784,7 @@ AppBackend.prototype.dumpDbSchemaPartial = async function dumpDbSchemaPartial(pa
|
|
|
2761
2784
|
lines.push('create table '+cualQuoteTableName+' (');
|
|
2762
2785
|
var fields = be.dumpDbTableFields(tableDef, opts,
|
|
2763
2786
|
function complements(fieldDef){
|
|
2764
|
-
if(
|
|
2787
|
+
if(be.isGeneratedSequence(fieldDef.sequence)){
|
|
2765
2788
|
tablesWithStrictSequence[tableName]={}
|
|
2766
2789
|
}
|
|
2767
2790
|
if(fieldDef.typeName==='text' && !fieldDef.allowEmptyText){
|
|
@@ -2785,7 +2808,7 @@ AppBackend.prototype.dumpDbSchemaPartial = async function dumpDbSchemaPartial(pa
|
|
|
2785
2808
|
' alter column '+db.quoteIdent(fieldDef.name)+' set not null;'
|
|
2786
2809
|
);
|
|
2787
2810
|
}
|
|
2788
|
-
if(
|
|
2811
|
+
if(be.isSequenceNonGenerated(fieldDef.sequence)){
|
|
2789
2812
|
fieldsForSequences.push(fieldDef);
|
|
2790
2813
|
}
|
|
2791
2814
|
}
|
|
@@ -2888,19 +2911,26 @@ AppBackend.prototype.dumpDbSchemaPartial = async function dumpDbSchemaPartial(pa
|
|
|
2888
2911
|
});
|
|
2889
2912
|
lines.push(tableDef.sql.postCreateSqls);
|
|
2890
2913
|
lines.push('');
|
|
2891
|
-
fieldsForSequences.
|
|
2914
|
+
await Promise.all(fieldsForSequences.map(async function(fieldDef) {
|
|
2892
2915
|
var sequence = fieldDef.sequence;
|
|
2893
|
-
|
|
2894
|
-
|
|
2895
|
-
"
|
|
2896
|
-
|
|
2897
|
-
|
|
2898
|
-
|
|
2899
|
-
|
|
2900
|
-
|
|
2901
|
-
|
|
2902
|
-
|
|
2903
|
-
|
|
2916
|
+
if (sequence.name) {
|
|
2917
|
+
if (sequence.madMax) throw new Error('a sequence with madMax cannot have name');
|
|
2918
|
+
lines.push("CREATE SEQUENCE "+db.quoteIdent(sequence.name)+" START "+db.quoteInteger(sequence.firstValue||1)+";");
|
|
2919
|
+
lines.push(
|
|
2920
|
+
"ALTER TABLE "+cualQuoteTableName+
|
|
2921
|
+
" ALTER COLUMN "+db.quoteIdent(fieldDef.name)+
|
|
2922
|
+
(sequence.prefix==null
|
|
2923
|
+
?" SET DEFAULT nextval("+db.quoteLiteral(sequence.name)+"::regclass);"
|
|
2924
|
+
:" SET DEFAULT ("+db.quoteLiteral(sequence.prefix)+" || nextval("+db.quoteLiteral(sequence.name)+"::regclass)::text);"
|
|
2925
|
+
)
|
|
2926
|
+
);
|
|
2927
|
+
lines.push('GRANT USAGE, SELECT ON SEQUENCE '+db.quoteIdent(sequence.name)+' TO '+user+';');
|
|
2928
|
+
} else if (sequence.madMax) {
|
|
2929
|
+
lines.push(await pgTriggers.dumpMaxIdTrigger(tableDef.sql.tableName, fieldDef.name, {grouping: sequence.madMax.grouping, firstValue: sequence.firstValue}));
|
|
2930
|
+
} else {
|
|
2931
|
+
throw new Error('a sequence without madMax nor name');
|
|
2932
|
+
}
|
|
2933
|
+
}));
|
|
2904
2934
|
lines.push('');
|
|
2905
2935
|
if(tableDef.sql.policies.enabled){
|
|
2906
2936
|
policyLines.push(`ALTER TABLE ${cualQuoteTableName} ENABLE ROW LEVEL SECURITY;`);
|
|
@@ -2937,7 +2967,7 @@ AppBackend.prototype.dumpDbSchemaPartial = async function dumpDbSchemaPartial(pa
|
|
|
2937
2967
|
}
|
|
2938
2968
|
lines.push(`
|
|
2939
2969
|
create or replace function set_app_user(p_user text) returns text
|
|
2940
|
-
|
|
2970
|
+
security definer volatile language plpgsql
|
|
2941
2971
|
as
|
|
2942
2972
|
$body$
|
|
2943
2973
|
declare
|
|
@@ -2953,8 +2983,11 @@ begin
|
|
|
2953
2983
|
else
|
|
2954
2984
|
select ${be.config.login.infoFieldList.map(fieldName => db.quoteIdent(fieldName)).join(', ')}
|
|
2955
2985
|
into ${be.config.login.infoFieldList.map(fieldName => db.quoteIdent('v_'+fieldName)).join(', ')}
|
|
2956
|
-
|
|
2957
|
-
|
|
2986
|
+
|
|
2987
|
+
from ${(be.config.login.from ?? (
|
|
2988
|
+
(be.config.login.schema?be.db.quoteIdent(be.config.login.schema)+'.':'')+
|
|
2989
|
+
be.db.quoteIdent(be.config.login.table)))}
|
|
2990
|
+
where ${db.quoteIdent(be.config.login.userFieldName)} = p_user;
|
|
2958
2991
|
${be.config.login.infoFieldList.map(fieldName => `
|
|
2959
2992
|
perform set_config('backend_plus._${fieldName}', v_${fieldName}, false);`).join('')}
|
|
2960
2993
|
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "backend-plus",
|
|
3
3
|
"description": "Backend for the anti Pareto rule",
|
|
4
|
-
"version": "2.5.
|
|
4
|
+
"version": "2.5.2-betha.10",
|
|
5
5
|
"author": "Codenautas <codenautas@googlegroups.com>",
|
|
6
6
|
"license": "MIT",
|
|
7
7
|
"repository": "codenautas/backend-plus",
|
|
@@ -35,12 +35,13 @@
|
|
|
35
35
|
"best-globals": "^2.0.1",
|
|
36
36
|
"big.js": "^7.0.1",
|
|
37
37
|
"body-parser": "^2.2.0",
|
|
38
|
-
"cast-error": "^0.1.
|
|
38
|
+
"cast-error": "^0.1.2",
|
|
39
39
|
"castellano": "^0.1.4",
|
|
40
40
|
"connect-pg-simple": "^10.0.0",
|
|
41
41
|
"cookie-parser": "^1.4.7",
|
|
42
|
-
"
|
|
43
|
-
"
|
|
42
|
+
"cors": "^2.8.5",
|
|
43
|
+
"dialog-promise": "^0.10.2",
|
|
44
|
+
"discrepances": "^0.2.9",
|
|
44
45
|
"express": "^5.1.0",
|
|
45
46
|
"express-session": "^1.18.1",
|
|
46
47
|
"express-useragent": "^1.0.15",
|
|
@@ -50,14 +51,15 @@
|
|
|
50
51
|
"json4all": "^1.4.0",
|
|
51
52
|
"lazy-some": "^0.1.0",
|
|
52
53
|
"like-ar": "^0.5.1",
|
|
53
|
-
"login-plus": "^1.7.
|
|
54
|
+
"login-plus": "^1.7.3",
|
|
54
55
|
"memorystore": "^1.6.7",
|
|
55
|
-
"mini-tools": "^1.13.
|
|
56
|
+
"mini-tools": "^1.13.3",
|
|
56
57
|
"moment": "^2.30.1",
|
|
57
58
|
"multiparty": "^4.2.3",
|
|
58
59
|
"nodemailer": "^7.0.3",
|
|
59
60
|
"numeral": "^2.0.6",
|
|
60
|
-
"pg-promise-strict": "^1.4.
|
|
61
|
+
"pg-promise-strict": "^1.4.3",
|
|
62
|
+
"pg-triggers": "0.4.3",
|
|
61
63
|
"pikaday": "^1.8.2",
|
|
62
64
|
"pug": "^3.0.3",
|
|
63
65
|
"read-yaml-promise": "^1.0.2",
|
|
@@ -76,13 +78,13 @@
|
|
|
76
78
|
"devDependencies": {
|
|
77
79
|
"@types/big.js": "^6.2.2",
|
|
78
80
|
"@types/expect.js": "~0.3.32",
|
|
79
|
-
"@types/express": "^5.0.
|
|
81
|
+
"@types/express": "^5.0.3",
|
|
80
82
|
"@types/express-useragent": "^1.0.5",
|
|
81
83
|
"@types/fs-extra": "^11.0.4",
|
|
82
84
|
"@types/js-yaml": "^4.0.9",
|
|
83
85
|
"@types/mocha": "^10.0.10",
|
|
84
86
|
"@types/multiparty": "~4.2.1",
|
|
85
|
-
"@types/node": "^
|
|
87
|
+
"@types/node": "^24.0.3",
|
|
86
88
|
"@types/nodemailer": "^6.4.17",
|
|
87
89
|
"@types/numeral": "~2.0.5",
|
|
88
90
|
"@types/session-file-store": "^1.2.5",
|
|
@@ -97,10 +99,10 @@
|
|
|
97
99
|
"karma-ie-launcher": "^1.0.0",
|
|
98
100
|
"karma-mocha": "^2.0.1",
|
|
99
101
|
"kill-9": "~0.4.3",
|
|
100
|
-
"mocha": "^11.
|
|
102
|
+
"mocha": "^11.7.0",
|
|
101
103
|
"nyc": "^17.1.0",
|
|
102
|
-
"puppeteer": "^24.
|
|
103
|
-
"sinon": "^
|
|
104
|
+
"puppeteer": "^24.10.2",
|
|
105
|
+
"sinon": "^21.0.0",
|
|
104
106
|
"supertest": "^7.1.1",
|
|
105
107
|
"types.d.ts": "~0.6.22",
|
|
106
108
|
"typescript": "^5.8.3",
|