Skip to content

Commit

Permalink
Merge branch 'release-1.7.0'
Browse files Browse the repository at this point in the history
  • Loading branch information
btamas committed Oct 9, 2020
2 parents c2a6419 + d360ab7 commit e6a4484
Show file tree
Hide file tree
Showing 4 changed files with 97 additions and 48 deletions.
20 changes: 16 additions & 4 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

9 changes: 6 additions & 3 deletions package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@oat-sa/tao-core-sdk",
"version": "1.6.3",
"version": "1.7.0",
"displayName": "TAO Core SDK",
"description": "Core libraries of TAO",
"homepage": "https://github.com/oat-sa/tao-core-sdk-fe#readme",
Expand Down Expand Up @@ -43,6 +43,7 @@
"@oat-sa/browserslist-config-tao": "^0.1.0",
"@oat-sa/eslint-config-tao": "^0.1.1",
"@oat-sa/expr-eval": "^1.3.0",
"@oat-sa/prettier-config": "^0.1.1",
"@oat-sa/tao-core-libs": "^0.2.0",
"@oat-sa/tao-qunit-testrunner": "^0.1.3",
"async": "^0.2.10",
Expand All @@ -68,6 +69,7 @@
"nyc": "^14.1.1",
"open-cli": "^5.0.0",
"popper.js": "1.15.0",
"prettier": "^2.1.2",
"promise-limit": "^2.7.0",
"qunit": "^2.9.2",
"raphael": "2.1.4",
Expand All @@ -84,11 +86,12 @@
"tooltip.js": "1.3.2"
},
"dependencies": {
"fastestsmallesttextencoderdecoder": "^1.0.14",
"fastestsmallesttextencoderdecoder": "1.0.14",
"idb-wrapper": "1.7.0",
"webcrypto-shim": "0.1.4"
},
"browserslist": [
"extends @oat-sa/browserslist-config-tao"
]
],
"prettier": "@oat-sa/prettier-config"
}
64 changes: 35 additions & 29 deletions src/core/digest.js
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*
* Copyright (c) 2018-2019 (original work) Open Assessment Technologies SA
* Copyright (c) 2018-2020 (original work) Open Assessment Technologies SA
*
*/

Expand All @@ -24,13 +24,12 @@
*
* @author Bertrand Chevrier <[email protected]>
*/
import _ from 'lodash';
import 'webcrypto-shim';
import { TextEncoder } from 'fastestsmallesttextencoderdecoder';

//get the native implementation of the CryptoSubtle
var subtle = window.crypto.subtle || window.crypto.webkitSubtle;
var supportedAlgorithms = [
const subtle = window.crypto.subtle || window.crypto.webkitSubtle;
const supportedAlgorithms = [
'SHA-1', //considered as not safe anymore
'SHA-256',
'SHA-384',
Expand All @@ -39,37 +38,44 @@ var supportedAlgorithms = [

/**
* Encode a buffer to an hexadecimal string
* @param {Number[]|ArrayBuffer} buffer
* @returns {String} the hex representation of the buffer
* @param {number[]|ArrayBuffer} buffer
* @returns {string} the hex representation of the buffer
*/
var bufferToHexString = function bufferToHexString(buffer) {
return [].map
.call(new Uint8Array(buffer), function(val) {
return ('00' + val.toString(16)).slice(-2);
})
.join('');
};
function bufferToHexString(buffer) {
return [...new Uint8Array(buffer)].map(val => `00${val.toString(16)}`.slice(-2)).join('');
}

/**
* Create a hash/checksum from a given string
* @param {String} utf8String - the string to hash
* @param {String} [selectedAlgorithm = 'SHA-256'] - how to hash
* Create a hash/checksum from a given string, blob or buffer
* @param {string|Blob|ArrayBuffer|Uint8Array} data - the data to hash
* @param {string} [selectedAlgorithm] - hashing algorithm
* @returns {Promise<String>} resolves with the hash of the string
* @throws {TypeError} if the algorithm is not available or the input string is missing
*/
export default function digest(utf8String, selectedAlgorithm) {
var algorithm;
if (!_.isString(selectedAlgorithm)) {
selectedAlgorithm = 'SHA-256';
}
algorithm = selectedAlgorithm.toUpperCase();
if (!_.contains(supportedAlgorithms, algorithm)) {
throw new TypeError('Unsupported digest algorithm : ' + algorithm);
export default function digest(data, selectedAlgorithm = 'SHA-256') {
let algorithm = selectedAlgorithm.toUpperCase();
if (!supportedAlgorithms.includes(algorithm)) {
throw new TypeError(`Unsupported digest algorithm : ${algorithm}`);
}
if (!_.isString(utf8String)) {
throw new TypeError('Please encode a string, not a ' + typeof utf8String);

let dataPromise;
if (data instanceof Uint8Array) {
dataPromise = Promise.resolve(data);
} else if (data instanceof ArrayBuffer) {
dataPromise = Promise.resolve(new Uint8Array([data]));
} else if (data instanceof Blob) {
dataPromise = new Promise((resolve, reject) => {
const reader = new FileReader();
reader.addEventListener('loadend', () => resolve(reader.result));
reader.addEventListener('abort', reject);
reader.addEventListener('error', reject);
reader.readAsArrayBuffer(data);
});
} else if (typeof data === 'string') {
dataPromise = Promise.resolve(new TextEncoder('utf-8').encode(data));
} else {
throw new TypeError(`Unsupported data type to digest with ${algorithm}`);
}
return subtle.digest(algorithm, new TextEncoder('utf-8').encode(utf8String)).then(function(buffer) {
return bufferToHexString(buffer);
});

return dataPromise.then(rawData => subtle.digest(algorithm, rawData)).then(buffer => bufferToHexString(buffer));
}
52 changes: 40 additions & 12 deletions test/core/digest/test.js
Original file line number Diff line number Diff line change
Expand Up @@ -25,35 +25,39 @@
define(['core/digest'], function(digest) {
'use strict';

const hello = new Uint8Array([72, 101, 108, 108, 111]); // "Hello" in binary
const blob = new Blob([hello], { type: 'text/plain' });
const file = new File([hello], 'hello.txt', { type: 'text/plain' });

QUnit.module('API');

QUnit.test('module', function(assert) {
QUnit.test('module', assert => {
assert.equal(typeof digest, 'function', 'The module exposes an function');
});

QUnit.module('Behavior');

QUnit.test('valid inputs', function(assert) {
QUnit.test('valid inputs', assert => {
assert.throws(
function() {
digest();
},
() => digest(),
TypeError,
'An input string is required'
);

assert.throws(
function() {
digest({});
},
() => digest({}),
TypeError,
'An input string is required'
);

assert.throws(
function() {
digest('foo', 'MD5');
},
() => digest(null),
TypeError,
'A valid input is required'
);

assert.throws(
() => digest('foo', 'MD5'),
TypeError,
'A valid algorithm is required'
);
Expand Down Expand Up @@ -93,7 +97,31 @@ define(['core/digest'], function(digest) {
algo: 'SHA-512',
output:
'00d7c8367e02fb59989bb05fa86421d7afbbf397b0babc2d2f2fb02da9ec65092e782242ac47a912de2d9e6979c543c1b42a93f2ca258a07f0095e67d28571e6'
}
},
{
title: 'sha256 from blob',
input: blob,
algo: 'SHA-256',
output: '185f8db32271fe25f561a6fc938b2e264306ec304eda518007d1764826381969'
},
{
title: 'sha256 from file',
input: file,
algo: 'SHA-256',
output: '185f8db32271fe25f561a6fc938b2e264306ec304eda518007d1764826381969'
},
{
title: 'sha256 from ArrayBuffer',
input: hello.buffer,
algo: 'SHA-256',
output: '6e340b9cffb37a989ca544e6bb780a2c78901d3fb33738768511a30617afa01d'
},
{
title: 'sha256 from Uint8Array',
input: hello,
algo: 'SHA-256',
output: '185f8db32271fe25f561a6fc938b2e264306ec304eda518007d1764826381969'
},
])
.test('digest', function(data, assert) {
var ready = assert.async();
Expand Down

0 comments on commit e6a4484

Please sign in to comment.