import { IOTAList, SignedTX, CommandType } from "./IOTAList"; import { RsaKeypair } from "../RsaKeypair"; export interface DataSource extends SignedTX { externalURL : string } export class SourceList extends IOTAList { private DataSources : DataSource[]; constructor(address : string, provider : string) { super(address, provider); } //Query PermissionList public QuerySourceList(address : string = this.address) : Promise { return new Promise((resolve, reject) => { this.DataSources = []; this.GetTransactionsFromAddress(address) .then((msgs) => { //Loop through all the permission messages on the address for(let i=0; i < msgs.length; i++) { //TODO: Verify that the tx actually follows the correct layout msgs[i] = msgs[i].slice(0,msgs[i].lastIndexOf("}")+1); let msg = JSON.parse(msgs[i]); msg.signedByUUID = msg.signedByUUID.slice(msg.signedByUUID.lastIndexOf(":")+1); //let permissionMessage : Permission = JSON.parse(msgs[i]); //Follow the command if(msg.commandType == CommandType.add) { //Add or overwrite the permission this.DataSources.push(msg); } else if(msg.commandType == CommandType.retract) { //Only remove a permission if it was there. for(let i=0; i< this.DataSources.length;i++) { if(this.DataSources[i].signedByUUID == msg.signedByUUID) { this.DataSources.splice(i,1); break; } } } } resolve(true); }) .catch((error) => { reject(error); }) }) } //Add an external source public AddDataSource(UUIDIssuer : string, externalURL : string, publicKeyId : string, privateKey : string) : Promise { return new Promise ((resolve, reject) => { //TODO: Verify that you have the right to add data sources //TODO: Check private key - public key signature match //Sign the transaction let keypair : RsaKeypair = new RsaKeypair(undefined, privateKey); let currentTimeStamp = Date.now(); let Signature = keypair.Sign(UUIDIssuer + publicKeyId + currentTimeStamp) //Create the Transactions let newDataSource : DataSource = { commandType : CommandType.add, externalURL : externalURL, signedByUUID : UUIDIssuer, publicKey : publicKeyId, time : currentTimeStamp, signature : Signature } //Put the TX on IOTA this.AddTransactionToAddress(JSON.stringify(newDataSource)) .then((isPosted) => { resolve(isPosted); }) .catch((error) => { reject(error); }); }); } public RemoveDataSource(UUIDIssuer : string, publicKeyId : string, privateKey : string ) : Promise { return new Promise((resolve, reject) => { //TODO: Verify that UUID published the DataSource or that the //Sign the transaction let keypair : RsaKeypair = new RsaKeypair(undefined, privateKey); let currentTimeStamp = Date.now(); let Signature = keypair.Sign(UUIDIssuer + publicKeyId + currentTimeStamp) //Create the Transactions let removeDataSource : DataSource = { commandType : CommandType.retract, externalURL : "", signedByUUID : UUIDIssuer, publicKey : publicKeyId, time : currentTimeStamp, signature : Signature } //Put the TX on IOTA this.AddTransactionToAddress(JSON.stringify(removeDataSource)) .then((isPosted) => { resolve(isPosted); }) .catch((error) => { reject(error); }); }); } public GetExternalSource( UUID : string) : Promise { return new Promise ((resolve, reject) => { //TODO: Verify the chain of permissions for(let i=this.DataSources.length-1; i>=0; i--) { if(this.DataSources[i].signedByUUID == UUID) { let source : DataSource = this.DataSources[i]; this.ValidateSignature(source.signedByUUID, source.publicKey, source.time, source.signature) .then((isVerified : boolean) => { resolve(isVerified?source.externalURL:null); }) .catch((error) => { reject(error); }); return; } } //Return no source resolve(null); }); } }