update checkdata.js
This commit is contained in:
@@ -2,7 +2,7 @@
|
||||
<html lang="fr">
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<title>apiXtribe pourquoi comment</title>
|
||||
<title>apxtrib pourquoi comment</title>
|
||||
<link rel="stylesheet" href="style.css">
|
||||
<script src="script.js"></script>
|
||||
</head>
|
||||
@@ -17,18 +17,18 @@ Our occidental society (globalization) wants us more and more money to control u
|
||||
|
||||
To make us under control, our masters print money and force us to breath it. We have no choice; they control institutions, they can stole our properties or our freedom, they drive the single thought. Forget strke and demonstration, to rebalance and create counter-powers, an alternative is to earn the minimum of their money to stay under their radar and keep our ressources (time, energy) to learn, create and share value for our tribes of friends, family, or people that share common view...
|
||||
A DAO, by design (the blockchain) cannot be control by a central power, because it is a common good, each actor has a benefit and is free to apply fair rules.<br>
|
||||
apiXtribes aims to allow any group of people to define rules to apply for their exchange of values.
|
||||
apxtribs aims to allow any group of people to define rules to apply for their exchange of values.
|
||||
|
||||
With our master's money to create value you have to respect their rules (a register company, list of standards, list of taxes, ...) in exchange you benefit of institutions like protections (police with the legitimate violence), justice (law), school, medical, ... If you are a good boy then master give you back cash grant.
|
||||
|
||||
If you agree with the master's world, and happy to let institution decide for you, this is fine (apiXtribe is not for you). But if you consider that diversity is more resilient than standard and **you want to have choices then this project is for you.** Who knows the futur ;-) apiXtribe could be use to run the democratie (demos kratos: by the people for the people).
|
||||
If you agree with the master's world, and happy to let institution decide for you, this is fine (apxtrib is not for you). But if you consider that diversity is more resilient than standard and **you want to have choices then this project is for you.** Who knows the futur ;-) apxtrib could be use to run the democratie (demos kratos: by the people for the people).
|
||||
|
||||
## Why money is the sinews of war
|
||||
|
||||
Our masters killed social ties by implementing the KPI (Key Performance Indicator) to quantify the value of each of us base on their rules. Their money is magic, they use as KPI of an individual value as well as the tools to drive our life. In occident, who can survive today without money in his pocket or in master's bank?
|
||||
|
||||
By **disconnecting value of money with gold or other "physical limit"** the money just value what they decide.<br>
|
||||
apiXtribe use a crypto (that looks like a money but is not a money) to value each rule application to create a proof of work and at least a proof of stake that any human involve has an interest to protect it.
|
||||
apxtrib use a crypto (that looks like a money but is not a money) to value each rule application to create a proof of work and at least a proof of stake that any human involve has an interest to protect it.
|
||||
|
||||
Then rules (**contracts**) can be set by anyone based on **an algo like if/then** between 2 humans. When the condition is trig then something is register in the blockchain.
|
||||
|
||||
@@ -45,20 +45,20 @@ Then rules (**contracts**) can be set by anyone based on **an algo like if/then*
|
||||
"B is baned of the community"
|
||||
```
|
||||
|
||||
**apiXtribe blockchain will register this standard "contracts" and "reputation" of those who respects or not contracts. This cannot be change by any one and any one can read it.**<br>
|
||||
A and B are just unique identificator (anonymous or not), to prove a human own A or B, apiXtribe use cryptograpĥic PGP based on public/private key. apiXtribe needs a network topology to be strong enough to avoid central control. This is why apiXtribe recommand rewarding rules to actor that provide electricity, machine, network access. Virtual world exist because physical one exist.
|
||||
**apxtrib blockchain will register this standard "contracts" and "reputation" of those who respects or not contracts. This cannot be change by any one and any one can read it.**<br>
|
||||
A and B are just unique identificator (anonymous or not), to prove a human own A or B, apxtrib use cryptograpĥic PGP based on public/private key. apxtrib needs a network topology to be strong enough to avoid central control. This is why apxtrib recommand rewarding rules to actor that provide electricity, machine, network access. Virtual world exist because physical one exist.
|
||||
|
||||
Until you stay **in crypto world, you just exchange data so no tax** (no master's rules). You can sale a service against money until you respect master/country's rule of this money (company that collect value tax, register turnover, ...). Then you can deliver crypto to your customer to consume your's or other's services when they want. If you exchange token against gov money then you have to respect your gov's laws (some country's law ask you to pay tax onto added value). So be aware of what you are doing some gov can kill you or put you in jail to exchange their money or data. This Xtrib coin is not for speculation is for social link without man in the middle that stole you.
|
||||
</p>
|
||||
<p>
|
||||
**As a non tech,** you can invest and request to get your own nation or town (become a mayor) or tribe (become a druid). As non tech you'll need the help of a dev that will help you to modelise and setup Contracts. Any way you can also simply join any tribe as pagan and sales data/product and exchange it again Xtrib coin of a nation.
|
||||
For non tech, if you have a project please request it to [support@apixtribe.org](mailto:support@apixtribe.org)
|
||||
For non tech, if you have a project please request it to [support@apxtrib.org](mailto:support@apxtrib.org)
|
||||
|
||||
**As tech**:
|
||||
|
||||
**- As sysadmin** you can install a town, for yourself or for a "non tech" and earn Xtrib in exchange<br>
|
||||
**- As back-end and front-end dev** you can dev web service (node.js express static web based on pwa) that you can sale to a druid or a mayor, or become yourself a druid and host a town to sale usage against Xtribe.<br>
|
||||
**- As a former** you can create tuto or training to explain how to install an apiXtribe node, how to dev quickly an app with a setup. This is agnostic about the front-end pwa framework, react, vue, angular, .. . For the back-end is suitable for node.js dev but you can use any linux command to produce something to deliver accross apiXtribe.<br>
|
||||
**- As a former** you can create tuto or training to explain how to install an apxtrib node, how to dev quickly an app with a setup. This is agnostic about the front-end pwa framework, react, vue, angular, .. . For the back-end is suitable for node.js dev but you can use any linux command to produce something to deliver accross apxtrib.<br>
|
||||
**- As a newbie** you can join this open source project to learn how to dev as a part of the team and to increase your portfolio of node.js/linux project.
|
||||
|
||||
We strongly believe in the cypher punk philosophy french :[cypher punk manifesto](https://dev.ndda.fr/cypherpunkmanifestofrench.html) english: [cypher punk manifesto](https://dev.ndda.fr/cypherpunkmanifestoenglish.html).
|
@@ -2,12 +2,12 @@
|
||||
<html lang="fr">
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<title>ANTS Nation</title>
|
||||
<title>Nation Base contract</title>
|
||||
<link rel="stylesheet" href="static/css/style.css">
|
||||
<script src="static/js/script.js"></script>
|
||||
</head>
|
||||
<body>
|
||||
<p> Info sur la nation des ANTS leur ville pour les rejoindre</p>
|
||||
<p> Info sur lla nation de <base href=""></p>
|
||||
<p> </p>
|
||||
</body>
|
||||
</html>
|
@@ -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"]
|
||||
}
|
13
nationchains/town_base.html
Normal file
13
nationchains/town_base.html
Normal file
@@ -0,0 +1,13 @@
|
||||
<!doctype html>
|
||||
<html lang="fr">
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<title>Town base contract</title>
|
||||
<link rel="stylesheet" href="static/css/style.css">
|
||||
<script src="static/js/script.js"></script>
|
||||
</head>
|
||||
<body>
|
||||
<p> Info sur le contrat de base d'une ville</p>
|
||||
<p> </p>
|
||||
</body>
|
||||
</html>
|
Reference in New Issue
Block a user