HASH File. how i can get??

Hello, I am trying to get the HASH value of a file. The fact, is that I want, before a user uploads a file, to check that that file has not been previously uploaded.
I have looked in ARAS and the system already saves that value in "checksum" itemtype "file", but it does not do any checking. This entire process is done in the file "xxhash-asm.min.js", which is in innovator\client\vendors.
But the line where it calculates it (line2) is not tabulated and has 132,387 characters, and I am not clear. I have tried other methods, to make myself a method, but it fails on this line: "crypto.subtle.digest('SHA-256' , data).then(function (hashBuffer) {"

Any suggestions, I suppose there must be an easier way to calculate/extract the HASH of a file.

My method:

var innovator = new Innovator();

aras.vault.selectFile().then(function (fileObject) {
  file = fileObject;

  var reader = new FileReader();
  reader.readAsText(file);

  // Aquí calculamos el hash del contenido del archivo
  reader.onload = function (readerEvent) {
    var content = readerEvent.target.result; // Este es el contenido del archivo

    // Calcular el hash del contenido del archivo
    calcularHashDeContenido(content, function (hash) {
      alert('Hash del archivo:', hash);
    });
  };
});

// Función para calcular el hash de un contenido
function calcularHashDeContenido(content, callback) {

  const crypto = window.crypto || window.msCrypto; // Obtener la implementación de crypto
  const encoder = new TextEncoder();
  const data = encoder.encode(content);
alert(1);
  crypto.subtle.digest('SHA-256', data).then(function (hashBuffer) {
alert(2);      
    const hashArray = Array.from(new Uint8Array(hashBuffer));
    const hashHex = hashArray.map(byte => byte.toString(16).padStart(2, '0')).join('');
    callback(hashHex);
  });
}

I see in js files in ARAS Directory, that exist "getFileChecksum(fileName);", but I can't get it to work.

This is in "\Aras\Innovator\Innovator\Client\javascript\Aras\Client\Controls\Public" file Vault.js

Parents
  • Ok, as I thought it was easier than what I was trying.

    With "getFileChecksum" we get the value from the HASH without any problem, but we have to pass the value through a "file object" and I don't know how to pass the filepath through a variable, for example "filename".

    aras.vault.selectFile().then(function(file) {
    	alert( aras.vault.getFileChecksum(file));
    	
    	
        var fileName = "C:\\Users\\fernando.coronil\\Downloads\\Prueba.TXT";
    	alert( aras.vault.getFileChecksum(fileName));
    	
    	});
    

    Line 1-2 works fine.

    Line 5-6 i get an error: "undefined".

    I try too to load the file object in the itemType "Document":

    But nothing. i dont know how i must to get this as an file object. Sob

  • Hi,

    great use case! I tried something similar 7 years ago, but only tried to match names and inform the user that duplicates exists. But I never used the draft.

    It´s true that Innovator doesn´t use the checksum in any way. 

    Where do you trigger your aras.vault.select function? Do you currently only use the Method editor? Or did you overwrite the relationship file selector?

    When your function is just used in a JS Method, the "undefined" error makes sense. You use aras.vault to pick a file. "File" is your fileobject. You use it in the alert to get the checksum. So far everything fine.

    Then you write a path to a local file and use this one to get the checksum. This will not work, at least not in todays world (previous browsers from the 90s had some options...). JS itself cannot read local content automatically. That´s a security constraint. Just imagine every website in the world would have the potential power to read your local desktop content. So JS can only work with files, actively provided by the user with a file picker. 

    There are more flexible upload file options available than the aras.vault selector. But it depends on your overall usecase. At which point of the upload process do you want to do the checksum check? 

  • Hello Angela, thanks to write!!!.

    great use case! I tried something similar 7 years ago, but only tried to match names and inform the user that duplicates exists. But I never used the draft.

    Perfect, if I get it to work I'll leave you the code in case it helps the community.

    It´s true that Innovator doesn´t use the checksum in any way. 

    It is strange, since in the itemtype "Document", there is the checksum attribute, which is in "File" and as foreign in "Document File". The most logical thing, and even more so if there are many users, is that it will control in some way so that duplicate files are not uploaded.

    Right now, in my version of ARAS, when you press the save button "save item", icon of a 3 1/2 floppy disk, from my time, hahaha. ARAS calculates the checksum and saves it. But as I mentioned, he does it in the file "xxhash-asm.min.js", in the line 2, but it is not tabulated and has 132,387 characters, why ARAS???.
    From what I have seen, it does this if a file is added and it is saved, if 2 files are added it does not calculate the checksum, I don't know why!

    We had thought that the verification would be done when the user clicks on saving the Item. Since you can add the file in two ways, adding using the button, or doing a drag and drop in the grid.
    Ideally, if it is through the add button it should not be a problem, since the dialog box appears, but if it is dragged, it should handle the event. ARAS already executes code, since it adds the name of the file.

    If not, then we'll see if we put the check right after saving, to notify the user and edit the line. But ideally it would not be able to save or upload the file.

    Regarding the "limitation" of passing the file path, it is logical and after 2 days and reading a thousand sites I was imagining it. If it weren't like that it would be a waste!!

    Well, I'm going to see how I can take the file from the "Files" grid, if possible, and call getFileChecksum.

    Thank you very much Angela!!!

  • I definitely think some users use the checksum in some way. But so far I haven´t seen Innovator using it. 

    Innovator was not designed to encourage users to "reuse" file. But to be fair, hardly any of the software tools that I know are designed this way. I assume this is some kind of standard that has a reason. But I don´t know. Innovator at least reuses files when a new revision is created. Confluence by Atlassian is much worse. It copies the files on each revision. This will lead to funny results when user embed 8GB videos and then the software counts any minor edit as new revision. 

    I so far haven´t had much problems when reusing files in Innovator. We encourage our users to do it themselves. Only Visual Collaboration couldn´t link reused files in the past. Not sure if it works today, but keep an eye on that if the feature is relevant.

    My Innovator 12 doesn´t have the xxhash-asm. But the "vendors" folder indicate, that it is an external library. Probably this one: https://github.com/Cyan4973/xxHash

    When Aras has replaced this one in the newer versions, I wouldn´t spent too much time to understand this one.

    Here is a very old onInsertRow test Method that I once made: It checks the files as soon as the user drags it to the file relationship. Note the first sentence!! The code is called multiple times when user insert multiple files. This will lead to notable performance problems. You can use it on a test server, but not in production. You can try if you can read the checksum instead of the filename.

    It´s outdated code written against Innovator 11. Perfectly for you, I assume. But I wouldn´t use "soapSend", "var", "top" or the "typeOf" lines anymore. It´s really old code and it was one of the first Innovator Methods I ever created:

    // Obsolete. Method is not good for performance
    
    // Angela [...] / 23.10.2017
    // Users should not upload the same files more than once (except, of course, if they really want and need it.)
    // Especially compliance files or datasheets that are applicaple for multible Items should be reused and not reuploaded again.
    // This method check if one or more files with the same file name are already available on the vault server.
    // The result will be displayed in a small info box on the left bottom.
    // This Method is used in relevant RelationshipTypes (Action: OnInsertRow) and not the ItemTypes itself!
    
    // Possilbe notification variants:
    // top.aras.AlertError("Das File heißt " + filename); // classical Error message
    // aras.AlertSuccess("Das File heißt " + filename); // Info box at the bottom left
    // alert("Das File heißt " + filename); // Error message in the browser
    
    // Ideas for further development:
    // Instead of info box show dialog window with following options: 1. Keep my new file; 2. Use file from server; 3. Abort
    // Add file WhereUsed info to info message: The File 1234.pdf is also used in Part Multicomp xy.
    
    var prt = typeof(parent.document.item) == "object" ? parent.document : parent.parent;
    var tmpThisItem = typeof(parent.document.thisItem) == "object" ? parent.document.thisItem : parent.thisItem;
    var relshipNd = prt.item.selectSingleNode("Relationships/Item[@id='" + relationshipID + "' and related_id/Item]");
    if (!relshipNd) return;
    var relatedNd = relshipNd.selectSingleNode("related_id/Item");
    var filename = top.aras.getItemProperty(relatedNd, "filename", undefined); // get File name propery
    // var fileid = top.aras.getItemProperty(relatedNd, "id", undefined); // get File id propery
    // var thisRel = tmpThisItem.getItemsByXPath("//Item[@id='" + relationshipID + "']").getItemByIndex(0);
    // var relationshipName = thisRel.getType(); // get name of Relationship
    
     // Look for Files with the same name
    var query ="<Item type=\"File\" select=\"filename\">"
    	+ "<filename>" + filename + "</filename>" 
        + "</Item>";
    
    var fileItem = aras.soapSend("GetItem", query);
    
    if (fileItem.getFaultCode() !== 0) // no Files found
    { 
    	aras.AlertSuccess("Es ist noch kein File mit dem Namen " + filename + " auf dem Server vorhanden." ); 
    	return;
    }
    
    var fileNodes = fileItem.getResult().selectNodes("Item");
    var filesCount = fileNodes.length;
    
    if (filesCount == 1)
    {
         aras.AlertSuccess("Es ist akuell 1 File mit dem Namen " + filename + " auf dem Server vorhanden!" );
    } else {
         aras.AlertSuccess("Es sind aktuell " + filesCount + " Files mit dem Namen " + filename + " auf dem Server vorhanden!"); 
    }
    return;

    Your approach with checking the files before save/update is better. You can check the file relationships when clicking on save. I maybe have a codesample somewhere, but haven´t checked it yet.

Reply
  • I definitely think some users use the checksum in some way. But so far I haven´t seen Innovator using it. 

    Innovator was not designed to encourage users to "reuse" file. But to be fair, hardly any of the software tools that I know are designed this way. I assume this is some kind of standard that has a reason. But I don´t know. Innovator at least reuses files when a new revision is created. Confluence by Atlassian is much worse. It copies the files on each revision. This will lead to funny results when user embed 8GB videos and then the software counts any minor edit as new revision. 

    I so far haven´t had much problems when reusing files in Innovator. We encourage our users to do it themselves. Only Visual Collaboration couldn´t link reused files in the past. Not sure if it works today, but keep an eye on that if the feature is relevant.

    My Innovator 12 doesn´t have the xxhash-asm. But the "vendors" folder indicate, that it is an external library. Probably this one: https://github.com/Cyan4973/xxHash

    When Aras has replaced this one in the newer versions, I wouldn´t spent too much time to understand this one.

    Here is a very old onInsertRow test Method that I once made: It checks the files as soon as the user drags it to the file relationship. Note the first sentence!! The code is called multiple times when user insert multiple files. This will lead to notable performance problems. You can use it on a test server, but not in production. You can try if you can read the checksum instead of the filename.

    It´s outdated code written against Innovator 11. Perfectly for you, I assume. But I wouldn´t use "soapSend", "var", "top" or the "typeOf" lines anymore. It´s really old code and it was one of the first Innovator Methods I ever created:

    // Obsolete. Method is not good for performance
    
    // Angela [...] / 23.10.2017
    // Users should not upload the same files more than once (except, of course, if they really want and need it.)
    // Especially compliance files or datasheets that are applicaple for multible Items should be reused and not reuploaded again.
    // This method check if one or more files with the same file name are already available on the vault server.
    // The result will be displayed in a small info box on the left bottom.
    // This Method is used in relevant RelationshipTypes (Action: OnInsertRow) and not the ItemTypes itself!
    
    // Possilbe notification variants:
    // top.aras.AlertError("Das File heißt " + filename); // classical Error message
    // aras.AlertSuccess("Das File heißt " + filename); // Info box at the bottom left
    // alert("Das File heißt " + filename); // Error message in the browser
    
    // Ideas for further development:
    // Instead of info box show dialog window with following options: 1. Keep my new file; 2. Use file from server; 3. Abort
    // Add file WhereUsed info to info message: The File 1234.pdf is also used in Part Multicomp xy.
    
    var prt = typeof(parent.document.item) == "object" ? parent.document : parent.parent;
    var tmpThisItem = typeof(parent.document.thisItem) == "object" ? parent.document.thisItem : parent.thisItem;
    var relshipNd = prt.item.selectSingleNode("Relationships/Item[@id='" + relationshipID + "' and related_id/Item]");
    if (!relshipNd) return;
    var relatedNd = relshipNd.selectSingleNode("related_id/Item");
    var filename = top.aras.getItemProperty(relatedNd, "filename", undefined); // get File name propery
    // var fileid = top.aras.getItemProperty(relatedNd, "id", undefined); // get File id propery
    // var thisRel = tmpThisItem.getItemsByXPath("//Item[@id='" + relationshipID + "']").getItemByIndex(0);
    // var relationshipName = thisRel.getType(); // get name of Relationship
    
     // Look for Files with the same name
    var query ="<Item type=\"File\" select=\"filename\">"
    	+ "<filename>" + filename + "</filename>" 
        + "</Item>";
    
    var fileItem = aras.soapSend("GetItem", query);
    
    if (fileItem.getFaultCode() !== 0) // no Files found
    { 
    	aras.AlertSuccess("Es ist noch kein File mit dem Namen " + filename + " auf dem Server vorhanden." ); 
    	return;
    }
    
    var fileNodes = fileItem.getResult().selectNodes("Item");
    var filesCount = fileNodes.length;
    
    if (filesCount == 1)
    {
         aras.AlertSuccess("Es ist akuell 1 File mit dem Namen " + filename + " auf dem Server vorhanden!" );
    } else {
         aras.AlertSuccess("Es sind aktuell " + filesCount + " Files mit dem Namen " + filename + " auf dem Server vorhanden!"); 
    }
    return;

    Your approach with checking the files before save/update is better. You can check the file relationships when clicking on save. I maybe have a codesample somewhere, but haven´t checked it yet.

Children
No Data