@activeledger/activeprotocol
Version:
Underlying protocol which handles consensus and the smart contract virtual machine of Activeledger
240 lines • 9.96 kB
JavaScript
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.PermissionsChecker = void 0;
const activedefinitions_1 = require("@activeledger/activedefinitions");
class PermissionsChecker {
constructor(entry, db, checkRevs, securityCache, shared) {
this.entry = entry;
this.db = db;
this.checkRevs = checkRevs;
this.securityCache = securityCache;
this.shared = shared;
}
async process(data, inputs = true) {
this.inputs = inputs;
this.data = data;
try {
const streams = await this.buildPromises();
return this.processStreams(streams);
}
catch (error) {
return Promise.reject(error);
}
}
async buildPromises() {
const keys = [];
let contractDataIncluded = false;
for (let i = this.data.length; i--;) {
const filteredPrefix = this.shared.filterPrefix(this.data[i], true);
const suffix = this.data[i].split(":")[1];
contractDataIncluded = suffix === "data";
if (keys.indexOf(filteredPrefix) === -1) {
keys.push(filteredPrefix + ":stream");
keys.push(filteredPrefix);
}
}
try {
const docs = await this.db.allDocs({
keys,
include_docs: true,
});
const reorder = {};
const results = [];
for (let i = docs.rows.length; i--;) {
const baseDoc = docs.rows[i].doc._id.replace(":stream", "");
let iMeta = null;
let iState = null;
if (baseDoc === docs.rows[i].doc._id) {
iState = docs.rows[i].doc;
}
else {
iMeta = docs.rows[i].doc;
if (iMeta.contractlock &&
iMeta.contractlock.length &&
iMeta.contractlock.indexOf(this.entry.$tx.$contract) === -1) {
throw {
code: 1700,
reason: "Stream contract locked",
};
}
if (iMeta.namespaceLock &&
iMeta.namespaceLock.length &&
iMeta.namespaceLock.indexOf(this.entry.$tx.$namespace) === -1) {
throw {
code: 1710,
reason: "Stream namespace locked",
};
}
}
if (!reorder[baseDoc]) {
reorder[baseDoc] = results.push({
state: iState,
meta: iMeta,
});
}
else {
const result = results[reorder[baseDoc] - 1];
if (result.state) {
if (iMeta)
result.meta = iMeta;
}
else {
if (iState)
result.state = iState;
}
}
}
if (contractDataIncluded) {
for (let i = results.length; i--;) {
const sId = results[i].state._id;
if (sId && sId.indexOf(":data")) {
let cRes = results[i];
cRes.meta = {
_id: `${cRes.state._id}:meta`,
_rev: "0-context"
};
results[i] = cRes;
}
}
}
if (results.length === (keys.length / 2)) {
return results;
}
else {
throw {
code: 950,
reason: "Stream(s) not found",
};
}
}
catch (error) {
error.code = 950;
error.reason = "Stream(s) not found";
throw error;
}
}
processStreams(stream) {
return new Promise((resolve, reject) => {
let i = stream.length;
while (i--) {
let streamId = stream[i].state._id;
const revType = this.inputs ? this.entry.$revs.$i : this.entry.$revs.$o;
const currentRevision = stream[i].meta._rev + ":" + stream[i].state._rev;
if (revType && revType[streamId]) {
if (revType[streamId] !== currentRevision) {
return reject({
code: 1200,
reason: (this.inputs ? "Input" : "Output") +
" Stream Position Incorrect",
});
}
}
else {
revType[streamId] = currentRevision;
}
if (this.inputs || this.securityCache.signedOutputs) {
let nhpkCheck = false;
let nhpkCheckIO = this.inputs ? this.entry.$tx.$i : this.entry.$tx.$o;
if (this.securityCache.hardenedKeys) {
const nhpkDataCheck = nhpkCheckIO[this.shared.getLabelIOMap(this.inputs, streamId)]
.$nhpk;
if (!nhpkDataCheck) {
return reject({
code: 1230,
reason: (this.inputs ? "Inputs" : "Output") +
" Security Hardened Key Transactions Only",
});
}
else {
nhpkCheck = true;
}
}
if (stream[i].meta.authorities) {
this.signatureCheck(streamId, stream[i], nhpkCheck, nhpkCheckIO, reject);
}
else {
const type = stream[i].meta.type ? stream[i].meta.type : "rsa";
const sigCheck = this.shared.signatureCheck(stream[i].meta.public, this.entry.$sigs[this.shared.filterPrefix(streamId)], type);
if (!sigCheck) {
return reject({
code: 1220,
reason: (this.inputs ? "Input" : "Output") + " Signature Incorrect",
});
}
}
}
}
resolve(stream);
});
}
signatureCheck(streamId, stream, nhpkCheck, nhpkCheckIO, reject) {
const sigCheck = (authority) => this.shared.signatureCheck(authority.public, this.entry.$sigs[this.shared.filterPrefix(streamId)], authority.type);
const isLedgerAuthSignatures = activedefinitions_1.ActiveDefinitions.LedgerTypeChecks.isLedgerAuthSignatures(this.entry.$sigs[this.shared.filterPrefix(streamId)]);
if (isLedgerAuthSignatures) {
const sigStreamKeys = Object.keys(this.entry.$sigs[this.shared.filterPrefix(streamId)]);
const authorities = stream.meta.authorities.length;
if (sigStreamKeys.length > authorities) {
return reject({
code: 1225,
reason: (this.inputs ? "Input" : "Output") +
" Incorrect Signature List Length",
});
}
const sigCheck = sigStreamKeys.every((sigStream) => {
if (nhpkCheck) {
const nhpk = false;
if (!nhpk) {
return reject({
code: 1230,
reason: (this.inputs ? "Input" : "Output") +
" Security Hardened Key Transactions Only",
});
}
}
else {
const signature = this.entry.$sigs[this.shared.filterPrefix(streamId)][sigStream];
const authCheck = stream.meta.authorities.some((authority) => {
if (authority.hash === sigStream) {
return this.shared.signatureCheck(authority.public, signature, authority.type);
}
else {
return false;
}
});
return authCheck;
}
});
if (!sigCheck) {
}
}
else {
const authorityCheck = stream.meta.authorities.some((authority) => {
const nhpk = nhpkCheckIO[this.shared.getLabelIOMap(this.inputs, streamId)].$nhpk;
if (nhpkCheck && !nhpk) {
return reject({
code: 1230,
reason: (this.inputs ? "Input" : "Output") +
" Security Hardened Key Transactions Only",
});
}
if (authority.hash && sigCheck(authority)) {
this.entry.$sigs[this.shared.filterPrefix(streamId)] = {
[authority.hash]: this.entry.$sigs[this.shared.filterPrefix(streamId)],
};
return true;
}
else {
return false;
}
});
if (!authorityCheck) {
return reject({
code: 1220,
reason: (this.inputs ? "Input" : "Output") + " Signature Incorrect",
});
}
}
}
}
exports.PermissionsChecker = PermissionsChecker;
//# sourceMappingURL=permissionsChecker.js.map