feat: init; from commit c3adcb2e6bc94b46f4f34c03bc62abcce6c7e1a0 of BDContract
This commit is contained in:
commit
4379b1745e
1
.gitignore
vendored
Normal file
1
.gitignore
vendored
Normal file
@ -0,0 +1 @@
|
||||
/.idea
|
7
README.md
Normal file
7
README.md
Normal file
@ -0,0 +1,7 @@
|
||||
#文件说明
|
||||
|
||||
1) 最小可直接使用:./js目录下的createWS.js,cryptico.js,sm2.js 三个脚本 。
|
||||
|
||||
2)直接打开bdwareclinet.html,在地址中填入单节点运行的地址,如127.0.0.1:18000。可在界面中试调合约。
|
||||
|
||||
3)参考bdwareclient.js的写法,并配合说明文档中的ContractAPI.html进行使用。
|
173
bdwareclient.html
Normal file
173
bdwareclient.html
Normal file
@ -0,0 +1,173 @@
|
||||
<html>
|
||||
<head>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
|
||||
<meta http-equiv="Cache-Control" content="no-cache" />
|
||||
<title>数瑞客户端</title>
|
||||
|
||||
<script src="./js/createWS.js"></script>
|
||||
<script src="./js/cryptico.js"></script>
|
||||
<script src="./js/jquery-2.1.4.js"></script>
|
||||
<script src="./js/bootstrap.min.js"></script>
|
||||
<script src="./js/commonutil.js"></script>
|
||||
|
||||
<link href="./css/common.css" rel="stylesheet">
|
||||
<link href="./css/bootstrap.min.css" rel="stylesheet">
|
||||
<script src="./js/vue.js"></script>
|
||||
<script src="./js/bdwareclient.js"></script>
|
||||
<script src="./js/sm2.js"></script>
|
||||
</head>
|
||||
<body>
|
||||
<header
|
||||
class="headerFooter navbar navbar-default navbar-fixed-top navColor ">
|
||||
<div class="col-10">
|
||||
<div class="input-group">
|
||||
<a class="navbar-brand" href="#"> <img alt="Brand"
|
||||
src="./img/logo-1.png" style="height: 30px">
|
||||
</a><a class="navbar-brand">数瑞浏览器 </a> <input id="urlInput"
|
||||
type="text" class="form-control" placeholder="输入地址">
|
||||
|
||||
<button class="btn btn-outline-secondary" type="button"
|
||||
onclick="connectNode()">GO</button>
|
||||
<button class="btn btn-outline-secondary" id="switchRenderBtn" type="button"
|
||||
onclick="changeRender()">不加载界面</button>
|
||||
<span> </span>
|
||||
<div class="input-group-append">
|
||||
<select id="selectContract" class="custom-select"
|
||||
style="-webkit-appearance: none" onchange="changeApp()">
|
||||
<option selected>选择合约</option>
|
||||
</select>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
<div class=" nav navbar-right userName" data-toggle="modal"
|
||||
data-target="#pubkeyDialog">欢迎, {{shortName}}</div>
|
||||
</header>
|
||||
|
||||
<div id="main">
|
||||
<div class="row h-100" id="mainDiv"></div>
|
||||
</div>
|
||||
<!-- 用于配置sm2密钥的对话框 -->
|
||||
<div class="modal fade" id="pubkeyDialog" tabindex="-1" role="dialog"
|
||||
aria-labelledby="exampleModalCenterTitle" aria-hidden="true">
|
||||
<div class="modal-dialog modal-dialog-centered" role="document">
|
||||
<div class="modal-content">
|
||||
<div class="modal-header">
|
||||
<h5 class="modal-title" id="exampleModalLongTitle">用户信息</h5>
|
||||
<button type="button" class="close" data-dismiss="modal"
|
||||
aria-label="Close">
|
||||
<span aria-hidden="true">×</span>
|
||||
</button>
|
||||
</div>
|
||||
<div class="modal-body">
|
||||
<div class="row" style="padding-left: 16px; padding-right: 16px">
|
||||
|
||||
<div class="input-group mb-3">
|
||||
<div class="input-group-prepend">
|
||||
<label class="input-group-text" for="localKeyList">本地公钥</label>
|
||||
</div>
|
||||
|
||||
<select class="custom-select"
|
||||
aria-label="Example select with button addon"
|
||||
style="appearance: none" v-model="selectedSM2Key"
|
||||
@change="changeSM2Key($event)">
|
||||
<option v-for="(item,index) in sm2KeyList" :key="index"
|
||||
:value='item.id'>{{item.title}}</option>
|
||||
</select>
|
||||
<div class="input-group-append">
|
||||
<button class="btn btn-outline-primary" for="localKeyList"
|
||||
v-on:click="exportPubkey">导出公钥</button>
|
||||
</div>
|
||||
<div class="input-group-append">
|
||||
<button class="btn btn-outline-danger" for="localKeyList"
|
||||
v-on:click="deletePubkey">删除公钥</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row" style="padding-left: 16px; padding-right: 16px">
|
||||
|
||||
<div class="input-group mb-1">
|
||||
<div class="input-group-prepend">
|
||||
<label class="input-group-text" for="localKeyList">当前SM2密钥</label>
|
||||
</div>
|
||||
<input type="text" class="form-control" placeholder="(请复制并妥善保存)"
|
||||
disabled="disabled" aria-label=""
|
||||
aria-describedby="basic-addon1">
|
||||
|
||||
<div class="input-group-append">
|
||||
<button type="button" class="btn btn-outline-primary"
|
||||
id="generatePubkeyBtn" v-on:click="generatePubkey">生成新公钥</button>
|
||||
<button type="button" class="btn btn-outline-primary"
|
||||
data-dismiss="modal" id="importPubkeyBtn"
|
||||
v-on:click="importPubkey">导入公钥</button>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
<textarea class="form-control mb-3" title="复制密钥,并妥善保存"
|
||||
id="sm2KeyTextarea" v-model="sm2KeyStr"
|
||||
style="width: 100%; min-height: 150px" rows="" cols="">
|
||||
</textarea>
|
||||
<div class="row" style="padding-left: 16px; padding-right: 16px;">
|
||||
|
||||
</div>
|
||||
<div class="row" style="padding-left: 16px; padding-right: 16px">
|
||||
<span>我的权限:{{myRole}}</span>
|
||||
</div>
|
||||
<div class="input-group">
|
||||
<select id="inputGroupSelect04" v-model="test"
|
||||
class="custom-select" style="appearance: none"
|
||||
@change="changeProduct($event)">
|
||||
<option v-for="(item,index) in productList" :key="index"
|
||||
:value='item.id'>{{item.title}}</option>
|
||||
</select>
|
||||
<div class="input-group-append">
|
||||
<button class="btn btn-outline-primary" type="button"
|
||||
v-on:click="applyRole">角色认证</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
|
||||
<div class="modal fade" id="dialog" tabindex="-1" role="dialog"
|
||||
aria-labelledby="exampleModalLabel" aria-hidden="true">
|
||||
<div class="modal-dialog" role="document">
|
||||
<div class="modal-content">
|
||||
<div class="modal-header">
|
||||
<h5 class="modal-title" id="dialogTitleH5">Modal title</h5>
|
||||
<button type="button" class="close" data-dismiss="modal"
|
||||
aria-label="Close">
|
||||
<span aria-hidden="true">×</span>
|
||||
</button>
|
||||
</div>
|
||||
<div class="modal-body" id="dialogBodyDiv">...</div>
|
||||
<div class="modal-footer">
|
||||
<button type="button" class="btn btn-outline-secondary"
|
||||
data-dismiss="modal">关闭
|
||||
</button>
|
||||
<button type="button" id="dialogConfimBtn"
|
||||
class="btn btn-outline-primary" data-dismiss="modal">确定
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<script>
|
||||
var h = document.body.clientHeight
|
||||
- $("header").css("height").replace("px", "")
|
||||
|
||||
$("#main").css("height", h + "px");
|
||||
init();
|
||||
|
||||
//initWSocket();
|
||||
</script>
|
||||
|
||||
</body>
|
||||
</html>
|
1
css/bootstrap.min.css
vendored
Normal file
1
css/bootstrap.min.css
vendored
Normal file
File diff suppressed because one or more lines are too long
128
css/common.css
Normal file
128
css/common.css
Normal file
@ -0,0 +1,128 @@
|
||||
.navColor {
|
||||
background: #882929;
|
||||
color: white;
|
||||
}
|
||||
|
||||
.userName {
|
||||
padding-left: 10px;
|
||||
padding-right: 10px;
|
||||
border: 1px solid rgba(0, 0, 0, .125);
|
||||
border-radius: 5px;
|
||||
background: white;
|
||||
color: #2E324C;
|
||||
}
|
||||
|
||||
.userName:hover {
|
||||
cursor: pointer;
|
||||
background: rgb(68, 110, 155);
|
||||
color: white;
|
||||
border-radius: 5px;
|
||||
}
|
||||
|
||||
#horiNav {
|
||||
padding-top: 10px;
|
||||
border: 1px solid rgba(0, 0, 0, .05);
|
||||
background: #f8f9fa;
|
||||
}
|
||||
|
||||
#outputNav {
|
||||
padding-top: 10px;
|
||||
border: 1px solid rgba(0, 0, 0, .05);
|
||||
background: #f8f9fa;
|
||||
}
|
||||
|
||||
div .card {
|
||||
background: #f8f9fa;
|
||||
}
|
||||
|
||||
#main {
|
||||
background: white;
|
||||
color: black;
|
||||
}
|
||||
.active>.iconimg {
|
||||
height: 25px;
|
||||
width: 25px;
|
||||
margin-right: 10px;
|
||||
filter: invert(100%);
|
||||
}
|
||||
|
||||
.iconimg {
|
||||
height: 25px;
|
||||
width: 25px;
|
||||
margin-right: 10px;
|
||||
filter: invert(15%) sepia(11%) saturate(2467%) hue-rotate(194deg)
|
||||
brightness(94%) contrast(84%);
|
||||
}
|
||||
|
||||
.buttonimg {
|
||||
height: 24px;
|
||||
width: 24px;
|
||||
filter: invert(15%) sepia(11%) saturate(2467%) hue-rotate(194deg)
|
||||
brightness(94%) contrast(84%);
|
||||
}
|
||||
|
||||
.closeimg {
|
||||
height: 12px;
|
||||
width: 12px;
|
||||
filter: invert(15%) sepia(11%) saturate(2467%) hue-rotate(194deg)
|
||||
brightness(94%) contrast(84%);
|
||||
|
||||
}
|
||||
|
||||
.closeimg:hover {
|
||||
cursor:pointer;
|
||||
|
||||
}
|
||||
|
||||
.active>.closeimg {
|
||||
filter: invert(100%);
|
||||
}
|
||||
|
||||
.trigimg {
|
||||
height: 20px;
|
||||
width: 20px;
|
||||
}
|
||||
|
||||
.projectLine.collapsed {
|
||||
background: #D5D6DB;
|
||||
color: #2E324C;
|
||||
}
|
||||
|
||||
.projectLine {
|
||||
background: #2E324C;
|
||||
color: white;
|
||||
}
|
||||
|
||||
.projectLine.collapsed:hover {
|
||||
background: #2E324C;
|
||||
color: white;
|
||||
}
|
||||
|
||||
button:hover>.trigimg {
|
||||
filter: invert(100%);
|
||||
}
|
||||
|
||||
button[aria-expanded="true"]>.trigimg {
|
||||
filter: invert(100%);
|
||||
}
|
||||
|
||||
button:hover>.buttonimg {
|
||||
height: 24px;
|
||||
width: 24x;
|
||||
filter: invert(100%);
|
||||
}
|
||||
|
||||
.headerFooter {
|
||||
background: #2E324C;
|
||||
color: white;
|
||||
}
|
||||
|
||||
.outline-btn {
|
||||
border: 1px solid #999;
|
||||
border-radius: 3px;
|
||||
}
|
||||
|
||||
div.filter-option {
|
||||
border: 1px solid #999;
|
||||
border-radius: 3px;
|
||||
}
|
BIN
img/logo-1.png
Normal file
BIN
img/logo-1.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 13 KiB |
786
js/bdwareclient.js
Normal file
786
js/bdwareclient.js
Normal file
@ -0,0 +1,786 @@
|
||||
var dtLang = {
|
||||
"sProcessing": "处理中...",
|
||||
"lengthMenu": '显示 <select>' + '<option value="5">5</option>'
|
||||
+ '<option value="20">20</option>'
|
||||
+ '<option value="100">100</option>'
|
||||
+ '<option value="-1">全部</option>' + '</select> 项结果',
|
||||
"sZeroRecords": "没有匹配结果",
|
||||
"sInfo": "显示第 _START_ 至 _END_ 项结果,共 _TOTAL_ 项",
|
||||
"sInfoEmpty": "显示第 0 至 0 项结果,共 0 项",
|
||||
"sInfoFiltered": "(由 _MAX_ 项结果过滤)",
|
||||
"sInfoPostFix": "",
|
||||
"sSearch": "搜索:",
|
||||
"sUrl": "",
|
||||
"sEmptyTable": "表中数据为空",
|
||||
"sLoadingRecords": "载入中...",
|
||||
"sInfoThousands": ",",
|
||||
"oPaginate": {
|
||||
"sFirst": "首页",
|
||||
"sPrevious": "上页",
|
||||
"sNext": "下页",
|
||||
"sLast": "末页"
|
||||
},
|
||||
"oAria": {
|
||||
"sSortAscending": ": 以升序排列此列",
|
||||
"sSortDescending": ": 以降序排列此列"
|
||||
}
|
||||
};
|
||||
|
||||
function applyRole(role) {
|
||||
global.wssocket.send("{\"action\":\"applyNodeRole\",\"role\":\"" + role
|
||||
+ "\",\"pubKey\":\"" + global.sm2Key.publicKey + "\"}");
|
||||
}
|
||||
|
||||
function WSHandler(event) {
|
||||
console.log(event);
|
||||
data = event.data;
|
||||
// console.log(" -->" + data);
|
||||
try {
|
||||
var obj = JSON.parse(data);
|
||||
|
||||
switch (obj.action) {
|
||||
case 'onTransferTo':
|
||||
onTransferTo(obj);
|
||||
break;
|
||||
case 'onHashResult':
|
||||
onHashResult(obj);
|
||||
break;
|
||||
case 'onListMemoryFiles':
|
||||
onListMemoryFiles(obj);
|
||||
break;
|
||||
case 'onDumpContract':
|
||||
onDumpContract(obj);
|
||||
break;
|
||||
case 'onChangeDumpPeriod':
|
||||
onChangeDumpPeriod(obj);
|
||||
break;
|
||||
case 'onGetDumpPeriod':
|
||||
onGetDumpPeriod(obj);
|
||||
break;
|
||||
case 'onStaticVerifyResult':
|
||||
onStaticVerifyResult(obj);
|
||||
break;
|
||||
case "onListContractProcess":
|
||||
onListContractProcess(obj);
|
||||
break;
|
||||
case "onDeleteFile":
|
||||
onDeleteFile(obj);
|
||||
break;
|
||||
case "onCancelAuth":
|
||||
onCancelAuth(obj);
|
||||
break;
|
||||
case "onDownloadContract":
|
||||
onDownloadFile(obj);
|
||||
break;
|
||||
case "onChangePublic":
|
||||
onChangePublic(obj);
|
||||
break;
|
||||
case "onListProjects":
|
||||
onListProjects(obj);
|
||||
break;
|
||||
case "onListProject":
|
||||
onListProject(obj);
|
||||
break;
|
||||
case "onListLocalNodeLog":
|
||||
onListLocalNodeLog(obj);
|
||||
break;
|
||||
case "onListLocalNodeLogPie":
|
||||
onListLocalNodeLogPie(obj);
|
||||
break;
|
||||
case "onListLocalNodeLogLine":
|
||||
onListLocalNodeLogLine(obj);
|
||||
break;
|
||||
case "onListTheContractProcess":
|
||||
onListTheContractProcess(obj);
|
||||
break;
|
||||
case "onListLocalContractLog":
|
||||
onListLocalContractLog(obj);
|
||||
break;
|
||||
case "onListLocalContractLogPie":
|
||||
onListLocalContractLogPie(obj);
|
||||
break;
|
||||
case "onListLocalContractLogLine":
|
||||
onListLocalContractLogLine(obj);
|
||||
break;
|
||||
case "onGetNodeSessionID":
|
||||
case "onSessionID":
|
||||
onGetNodeSessionID(obj);
|
||||
break;
|
||||
case "onLogin":
|
||||
onNodeLogin(obj);
|
||||
break;
|
||||
case "onGetNodeRole":
|
||||
case "onGetRole":
|
||||
onGetNodeRole(obj);
|
||||
break;
|
||||
case "onApplyRole":
|
||||
onApplyRole(obj);
|
||||
break;
|
||||
case "onListAllAuthRole":
|
||||
onListAllAuthRole(obj);
|
||||
break;
|
||||
case "onListUnAuthRole":
|
||||
onListUnAuthRole(obj);
|
||||
break;
|
||||
case "onDeleteRole":
|
||||
onDeleteRole(obj);
|
||||
break;
|
||||
case "onCountRole":
|
||||
onCountRole(obj);
|
||||
break;
|
||||
case "onAuthNodeRole":
|
||||
onAuthNodeRole(obj);
|
||||
break;
|
||||
case "onApplyNet":
|
||||
onApplyNet(obj);
|
||||
break;
|
||||
case "onLoadNodeConfig":
|
||||
onLoadNodeConfig(obj);
|
||||
break;
|
||||
case "onChangeNodeName":
|
||||
onChangeNodeName(obj);
|
||||
break;
|
||||
case "onChangeYJSPath":
|
||||
onChangeYJSPath(obj);
|
||||
break;
|
||||
case "onChangeIpPort":
|
||||
onChangeIpPort(obj);
|
||||
break;
|
||||
case "onGetLicenceExpiredDate":
|
||||
$("#expiredDate").html(convertDate(data.data));
|
||||
break;
|
||||
case "onGetPeerID":
|
||||
global.peerID = obj.data;
|
||||
// getNodeTrustUnits();//still connecting to centerportalws
|
||||
break;
|
||||
case "onViewContractInstance":
|
||||
onViewContractInstance(obj);
|
||||
break;
|
||||
case 'onExecuteResult':
|
||||
onExecuteResult(obj);
|
||||
break;
|
||||
case 'onExecuteContractTrustfully':
|
||||
onExecuteContractTrustfully(obj);
|
||||
break;
|
||||
case 'onUploadFile':
|
||||
onUploadFile(obj);
|
||||
break;
|
||||
case 'onStartContract':
|
||||
onStartContract(obj);
|
||||
break;
|
||||
case 'onStartContractConfig':
|
||||
onStartContractConfig(obj);
|
||||
break;
|
||||
case 'onKillContractProcess':
|
||||
onStopContract(obj);
|
||||
break;
|
||||
case 'onKillAllContract':
|
||||
onKillAllContract(obj);
|
||||
break;
|
||||
case 'onSetPermission':
|
||||
onSetPermission(obj);
|
||||
break;
|
||||
case 'onOutputStream':
|
||||
displayOutput(obj);
|
||||
break;
|
||||
case 'onChangeNodeCenter':
|
||||
console.log("onChangeNodeCenter");
|
||||
onChangeNodeCenter(obj);
|
||||
break;
|
||||
case 'onException':
|
||||
onException(obj);
|
||||
break;
|
||||
// logException(obj);
|
||||
// break;
|
||||
default:
|
||||
displayOutput(obj);
|
||||
break;
|
||||
}
|
||||
} catch (err) {
|
||||
console.log(err);
|
||||
}
|
||||
}
|
||||
|
||||
function onException(obj) {
|
||||
if (obj.data.startsWith("unauthorised action")) {
|
||||
const action = obj.data.replace("unauthorised action ", "");
|
||||
switch (action) {
|
||||
case "listContractProcess":
|
||||
mainVue.contracts = [];
|
||||
if (global.urlparam["contract"]) {
|
||||
appendTargetContract(global.urlparam["contract"]);
|
||||
} else
|
||||
alertNoPermission("listContractProcess无授权,请申请ContractUser权限", "提示");
|
||||
break;
|
||||
default:
|
||||
alertNoPermission(action + "无权限", "提示");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function alertNoPermission(message, title) {
|
||||
const npSpan = $("#nopermissionSpan");
|
||||
if (npSpan.length > 0) {
|
||||
console.log(message + " status:" + $("#dialog")[0].getAttribute("class"));
|
||||
npSpan.append("<br/>" + message);
|
||||
} else {
|
||||
let body = "<div class='row'><div class='col-sm-12'><span id='nopermissionSpan'>";
|
||||
body += message;
|
||||
body += "</span></div></div>";
|
||||
$("#dialogBodyDiv").html(body);
|
||||
showDialog("提示", function () {
|
||||
$("#dialogBodyDiv").html("");
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
function onExecuteResult(obj) {
|
||||
console.log(obj);
|
||||
global.executeResult = obj;
|
||||
if (global.executeResult.size) {
|
||||
onExecuteContractTrustfully(obj);
|
||||
}
|
||||
onExecuteResultInternal(obj);
|
||||
}
|
||||
|
||||
function showContractResult(requestID) {
|
||||
var data = global.responseCollector[requestID][0];
|
||||
result = data;
|
||||
$("#statusSpan")[0].innerHTML = result.status;
|
||||
$("#timeSpan")[0].innerHTML = "调用耗时:" + data.executeTime + "(ms)";
|
||||
if (result.result instanceof Object){
|
||||
$("#responseArea")[0].value = JSON.stringify(result.result);
|
||||
$("#timeSpan")[0].innerHTML +="<br> JSON格式";
|
||||
}else{
|
||||
$("#timeSpan")[0].innerHTML +="<br> 字符串格式";
|
||||
$("#responseArea")[0].value = result.result;
|
||||
}
|
||||
if (global.responseCollector[requestID].hashCode!=undefined)
|
||||
$("#hashDisplayDiv").html("溯源指纹:" + global.responseCollector[requestID].hashCode);
|
||||
}
|
||||
|
||||
|
||||
function switchContractResult() {
|
||||
const requestID = reqIDSpan.value;
|
||||
showContractResult(requestID);
|
||||
}
|
||||
|
||||
function showInconsistentResult(list) {
|
||||
global.resultList = list;
|
||||
let html = "<table class='table table-striped'><thead><tr><td>status</td><td>executeTime</td><td>result</td></tr></thead><tbody>";
|
||||
for (const r of list) {
|
||||
html += "<tr><td>";
|
||||
const data = JSON.parse(r.data);
|
||||
html += data.status;
|
||||
html += "</td><td>";
|
||||
html += r.executeTime;
|
||||
html += "</td><td><textarea class='form-control'>";
|
||||
html += data.result;
|
||||
html += "</textarea></td></tr>";
|
||||
}
|
||||
html += "</tbody></table>";
|
||||
const consistencyResult = $("#consistencyResult");
|
||||
if (consistencyResult.length > 0) {
|
||||
consistencyResult.html(html);
|
||||
} else {
|
||||
$("#dialogBodyDiv").html(html);
|
||||
showDialog("调用结果不一致", function () {
|
||||
}, () => {
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
function showDialog(title, cb, cancelcb) {
|
||||
$("#dialogTitleH5").html(title);
|
||||
$("#dialogConfimBtn").off("click").on("click", cb);
|
||||
$("#dialogCloseBtn").off("click").on("click", cancelcb);
|
||||
$("#dialog").modal("show");
|
||||
}
|
||||
|
||||
function onHashResult(obj) {
|
||||
$("#hashDisplayDiv").html("溯源指纹:" + obj.data);
|
||||
global.responseCollector[obj.responseID].hashCode = obj.data;
|
||||
}
|
||||
|
||||
function displayOutput(obj) {
|
||||
console.log(obj);
|
||||
}
|
||||
|
||||
function initWSocket() {
|
||||
let host = $("#urlInput")[0].value;
|
||||
if (!host.startsWith("ws")) {
|
||||
host = "ws://" + host;
|
||||
}
|
||||
if (host.endsWith("/SCIDE")) {
|
||||
host += "/SCExecutor";
|
||||
} else if (host.endsWith("/SCIDE/")) {
|
||||
host += "SCExecutor";
|
||||
} else if (host.endsWith("NodeCenterWS")) {
|
||||
//..
|
||||
} else if (!host.endsWith("/SCIDE/SCExecutor")) {
|
||||
host += "/SCIDE/SCExecutor";
|
||||
}
|
||||
console.log("connect ws:" + host);
|
||||
global.wssocket = createWssocket(host, () => {
|
||||
getSession();
|
||||
}, WSHandler);
|
||||
global.responseCollector = {};
|
||||
global.commited = {};
|
||||
}
|
||||
|
||||
function getSession() {
|
||||
global.wssocket.send("{\"action\":\"getSessionID\"}");
|
||||
}
|
||||
|
||||
function exportSMKeyPair() {
|
||||
const dialog = $("#dialog");
|
||||
dialog.html("Save Your key:<br/>" + JSON.stringify(global.sm2Key));
|
||||
dialog.dialog("open");
|
||||
}
|
||||
|
||||
// ====== wsHandler
|
||||
function onGetNodeSessionID(data) {
|
||||
console.log("onGetNodeSessionID");
|
||||
global.session = data.session;
|
||||
const loginParam = {
|
||||
pubKey: global.sm2Key.publicKey,
|
||||
signature: sm2.doSignature(global.session, global.sm2Key.privateKey,{hash:true,der:true}),
|
||||
action: "login"
|
||||
};
|
||||
global.wssocket.send(JSON.stringify(loginParam));
|
||||
}
|
||||
|
||||
function onNodeLogin(data) {
|
||||
pubkeyDialogVue.myRole = data.data;
|
||||
global.myRole = data.data;
|
||||
listContracts();
|
||||
}
|
||||
|
||||
function listContracts() {
|
||||
global.wssocket.send(JSON.stringify({action: "listContractProcess"}));
|
||||
}
|
||||
|
||||
function changeApp() {
|
||||
global.currentContract = global.contracts[$("#selectContract")[0].value];
|
||||
if (!global.currentContract) {
|
||||
return;
|
||||
}
|
||||
console.log(global.currentContract);
|
||||
changeAppInternal(needRender(global.currentContract));
|
||||
}
|
||||
|
||||
function changeAppInternal(requireRendering) {
|
||||
if ((global.urlparam["noRender"] !== "true") && requireRendering) {
|
||||
$("#mainDiv")[0].innerHTML = "";
|
||||
executeCurrentContract("getMainFrame", "", parseMainFrame);
|
||||
} else {
|
||||
let title = "只包含计算逻辑";
|
||||
if (requireRendering) {
|
||||
title = "包含界面";
|
||||
}
|
||||
title += getContractDesp();
|
||||
const html = " <div class='container'> <div class=\"card mt-3 \">\n"
|
||||
+ " <div class=\"card-body\">\n"
|
||||
+ " <h5 class=\"card-title\">"
|
||||
+ title
|
||||
+ "</h5>\n"
|
||||
+ " <div class=\"card-body\" >\n"
|
||||
+ " <div class=\"row\">\n"
|
||||
+ " <div class=\"col-sm-12 d-flex justify-content-center\">\n"
|
||||
+ " <div class=\"input-group mb-2\">\n"
|
||||
+ " <div class=\"input-group-prepend\">\n"
|
||||
+ " <select id=\"selectAction\" onchange=\"showDescription()\" class=\"custom-select\" style=\"-webkit-appearance: none;\"><option value=\"-1\">选择方法</option></select> \n"
|
||||
+ " </div>\n"
|
||||
+ " <input type=\"text\" class=\"form-control\" id=\"argInput\" placeholder=\"填写参数\" >\n"
|
||||
+ " <div class=\"input-group-append\">\n"
|
||||
+ " <button class=\"btn btn-outline-secondary\" type=\"button\" \n"
|
||||
+ " onclick=\"triggerExecuteCurrentContract()\">\n"
|
||||
+ " 调用\n"
|
||||
+ " </button>\n"
|
||||
+ " </div>\n"
|
||||
+ " </div>\n"
|
||||
+ " </div>\n"
|
||||
+ " </div>"
|
||||
+ "<div class='row mb-2'><div class='col-sm-12 d-flex '>"
|
||||
+ "<div class=\"input-group\" ><div class=\"input-group-prepend\" > <span class=\"input-group-text\" >方法描述</span></div><input class=\"input-group-text form-control\" id=\"descriptionSpan\" placeholder=\"暂无\"></input></div>"
|
||||
+ "</div></div>"
|
||||
+ "<div class='row mb-4'><div class='col-sm-12 d-flex'>"
|
||||
+ "<div class=\"input-group \" ><div class=\"input-group-prepend\" > <span class=\"input-group-text\" >http接口</span></div><input class=\"input-group-text form-control\" id=\"sigOutput\"></input></div></div></div>\n"
|
||||
+ " <h5 class=\"card-title\">调用结果</h5>\n"
|
||||
+ " <div class=\"input-group mb-3\">\n"
|
||||
+ " <div class=\"input-group-prepend\">\n"
|
||||
+ " <select class=\"custom-select form-control\" onchange='switchContractResult()' style=\"-webkit-appearance:none; appearance:none; height:100%\" id=\"reqIDSpan\"><option>请求ID</option></select>\n"
|
||||
+ " </div>\n"
|
||||
+ " <div class=\"input-group-append\"><span class=\"input-group-text\" id=\"statusSpan\">调用状态</span></div>\n"
|
||||
+ " <div class=\"input-group-append\"><span class=\"input-group-text\" id=\"timeSpan\">调用耗时</span></div>\n"
|
||||
+ " <textarea id=\"responseArea\" class=\"form-control\"></textarea>\n"
|
||||
+ " </div><div class='row mb-3'><div class='col-sm-12 d-flex' id='consistencyResult'> </div></div>"
|
||||
+ " <div class='row'><div class='col-sm-12 d-flex' id='hashDisplayDiv'> </div></div>"
|
||||
+ " </div>\n"
|
||||
+ " </div>\n"
|
||||
+ " </div></div>\n" + "";
|
||||
$("#mainDiv")[0].innerHTML = html;
|
||||
for (const f of global.currentContract.exportedFunctions) {
|
||||
$('#selectAction')
|
||||
.append(`<option value="${f.functionName}">${f.functionName}</option>`);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function getContractDesp() {
|
||||
try {
|
||||
const annos = global.currentContract.annotations;
|
||||
for (const anno of annos) {
|
||||
if (anno.type === "Description") {
|
||||
return ", " + JSON.parse(anno.args[0]);
|
||||
}
|
||||
}
|
||||
} catch (e) {
|
||||
console.log(e);
|
||||
}
|
||||
return "";
|
||||
}
|
||||
|
||||
function triggerExecuteCurrentContract() {
|
||||
const funPos = $("#selectAction")[0].value;
|
||||
console.log(funPos);
|
||||
if (funPos < 0) {
|
||||
$("#dialogBodyDiv").html("请选择方法。");
|
||||
showDialog("提示");
|
||||
return;
|
||||
}
|
||||
var funNode;
|
||||
for(var i = 0;i < global.currentContract.exportedFunctions.length;i++){
|
||||
if(global.currentContract.exportedFunctions[i].functionName == funPos){
|
||||
funNode = global.currentContract.exportedFunctions[i];
|
||||
break;
|
||||
}
|
||||
}
|
||||
console.log(funNode);
|
||||
const argInput = $("#argInput");
|
||||
executeCurrentContract(funNode.functionName, argInput[0].value,
|
||||
fillResultInternal);
|
||||
const iHtml = "/SCIDE/SCManager?action=executeContract&contractID="
|
||||
+ global.currentContract.name + "&operation="
|
||||
+ funNode.functionName + "&arg=" + argInput[0].value
|
||||
+ "&pubkey=" + global.sm2Key.publicKey + "&signature=";
|
||||
const toSign = global.currentContract.name + "|" + funNode.functionName + "|"
|
||||
+ argInput[0].value + "|" + global.sm2Key.publicKey;
|
||||
const signature = sm2.doSignature(toSign, global.sm2Key.privateKey,{hash:true,der:true});
|
||||
let urlPre = $("#urlInput")[0].value;
|
||||
if (urlPre.startsWith("ws")) {
|
||||
urlPre = urlPre.replace("ws", "http");
|
||||
}
|
||||
$("#sigOutput")[0].value = (urlPre + iHtml + signature);
|
||||
}
|
||||
|
||||
function showDescription() {
|
||||
const funPos = $("#selectAction")[0].value;
|
||||
console.log($("#selectAction")[0]);
|
||||
console.log(funPos);
|
||||
console.log(global.currentContract.exportedFunctions);
|
||||
var funNode;
|
||||
for(var i = 0;i < global.currentContract.exportedFunctions.length;i++){
|
||||
if(global.currentContract.exportedFunctions[i].functionName == funPos){
|
||||
funNode = global.currentContract.exportedFunctions[i];
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
console.log(funNode);
|
||||
for (const anno of funNode.annotations) {
|
||||
if (anno.type === "Description") {
|
||||
descriptionSpan.value = JSON.parse(anno.args[0]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function fillResultInternal(result, data) {
|
||||
if (global.responseCollector[data.responseID]==undefined){
|
||||
global.responseCollector[data.responseID]=[];
|
||||
const reqIDSpan = $("#reqIDSpan");
|
||||
reqIDSpan.append("<option value='" + data.responseID + "'>" + data.responseID + "</option>");
|
||||
reqIDSpan[0].value = data.responseID;
|
||||
}
|
||||
global.responseCollector[data.responseID].push(data);
|
||||
$("#statusSpan")[0].innerHTML = result.status;
|
||||
$("#timeSpan")[0].innerHTML = "调用耗时:" + data.executeTime + "(ms)";
|
||||
if (result.result instanceof Object){
|
||||
$("#responseArea")[0].value = JSON.stringify(result.result);
|
||||
$("#timeSpan")[0].innerHTML +="<br> JSON格式";
|
||||
}else{
|
||||
$("#timeSpan")[0].innerHTML +="<br> 字符串格式";
|
||||
$("#responseArea")[0].value = result.result;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
function parseMainFrame(data) {
|
||||
console.log("parseMainFrame");
|
||||
console.log(data);
|
||||
const mainHtml = data.result;
|
||||
executeCurrentContract("loadResource", mainHtml, loadMain);
|
||||
}
|
||||
|
||||
function loadMain(data) {
|
||||
const html = data.result;
|
||||
$("#mainDiv").append(html);
|
||||
setTimeout(function () {
|
||||
console.log("listSize:");
|
||||
const scriptList = $("#mainDiv script");
|
||||
global.scriptList = [];
|
||||
global.scriptOrder = 0;
|
||||
console.log("listSize:" + scriptList.length);
|
||||
for (var i=0;i<scriptList.length;i++) {
|
||||
const script = scriptList[i];
|
||||
const re = script.getAttribute("fromContract");
|
||||
if (!re) {
|
||||
continue;
|
||||
}
|
||||
global.scriptList.push(re);
|
||||
}
|
||||
if (global.scriptList.length > 0) {
|
||||
executeCurrentContract("loadResource", global.scriptList[0], loadScript);
|
||||
}
|
||||
const linkList = $("#mainDiv link");
|
||||
for (var i=0; i<linkList.length;i++) {
|
||||
const link = linkList[i];
|
||||
const re = link.getAttribute("fromContract");
|
||||
executeCurrentContract("loadResource", re, loadCss);
|
||||
}
|
||||
}, 100);
|
||||
}
|
||||
|
||||
function loadScript(data) {
|
||||
console.log("loadScript");
|
||||
global.lastScript = data;
|
||||
setTimeout(eval, 1, global.lastScript.result);
|
||||
global.scriptOrder++;
|
||||
if (global.scriptOrder < global.scriptList.length) {
|
||||
executeCurrentContract("loadResource", global.scriptList[global.scriptOrder], loadScript);
|
||||
}
|
||||
}
|
||||
|
||||
function loadCss(data) {
|
||||
console.log("loadScript");
|
||||
global.lastCss = data;
|
||||
const ele = document.createElement("style");
|
||||
ele.setAttribute("type", "text/css");
|
||||
ele.innerHTML = data.result;
|
||||
document.body.append(ele);
|
||||
}
|
||||
|
||||
function needRender(con) {
|
||||
for (const fun of con.exportedFunctions) {
|
||||
console.log(fun);
|
||||
if (fun.functionName === "needRender") {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
function onListContractProcess(data) {
|
||||
console.log(data);
|
||||
console.log(data.data);
|
||||
global.contracts = JSON.parse(data.data);
|
||||
if (global.urlparam["contract"]) {
|
||||
appendTargetContract(global.urlparam["contract"]);
|
||||
} else {
|
||||
renewList();
|
||||
}
|
||||
}
|
||||
|
||||
function renewList() {
|
||||
const selectedContract = $("#selectContract");
|
||||
selectedContract.html("");
|
||||
selectedContract.append("<option value='-1'>选择合约</option>");
|
||||
let selectValue = -1;
|
||||
console.log(global.contracts);
|
||||
console.log(global.contracts.length);
|
||||
for (let i = 0; i < global.contracts.length; ++i) {
|
||||
const c = global.contracts[i];
|
||||
console.log(c);
|
||||
if (!c.id) {
|
||||
c.id = c.contractID;
|
||||
}
|
||||
if (!c.name) {
|
||||
c.name = c.contractName;
|
||||
}
|
||||
selectedContract.append(`<option value='${i}'>${c.name}</option>`);
|
||||
if (global.urlparam["contract"]) {
|
||||
if (global.urlparam["contract"] === c.name
|
||||
|| global.urlparam["contract"] === c.id) {
|
||||
selectValue = i;
|
||||
}
|
||||
}
|
||||
}
|
||||
console.log(selectValue);
|
||||
selectedContract[0].value = selectValue;
|
||||
if (global.urlparam["contract"]) {
|
||||
changeApp();
|
||||
}
|
||||
}
|
||||
|
||||
function appendTargetContract(target) {
|
||||
global.wssocket.send(JSON.stringify({
|
||||
action: "listTheContractProcess",
|
||||
contractID: target
|
||||
}));
|
||||
}
|
||||
|
||||
function onListTheContractProcess(target) {
|
||||
console.log(target);
|
||||
const c = JSON.parse(target.data);
|
||||
let hasTheSame = false;
|
||||
if (!global.contracts) {
|
||||
global.contracts = [];
|
||||
}
|
||||
for (const con of global.contracts) {
|
||||
if (con.id === c.id) {
|
||||
hasTheSame = true;
|
||||
}
|
||||
}
|
||||
if (!hasTheSame) {
|
||||
global.contracts.push(c);
|
||||
}
|
||||
renewList();
|
||||
//"884422533"
|
||||
}
|
||||
|
||||
function onListLocalNodeLog(data) {
|
||||
const userManTab = $("#v-pills-userManager-tab")[0];
|
||||
if (userManTab.getAttribute("aria-selected") === "true") {
|
||||
drawUserActivityGraph(data);
|
||||
} else {
|
||||
drawLocalLogGraphs(data);
|
||||
}
|
||||
}
|
||||
|
||||
function onListAllAuthRole(data) {
|
||||
console.log("onListAllAuthRole");
|
||||
fillAuthRoleData(data.data);
|
||||
}
|
||||
|
||||
function onListUnAuthRole(data) {
|
||||
console.log("onListUnAuthRole");
|
||||
fillUnAuthRoleData(data.data);
|
||||
}
|
||||
|
||||
function onApplyNet(data) {
|
||||
console.log("onApplyNet");
|
||||
}
|
||||
|
||||
function onCountRole(data) {
|
||||
console.log("onCountRole");
|
||||
setUserTypeDistribution(data.data);
|
||||
}
|
||||
|
||||
function onAuthNodeRole(data) {
|
||||
myToast("授权/忽略操作", data.data);
|
||||
if (data.data === "success") {
|
||||
global.wssocket.send(JSON.stringify({action: "listAllAuthRole"}));
|
||||
global.wssocket.send(JSON.stringify({action: "listUnAuthRole"}));
|
||||
}
|
||||
}
|
||||
|
||||
function onApplyRole(data) {
|
||||
console.log(data.data);
|
||||
myToast("申请操作", data.data);
|
||||
}
|
||||
|
||||
function onDeleteRole(data) {
|
||||
myToast("删除操作", data.data);
|
||||
global.wssocket.send(JSON.stringify({action: "listAllAuthRole"}));
|
||||
}
|
||||
|
||||
// ====== wsHandler done!
|
||||
|
||||
function myToast(title, msg) {
|
||||
toastVue.toastTitle = title;
|
||||
toastVue.toastMessage = msg;
|
||||
$("#alertDiv").toast("show");
|
||||
}
|
||||
|
||||
function countChar(str, c) {
|
||||
let ret = 0;
|
||||
for (const ch of str) {
|
||||
if (ch === c) {
|
||||
ret++;
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
function generate() {
|
||||
const key = sm2.generateKeyPairHex();
|
||||
global.sm2Key = key;
|
||||
localStorage.setItem("PrivKey", JSON.stringify(key));
|
||||
}
|
||||
|
||||
function killAllContract() {
|
||||
global.wssocket.send(JSON.stringify({action: "killAllContract"}));
|
||||
}
|
||||
|
||||
function init() {
|
||||
initVue();
|
||||
|
||||
initGlobal();
|
||||
global.urlparam = getRequestParameters();
|
||||
|
||||
if (global.urlparam["noRender"] === "true") {
|
||||
switchRenderBtn.innerHTML = "加载界面";
|
||||
}
|
||||
global.cbs = {};
|
||||
|
||||
const urlInput = $("#urlInput");
|
||||
if (global.urlparam["self"] === "true") {
|
||||
if (document.location.href.startsWith("http")) {
|
||||
let path = document.location.origin + document.location.pathname;
|
||||
path = path.replace("/client/bdwareclient.html", "");
|
||||
urlInput[0].value = path.replace("http",
|
||||
"ws");
|
||||
if (global.urlparam["withNodeCenterWS"] === "true") {
|
||||
urlInput[0].value += "/NodeCenterWS";
|
||||
}
|
||||
connectNode();
|
||||
}
|
||||
} else if (global.urlparam["nodeAddr"]) {
|
||||
urlInput[0].value = global.urlparam["nodeAddr"];
|
||||
connectNode();
|
||||
} else {
|
||||
const lastNode = localStorage.getItem("lastNode");
|
||||
if (lastNode) {
|
||||
urlInput[0].value = lastNode;
|
||||
connectNode();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function connectNode() {
|
||||
localStorage.setItem("lastNode", $("#urlInput")[0].value);
|
||||
initWSocket();
|
||||
}
|
||||
|
||||
function getRequestParameters() {
|
||||
const arr = (location.search || "").replace(/^\?/, '').split("&");
|
||||
const params = {};
|
||||
for (const a of arr) {
|
||||
const data = a.split("=");
|
||||
if (data.length === 2) {
|
||||
params[data[0]] = data[1];
|
||||
}
|
||||
}
|
||||
return params;
|
||||
}
|
||||
|
||||
function changeRender() {
|
||||
if (global.urlparam["noRender"] === "true") {
|
||||
global.urlparam["noRender"] = undefined;
|
||||
switchRenderBtn.innerHTML = "不加载界面";
|
||||
} else {
|
||||
global.urlparam["noRender"] = "true";
|
||||
switchRenderBtn.innerHTML = "加载界面";
|
||||
}
|
||||
changeApp();
|
||||
}
|
7
js/bootstrap.min.js
vendored
Normal file
7
js/bootstrap.min.js
vendored
Normal file
File diff suppressed because one or more lines are too long
229
js/commonutil.js
Normal file
229
js/commonutil.js
Normal file
@ -0,0 +1,229 @@
|
||||
var getDateDaysBefore = function(daysAgo) {
|
||||
var dateStr = new Date().toISOString().substring(0, 10);
|
||||
var ret = new Date(dateStr).getTime() - daysAgo * 24 * 3600 * 1000;
|
||||
return ret;
|
||||
};
|
||||
var primaryColor = "#2E324C";
|
||||
|
||||
// ======Vue start
|
||||
var headerVue = "";
|
||||
var pubkeyDialogVue = "";
|
||||
var mainVue = "";
|
||||
|
||||
var select = "";
|
||||
var initVue = function() {
|
||||
console.log("[nodePortal.js] initVue : ");
|
||||
headerVue = new Vue({
|
||||
el : 'header',
|
||||
data : {
|
||||
shortName : "00000"
|
||||
}
|
||||
});
|
||||
pubkeyDialogVue = new Vue({
|
||||
el : '#pubkeyDialog',
|
||||
data : {
|
||||
sm2KeyStr : "00000",
|
||||
myRole : "匿名用户",
|
||||
test:"0",
|
||||
selectedSM2Key:"0",
|
||||
productList:[{id:0,title:"ContractProvider"},{id:1,title:"ContractUser"},{id:2,title:"ContractInstanceManager"}],
|
||||
sm2KeyList:[]
|
||||
},
|
||||
methods : {
|
||||
importPubkey : function() {
|
||||
console.log("importkey trigged");
|
||||
try {
|
||||
var sm2Key = JSON.parse(this.sm2KeyStr);
|
||||
if (sm2Key.publicKey == undefined
|
||||
|| sm2Key.privateKey == undefined) {
|
||||
this.sm2KeyStr = (JSON.stringify(global.sm2Key));
|
||||
} else {
|
||||
global.sm2Key = sm2Key;
|
||||
localStorage.setItem("PrivKey", JSON
|
||||
.stringify(sm2Key));
|
||||
headerVue.shortName = global.sm2Key.publicKey
|
||||
.substr(0, 5);
|
||||
var newKey = {};
|
||||
newKey.id = this.sm2KeyList.length;
|
||||
newKey.title = headerVue.shortName;
|
||||
newKey.sm2Key = this.sm2KeyStr;
|
||||
this.sm2KeyList.push(newKey);
|
||||
localStorage.setItem("PrivKeyList",JSON.stringify(this.sm2KeyList));
|
||||
|
||||
getSession();
|
||||
listProjects("priv");
|
||||
}
|
||||
} catch (e) {
|
||||
console.log(e);
|
||||
this.sm2KeyStr = (JSON.stringify(global.sm2Key));
|
||||
}
|
||||
},
|
||||
generatePubkey : function() {
|
||||
console.log("generate pubkey trigged");
|
||||
var sm2Key = sm2.generateKeyPairHex();
|
||||
this.sm2KeyStr = JSON.stringify(sm2Key);
|
||||
global.sm2Key = sm2Key;
|
||||
localStorage.setItem("PrivKey", JSON
|
||||
.stringify(sm2Key));
|
||||
headerVue.shortName = global.sm2Key.publicKey
|
||||
.substr(0, 5);
|
||||
var newKey = {};
|
||||
newKey.id = this.sm2KeyList.length;
|
||||
newKey.title = headerVue.shortName;
|
||||
newKey.sm2Key = this.sm2KeyStr;
|
||||
this.sm2KeyList.push(newKey);
|
||||
this.selectedSM2Key = newKey.id;
|
||||
localStorage.setItem("PrivKeyList",JSON.stringify(this.sm2KeyList));
|
||||
getSession();
|
||||
},
|
||||
changeProduct(event) {
|
||||
this.test = event.target.value; // 获取option对应的value值
|
||||
this.role = this.productList[this.test].title;
|
||||
console.log("选了",this.role);
|
||||
global.role=this.role;
|
||||
},
|
||||
apply : function() {
|
||||
console.log("apply");
|
||||
global.wssocket
|
||||
.send("{\"action\":\"applyNet\",\"role\":\"NodeManager\"}");
|
||||
|
||||
},
|
||||
applyRole : function() {
|
||||
var role=this.productList[this.test];
|
||||
console.log("applyRole, "+role);
|
||||
applyRole(role.title);
|
||||
|
||||
},changeSM2Key:function(event){
|
||||
var order = event.target.value; // 获取option对应的value值
|
||||
if (order == undefined)
|
||||
return;
|
||||
console.log("changeSM2Key, -->"+order);
|
||||
headerVue.shortName = this.sm2KeyList[order].title;
|
||||
this.selectedSM2Key = order;
|
||||
this.sm2KeyStr = this.sm2KeyList[order].sm2Key;
|
||||
global.sm2Key = JSON.parse(this.sm2KeyStr);
|
||||
localStorage.setItem("PrivKey", this.sm2KeyStr);
|
||||
getSession();
|
||||
},deletePubkey:function(event){
|
||||
var order = this.selectedSM2Key;
|
||||
var obj = this.sm2KeyList[order];
|
||||
if (this.sm2KeyList.length==1){
|
||||
alert("最后一对密钥不可以删除");
|
||||
return;
|
||||
}
|
||||
var newList = [];
|
||||
for (var i=0;i<order;i++){
|
||||
newList.push(this.sm2KeyList[i]);
|
||||
};
|
||||
for (var i=order/1 +1;i<this.sm2KeyList.length;i++){
|
||||
newList.push(this.sm2KeyList[i]);
|
||||
};
|
||||
this.sm2KeyList = newList;
|
||||
for (var i=0;i<newList.length;i++){
|
||||
newList[i].id = i;
|
||||
}
|
||||
if (order>=newList.length){
|
||||
order --;
|
||||
}
|
||||
console.log("after delete, size:"+newList.length+" order:"+order);
|
||||
localStorage.setItem("PrivKeyList", JSON.stringify(newList));
|
||||
headerVue.shortName = this.sm2KeyList[order].title;
|
||||
this.selectedSM2Key = order + "";
|
||||
this.sm2KeyStr = this.sm2KeyList[order].sm2Key;
|
||||
global.sm2Key = JSON.parse(this.sm2KeyStr);
|
||||
localStorage.setItem("PrivKey", this.sm2KeyStr);
|
||||
getSession();
|
||||
},exportPubkey : function(event){
|
||||
var uri = "data:text/html,";
|
||||
uri+=localStorage.getItem("PrivKeyList");
|
||||
var link = document.createElement("a");
|
||||
link.download = "sm2keyList.json";
|
||||
link.href = uri;
|
||||
document.body.appendChild(link);
|
||||
link.click();
|
||||
document.body.removeChild(link);
|
||||
delete link;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
});
|
||||
|
||||
mainVue = new Vue({
|
||||
el : "#main",
|
||||
data : {
|
||||
licenceDueDate : "已过期",
|
||||
licenceNodes : 0,
|
||||
offlineLicence : undefined,
|
||||
licenceRemark : undefined,
|
||||
userCount:".",
|
||||
contractCount:".",
|
||||
nodeCount:".",
|
||||
eventCount:".",
|
||||
unitCount:".",
|
||||
pubDialogVue:{},
|
||||
projects:[],
|
||||
contracts:[],
|
||||
contractFunctions:[],
|
||||
openedFiles:[{
|
||||
isDir: false,
|
||||
val: "Please Checkout code from left side!",
|
||||
path: "Hello",
|
||||
name: "Hello"
|
||||
}]
|
||||
|
||||
}
|
||||
});
|
||||
|
||||
};
|
||||
// ======Vue done
|
||||
|
||||
var initGlobal = function() {
|
||||
if (window.global==undefined){
|
||||
window.global = {};
|
||||
}
|
||||
global.sm2Key = localStorage.getItem("PrivKey");
|
||||
global.result = "";
|
||||
if (global.sm2Key == undefined || global.sm2Key == null
|
||||
|| global.sm2Key.length < 100) {
|
||||
generate();
|
||||
} else {
|
||||
global.sm2Key = JSON.parse(global.sm2Key);
|
||||
}
|
||||
headerVue.shortName = global.sm2Key.publicKey.substr(0, 5);
|
||||
pubkeyDialogVue.sm2KeyStr = JSON.stringify(global.sm2Key);
|
||||
mainVue.pubDialogVue = pubkeyDialogVue;
|
||||
var keyListStr = localStorage.getItem("PrivKeyList");
|
||||
if (keyListStr==undefined){
|
||||
var keyObj = {};
|
||||
keyObj.id = 0;
|
||||
keyObj.title = headerVue.shortName;
|
||||
keyObj.sm2Key = pubkeyDialogVue.sm2KeyStr;
|
||||
pubkeyDialogVue.sm2KeyList = [];
|
||||
pubkeyDialogVue.sm2KeyList.push(keyObj);
|
||||
pubkeyDialogVue.selectedSM2Key = 0;
|
||||
// mainVue.sm2KeyList = pubkeyDialogVue.sm2KeyList;
|
||||
// mainVue.selectedSM2Key = 0;
|
||||
} else{
|
||||
pubkeyDialogVue.sm2KeyList = JSON.parse(keyListStr);
|
||||
pubkeyDialogVue.selectedSM2Key = -1;
|
||||
for (var i=0;i<pubkeyDialogVue.sm2KeyList.length;i++){
|
||||
var obj = pubkeyDialogVue.sm2KeyList[i];
|
||||
if (obj.sm2Key==pubkeyDialogVue.sm2KeyStr){
|
||||
pubkeyDialogVue.selectedSM2Key = i;
|
||||
// mainVue.sm2KeyList = pubkeyDialogVue.sm2KeyList;
|
||||
// mainVue.selectedSM2Key = pubkeyDialogVue.selectedSM2Key;
|
||||
return;
|
||||
}
|
||||
}
|
||||
var keyObj = {};
|
||||
keyObj.id = pubkeyDialogVue.sm2KeyList.length;
|
||||
keyObj.title = headerVue.shortName;
|
||||
keyObj.sm2Key = pubkeyDialogVue.sm2KeyStr;
|
||||
pubkeyDialogVue.sm2KeyList.push(keyObj);
|
||||
pubkeyDialogVue.selectedSM2Key = keyObj.id;
|
||||
// mainVue.sm2KeyList = pubkeyDialogVue.sm2KeyList;
|
||||
// mainVue.selectedSM2Key = pubkeyDialogVue.selectedSM2Key;
|
||||
|
||||
}
|
||||
}
|
256
js/createWS.js
Normal file
256
js/createWS.js
Normal file
@ -0,0 +1,256 @@
|
||||
var createWssocket = function(wsurl, onopen, handler) {
|
||||
console.log("[createWS.js] createWssocket : " + wsurl);
|
||||
var retsocket = {};
|
||||
retsocket.handlerList = [];
|
||||
if (handler != undefined)
|
||||
retsocket.handlerList.push(handler);
|
||||
var wssocket = new WebSocket(wsurl);
|
||||
wssocket.onerror = function(error) {
|
||||
console.log(error);
|
||||
};
|
||||
|
||||
wssocket.onopen = onopen;
|
||||
var onmessage = function(event) {
|
||||
var obj = JSON.parse(event.data);
|
||||
switch (obj.action) {
|
||||
case 'sendNextSegment':
|
||||
retsocket.sendNextSegment();
|
||||
break;
|
||||
case 'sendSeg':
|
||||
retsocket.receiveSeg(obj);
|
||||
break;
|
||||
default:
|
||||
for (var i = 0; i < retsocket.handlerList.length; i++) {
|
||||
var h = retsocket.handlerList[i];
|
||||
h(event, wssocket);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
var reconnect = function(error) {
|
||||
setTimeout(function() {
|
||||
console.log("[createWS.js] try to reconnect");
|
||||
wssocket = new WebSocket(wsurl);
|
||||
wssocket.onclose = reconnect;
|
||||
wssocket.onmessage = onmessage;
|
||||
wssocket.onopen = onopen;
|
||||
}, 1000);
|
||||
};
|
||||
wssocket.onclose = reconnect;
|
||||
|
||||
retsocket.receiveSeg = function(obj) {
|
||||
if (obj.cid == 'start') {
|
||||
retsocket.toReceive = "";
|
||||
}
|
||||
retsocket.toReceive += obj.data;
|
||||
if (obj.cid == 'done') {
|
||||
console.log("[receiveSeg] Received AllData:" + retsocket.toReceive);
|
||||
var event = {};
|
||||
event.data = retsocket.toReceive;
|
||||
retsocket.toReceive = "";
|
||||
handler(event);
|
||||
}
|
||||
};
|
||||
wssocket.onmessage = onmessage;
|
||||
|
||||
retsocket.isSending = false;
|
||||
retsocket.sendList = [];
|
||||
retsocket.monitor = function() {
|
||||
if (!retsocket.isSending) {
|
||||
if (retsocket.sendList.length > 0) {
|
||||
retsocket.send(retsocket.sendList.pop());
|
||||
}
|
||||
}
|
||||
setTimeout(retsocket.monitor, 1000);
|
||||
};
|
||||
// TODO: we don't need monitor at all?
|
||||
retsocket.monitor();
|
||||
retsocket.send = function(str) {
|
||||
if (retsocket.isSending) {
|
||||
retsocket.sendList.push(str);
|
||||
return;
|
||||
}
|
||||
if (str.length > 1024) {
|
||||
retsocket.isSending = true;
|
||||
retsocket.toSend = str.substr(1024);
|
||||
var obj = {};
|
||||
obj.isSegment = true;
|
||||
obj.data = str.substr(0, 1024);
|
||||
wssocket.send(JSON.stringify(obj));
|
||||
} else
|
||||
wssocket.send(str);
|
||||
};
|
||||
retsocket.sendNextSegment = function() {
|
||||
var str = retsocket.toSend;
|
||||
if (str.length > 1024) {
|
||||
retsocket.toSend = str.substr(1024);
|
||||
var obj = {};
|
||||
obj.isSegment = true;
|
||||
obj.data = str.substr(0, 1024);
|
||||
wssocket.send(JSON.stringify(obj));
|
||||
} else {
|
||||
retsocket.toSend = "";
|
||||
var obj = {};
|
||||
obj.isSegment = false;
|
||||
obj.data = str;
|
||||
wssocket.send(JSON.stringify(obj));
|
||||
retsocket.isSending = false;
|
||||
if (retsocket.sendList.length > 0) {
|
||||
retsocket.send(retsocket.sendList.pop());
|
||||
}
|
||||
}
|
||||
};
|
||||
retsocket.isOpen = function() {
|
||||
return wssocket.readyState;
|
||||
}
|
||||
retsocket.addHandler = function(handler) {
|
||||
retsocket.handlerList.push(handler);
|
||||
}
|
||||
return retsocket;
|
||||
};
|
||||
|
||||
var aesDecrypt = function(data) {
|
||||
data = cryptico.b64to256(data);
|
||||
var encryptedBlocks = cryptico.string2bytes(data);
|
||||
var exkey = global.aesKey.slice(0);
|
||||
aes.ExpandKey(exkey);
|
||||
aes.Decrypt(encryptedBlocks, exkey);
|
||||
return cryptico.bytes2string(encryptedBlocks);
|
||||
|
||||
};
|
||||
var aesEncrypt = function(data, aesKey) {
|
||||
var key = aesKey;
|
||||
var exkey = key.slice(0);
|
||||
aes.ExpandKey(exkey);
|
||||
var blocks = my.string2bytes(data);
|
||||
blocks = my.pad16(blocks);
|
||||
aes.Encrypt(blocks, exkey);
|
||||
ciphertext = cryptico.bytes2string(blocks);
|
||||
ciphertext = cryptico.b256to64(ciphertext);
|
||||
return ciphertext;
|
||||
};
|
||||
var rsaEncrypt = function(data, rsaKey) {
|
||||
var rsa = new RSAKey();
|
||||
rsa.setPublic(rsaKey.n, rsaKey.e1);
|
||||
var result = rsa.encrypt(data);
|
||||
return result;
|
||||
};
|
||||
var loadRSAKey = function(rsaKey) {
|
||||
var str = cryptico.b64to256(rsaKey);
|
||||
str = str.split(",");
|
||||
var ret = {};
|
||||
ret.n = str[0];
|
||||
ret.e1 = str[1];
|
||||
ret.e2 = str[2];
|
||||
return ret;
|
||||
};
|
||||
var testRSA = function() {
|
||||
pubKey = loadRSAKey(global.privKey);
|
||||
reqContent = {};
|
||||
reqContent.action = "main";
|
||||
reqContent.arg = "[{\"score\":20},{\"score\":20}]";
|
||||
reqContent.contractID = "abc";
|
||||
eReq = encryptReq(reqContent, pubKey);
|
||||
url = "http://localhost:8080/SCIDE/SCManager?action=executeContractEncrypted&contractRequest="
|
||||
+ encodeURIComponent(JSON.stringify(eReq));
|
||||
};
|
||||
|
||||
var encryptReq = function(reqContent, pubKey) {
|
||||
// global.pubKey = loadRSAKey(global.privKey);
|
||||
var aes = {};
|
||||
aes.key = cryptico.generateAESKey();
|
||||
var aesObj = JSON.stringify(aes);
|
||||
var rsa = new RSAKey();
|
||||
rsa.setPrivate(pubKey.n, pubKey.e1, pubKey.e2);
|
||||
var encrypedReq = {};
|
||||
encrypedReq.action = rsa.decrypt(aesObj);
|
||||
encrypedReq.contractID = reqContent.contractID;
|
||||
reqContent.contractID = undefined;
|
||||
encrypedReq.arg = JSON.stringify(reqContent);
|
||||
encrypedReq.arg = aesEncrypt(encrypedReq.arg, aes.key);
|
||||
encrypedReq.requester = pubKey.n + "," + pubKey.e1 + "," + "0";
|
||||
encrypedReq.requester = cryptico.b256to64(encrypedReq.requester);
|
||||
return encrypedReq;
|
||||
};
|
||||
|
||||
var onExecuteResultInternal = function(data) {
|
||||
console.log(data);
|
||||
global.executeResult = data;
|
||||
var reqId = data.responseID;
|
||||
var callback = global.cbs[data.responseID];
|
||||
if (callback != undefined) {
|
||||
callback(global.executeResult, data);
|
||||
}
|
||||
};
|
||||
window.executeContract = function(contractID, method, strarg, cb) {
|
||||
var sm2Key = global.sm2Key;
|
||||
var request = {};
|
||||
request.action = "executeContract";
|
||||
request.requestID = new Date().getTime() + "_"
|
||||
+ Math.floor(Math.random() * 10000);
|
||||
|
||||
global.cbs[request.requestID] = cb;
|
||||
request.contractID = contractID;
|
||||
request.operation=method;
|
||||
request.arg = strarg;
|
||||
|
||||
if (sm2Key != undefined) {
|
||||
request.pubkey = sm2Key.publicKey;
|
||||
request.signature = sm2.doSignature(request.contractID + "|"
|
||||
+ method + "|" + strarg + "|" + sm2Key.publicKey,
|
||||
sm2Key.privateKey,{hash:true,der:true});
|
||||
}
|
||||
|
||||
global.wssocket.send(JSON.stringify(request));
|
||||
};
|
||||
|
||||
window.executeCurrentContract = function(method, strarg, cb) {
|
||||
console.log("executeCurrentContract");
|
||||
var contract = global.currentContract;
|
||||
executeContract(contract.id, method, strarg, cb);
|
||||
};
|
||||
|
||||
|
||||
window.loadBDWareWebSDK = function(url, onopen, handler) {
|
||||
if (window.global == undefined) {
|
||||
window.global = {};
|
||||
}
|
||||
if (global.sm2Key == undefined) {
|
||||
if (sm2 != undefined)
|
||||
global.sm2Key = sm2.generateKeyPairHex();
|
||||
}
|
||||
if (global.cbs == undefined) {
|
||||
global.cbs = {};
|
||||
}
|
||||
if (global.wssocket == undefined) {
|
||||
global.wssocket = createWssocket(url, onopen, function(event, wss) {
|
||||
var data = event.data;
|
||||
var obj = JSON.parse(data);
|
||||
switch (obj.action) {
|
||||
case 'onExecuteResult':
|
||||
onExecuteResultInternal(obj);
|
||||
default:
|
||||
}
|
||||
handler(event, global.wssocket);
|
||||
});
|
||||
} else {
|
||||
if (onopen != undefined)
|
||||
onopen();
|
||||
global.wssocket.addHandler(handler);
|
||||
}
|
||||
};
|
||||
// Usage:
|
||||
// Approach 1:
|
||||
// var url = "ws://" +
|
||||
// document.location.host+(document.location.pathname.replace("scide.html",
|
||||
// "SCExecutor"));
|
||||
// global.wssocket = createWssocket(url, WSHandler);
|
||||
|
||||
// Approach 2:
|
||||
// loadBDWareWebSDK(url,function(){},WSHandler);
|
||||
// global.currentContract = {'id':'DataAnalysisSample'};
|
||||
// executeContract("contractID","methodName","arg",function(data){
|
||||
// });
|
||||
// executeCurrentContract("methodName","arg",function(data){
|
||||
// });
|
||||
// the bdware client won't call this method
|
3560
js/cryptico.js
Normal file
3560
js/cryptico.js
Normal file
File diff suppressed because it is too large
Load Diff
9210
js/jquery-2.1.4.js
vendored
Normal file
9210
js/jquery-2.1.4.js
vendored
Normal file
File diff suppressed because it is too large
Load Diff
Loading…
Reference in New Issue
Block a user