This commit is contained in:
philc 2023-05-16 10:31:27 +02:00
parent 433fe035b9
commit 85862577b2
160 changed files with 268 additions and 202 deletions

15
.gitignore vendored
View File

@ -1,14 +1,5 @@
/node_modules /node_modules
/tmp /nationchains
/nginx /adminapi/www/nginx_adminapx.conf
/cleaning /adminapi/www/adminapx/conf/setup_xx.json
/nationchains/blocks
/nationchains/deals
/nationchains/logs
/nationchains/nations
/nationchains/pagans
/nationchains/towns
/nationchains/tribes
/nationchains/www/nginx_adminapx.conf
/nationchainssave
/yarn* /yarn*

View File

@ -1,5 +1,9 @@
{ {
"dns": ["adminapx"], "dns": ["adminapx"],
"towns": [
{ "townId": "wall", "nationId": "ants", "url": "wall-ants.ndda.fr" },
{ "townId": "hill", "nationId": "ants", "url": "hill-ants.ndda.fr" }
],
"api": { "api": {
"port": 3020, "port": 3020,
"languages": ["en", "fr"], "languages": ["en", "fr"],

View File

@ -1,18 +1,18 @@
server { server {
server_name {{#dns}} {{.}} {{/dns}}; server_name {{#dns}} {{.}} {{/dns}};
access_log {{{dirname}}}/{{{nginx.fswww}}}logs/nginx/{{{nginx.website}}}.{{{nginx.tribeid}}}.access.log main; access_log {{{nginx.logs}}}.access.log main;
location ~* /nationchains/(schema|blocks|pagans|towns|nations)/ { location ~* /nationchains/(schema|blocks|pagans|towns|nations)/ {
# Warning: never add tribes for keeping it private # Warning: never add tribes for keeping it private
root {{{dirname}}}/; root {{{dirapi}}}/;
} }
# /plugins/pluginame/components/xxx?plugin=pluginname&pluginkey=key # /plugins/pluginame/components/xxx?plugin=pluginname&pluginkey=key
# acess if exist pluginkey # acess if exist pluginkey
location /plugins/ { location /plugins/ {
add_header X-debug "plugins local $arg_plugin/keys/$arg_pluginkey sent"; add_header X-debug "plugins local $arg_plugin/keys/$arg_pluginkey sent";
root {{{dirname}}}/{{{nginx.fswww}}}/plugins/; root {{{nginx.fswww}}}/plugins/;
if (-f {{{dirname}}}/{{{nginx.fswww}}}/plugins/$arg_plugin/keys/$arg_pluginkey) { if (-f {{{nginx.fswww}}}/plugins/$arg_plugin/keys/$arg_pluginkey) {
rewrite /plugins/([^/]+)/components/([^\?]+) /$1/components/$2 break; rewrite /plugins/([^/]+)/components/([^\?]+) /$1/components/$2 break;
} }
return 403 "No valid token access for plugin:$arg_plugin with token:$arg_pluginkey please ask your admin"; return 403 "No valid token access for plugin:$arg_plugin with token:$arg_pluginkey please ask your admin";
@ -20,12 +20,12 @@ server {
location /cdn/ { location /cdn/ {
rewrite /cdn/(.*$) /$1 break; rewrite /cdn/(.*$) /$1 break;
root {{{dirname}}}/{{{nginx.fswww}}}www/cdn/; root {{{nginx.fswww}}}www/cdn/;
} }
location /spacedev/ { location /spacedev/ {
rewrite /spacedev/(.*$) /$1 break; rewrite /spacedev/(.*$) /$1 break;
root {{{dirname}}}/{{{nginx.fswww}}}spacedev/{{{nginx.website}}}/dist/; root {{{nginx.fswww}}}spacedev/{{{nginx.website}}}/dist/;
} }
location /api/ { location /api/ {
@ -36,7 +36,7 @@ server {
} }
location / { location / {
root {{{dirname}}}/{{{nginx.fswww}}}www/{{{nginx.website}}}; root {{{nginx.fswww}}}/{{{nginx.website}}};
index index.html {{{nginx.pageindex}}}; index index.html {{{nginx.pageindex}}};
} }
error_page 404 /404.html; error_page 404 /404.html;

View File

@ -47,7 +47,7 @@
<body> <body>
<div id="apxtitle" class="p-5 bg-primary text-white text-center" apptoload="app.load('apxtitle','title','setup')" <div id="apxtitle" class="p-5 bg-primary text-white text-center" apptoload="app.load('apxtitle','title','setup')"
add2data tpldata="static/tpldata/setup_en.json"> add2data tpldata="static/tpldata/setup_xx.json">
<h1>apXtrib</h1> <h1>apXtrib</h1>
<p> Manage and understand apXtrib back-end</p> <p> Manage and understand apXtrib back-end</p>
</div> </div>
@ -90,8 +90,8 @@
<ul class="dropdown-menu"> <ul class="dropdown-menu">
<li><a class="dropdown-item" add2data tpl="static/tpl/townsetup_en.mustache" <li><a class="dropdown-item" add2data tpl="static/tpl/townsetup_en.mustache"
onclick="app.load('apxmain','townsetup','setup')">Chain a town</a></li> onclick="app.load('apxmain','townsetup','setup')">Chain a town</a></li>
<li><a class="dropdown-item" href="#">Create Tribe</a></li>
<li><a class="dropdown-item" href="#">Manage Tribes</a></li> <li><a class="dropdown-item" href="#">Manage Tribes</a></li>
<li><a class="dropdown-item" href="#">Backup Town/Tribes</a></li>
<li> <li>
<hr class="dropdown-divider"> <hr class="dropdown-divider">
</li> </li>

View File

Before

Width:  |  Height:  |  Size: 3.7 KiB

After

Width:  |  Height:  |  Size: 3.7 KiB

View File

Before

Width:  |  Height:  |  Size: 7.0 KiB

After

Width:  |  Height:  |  Size: 7.0 KiB

View File

Before

Width:  |  Height:  |  Size: 7.2 KiB

After

Width:  |  Height:  |  Size: 7.2 KiB

View File

Before

Width:  |  Height:  |  Size: 10 KiB

After

Width:  |  Height:  |  Size: 10 KiB

View File

Before

Width:  |  Height:  |  Size: 6.6 KiB

After

Width:  |  Height:  |  Size: 6.6 KiB

View File

Before

Width:  |  Height:  |  Size: 4.5 KiB

After

Width:  |  Height:  |  Size: 4.5 KiB

View File

Before

Width:  |  Height:  |  Size: 4.2 KiB

After

Width:  |  Height:  |  Size: 4.2 KiB

View File

@ -126,6 +126,7 @@ pagans.createIdentity = async (alias, passphrase = "") => {
console.log(keys); console.log(keys);
document.getElementById("privatekey").setAttribute("key", keys.privateKey); document.getElementById("privatekey").setAttribute("key", keys.privateKey);
document.getElementById("publickey").setAttribute("key", keys.publicKey); document.getElementById("publickey").setAttribute("key", keys.publicKey);
apx.data.tmp = keys; // to make it available for btn download
document.getElementById("generatekeys").classList.add("d-none"); document.getElementById("generatekeys").classList.add("d-none");
document.getElementById("trustintribe").classList.remove("d-none"); document.getElementById("trustintribe").classList.remove("d-none");
document.getElementById("downloadkeys").classList.remove("d-none"); document.getElementById("downloadkeys").classList.remove("d-none");

View File

@ -0,0 +1,9 @@
/*eslint no-undef:0*/
/*eslint-env browser*/
"use strict";
var towns = towns || {};
towns.lauch =()=>{
}

View File

@ -2,32 +2,64 @@
<div class="col-sm-6" data-spacename="explain"> <div class="col-sm-6" data-spacename="explain">
<h2>How it works</h2> <h2>How it works</h2>
<p class="small"> <p class="small">
Mandatory: apixtrib header have to set with:<br> Mandatory: any apixtrib request <b>header</b> have to set with:<br>
* {xalias,xhash,xdays,xtribe,xlang,xapp}<br> {xalias,xhash,xdays,xtribe,xlang,xapp}<br>
* xhash is a detached signature done with public and private key of message: 'alias_xdays' where xdays is a time
stamp
a xhash has an elapse of 24hours after it has to be recreate.<br>
We need in local storage auth for this example {alias,passphrase,privatekey, publickey} to be able to create a This webapp use :
detached signature<br> </p>
On the server side we check that signature xhash of alias_timestamp is valid with the public key <ul>
<li class="small">apxtribcli.js: that manage a localstorage item call xapp (this example: adminapx) to save and
update data from
api to local
webapp: status; template,...)</li>
<li class="small">apxapp.js: viewer to manipulate DOM and bootstrapV5 framework to collect data</li>
<li class="small">apxpagans.js: controler that manage get, create, update, delete pagans</li>
</ul>
<p class="small">
<b>In few words:</b><br>
A Pagan is <b> identify by an Alias (for human)</b> known by api as a <b>publicKey</b> (for machine).<br>
The owner of this Alias (stored in header xalias) have a privateKey generate when a Pagan is created.
This private key is used to sign (with openpgp.js detachedsignature) the message "xalias_xdays" where xdays is a
timestamp this <b>signature is store into xhash</b> (header)
It is possible to trust a tribe to store this privateKey (and passphrase that encrypt this privatekey, that can be
empty, if not the passphrase is needed to uncipher the stored privateKey).<br>
<b>api accept only xhash with a timestamp less than 24hours</b>. Means app needs to store privatekey.
</p>
<p class="small">When authenticated, a Pagan can be identify as a Person into a tribe (xtribe) and then has an
object
instance of Person named "alias" into the tribe space (means /nationchains/tribe/xtribe/Person/alias.json).<br>
In this file we get a key call accessright based onto the schema accessright to the ressource of the xtribe
only.
</p>
<p class="small">
<b>accessright is based on a CRUDOwner rules per object</b>. Owner of an instance can do any things on his data
(until it respects schema). An object can have multiple Owners.<br>
Other user needs to have specifics right to act on object instance {objectname:'CRUD', ..}.<br>
Person can have key "profil" user of an app to manage webapp but action has to be on line with accessright to
work.
</p> </p>
<p> Alias is a unique string that humainly help to find a PublicKey that is the real identity.
To get the list of existing alias</p>
<button type="button" class="btn btn-outline-success btn-sm" <button type="button" class="btn btn-outline-success btn-sm"
onclick="app.runapirequest('modalinfo',{method:'GET',url:'nationchains/pagans/idx/alias_all.json'},{title:'Alias list',body:'',actions:[], classmodaldialog:'modal-xl'})">show onclick="app.runapirequest('modalinfo',{method:'GET',url:'nationchains/pagans/idx/alias_all.json'},{title:'Alias list',body:'',actions:[], classmodaldialog:'modal-xl'})">Show
it</button> list of alias</button>
</p> </p>
<code> <code>
GET nationchains/pagans/idx/alias_all.json -> data:{alias:{alias:publicKey}} GET nationchains/pagans/idx/alias_all.json -> data:{alias:{alias:publicKey}}
</code> </code>
<p>To allow trustable Tribe to store the Private and Passphrase Key, you get from the townId_all.json key:tribes</p> <p>To allow trustable Tribe to store the Private and Passphrase Key, you get from the townId_all.json key:tribes
</p>
<button type="button" class="btn btn-outline-success btn-sm" <button type="button" class="btn btn-outline-success btn-sm"
onclick="app.runapirequest('modalinfo',{method:'GET',url:'nationchains/towns/idx/townId_all.json'},{title:'Tribes list',body:'',actions:[], classmodaldialog:'modal-xl'})">show onclick="app.runapirequest('modalinfo',{method:'GET',url:'nationchains/towns/idx/townId_all.json'},{title:'Tribes list',body:'',actions:[], classmodaldialog:'modal-xl'})">Show
it</button> list of tribe</button>
<code> <code>
GET /nationchains/towns/idx/townId_all.json -> data:{townId:{tribes:[list of tribeId inside a town]}} GET /nationchains/towns/idx/townId_all.json -> data:{townId:{tribes:[list of tribeId inside a town]}}
</code> </code>
<h3> Am I authenticated to api</h3>
<p></p>
xhash is a detached signature done with public and private key of message: 'alias_xdays' where xdays is a time
stamp
a xhash has an elapse of 24hours after it has to be recreate.<br>
create
</div> </div>
<div class="col-sm-6" data-spacename="userinterface"> <div class="col-sm-6" data-spacename="userinterface">
@ -117,9 +149,10 @@
<div id="downloadkeys" class="btn-group d-none"> <div id="downloadkeys" class="btn-group d-none">
<p>Download your keys at least PrivateKey this have to save in a secret place</p> <p>Download your keys at least PrivateKey this have to save in a secret place</p>
<button id="privatekey" key="" class="btn btn-outline-primary" <button id="privatekey" key="" class="btn btn-outline-primary"
onclick="app.downloadlink('auth.privateKey',apx.data,apx.data.headers.xapp);">Download PrivateKey</button> onclick="app.downloadlink('tmp.privateKey',apx.data,apx.data.headers.xapp);">Download
PrivateKey</button>
<button id="publickey" key="" class="btn btn-outline-primary" <button id="publickey" key="" class="btn btn-outline-primary"
onclick="app.downloadlink('auth.publicKey',this.getAttribute('key'),apx.data.headers.xapp);">Download onclick="app.downloadlink('tmp.publicKey',apx.data,apx.data.headers.xapp);">Download
PublicKey</button> PublicKey</button>
</div> </div>
<div id="createId" class="col-12 d-none"> <div id="createId" class="col-12 d-none">

View File

Before

Width:  |  Height:  |  Size: 7.5 KiB

After

Width:  |  Height:  |  Size: 7.5 KiB

View File

Before

Width:  |  Height:  |  Size: 28 KiB

After

Width:  |  Height:  |  Size: 28 KiB

View File

Before

Width:  |  Height:  |  Size: 8.6 KiB

After

Width:  |  Height:  |  Size: 8.6 KiB

View File

Before

Width:  |  Height:  |  Size: 566 B

After

Width:  |  Height:  |  Size: 566 B

View File

Before

Width:  |  Height:  |  Size: 1.1 KiB

After

Width:  |  Height:  |  Size: 1.1 KiB

View File

Before

Width:  |  Height:  |  Size: 24 KiB

After

Width:  |  Height:  |  Size: 24 KiB

View File

Before

Width:  |  Height:  |  Size: 106 KiB

After

Width:  |  Height:  |  Size: 106 KiB

View File

Before

Width:  |  Height:  |  Size: 3.7 KiB

After

Width:  |  Height:  |  Size: 3.7 KiB

View File

Before

Width:  |  Height:  |  Size: 7.0 KiB

After

Width:  |  Height:  |  Size: 7.0 KiB

View File

Before

Width:  |  Height:  |  Size: 7.2 KiB

After

Width:  |  Height:  |  Size: 7.2 KiB

View File

Before

Width:  |  Height:  |  Size: 10 KiB

After

Width:  |  Height:  |  Size: 10 KiB

View File

Before

Width:  |  Height:  |  Size: 6.6 KiB

After

Width:  |  Height:  |  Size: 6.6 KiB

View File

Before

Width:  |  Height:  |  Size: 4.5 KiB

After

Width:  |  Height:  |  Size: 4.5 KiB

View File

Before

Width:  |  Height:  |  Size: 4.2 KiB

After

Width:  |  Height:  |  Size: 4.2 KiB

Some files were not shown because too many files have changed in this diff Show More