update checkdata.js
This commit is contained in:
@@ -3,183 +3,299 @@ This module have to be independant of any external package
|
||||
it is shared between back and front and is usefull
|
||||
to apply common check in front before sending it in back
|
||||
can be include in project with
|
||||
<script src="https://apiback.maildigit.fr/js/checkdata.js"></script>
|
||||
or with const checkdata = require('../public/js/checkdata.js')
|
||||
|
||||
- into a browser : <script src="https://townName.nationName.dns/socialworld/contracts/check.js"></script>
|
||||
- into a node.js : const check = require( `../nationchains/socialworld/contracts/check.js`);
|
||||
*/
|
||||
|
||||
// --##
|
||||
|
||||
const checkdata = {};
|
||||
// each checkdata.test. return true or false
|
||||
checkdata.test = {};
|
||||
|
||||
checkdata.test.emailadress = ( ctx, email ) => {
|
||||
const regExp = /^(([^<>()[\]\\.,;:\s@\"]+(\.[^<>()[\]\\.,;:\s@\"]+)*)|(\".+\"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/;
|
||||
return regExp.test( email );
|
||||
const check = {};
|
||||
check.schema = {};
|
||||
check.schema.properties = {};
|
||||
check.schema.properties.type = {};
|
||||
check.schema.properties.type.string = (str) => typeof str === "string";
|
||||
check.schema.properties.type.number = (n) => typeof n === "number";
|
||||
check.schema.properties.type.integer = (n) =>
|
||||
n != "" && !isNaN(n) && Math.round(n) == n;
|
||||
check.schema.properties.type.float = (n) =>
|
||||
n != "" && !isNaN(n) && Math.round(n) != n; //not yet in json schema
|
||||
check.schema.properties.minLength = (str, min) =>
|
||||
typeof str === "string" && str.length > parseInt(min);
|
||||
check.schema.properties.maxLength = (str, max) =>
|
||||
typeof str === "string" && str.length < parseInt(max);
|
||||
check.schema.properties.multipleOf = (n, val) =>
|
||||
typeof n === "number" &&
|
||||
typeof val === "number" &&
|
||||
parseFloat(n) / parseFloat(val) -
|
||||
Math.round(parseFloat(n) / parseFloat(val)) <
|
||||
0.0000001;
|
||||
check.schema.properties.range = (
|
||||
n,
|
||||
minimum,
|
||||
exclusiveMinimum,
|
||||
maximum,
|
||||
exclusiveMaximum
|
||||
) => {
|
||||
//console.log(minimum,exclusiveMinimum,maximum, exclusiveMaximum,n)
|
||||
if (typeof n !== "number") return false;
|
||||
if (minimum && parseFloat(n) < parseFloat(minimum)) return false;
|
||||
if (exclusiveMinimum && parseFloat(n) <= parseFloat(exclusiveMinimum))
|
||||
return false;
|
||||
if (maximum && parseFloat(n) > parseFloat(maximum)) return false;
|
||||
if (exclusiveMaximum && parseFloat(n) >= parseFloat(exclusiveMaximum))
|
||||
return false;
|
||||
return true;
|
||||
};
|
||||
check.schema.properties.pattern = (str, pattern) => {
|
||||
try {
|
||||
new RegExp(pattern);
|
||||
} catch (e) {
|
||||
return false;
|
||||
}
|
||||
return pattern.test(str);
|
||||
};
|
||||
check.schema.properties.enum = (str, enumvalues) =>
|
||||
typeof str === "string" && enumvalues.includes(str);
|
||||
// see format https://json-schema.org/understanding-json-schema/reference/string.html#format
|
||||
check.schema.properties.format = {
|
||||
"date-time": / /,
|
||||
time: / /,
|
||||
date: / /,
|
||||
duration: / /,
|
||||
email:
|
||||
/^(([^<>()[\]\\.,;:\s@\"]+(\.[^<>()[\]\\.,;:\s@\"]+)*)|(\".+\"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/,
|
||||
"idn-email": / /,
|
||||
uuid: /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/,
|
||||
uri: / /,
|
||||
"uri-reference": / /,
|
||||
iri: / /,
|
||||
hostname: / /,
|
||||
"idn-hostname": / /,
|
||||
ipv4: /^([0–9]{1,3}.){3}.([0–9]{1,3})$/,
|
||||
ipv6: /^((([0–9A-Fa-f]{1,4}:){7}[0–9A-Fa-f]{1,4})|(([0–9A-Fa-f]{1,4}:){6}:[0–9A-Fa-f]{1,4})|(([0–9A-Fa-f]{1,4}:){5}:([0–9A-Fa-f]{1,4}:)?[0–9A-Fa-f]{1,4})|(([0–9A-Fa-f]{1,4}:){4}:([0–9A-Fa-f]{1,4}:){0,2}[0–9A-Fa-f]{1,4})|(([0–9A-Fa-f]{1,4}:){3}:([0–9A-Fa-f]{1,4}:){0,3}[0–9A-Fa-f]{1,4})|(([0–9A-Fa-f]{1,4}:){2}:([0–9A-Fa-f]{1,4}:){0,4}[0–9A-Fa-f]{1,4})|(([0–9A-Fa-f]{1,4}:){6}((b((25[0–5])|(1d{2})|(2[0–4]d)|(d{1,2}))b).){3}(b((25[0–5])|(1d{2})|(2[0–4]d)|(d{1,2}))b))|(([0–9A-Fa-f]{1,4}:){0,5}:((b((25[0–5])|(1d{2})|(2[0–4]d)|(d{1,2}))b).){3}(b((25[0–5])|(1d{2})|(2[0–4]d)|(d{1,2}))b))|(::([0–9A-Fa-f]{1,4}:){0,5}((b((25[0–5])|(1d{2})|(2[0–4]d)|(d{1,2}))b).){3}(b((25[0–5])|(1d{2})|(2[0–4]d)|(d{1,2}))b))|([0–9A-Fa-f]{1,4}::([0–9A-Fa-f]{1,4}:){0,5}[0–9A-Fa-f]{1,4})|(::([0–9A-Fa-f]{1,4}:){0,6}[0–9A-Fa-f]{1,4})|(([0–9A-Fa-f]{1,4}:){1,7}:))$/,
|
||||
telephonefr: /^0[1-9][0-9]{9}$/,
|
||||
telephoneinter: /^\+*(\d{3})*[0-9,\-]{8,}/,
|
||||
password:
|
||||
/^(?=.*[a-z])(?=.*[A-Z])(?=.*\d)(?=.*[$@$!%*?&.])[A-Za-z\d$@$!%*?&.{}:|\s]{8,}/,
|
||||
postalcodefr: /(^\d{5}$)|(^\d{5}-\d{4}$)/,
|
||||
};
|
||||
|
||||
check.schema.validation = (schema) => {
|
||||
/*validate a schema structure*/
|
||||
const res = { status: 200, err: [] };
|
||||
if (schema.properties) {
|
||||
Object.keys(schema.properties).forEach((p) => {
|
||||
const properties = schema.properties;
|
||||
if (
|
||||
properties[p].type &&
|
||||
typeof properties[p].type === "string" &&
|
||||
!check.schema.properties.type[properties[p].type]
|
||||
) {
|
||||
res.err.push({
|
||||
info: "|checkdata|typedoesnotexistinschema",
|
||||
moreinfo: ` ${properties[p].type}`,
|
||||
});
|
||||
}
|
||||
if (
|
||||
properties[p].type &&
|
||||
typeof properties[p].type === "object" &&
|
||||
Array.isArray(properties[p].type)
|
||||
) {
|
||||
properties[p].type.forEach((tp) => {
|
||||
if (!check.schema.properties.type[tp])
|
||||
res.err.push({
|
||||
info: "|checkdata|typedoesnotexistinschema",
|
||||
moreinfo: `${tp} of ${properties[p].type}`,
|
||||
});
|
||||
});
|
||||
}
|
||||
if (
|
||||
properties[p].format &&
|
||||
!check.schema.properties.format[properties[p].format]
|
||||
) {
|
||||
res.err.push({
|
||||
info: "|checkdata|formatdoesnotexistinschema",
|
||||
moreinfo: ` ${properties[p].format}`,
|
||||
});
|
||||
}
|
||||
if (properties[p].enum && !Array.isArray(properties[p].enum)) {
|
||||
res.err.push({
|
||||
info: "|checkdata|enumisnotarrayinschema",
|
||||
moreinfo: ` ${properties[p].enum}`,
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
// 406 means not acceptable
|
||||
if (res.err.length > 0) res.status = 406;
|
||||
return res;
|
||||
};
|
||||
|
||||
check.schema.data = (schema, ctx, data) => {
|
||||
/* validate a data set with a schema in a context ctx */
|
||||
/*
|
||||
console.log('#################')
|
||||
console.log(schema);
|
||||
console.log('---------')
|
||||
console.log(data)
|
||||
*/
|
||||
const validschema = check.schema.validation(schema);
|
||||
if (validschema.status != 200) return validschema;
|
||||
const res = { status: 200, err: [] };
|
||||
if (schema.properties) {
|
||||
const properties = schema.properties;
|
||||
Object.keys(properties).forEach((p) => {
|
||||
//type is mandatory in a propertie
|
||||
if (data[p]) {
|
||||
const typlist =
|
||||
properties[p].type && typeof properties[p].type === "string"
|
||||
? [properties[p].type]
|
||||
: properties[p].type;
|
||||
let valid = false;
|
||||
typlist.forEach((typ) => {
|
||||
// at least one test have to be ok
|
||||
if (check.schema.properties.type[typ](data[p])) valid = true;
|
||||
});
|
||||
if (!valid)
|
||||
res.err.push({
|
||||
info: "|checkdata|dataerrpropertie",
|
||||
moreinfo: `${p} : ${data[p]}`,
|
||||
});
|
||||
|
||||
if (
|
||||
properties[p].minLength &&
|
||||
!check.schema.properties.minLength(data[p], properties[p].minLength)
|
||||
) {
|
||||
res.err.push({
|
||||
info: "|checkdata|dataerrpropertie",
|
||||
moreinfo: `${p} : ${data[p]} minLength:${properties[p].minLength}`,
|
||||
});
|
||||
}
|
||||
if (
|
||||
properties[p].maxLength &&
|
||||
!check.schema.properties.maxLength(data[p], properties[p].maxLength)
|
||||
) {
|
||||
res.err.push({
|
||||
info: "|checkdata|dataerrpropertie",
|
||||
moreinfo: `${p} : ${data[p]} maxLength:${properties[p].maxLength}`,
|
||||
});
|
||||
}
|
||||
if (
|
||||
properties[p].multipleOf &&
|
||||
!check.schema.properties.multipleOf(data[p], properties[p].multipleOf)
|
||||
) {
|
||||
res.err.push({
|
||||
info: "|checkdata|dataerrpropertie",
|
||||
moreinfo: `${p} : ${data[p]} not a multipleOf:${properties[p].multipleOf}`,
|
||||
});
|
||||
}
|
||||
if (
|
||||
properties[p].minimum ||
|
||||
properties[p].maximum ||
|
||||
properties[p].exclusiveMinimum ||
|
||||
properties[p].exclusiveMaximum
|
||||
) {
|
||||
// test range
|
||||
if (
|
||||
!check.schema.properties.range(
|
||||
data[p],
|
||||
properties[p].minimum,
|
||||
properties[p].exclusiveMinimum,
|
||||
properties[p].maximum,
|
||||
properties[p].exclusiveMaximum
|
||||
)
|
||||
) {
|
||||
res.err.push({
|
||||
info: "|checkdata|dataerrpropertie",
|
||||
moreinfo: `${p} : ${data[p]} not in range ${properties[p].minimum} exclu: ${properties[p].exclusiveMinimum} and ${properties[p].maximum} exclu: ${properties[p].exclusiveMaximum}`,
|
||||
});
|
||||
}
|
||||
}
|
||||
if (
|
||||
properties[p].enum &&
|
||||
!check.schema.properties.enum(data[p], properties[p].enum)
|
||||
) {
|
||||
res.err.push({
|
||||
info: "|checkdata|dataerrpropertie",
|
||||
moreinfo: `${p} : ${data[p]} not in enum list :${properties[p].enum}`,
|
||||
});
|
||||
}
|
||||
if (properties[p].format) {
|
||||
properties[p].pattern =
|
||||
check.schema.properties.format[properties[p].format];
|
||||
}
|
||||
if (
|
||||
properties[p].pattern &&
|
||||
!check.schema.properties.pattern(data[p], properties[p].pattern)
|
||||
) {
|
||||
res.err.push({
|
||||
info: "|checkdata|dataerrpropertie",
|
||||
moreinfo: `${p} : ${data[p]} problem pattern or format ${properties[p].pattern}`,
|
||||
});
|
||||
}
|
||||
} else if (schema.required.includes(p)) {
|
||||
res.err.push({
|
||||
info: "|checkdata|dataerrpropertiesrequired",
|
||||
moreinfo: `${p}`,
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
if (res.err.length > 0) res.status = 417;
|
||||
return res;
|
||||
};
|
||||
|
||||
/*
|
||||
* @emaillist = "email1,email2, email3"
|
||||
* it check if each eamil separate by , are correct
|
||||
*/
|
||||
checkdata.test.emailadresslist = ( ctx, emaillist ) => {
|
||||
//console.log(emaillist.split(','))
|
||||
if( emaillist.length > 0 ) {
|
||||
const emails = emaillist.split( ',' );
|
||||
for( var i in emails ) {
|
||||
//console.log(emails[i])
|
||||
if( !checkdata.test.emailadress( "", emails[ i ].trim() ) ) {
|
||||
return false
|
||||
}
|
||||
}
|
||||
};
|
||||
return true;
|
||||
};
|
||||
|
||||
checkdata.test.password = ( ctx, pwd ) => {
|
||||
const regExp = new RegExp(
|
||||
/^(?=.*[a-z])(?=.*[A-Z])(?=.*\d)(?=.*[$@$!%*?&.])[A-Za-z\d$@$!%*?&.{}:|\s]{8,}/
|
||||
);
|
||||
return regExp.test( pwd );
|
||||
};
|
||||
checkdata.test.required = ( ctx, val ) =>
|
||||
( val != null && val != 'undefined' && val.length > 0 ) || ( !!val && val.constructor === Array && val.length > 0 ) || ( !!val && val.constructor === Object && Object.keys( val )
|
||||
.length > 0 );
|
||||
|
||||
checkdata.test.isNumber = ( ctx, n ) => typeof n === 'number';
|
||||
checkdata.test.isInt = ( ctx, n ) => n != '' && !isNaN( n ) && Math.round( n ) == n;
|
||||
checkdata.test.isFloat = ( ctx, n ) => n != '' && !isNaN( n ) && Math.round( n ) != n;
|
||||
checkdata.test.unique = ( ctx, val ) => {
|
||||
if( ctx.list[ ctx.currentfield ] ) {
|
||||
return !ctx.list[ ctx.currentfield ].includes( val );
|
||||
} else {
|
||||
console.log( 'ERR no list for field:' + ctx.currentfield );
|
||||
return false;
|
||||
}
|
||||
};
|
||||
checkdata.test.isDateDay = ( ctx, dateDay ) => true;
|
||||
/* checkdata.test.filterInvalidInArray = (array, validate) =>
|
||||
array ? array.filter(el => !validate(el)) : true;
|
||||
// return true when every elements is valid
|
||||
Normalize data link to check.schema.properties.format
|
||||
or any normalization to get consistent data
|
||||
*/
|
||||
|
||||
checkdata.test.postalCode = ( ctx, postalCode ) => {
|
||||
if( postalCode.length == 0 ) return true;
|
||||
const regExp = new RegExp( /(^\d{5}$)|(^\d{5}-\d{4}$)/ );
|
||||
return regExp.test( postalCode );
|
||||
const normalize={};
|
||||
normalize.telephonefr =(phone)=>{
|
||||
phone = phone.trim().replace(/[- .]/g, "");
|
||||
if (
|
||||
check.schema.properties.format.telephoenfr(phone) &&
|
||||
phone.length == 10 &&
|
||||
phone[0] == "0"
|
||||
) {
|
||||
phone = "+33 " + phone.substring(1);
|
||||
}
|
||||
return phone;
|
||||
};
|
||||
/**
|
||||
* PHONE
|
||||
*/
|
||||
checkdata.test.phoneNumber = ( ctx, phoneNumber ) => {
|
||||
if( phoneNumber.length == 0 ) return true;
|
||||
phoneNumber = phoneNumber.trim()
|
||||
.replace( /[- .]/g, '' )
|
||||
//french number
|
||||
const regExpfr = new RegExp( /^0[1-9][0-9]{9}$/ );
|
||||
const regExpInternational = new RegExp( /^\+*(\d{3})*[0-9,\-]{8,}/ );
|
||||
return regExpfr.test( phoneNumber ) || regExpInternational.test( phoneNumber );
|
||||
};
|
||||
/*
|
||||
* @phonelist = "phone1,phone2,phone3"
|
||||
* it check if each phone separate by , are correct
|
||||
*/
|
||||
checkdata.test.phoneNumberlist = ( ctx, phonelist ) => {
|
||||
//console.log(emaillist.split(','))
|
||||
if( phonelist.length > 0 ) {
|
||||
const phones = phonelist.split( ',' );
|
||||
for( var i in phones ) {
|
||||
//console.log(emails[i])
|
||||
if( !checkdata.test.phoneNumber( "", phones[ i ].trim() ) ) {
|
||||
return false
|
||||
}
|
||||
}
|
||||
};
|
||||
return true;
|
||||
normalize.zfill10 = (num) => {
|
||||
let s = num + "";
|
||||
while (s.length < 10) s = "0" + s;
|
||||
return s;
|
||||
};
|
||||
|
||||
// checkdata.normalize take a correct data then reformat it to harmonise it
|
||||
checkdata.normalize = {};
|
||||
checkdata.normalize.phoneNumber = ( ctx, phone ) => {
|
||||
phone = phone.trim()
|
||||
.replace( /[- .]/g, '' );
|
||||
if( checkdata.test.phoneNumber( '', phone ) && phone.length == 10 && phone[ 0 ] == "0" ) {
|
||||
phone = '+33 ' + phone.substring( 1 );
|
||||
}
|
||||
return phone;
|
||||
}
|
||||
checkdata.normalize.upperCase = ( ctx, txt ) => txt.toUpperCase();
|
||||
checkdata.normalize.lowerCase = ( ctx, txt ) => txt.toLowerCase();
|
||||
|
||||
check.test.unique = (ctx, val) => {
|
||||
if (ctx.list[ctx.currentfield]) {
|
||||
return !ctx.list[ctx.currentfield].includes(val);
|
||||
} else {
|
||||
console.log("ERR no list for field:" + ctx.currentfield);
|
||||
return false;
|
||||
}
|
||||
};
|
||||
|
||||
// check.normalize take a correct data then reformat it to harmonise it
|
||||
check.normalize = {};
|
||||
check.normalize.phoneNumber = (ctx, phone) => {
|
||||
phone = phone.trim().replace(/[- .]/g, "");
|
||||
if (
|
||||
check.test.phoneNumber("", phone) &&
|
||||
phone.length == 10 &&
|
||||
phone[0] == "0"
|
||||
) {
|
||||
phone = "+33 " + phone.substring(1);
|
||||
}
|
||||
return phone;
|
||||
};
|
||||
check.normalize.upperCase = (ctx, txt) => txt.toUpperCase();
|
||||
check.normalize.lowerCase = (ctx, txt) => txt.toLowerCase();
|
||||
// fixe 10 position et complete par des 0 devant
|
||||
checkdata.normalize.zfill10 = ( ctx, num ) => {
|
||||
let s = num + '';
|
||||
while( s.length < 10 ) s = '0' + s;
|
||||
return s;
|
||||
};
|
||||
/*let tt = "+33 1 02.03 04 05";
|
||||
console.log(checkdata.test.phoneNumber('', tt))
|
||||
console.log(checkdata.normalize.phoneNumber('', tt))
|
||||
*/
|
||||
checkdata.evaluate = ( contexte, referential, data ) => {
|
||||
/*
|
||||
* contexte object {} with full info for evaluation
|
||||
* file referential path to get object to apply
|
||||
* data related to object
|
||||
- return {validefor =[keyword of error] if empty no error,
|
||||
clean data eventually reformated
|
||||
updateDatabase}
|
||||
*/
|
||||
console.log( 'contexte', contexte );
|
||||
console.log( 'referentiel', referential );
|
||||
console.log( 'data', data );
|
||||
const invalidefor = [];
|
||||
const objectdef = {};
|
||||
const listfield = referential.map( ch => {
|
||||
objectdef[ ch.idfield ] = ch;
|
||||
return ch.idfield;
|
||||
} );
|
||||
|
||||
Object.keys( data )
|
||||
.forEach( field => {
|
||||
if( !listfield.includes( field ) ) {
|
||||
// some data can be inside an object with no control at all
|
||||
// they are used for process only
|
||||
// i leave it in case it will become a non sens
|
||||
// invalidefor.push('ERRFIELD unknown of referentials ' + field);
|
||||
} else {
|
||||
if( objectdef[ field ].check ) {
|
||||
// check data with rule list in check
|
||||
objectdef[ field ].check.forEach( ctrl => {
|
||||
console.log( 'ctrl', ctrl );
|
||||
contexte.currentfield = field;
|
||||
if( !checkdata.test[ ctrl ] ) {
|
||||
invalidefor.push( 'ERR check function does not exist :' + ctrl + '___' + field )
|
||||
} else {
|
||||
if( !checkdata.test[ ctrl ]( contexte, data[ field ] ) )
|
||||
invalidefor.push( 'ERR' + ctrl + '___' + field );
|
||||
}
|
||||
} );
|
||||
}
|
||||
|
||||
if( objectdef[ field ].nouserupdate ) {
|
||||
// check if user can modify this information
|
||||
console.log(
|
||||
'evaluation :' + field + ' -- ' + objectdef[ field ].nouserupdate,
|
||||
eval( objectdef[ field ].nouserupdate )
|
||||
);
|
||||
const evalright = eval( objectdef[ field ].nouserupdate );
|
||||
objectdef[ field ].nouserupdate = evalright;
|
||||
}
|
||||
}
|
||||
} );
|
||||
console.log( {
|
||||
invalidefor,
|
||||
data
|
||||
} );
|
||||
return {
|
||||
invalidefor,
|
||||
data
|
||||
};
|
||||
check.normalize.zfill10 = (ctx, num) => {
|
||||
let s = num + "";
|
||||
while (s.length < 10) s = "0" + s;
|
||||
return s;
|
||||
};
|
||||
|
||||
if( typeof module !== 'undefined' ) module.exports = checkdata;
|
||||
if (typeof module !== "undefined") module.exports = check;
|
||||
|
5
nationchains/socialworld/contracts/lg/checkdata_en.json
Normal file
5
nationchains/socialworld/contracts/lg/checkdata_en.json
Normal file
@@ -0,0 +1,5 @@
|
||||
{
|
||||
"typedoesnnotexistinschema":"This type in your propertie is not manage by checkdata.js",
|
||||
"dataerrpropertie":"Check your data that not fit your schema rules propertie",
|
||||
"dataerrpropertiesrequired":"This propertie is required and not present in your data"
|
||||
}
|
36
nationchains/socialworld/contracts/nation_base.js
Normal file
36
nationchains/socialworld/contracts/nation_base.js
Normal file
@@ -0,0 +1,36 @@
|
||||
/*
|
||||
Ants nation contract
|
||||
*/
|
||||
|
||||
const Contract={
|
||||
object:"nation",
|
||||
id:"ants",
|
||||
version:"0.0.0",
|
||||
dt_create:"20230307",
|
||||
dt_update:"",
|
||||
info:"https://apxtrib.crabdance.com/nation_base.html",
|
||||
};
|
||||
|
||||
Contract.trigger = ()=>{
|
||||
// Identification of rule to trig
|
||||
// Create token for a tribe =>
|
||||
}
|
||||
|
||||
Contract.druidAllowedtoCreateToken = (tokenconf, hashtokenconf)=>{
|
||||
/*
|
||||
@tokenconf ={
|
||||
tokenvalue: float value in apxtr,
|
||||
quantity: int number of token,
|
||||
druidId: uuid,
|
||||
costrequest: float cost of this in apxtr to the mayorId
|
||||
}
|
||||
Check balance druid wallet
|
||||
@return {status:200, data:{transacId:blocktimestamp,tokens:[token1, token2, ...]}
|
||||
{status:<>200, info:'error message'}
|
||||
Store transaction in open block with transacId
|
||||
A token = druidUuid_hash(with blockchain elected privatekey)
|
||||
Druid can sale his token with his rules at a tribe level but any user that request an exchange ffrom a token
|
||||
*/
|
||||
}
|
||||
|
||||
module.exports = Contract;
|
@@ -6,7 +6,7 @@ const moment = require( 'moment' );
|
||||
const config = require( '../config' );
|
||||
const utils = {};
|
||||
|
||||
console.log( "Check in /utils/index.js to find usefull function for your dev.\n Feel free to send suggestion, code to maintainer of apixtribe project (see /package.json to get email).\n We'll add to the roadmap to add it." );
|
||||
console.log( "Check in /utils/index.js to find usefull function for your dev.\n Feel free to send suggestion, code to maintainer of apxtrib project (see /package.json to get email).\n We'll add to the roadmap to add it." );
|
||||
|
||||
/**
|
||||
* EMAIL
|
||||
|
36
nationchains/socialworld/contracts/town_base.js
Normal file
36
nationchains/socialworld/contracts/town_base.js
Normal file
@@ -0,0 +1,36 @@
|
||||
/*
|
||||
Town contract:town_base
|
||||
*/
|
||||
|
||||
const Contract={
|
||||
object:"town",
|
||||
id:"town_base",
|
||||
version:"0.0.0",
|
||||
dt_create:"20230307",
|
||||
dt_update:"",
|
||||
info:"https://apxtrib.crabdance.com/town_base.html",
|
||||
};
|
||||
|
||||
Contract.trigger = ()=>{
|
||||
// Identification of rule to trig
|
||||
// Create token for a tribe =>
|
||||
}
|
||||
|
||||
Contract.druidAllowedtoCreateToken = (tokenconf, hashtokenconf)=>{
|
||||
/*
|
||||
@tokenconf ={
|
||||
tokenvalue: float value in apxtr,
|
||||
quantity: int number of token,
|
||||
druidId: uuid,
|
||||
costrequest: float cost of this in apxtr to the mayorId
|
||||
}
|
||||
Check balance druid wallet
|
||||
@return {status:200, data:{transacId:blocktimestamp,tokens:[token1, token2, ...]}
|
||||
{status:<>200, info:'error message'}
|
||||
Store transaction in open block with transacId
|
||||
A token = druidUuid_hash(with blockchain elected privatekey)
|
||||
Druid can sale his token with his rules at a tribe level but any user that request an exchange ffrom a token
|
||||
*/
|
||||
}
|
||||
|
||||
module.exports = Contract;
|
146
nationchains/socialworld/contracts/unittest/checkdata.js
Normal file
146
nationchains/socialworld/contracts/unittest/checkdata.js
Normal file
@@ -0,0 +1,146 @@
|
||||
/*
|
||||
Unit testing
|
||||
*/
|
||||
const assert = require("assert");
|
||||
const checkdata = require("../checkdata.js");
|
||||
|
||||
const ut = { name: "checkdata" };
|
||||
|
||||
const schema = {
|
||||
$schema: "http://json-schema.org/schema#",
|
||||
title: "Dummy schema to test checkdata.js",
|
||||
description: "Checkdata is use on server as well as into a browser",
|
||||
$comment: "We change schema type on the fly to simplify the test",
|
||||
type: "Object",
|
||||
properties: {
|
||||
totest: {},
|
||||
},
|
||||
};
|
||||
const testproperties = [
|
||||
{
|
||||
name: "test1",
|
||||
data: { totest: "blabla" },
|
||||
properties: { totest: { type: "string" } },
|
||||
status: 200
|
||||
},
|
||||
{
|
||||
name: "test2",
|
||||
data: { totest: 123 },
|
||||
properties: { totest: { type: "string" } },
|
||||
status: 417
|
||||
},
|
||||
{
|
||||
name: "test3",
|
||||
data: { totest: 123.13 },
|
||||
properties: { totest: { type: "integer" } },
|
||||
status: 417
|
||||
},
|
||||
{
|
||||
name: "test4",
|
||||
data: { totest: 123 },
|
||||
properties: { totest: { type: "number" } },
|
||||
status: 200
|
||||
},
|
||||
{
|
||||
name: "test5",
|
||||
data: { totest: 12312 },
|
||||
properties: { totest: { type: "number" } },
|
||||
status: 200
|
||||
},
|
||||
{
|
||||
name: "test6",
|
||||
data: { totest: 12.313 },
|
||||
properties: { totest: { type: "float" } },
|
||||
status: 200
|
||||
},
|
||||
{
|
||||
name: "test7",
|
||||
data: { totest: "blablab sfde" },
|
||||
properties: { totest: { type: "string", minLength: 1111 } },
|
||||
status: 417
|
||||
},
|
||||
{
|
||||
name: "test8",
|
||||
data: { totest: "blablab sfde" },
|
||||
properties: { totest: { type: "string", minLength: 4, maxLength: 128} },
|
||||
status: 200
|
||||
},
|
||||
{
|
||||
name: "test9",
|
||||
data: { totest: 12 },
|
||||
properties: { totest: { type: "integer", multipleOf:3} },
|
||||
status: 200
|
||||
},
|
||||
{
|
||||
name: "test10",
|
||||
data: { totest: 9 },
|
||||
properties: { totest: { type: "number", minimum:-10, exclusiveMaximum:10} },
|
||||
status: 200
|
||||
},
|
||||
{
|
||||
name: "test11",
|
||||
data: { totest: 10 },
|
||||
properties: { totest: { type: "number", minimum:-10, exclusiveMaximum:10} },
|
||||
status: 417
|
||||
},
|
||||
{
|
||||
name: "test12",
|
||||
data: { totest: "gfhrtabcdgfr" },
|
||||
properties: { totest: { type: "string", pattern:/.*abc.*/} },
|
||||
status: 200
|
||||
},
|
||||
{
|
||||
name: "test13",
|
||||
data: { totest: "toto@google.com" },
|
||||
properties: { totest: { type: "string", format:"email"} },
|
||||
status: 200
|
||||
},
|
||||
{
|
||||
name: "test14",
|
||||
data: { totest: "Aze123@0" },
|
||||
properties: { totest: { type: "string", format:"password"} },
|
||||
status: 200
|
||||
},
|
||||
{
|
||||
name: "test15",
|
||||
data: { totest: "value1" },
|
||||
properties: { totest: { type: "string", enum:["value1","value2","value3"]} },
|
||||
status: 200
|
||||
},
|
||||
{
|
||||
name: "test16",
|
||||
data: { totest: ["t1","t2"] },
|
||||
properties: { totest: { type: ["string", "number"] }},
|
||||
status: 417
|
||||
}
|
||||
,
|
||||
{
|
||||
name: "test17",
|
||||
data: { totest: 12 },
|
||||
properties: { totest: { type: ["string", "number"] }},
|
||||
status: 200
|
||||
}
|
||||
];
|
||||
|
||||
ut.testproperties = (options) => {
|
||||
let msg = "";
|
||||
testproperties.forEach((t) => {
|
||||
schema.properties = t.properties;
|
||||
const res = checkdata.schema.data(schema, {}, t.data);
|
||||
if (res.status != t.status) {
|
||||
msg = (msg == "") ? "Unconsistent testproperties() name list: " : `${msg},`;
|
||||
if (options.verbose) {
|
||||
console.log(t)
|
||||
console.log(res);
|
||||
}
|
||||
msg += res.err.map((e) => ` ${t.name} ${e.info}`);
|
||||
}
|
||||
});
|
||||
return assert.deepEqual(msg, "", msg);
|
||||
};
|
||||
|
||||
ut.run = (options) => {
|
||||
console.log("Test checkdata properties");
|
||||
ut.testproperties(options);
|
||||
};
|
||||
module.exports = ut;
|
@@ -1,36 +0,0 @@
|
||||
[
|
||||
{
|
||||
"idfield": "name",
|
||||
"nouserupdate": true,
|
||||
"nouservisible": true,
|
||||
"desc": {
|
||||
"fr": "Nom unique d'une nation dans un monde social",
|
||||
"en": "A unique nation name in a social world"
|
||||
},
|
||||
"desclong": {
|
||||
"fr": "Nom unique identifiant une nation dans le monde social créer par un maire d'une nouvelle ville avec un contrat sociale specifique",
|
||||
"en": "Unique nation name in the social world created by a mayor of a town."
|
||||
},
|
||||
"info": {
|
||||
"fr": "<p> Une nation posséde un nom unique, un contrat sociale (contracts/name.js) signé et validé par tous les maires des villes associées à cette nation </p>",
|
||||
"en": "<p> A nation is defined by this unique name and a contratcs/nationname.js signed by each town's major define the common nation rules</p>"
|
||||
},
|
||||
"check": ["required", "unique"],
|
||||
"type": "text",
|
||||
"questioncollecte":"questioninput",
|
||||
"searchindex":["all"]
|
||||
},
|
||||
{
|
||||
"idfield": "nationtype",
|
||||
"searchindex": ["name"],
|
||||
"check": ["required"],
|
||||
"desc": {
|
||||
"fr": "Type de nation"
|
||||
},
|
||||
"default": "ACTIVE",
|
||||
"type": "data",
|
||||
"questioncollect": "questionselect",
|
||||
"data": "state.json"
|
||||
},
|
||||
|
||||
]
|
@@ -1,265 +0,0 @@
|
||||
[{
|
||||
"idfield": "UUID",
|
||||
"nouserupdate": true,
|
||||
"nouservisible": true,
|
||||
"desc": {
|
||||
"fr": "identifiant utilisateur",
|
||||
"en": "user id"
|
||||
},
|
||||
"desclong": {
|
||||
"fr": "Identifiant unique généré via UUID v4",
|
||||
"en": "unique Id from a UUID v4"
|
||||
},
|
||||
"info": {
|
||||
"fr": "<p> L'usage d'UUID v4 permet de générer un code unique sans centralisation, car il est basé sur un timestamp et une clé crypto ce qui donne un code du type 7d8291c0-e137-11e8-9f7b-1dc8e57bed33 </p>",
|
||||
"en": "<p> UUID v4 allow a client to generate a unique code without centralisation, base on a timestamp and a salt it looks like 7d8291c0-e137-11e8-9f7b-1dc8e57bed33</p>"
|
||||
},
|
||||
"check": ["required", "unique"],
|
||||
"type": "text",
|
||||
"tpl": "input"
|
||||
},
|
||||
{
|
||||
"idfield": "LOGIN",
|
||||
"nouserupdate": true,
|
||||
"check": ["required", "unique"],
|
||||
"desc": {
|
||||
"fr": "login",
|
||||
"en": "login"
|
||||
},
|
||||
"type": "text",
|
||||
"tpl": "input",
|
||||
"info": {
|
||||
"fr": "<p>Le login doit être unique sur une instance d'apixtribe.</p><p> Pour échanger en dehors d'une instance apixtribe on utilise la clé public du user ou pour un humain login@apixtribe.domain.xx avec le nom du domaine qui heberge l'instance</p><p> Ou encore login@domain.xx tout domain.xx utilisé pour heberger un espace web client /tribeid/www/</p>",
|
||||
"en": "<p>Login have to be unique into an apixtribe instance</p><p> To exchange outside of an apixtribe instance, we use PublicKey or login@apixtribe.domain.xx or login@domainclient.xx where domain.xx is a apixtribe name server on internet and domain.xx is a tribeid name where a /tribeid/www is available on the net.</p>"
|
||||
}
|
||||
},
|
||||
{
|
||||
"idfield": "BIOGRAPHY",
|
||||
"desc": {
|
||||
"fr": "Vous en quelques mots",
|
||||
"en": "Few words"
|
||||
},
|
||||
"placeholder": {
|
||||
"fr": "",
|
||||
"en": ""
|
||||
},
|
||||
"rows": 2,
|
||||
"tpl": "textarea"
|
||||
},
|
||||
{
|
||||
"nouserupdate": true,
|
||||
"idfield": "PUBLICKEY",
|
||||
"desc": {
|
||||
"fr": "Votre clé public pour ce compte",
|
||||
"en": "Your public key for this uuid"
|
||||
},
|
||||
"info": {
|
||||
"fr": "<p>Cette clé est générée par votre navigateur, garder précisuesement votre clé privée que seule vous connaissez. En cas de perte de cette clé tous vos actifs seront perdus.</p><p>Cette méthode nous permet de vous garantir un contrôle total décentralisé.</p>",
|
||||
"en": "<p>This key was generated by your browser, keep the private key related to this public key.</p><p>We garanty your total control by this way</p>."
|
||||
},
|
||||
"tpl": "textarea"
|
||||
},
|
||||
{
|
||||
"idfield": "IMGAVATAR",
|
||||
"tpl": "inputimg",
|
||||
"altimg": "image avatar",
|
||||
"classimg": "rounded-circle img-responsive mt-2",
|
||||
"width": 128,
|
||||
"height:"
|
||||
128,
|
||||
"classdivupload": "mt-2",
|
||||
"classbtn": "btn-primary",
|
||||
"desc": {
|
||||
"fr": "changer votre avatar",
|
||||
"en": "upload an avatar"
|
||||
},
|
||||
"info": {
|
||||
"fr": "Pour un meilleur rendu, une mage carré de 128pc en foat jpg",
|
||||
"en": "For best results, use an image at least 128px by 128px in .jpg format"
|
||||
},
|
||||
|
||||
},
|
||||
{
|
||||
"idfield": "EMAIL",
|
||||
"desc": {
|
||||
"fr": "email",
|
||||
"en": "email"
|
||||
},
|
||||
"tpl": "input",
|
||||
"type": "email",
|
||||
"check": ["emailadress", "unique"],
|
||||
"placeholder": {
|
||||
"fr": "#@",
|
||||
"en": "@"
|
||||
}
|
||||
},
|
||||
{
|
||||
"idfield": "PHONE",
|
||||
"desc": {
|
||||
"fr": "Tel",
|
||||
"en": "Phone"
|
||||
},
|
||||
"check": ["phone"]
|
||||
"tpl": "input",
|
||||
"type": "text"
|
||||
},
|
||||
{
|
||||
"idfield": "NAME",
|
||||
"desc": {
|
||||
"fr": "Nom",
|
||||
"en": "Name"
|
||||
},
|
||||
"tpl": "input",
|
||||
"type": "text"
|
||||
},
|
||||
{
|
||||
"idfield": "FIRSTNAME",
|
||||
"desc": {
|
||||
"fr": "Prénom",
|
||||
"en": "First Name"
|
||||
},
|
||||
"tpl": "input",
|
||||
"type": "text"
|
||||
},
|
||||
{
|
||||
"idfield": "NICKNAME",
|
||||
"desc": {
|
||||
"fr": "Pseudo",
|
||||
"en": "Nickname"
|
||||
},
|
||||
"tpl": "input",
|
||||
"type": "text"
|
||||
},
|
||||
"info": {
|
||||
"fr": "<p>Nom avec lequel vous souhaitez qu'on vous reconnaisse sur l'instance de l'apixtribe </p><p>Attention ce nom n'est unique que sur une instance d'apixtribe. Un même speudo peut-être utilisé sur un autre serveur pour garantir l'identité vérifié pseudo@ domaine de rattachement.</p>",
|
||||
"en": "<p>Carrefull a pseudo is unique into an instance of apixtribe to be sure to contact the right person check pseudo@ domain</p>.<p> Pseudo can be changed that is not the case of login.</p>"
|
||||
},
|
||||
"tpl": "input",
|
||||
"type": "text"
|
||||
}, {
|
||||
"idfield": "COMPANYNAME",
|
||||
"desc": {
|
||||
"fr": "Nom de Société",
|
||||
"en": "Compagnie name"
|
||||
},
|
||||
"tpl": "input",
|
||||
"type": "text"
|
||||
}, {
|
||||
"idfield": "BILLINGADD",
|
||||
"desc": {
|
||||
"fr": "Adresse complete de facturation par defaut",
|
||||
"en": "Full billing adress default"
|
||||
},
|
||||
"tpl": "input",
|
||||
"type": "text",
|
||||
"placeholder": {
|
||||
"fr": "1 chemin du paradis - 91430 IGNY France",
|
||||
"en": "123 Main St- 123MZ -Oxford UK"
|
||||
}
|
||||
}, {
|
||||
"idfield": "DELIVERYADD",
|
||||
"desc": {
|
||||
"fr": "Adresse complete de livraison par defaut",
|
||||
"en": "Full delivery adress default"
|
||||
},
|
||||
"tpl": "input",
|
||||
"type": "text",
|
||||
"placeholder": {
|
||||
"fr": "1 chemin du paradis - 91430 IGNY France",
|
||||
"en": "123 Main St- 123MZ -Oxford UK"
|
||||
}
|
||||
}, {
|
||||
"idfield": "ADDRESS1",
|
||||
"desc": {
|
||||
"fr": "Adresse",
|
||||
"en": "Address"
|
||||
},
|
||||
"tpl": "input",
|
||||
"type": "text",
|
||||
"placeholder": {
|
||||
"fr": "1 chemin du paradis",
|
||||
"en": "123 Main St"
|
||||
}
|
||||
}, {
|
||||
"idfield": "ADDRESS2",
|
||||
"desc": {
|
||||
"fr": "Adresse 2",
|
||||
"en": "Address 2"
|
||||
},
|
||||
"tpl": "input",
|
||||
"type": "text",
|
||||
"placeholder": {
|
||||
"fr": "Appartement B",
|
||||
"en": "Apt B"
|
||||
}
|
||||
}, {
|
||||
"idfield": "CITY",
|
||||
"desc": {
|
||||
"fr": "Ville ",
|
||||
"en": "CITY"
|
||||
},
|
||||
"tpl": "input",
|
||||
"type": "text"
|
||||
}, {
|
||||
"idfield": "ZIP",
|
||||
"desc": {
|
||||
"fr": "Code Postal",
|
||||
"en": "ZIP"
|
||||
},
|
||||
"tpl": "input",
|
||||
"type": "text"
|
||||
}, {
|
||||
"idfield": "COUNTRY",
|
||||
"desc": {
|
||||
"fr": "Pays",
|
||||
"en": "Country"
|
||||
},
|
||||
"tpl": "input",
|
||||
"type": "text"
|
||||
}, {
|
||||
"nouserupdate": true,
|
||||
"idfield": "DATE_CREATE",
|
||||
"desc": {
|
||||
"fr": "Date de création",
|
||||
"en": "Create Date"
|
||||
},
|
||||
"tpl": "date",
|
||||
"format": "YYYY-MM-DD",
|
||||
"default": "moment(new Date()).format('YYYY-MM-DD')"
|
||||
}, {
|
||||
"nouserupdate": true,o
|
||||
"idfield": "DATE_UPDATE",
|
||||
"desc": {
|
||||
"fr": "Date mise à jour",
|
||||
"en": "Update date"
|
||||
},
|
||||
"tpl": "date",
|
||||
"format": "YYYY-MM-DD",
|
||||
"default": "moment(new Date()).format('YYYY-MM-DD')"
|
||||
}, {
|
||||
"nouserupdate": true,
|
||||
"idfield": "DATE_LASTLOGIN",
|
||||
"desc": {
|
||||
"fr": "Date de derniére connexion",
|
||||
"en": "Last date login"
|
||||
},
|
||||
"tpl": "date",
|
||||
"format": "YYYY-MM-DD",
|
||||
"default": "moment(new Date()).format('YYYY-MM-DD')"
|
||||
}, {
|
||||
"idfield": "ACCESSRIGHTS",
|
||||
"nouserupdate": true,
|
||||
"desc": {
|
||||
"fr": "Vos droits d'accès",
|
||||
"en": "Your access rights"
|
||||
},
|
||||
"default": {
|
||||
"app": {},
|
||||
"data": {
|
||||
"tribeidname": {
|
||||
"users": "O"
|
||||
}
|
||||
}
|
||||
},
|
||||
"tpl": "jsoneditor"
|
||||
}]
|
@@ -1 +0,0 @@
|
||||
[]
|
@@ -1,7 +1,5 @@
|
||||
{"UUID":"ants",
|
||||
"publickey":"123",
|
||||
"status":"open",
|
||||
"domain":["antsnation.mooo.com"],
|
||||
"svg":"",
|
||||
"towns":["hill"]
|
||||
{
|
||||
"nationId":"ants",
|
||||
"dtcreate":"2023-03-19T14:05:00+02:00",
|
||||
"contracts":"socialworld/contracts/nation_base.js"
|
||||
}
|
@@ -1,5 +0,0 @@
|
||||
{"UUID":"escape",
|
||||
"publickey":"123",
|
||||
"status":"open",
|
||||
"towns":["game"]
|
||||
}
|
@@ -0,0 +1,6 @@
|
||||
{"ants":{
|
||||
"nationId":"ants",
|
||||
"publickey":"123",
|
||||
"status":"unchain",
|
||||
"svg":""
|
||||
}}
|
@@ -1 +0,0 @@
|
||||
["escapenation"]
|
@@ -1 +0,0 @@
|
||||
{"archilinea":["escapenation","game"]}
|
19
nationchains/socialworld/objects/schema/lg/nations_en.json
Normal file
19
nationchains/socialworld/objects/schema/lg/nations_en.json
Normal file
@@ -0,0 +1,19 @@
|
||||
{
|
||||
"title":"Nation definition",
|
||||
"description":"A nation from apXtrib social world",
|
||||
"$comment":"",
|
||||
"properties":{
|
||||
"nationId":{
|
||||
"title":"Unique nation name",
|
||||
"description":"A unique string that define a nation a-z and 0-9 onlyin a social world"
|
||||
},
|
||||
"dtcreate":{
|
||||
"title":"Creation date",
|
||||
"description":"Nation date of creation"
|
||||
},
|
||||
"contracts":{
|
||||
"title":"Social contract of the nation",
|
||||
"description":"A uri of the signed js contract that rules this nation"
|
||||
}
|
||||
}
|
||||
}
|
@@ -0,0 +1,7 @@
|
||||
{
|
||||
"nationnamedesc":"Nom unique d'une nation dans un monde social",
|
||||
"nationnamedesclong":"Nom unique identifiant une nation dans le monde social créer par un maire d'une nouvelle ville avec un contrat sociale specifique",
|
||||
"nationnameinfo":"<p> Une nation posséde un nom unique, un contrat sociale (contracts/name.js) signé et validé par tous les maires des villes associées à cette nation </p>",
|
||||
"statusdesc":"Statut de la nation",
|
||||
"statusactive":"Nation active"
|
||||
}
|
42
nationchains/socialworld/objects/schema/lg/pagans_en.json
Normal file
42
nationchains/socialworld/objects/schema/lg/pagans_en.json
Normal file
@@ -0,0 +1,42 @@
|
||||
{
|
||||
"ERRcritical": "Critical Error",
|
||||
"loginAlreadyExist": "Login already exists",
|
||||
"emailAlreadyExist":"Email already exists",
|
||||
"failtoWritefs":"Fail to write on system",
|
||||
"successfullCreate": "Successfully created",
|
||||
"successfullDelete": "Successfully deleted",
|
||||
"serverNeedAuthentification":"This server needs authentification",
|
||||
"forbiddenAccess":"Forbidden Access",
|
||||
"userNotAllowtoCreate":"User is not allow to create",
|
||||
"userNotAllowtoUpdate":"User is not allow to update",
|
||||
"userNotAllowtoDelet":"User is not allow to delete",
|
||||
"uuidNotFound":"Paggans {{uuid}} not found for {{tribeName}}",
|
||||
"useremailNotfound":"Email not found",
|
||||
"loginDoesNotExist":" Login does not exist",
|
||||
"checkCredentials":" Check yopur credentials"
|
||||
"wrongPassword":"Check your password",
|
||||
"invalidData":"Check your data",
|
||||
"pswToosimple":"Password too simple, need to contain at least 8 caracters lower and uppercase, number and @! ...",
|
||||
"ERRemail":"Check your email",
|
||||
"ERRnewnewbisdiff":"Both password are not the same",
|
||||
"paganiddesc":"unique id",
|
||||
"paganiddesclong":"Unique Identification based on UUID.v4()",
|
||||
"paganidinfo":"<p> UUID v4 allow a client to generate a unique code without centralisation, base on a timestamp and a salt it looks like 7d8291c0-e137-11e8-9f7b-1dc8e57bed33</p>",
|
||||
"logindesc":"login",
|
||||
"logininfo":"<p>Login have to be unique into a town (composed of letter: a to z and 0 to 9)</p><p> To exchange outside of a town, we use PublicKey / uuid or login@tribeId.townId.nationId.dns</p>",
|
||||
"pswdesc":"A strong password minimum 8char uper lower number specialm char",
|
||||
"biographydesc":"Few words about you",
|
||||
"publickeyinfo":"<p>This key was generated by your browser, keep the private key related to this public key.</p><p>We garanty your total control by this way</p>.",
|
||||
"imgavatardesc":"Upload an avatar",
|
||||
"imgavatarinfo":"For best results, use an image at least 128px by 128px in .jpg format",
|
||||
"emaildesc":"Email de recuperation de mot de passe",
|
||||
"telephonedesc":"Phone",
|
||||
"familyNamedesc":"Last name",
|
||||
"givenNamedesc":"First name",
|
||||
"additionalNamedesc":"Nickname",
|
||||
"additionalNamesinfo":"<p>Carrefull a pseudo is unique into an instance of apxtrib to be sure to contact the right person check pseudo@ domain</p>.<p> Pseudo can be changed that is not the case of login.</p>",
|
||||
"dtcreatedesc":"Creation date",
|
||||
"dtupdatedesc":"last update",
|
||||
"dtlastlogindesc":"Last login access",
|
||||
"accessrightsdesc":"Your accessrigts"
|
||||
}
|
41
nationchains/socialworld/objects/schema/lg/pagans_fr.json
Normal file
41
nationchains/socialworld/objects/schema/lg/pagans_fr.json
Normal file
@@ -0,0 +1,41 @@
|
||||
{
|
||||
"ERRcritical": "Erreur critique",
|
||||
"loginAlreadyExist": "Ce login exist déjà",
|
||||
"emailAlreadyExist":"Cet email exist déjà",
|
||||
"failtoWritefs":"Impossible d'ecrire sur le serveur",
|
||||
"successfullCreate": "Création réussit",
|
||||
"successfullDelete": "Mise à jour effectuée",
|
||||
"serverNeedAuthentification":"Ce serveur a besoin d'une authentification",
|
||||
"forbiddenAccess":"Accès interdit",
|
||||
"userNotAllowtoCreate":"Pas d'autorisation de creation",
|
||||
"userNotAllowtoUpdate":"Pas d'autorisatiuon de mise à jour",
|
||||
"userNotAllowtoDelet":"Pas d'autorisation de suppression",
|
||||
"uuidNotFound":"Le paîen {{uuid}} n'existe pas dans la tribu {{tribeName}}",
|
||||
"useremailNotfound":"Email introuvable",
|
||||
"loginDoesNotExist":" Login introuvable",
|
||||
"checkCredentials":" Vérifier vos parametres d'accès"
|
||||
"wrongPassword":"Vérifier votre mot de passe",
|
||||
"invalidData":"Vérifier vos données",
|
||||
"pswToosimple":"Votre mot de passe est trop simple, doit contenir au moins 8 caractères avec des lettres majusculmes, minuscules des nombres et au moins un caractere special @! ...",
|
||||
"ERRemail":"Vérifier votre email",
|
||||
"ERRnewnewbisdiff":"Les 2 mots de passe ne sont pas identique",
|
||||
"uuiddesc":"Identifiant",
|
||||
"uuiddesclong":"Identifiant unique au format UUID.v4()",
|
||||
"uuidinfo":"<p> L'usage d'UUID v4 permet de générer un code unique sans centralisation, car il est basé sur un timestamp et une clé crypto ce qui donne un code du type 7d8291c0-e137-11e8-9f7b-1dc8e57bed33 </p>",
|
||||
"logindesc":"login",
|
||||
"logininfo":"<p>Le login doit être unique sur une instance d'apxtrib.</p><p> Pour échanger en dehors d'une instance apxtrib on utilise la clé public du user ou pour un humain login@trib.town§.nation.xx avec le nom du domaine qui heberge l'instance</p><p> Ou encore login@domain.xx tout domain.xx utilisé pour heberger un espace web client /tribeid/www/</p>",
|
||||
"biographydesc":"Vous en quelques mots",
|
||||
"publickeyinfo":"<p>Cette clé est générée par votre navigateur, garder précisuesement votre clé privée que seule vous connaissez. En cas de perte de cette clé tous vos actifs seront perdus.</p><p>Cette méthode nous permet de vous garantir un contrôle total décentralisé.</p>",
|
||||
"imgavatardesc":"Changer votren avatar",
|
||||
"imgavatarinfo":"Pour un meilleur rendu, une mage carré de 128pc en foat jpg",
|
||||
"emaildesc":"Email",
|
||||
"telephonedesc":"Tel",
|
||||
"familyNamedesc":"Nom",
|
||||
"givenNamedesc":"Prénom",
|
||||
"additionalNamedesc":"Pseudo",
|
||||
"additionalNamesinfo":"<p>Nom avec lequel vous souhaitez qu'on vous reconnaisse sur l'instance de l'apxtrib </p><p>Attention ce nom n'est unique que sur une instance d'apxtrib. Un même speudo peut-être utilisé sur un autre serveur pour garantir l'identité vérifié pseudo@ domaine de rattachement.</p>",
|
||||
"dtcreatedesc":"Date de creation",
|
||||
"dtupdatedesc":"Dernière mise à jour",
|
||||
"dtlastlogindesc":"Dernier accès au login",
|
||||
"accessrightsdesc":"Vos droits d'accès"
|
||||
}
|
8
nationchains/socialworld/objects/schema/lg/towns_en.json
Normal file
8
nationchains/socialworld/objects/schema/lg/towns_en.json
Normal file
@@ -0,0 +1,8 @@
|
||||
{
|
||||
"townnamedesc":"A unique town name in a nation for a social world",
|
||||
"townnamedesclong":"Unique town name in the social world created by a mayor.",
|
||||
"townnameinfo":"<p> A town is defined by this unique name and a contratcs/townname.js signed by each druid that create a tribe inside this town</p>",
|
||||
"antsnationdesc":"ants nation",
|
||||
"statusdesc":"Town's status",
|
||||
"statusactive":"Active Town"
|
||||
}
|
8
nationchains/socialworld/objects/schema/lg/towns_fr.json
Normal file
8
nationchains/socialworld/objects/schema/lg/towns_fr.json
Normal file
@@ -0,0 +1,8 @@
|
||||
{
|
||||
"townnamedesc":"Nom unique d'une ville dans une nation",
|
||||
"townnamedesclong":"Nom unique identifiant une ville dans une nation d'un monde social, créer par un maire d'une nouvelle ville avec un contrat sociale specifique",
|
||||
"townnameinfo":"<p> Une ville posséde un nom unique, un contrat sociale (contracts/name.js) signé et validé par tous les maires des villes associées à cette nation </p>",
|
||||
"antsnationdesc":"nation des ants",
|
||||
"statusdesc":"Statut de la ville",
|
||||
"statusactive":"Ville active"
|
||||
}
|
28
nationchains/socialworld/objects/schema/nations.json
Normal file
28
nationchains/socialworld/objects/schema/nations.json
Normal file
@@ -0,0 +1,28 @@
|
||||
{
|
||||
"$schema":"http://json-schema.org/schema#",
|
||||
"$id":"nationchains/socialworld/objects/schema/nations",
|
||||
"title": "Nation definition",
|
||||
"description": "A nation from apXtrib world",
|
||||
"$comment":"see ./lg/nations_lg.json for description in your languange lg",
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"nationId": {
|
||||
"type": "string",
|
||||
"pattern":"^[a-z0-9]*$"
|
||||
},
|
||||
"dtcreate": {
|
||||
"type": "string",
|
||||
"format":"datetime"
|
||||
},
|
||||
"contracts":{
|
||||
"type": "string",
|
||||
"format":"uri"
|
||||
}
|
||||
},
|
||||
"required": ["nationId", "dtcreate","contracts"],
|
||||
"additionalProperties":false,
|
||||
"apxprimarykey":"nationId",
|
||||
"apxsearchindex": [
|
||||
{ "key": "nationId", "value": [] }
|
||||
]
|
||||
}
|
86
nationchains/socialworld/objects/schema/pagans.json
Executable file
86
nationchains/socialworld/objects/schema/pagans.json
Executable file
@@ -0,0 +1,86 @@
|
||||
{
|
||||
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
||||
"$id": "socialworld/schema/pagans",
|
||||
"title":"Pagan definition",
|
||||
"description": "A pagan is an uuid to manage identity by deliver a way to its owner to proof he owns from a privatekey in the socialworld of apXtrib and manage access keys deliver by druid or mayor to interact physical ressource (CRUD on it).",
|
||||
"type": "objects",
|
||||
"properties":{
|
||||
"paganId":{
|
||||
"description": "|Pagans|paganiddesc",
|
||||
"apxdesclong": "|Pagans|paganiddesclong"
|
||||
"apxinfo":"|Pagans|paganidinfo",
|
||||
"type": "string",
|
||||
"apxtype":"uuidv4"
|
||||
},
|
||||
"login":{
|
||||
"description": "|Pagans|logindesc",
|
||||
"type": "string",
|
||||
"pattern":"^[a-z0-9]*$",
|
||||
"apxinfo": "|Pagans|logininfo"
|
||||
},
|
||||
"password":{
|
||||
"description": "|Pagans|pswdesc",
|
||||
"type": "string"
|
||||
},
|
||||
"townId":{
|
||||
"description":"",
|
||||
"type":"string",
|
||||
"$apxenumkey": "socialworld/objects/nations/searchindex/towns_townId_all.json"
|
||||
},
|
||||
"tribeId":{
|
||||
"description":"",
|
||||
"type":"string",
|
||||
"$apxenumkey": "tribes/objects/tribes/searchindex/tribes_tribeId_all.json"
|
||||
},
|
||||
"publicKey":{
|
||||
"description": "|Pagans|publickeydesc",
|
||||
"type":"string",
|
||||
"apxinfo": "|Pagans|publickeyinfo"
|
||||
},
|
||||
"biography":{
|
||||
"description": "|Pagans|biographydesc",
|
||||
"type":"string",
|
||||
"pattern":"^.{O,150}$"
|
||||
},
|
||||
"imgavatar":{
|
||||
"description": "|Pagans|imgavatardesc",
|
||||
"apxinfo": "|Pagans|imgavatarinfo",
|
||||
"type":"string",
|
||||
"apxtype":"file"
|
||||
},
|
||||
"emailrecup":{
|
||||
"description":"|Pagans|emaildesc",
|
||||
"tpl": "input",
|
||||
"type": "email",
|
||||
"check": ["emailadress", "unique"],
|
||||
},
|
||||
"dtcreate":{
|
||||
"description": "|Pagans|dtcreatedesc",
|
||||
"type":"string",
|
||||
"pattern":"^[0-9]{4}-(0?[1-9]|1[012])-(0?[1-9]|[12][0-9]|3[01])$",
|
||||
"default": "moment(new Date()).format('YYYY-MM-DD')"
|
||||
},"dtupdate": {
|
||||
"description": "|Pagans|dtupdatedesc",
|
||||
"type":"string",
|
||||
"pattern":"^[0-9]{4}-(0?[1-9]|1[012])-(0?[1-9]|[12][0-9]|3[01])$",
|
||||
"default": "moment(new Date()).format('YYYY-MM-DD')"
|
||||
},"dtlastlogin" {
|
||||
"description": "|Pagans|dtlastlogindesc",
|
||||
"type":"string",
|
||||
"pattern":"^[0-9]{4}-(0?[1-9]|1[012])-(0?[1-9]|[12][0-9]|3[01])$",
|
||||
"default": "moment(new Date()).format('YYYY-MM-DD')"
|
||||
},"accessrights": {
|
||||
"description": "|Pagans|accessrightsdesc",
|
||||
"type":"object",
|
||||
"$ref":"socialworld/schema/accessright.json"
|
||||
}
|
||||
},
|
||||
"required": ["paganId","login","townId", "tribeId"],
|
||||
"apxprimarykey": "paganId",
|
||||
"apxunique":["login"],
|
||||
"apxsearchindex": [
|
||||
{ "key": "login", "value": "paganId" },
|
||||
{ "key": "email", "value": "paganId" },
|
||||
{ "key": "token", "value": "paganId" }
|
||||
]
|
||||
}
|
45
nationchains/socialworld/objects/schema/towns.json
Normal file
45
nationchains/socialworld/objects/schema/towns.json
Normal file
@@ -0,0 +1,45 @@
|
||||
{
|
||||
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
||||
"$id": "socialworld/objects/schema/towns",
|
||||
"title": "Town",
|
||||
"description": "A town belonging to a nation from apXtrib world",
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"townId": {
|
||||
"description": "|Towns|townnamedesc",
|
||||
"desclong": "|Townss|townnamedesclong",
|
||||
"info": "|Towns|townnameinfo",
|
||||
"type": "string",
|
||||
"pattern":"^[a-z0-9]*$"
|
||||
},
|
||||
"nationId": {
|
||||
"description": "|Towns|nationdesc",
|
||||
"desclong": "|Townss|nationdesclong",
|
||||
"type": "string",
|
||||
"$apxenumkey": "socialworld/objects/nations/searchindex/nations_uuid_uuid.json"
|
||||
},
|
||||
"status": {
|
||||
"desc": "|Towns|statusdesc",
|
||||
"default": "active",
|
||||
"type": "string",
|
||||
"$apxenumkey": "data",
|
||||
"data": {
|
||||
"chain": { "desc": "|Towns|statuschain" },
|
||||
"tochain": { "desc": "|Towns|statustosync" },
|
||||
"unchain": { "desc": "|Towns|statusunchain" }
|
||||
}
|
||||
},
|
||||
"url": {
|
||||
"desc": "|Towns|urldesc",
|
||||
"type": "string",
|
||||
"apxtype":"url"
|
||||
}
|
||||
},
|
||||
"required": ["townId", "status", "nationId", "url"],
|
||||
"apxprimarykey": "townId",
|
||||
"apxsearchindex": [
|
||||
{ "key": "status", "value": "townId" },
|
||||
{ "key": "nationId", "value": "townId" },
|
||||
{ "key": "townId", "value": [] }
|
||||
]
|
||||
}
|
@@ -1,7 +0,0 @@
|
||||
{
|
||||
"url":"https://escape.game.apixtribe.org",
|
||||
"IP":"213.32.65.213",
|
||||
"mayorid":"123",
|
||||
"status":""
|
||||
"tribes":[]
|
||||
}
|
9
nationchains/socialworld/objects/towns/hill.json
Normal file
9
nationchains/socialworld/objects/towns/hill.json
Normal file
@@ -0,0 +1,9 @@
|
||||
{
|
||||
"id":"hill",
|
||||
"nationid":"ants",
|
||||
"contract":"town_base",
|
||||
"url":"https://hill.ants.mooo.com",
|
||||
"IP":"213.32.65.213",
|
||||
"mayorid":"123",
|
||||
"status":""
|
||||
}
|
@@ -0,0 +1 @@
|
||||
{"ants":["hill","wall"]}
|
@@ -0,0 +1,16 @@
|
||||
{"hill":{
|
||||
"townId":"hill",
|
||||
"nationId":"ants",
|
||||
"url":"https://hill.ants.mooo.com",
|
||||
"IP":"213.32.65.213",
|
||||
"mayorid":"123",
|
||||
"status":""
|
||||
},"wall":{
|
||||
"townId":"wall"
|
||||
"nationid":"ants",
|
||||
"url":"https://wall.ants.mooo.com",
|
||||
"IP":"213.32.65.213",
|
||||
"mayorid":"123",
|
||||
"status":""
|
||||
}
|
||||
}
|
9
nationchains/socialworld/objects/towns/wall.json
Normal file
9
nationchains/socialworld/objects/towns/wall.json
Normal file
@@ -0,0 +1,9 @@
|
||||
{
|
||||
"id":"wall",
|
||||
"nationid":"ants",
|
||||
"contract":"town_base",
|
||||
"url":"https://wall.ants.mooo.com",
|
||||
"IP":"213.32.65.213",
|
||||
"mayorid":"123",
|
||||
"status":""
|
||||
}
|
11
nationchains/socialworld/setup/townSetup.json
Executable file
11
nationchains/socialworld/setup/townSetup.json
Executable file
@@ -0,0 +1,11 @@
|
||||
{
|
||||
"sudoerUser": "phil",
|
||||
"nationName":"ants",
|
||||
"townName":"devndda",
|
||||
"tribeName":"devndda",
|
||||
"dns":"unchain",
|
||||
"paganslogin":"pat",
|
||||
"apiport": 3018,
|
||||
"language": ["fr", "en"],
|
||||
"jwtsecret": "longsentenceusedtoencryptionChangethisforproduction"
|
||||
}
|
13
nationchains/socialworld/setup/townconf.json
Normal file
13
nationchains/socialworld/setup/townconf.json
Normal file
@@ -0,0 +1,13 @@
|
||||
{
|
||||
"saltRounds":10,
|
||||
"exposedHeaders":[ "xauth", "xpaganid", "xlang", "xtribe", "xworkon", "xapp" ],
|
||||
"unittesting":["middlewares","models","routes","nationchains"],
|
||||
"appset":{"trust proxy":true},
|
||||
"bodyparse": {
|
||||
"urlencoded": {
|
||||
"limit": "50mb",
|
||||
"extended": true
|
||||
},
|
||||
"json": { "limit": "500mb" }
|
||||
}
|
||||
}
|
25
nationchains/socialworld/setup/tribeconf.json
Executable file
25
nationchains/socialworld/setup/tribeconf.json
Executable file
@@ -0,0 +1,25 @@
|
||||
{
|
||||
"tribeid": "${tribeName}",
|
||||
"genericpsw": "",
|
||||
"saltRounds": "12",
|
||||
"allowedDOMs": ["${townName}.${nationName}.${dns}"],
|
||||
"customization": {
|
||||
"claim": "Be a Producer, not a product.",
|
||||
"name": "apxtrib",
|
||||
"logo": "https://${townName}.${nationName}.${dns}/static/img/chartegraphique/logo_bgtransparent.png",
|
||||
"favicon": "https://${townName}.${nationName}.${dns}/static/img//chartegraphique/favicon.png",
|
||||
"colors": {
|
||||
"primary": "#01717B",
|
||||
"secondary": "#CA5F00",
|
||||
"success": "",
|
||||
"info": "",
|
||||
"warning": "",
|
||||
"danger": "",
|
||||
"light": "#fff",
|
||||
"dark": "#222"
|
||||
}
|
||||
},
|
||||
"smtp": {},
|
||||
"accepted-language": "fr,en",
|
||||
"langueReferential": ["fr"]
|
||||
}
|
Reference in New Issue
Block a user