diff --git a/CI/gen-prod-test.js b/CI/gen-prod-test.js index 0c1e11a09e3e1f4ed6e3f9d188c39ae3de148b78..ca517f6d2d6611cc3a3c668b61656a020e8f311e 100644 --- a/CI/gen-prod-test.js +++ b/CI/gen-prod-test.js @@ -3,7 +3,7 @@ const fs = require('fs'); fs.readdirSync('src/').forEach(fileName => { const orgContent = fs.readFileSync(`src/${fileName}`, 'utf8').replace(/from '\.\.\//g, 'from \'../../'); fs.writeFileSync(`generated/cov-env/${fileName}`, orgContent); - if (!fileName.includes('.test.')) return; + if (!fileName.includes('.test')) return; fs.writeFileSync(`generated/minified/${fileName}`, orgContent); const allJsTest = orgContent.replace( /import \* as app from '\.\/(crypto)\.mjs';/, diff --git a/npm/package.json b/npm/package.json index e9464dbeaedaa7bf739a1ef949fe53f4a1211423..73e07b719c77885f901c7931dd7f993da20772ff 100644 --- a/npm/package.json +++ b/npm/package.json @@ -19,5 +19,11 @@ "bugs": { "url": "https://framagit.org/g1/g1lib.js/-/issues" }, + "ava": { + "files": [ + "**/*.test*.mjs", + "*.test*.mjs" + ] + }, "license": "AGPL-3.0" } diff --git a/package-lock.json b/package-lock.json index 1157beef786c5335156da283869029c3bf37e78d..766f58f7e8cb8a29251f4ca986f05e34a5ed22c4 100644 --- a/package-lock.json +++ b/package-lock.json @@ -871,9 +871,9 @@ "dev": true }, "ansi-styles": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-5.1.0.tgz", - "integrity": "sha512-osxifZo3ar56+e8tdYreU6p8FZGciBHo5O0JoDAxMUqZuyNUb+yHEwYtJZ+Z32R459jEgtwVf1u8D7qYwU0l6w==", + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-5.2.0.tgz", + "integrity": "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==", "dev": true }, "anymatch": { diff --git a/package.json b/package.json index 34edaf8c9891d08394ecca621af2234eeac5239e..1e7412d7ecf62e888f1c970807e022bf8da878a3 100644 --- a/package.json +++ b/package.json @@ -28,8 +28,8 @@ "test:production:duplication": "jscpd ./", "test:production:complexity": "./node_modules/.bin/es6-plato -r -d generated/maintainability ./src/*", "test:production:complexity:badgesAndThreshold": "node CI/plato-badges.js", - "test:production:srcCoverage": "cd generated/cov-env/ && c8 ava", - "test:production:testMinified": "cd generated/minified/ && ava", + "test:production:srcCoverage": "cd generated/cov-env/ && c8 ava **.test.mjs", + "test:production:testMinified": "cd generated/minified/ && ava **.test.mjs", "test:production:test-e2e": "cd generated/minified/ && ava **.test-e2e.mjs", "test:production:clean": "rm -rf generated/minified/*.test*.mjs", "test:production:minified2npm": "cp -rf generated/minified/* generated/npm/", @@ -37,10 +37,10 @@ "watch2null": "chokidar src/* -c \"npm run test:dev:runTests 2>/dev/null\"" }, "dependencies": { + "js-sha256": "https://github.com/1000i100/js-sha256#master", "latinize-to-ascii": "^0.5.2", "scrypt-async-modern": "^3.0.12", - "tweetnacl": "^1.0.3", - "js-sha256": "https://github.com/1000i100/js-sha256#master" + "tweetnacl": "^1.0.3" }, "devDependencies": { "@jscpd/badge-reporter": "^3.3.23", @@ -58,10 +58,17 @@ "xo": "^0.38.2" }, "disabledDependenciesTODOAddComplexityQualityCheck": { + "noble-ed25519": "https://github.com/1000i100/noble-ed25519#master", "ecma-nacl": "^2.5.0", "codehawk-cli": "^6.0.3" }, - "ava": {}, + "ava": { + "files": [ + "**/*.test*.mjs", + "*.test*.mjs", + "!node_modules" + ] + }, "c8": { "all": true, "branches": 0.08, diff --git a/src/basex.mjs b/src/basex.mjs index 146fadae0210ce033a471d756eb2f9d12d15debd..6f011a58024389ec99969c3b4e3fda9b3b61d37c 100644 --- a/src/basex.mjs +++ b/src/basex.mjs @@ -1,5 +1,8 @@ // Inspired by bs58, base-x then @thi.ng/base-n module const B58_ALPHABET = '123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz'; +const B64_ALPHABET = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/' + +export const b64 = basex(B64_ALPHABET); export const b58 = basex(B58_ALPHABET); export const b16 = basex('0123456789abcdef'); export default basex; diff --git a/src/crypto.mjs b/src/crypto.mjs index 993af3b3f8c635eee0e04d9b78b0fe99db12be78..f662b162575d27ae90cb93a0fbde2e2f92419ca7 100644 --- a/src/crypto.mjs +++ b/src/crypto.mjs @@ -1,7 +1,8 @@ // Alt deps : import {generate_keypair} from "ecma-nacl/build/lib/signing/sign.js"; // Alt deps : import scrypt from "ecma-nacl/build/lib/scrypt/scrypt.js"; import nacl from '../generated/vendors/nacl.mjs'; -import {b58} from './basex.mjs'; +// Alt import * as ed25519 from '../node_modules/noble-ed25519/index.mjs'; +import {b58,b64} from './basex.mjs'; export {b58}; import sha from '../node_modules/js-sha256/src/sha256.mjs'; @@ -13,12 +14,10 @@ import scrypt from '../generated/vendors/scrypt.mjs'; export async function idSecPass2rawAll(idSec, pass) { const rawSeed = await saltPass2seed(idSec, pass); - const keyPair = seed2keyPair(rawSeed); - return { - seed: rawSeed, - publicKey: keyPair.publicKey, - secretKey: keyPair.secretKey - }; + const keyPair = await seed2keyPair(rawSeed); + keyPair.seed = rawSeed; + keyPair.pubKey = keyPair.publicKey; + return keyPair; } export function raw2b58(raws) { @@ -35,7 +34,19 @@ export async function idSecPass2cleanKeys(idSec, pass) { export function seed2keyPair(seed) { return generateKeypair(seed); } - +/* Noble edition +export async function seed2keyPair(rawSeed) { + const pubKey = await ed25519.getPublicKey(rawSeed); + console.log('pubKey',pubKey); + const naclLikePrivateKey = new Uint8Array(64); + naclLikePrivateKey.set(rawSeed); + naclLikePrivateKey.set(pubKey,32); + return { + publicKey:pubKey, + secretKey:naclLikePrivateKey + }; +} +*/ export async function saltPass2seed(idSec, pass) { const options = { logN: 12, @@ -79,6 +90,12 @@ export function b58pubKey2bin(b58pubKey) { binPubKey.set(decoded, 32 - decoded.length); return binPubKey; } +export function b58secretKey2bin(b58secretKey) { + const binSecretKey = new Uint8Array(64); + const decoded = b58.decode(b58secretKey); + binSecretKey.set(decoded, 64 - decoded.length); + return binSecretKey; +} export function checkKey(pubKeyWithChecksum) { const part = pubKeyWithChecksum.split(':'); @@ -94,3 +111,12 @@ export function checkKey(pubKeyWithChecksum) { if (pubKey2checksum(b58pubKey, true, true, false) === checkSum) return true; throw new Error('Bad checksum'); } + +export function sign(unsignedDocument,secretKey){ + const encoder = new TextEncoder(); + const decoder = new TextDecoder(); + const rawSign = nacl.sign.detached(encoder.encode(unsignedDocument.trim()), b58secretKey2bin(secretKey)); + const b64Sign = b64.encode(rawSign); + + return `${unsignedDocument.trim()}\n${b64Sign}`; +} diff --git a/src/crypto.test.mjs b/src/crypto.test.mjs index 378e09c2b968523ef0ef0a48c5ed2fd18b01ad6b..61eac96b8984729468cf5e59b4f58739a3bc1c9e 100644 --- a/src/crypto.test.mjs +++ b/src/crypto.test.mjs @@ -1,6 +1,5 @@ import test from 'ava'; import * as app from './crypto.mjs'; -import {b58} from "./crypto.mjs"; const idSec = 'a'; const mdp = 'b'; @@ -8,6 +7,24 @@ const mdp = 'b'; const pubKey = 'AoxVA41dGL2s4ogMNdbCw3FFYjFo5FPK36LuiW1tjGbG'; const secretKey = '3ZsmZhnRv137dS1s7Q3jFGKLTDyhkwguPHfnWBxzDCTTHKWGnYw9zBk3gcCUJCc72TEUuyzM7cqpo7c5LYhs1Qtv'; const seed = '9eADqX8V6VcPdJCHCVYiE1Vnift9nFNrvr9aTaXA5RJc'; +const unsignedDocument = ` +Version: 10 +Type: Identity +Currency: duniter_unit_test_currency +Issuer: AoxVA41dGL2s4ogMNdbCw3FFYjFo5FPK36LuiW1tjGbG +UniqueID: tic +Timestamp: 0-E3B0C44298FC1C149AFBF4C8996FB92427AE41E4649B934CA495991B7852B855 +`; +const signedDocument = ` +Version: 10 +Type: Identity +Currency: duniter_unit_test_currency +Issuer: AoxVA41dGL2s4ogMNdbCw3FFYjFo5FPK36LuiW1tjGbG +UniqueID: tic +Timestamp: 0-E3B0C44298FC1C149AFBF4C8996FB92427AE41E4649B934CA495991B7852B855 +??? +`; +test.skip('sign document', async t => t.is(await app.sign(unsignedDocument,secretKey), signedDocument)); test('b58 should decode/encode well', t => t.is(app.b58.encode(app.b58.decode(pubKey)), pubKey)); test('b58 on pubKey with leading 1', t => t.is(app.b58.encode(app.b58.decode('12BjyvjoAf5qik7R8TKDJAHJugsX23YgJGi2LmBUv2nx')), '12BjyvjoAf5qik7R8TKDJAHJugsX23YgJGi2LmBUv2nx')); @@ -16,9 +33,9 @@ test('b58 on pubKey without leading 1', t => t.is(app.b58.encode(app.b58.decode( test('saltPass2seed should convert salt & password to seed with scrypt', async t => { t.is(app.b58.encode(await app.saltPass2seed(idSec, mdp)), seed); }); -test('seed2keyPair should generate public and private key nacl/sodium way.', t => { +test('seed2keyPair should generate public and private key nacl/sodium way.', async t => { const rawSeed = app.b58.decode(seed); - const rawKeyPair = app.seed2keyPair(rawSeed); + const rawKeyPair = await app.seed2keyPair(rawSeed); t.is(app.b58.encode(rawKeyPair.publicKey), pubKey); t.is(app.b58.encode(rawKeyPair.secretKey), secretKey); }); diff --git a/src/data-pod-client.mjs b/src/data-pod-client.mjs index e69de29bb2d1d6434b8b29ae775ad8c2e48c5391..cb0ff5c3b541f646105198ee23ac0fc3d805023e 100644 --- a/src/data-pod-client.mjs +++ b/src/data-pod-client.mjs @@ -0,0 +1 @@ +export {}; diff --git a/src/data-pod-client.test-e2e.mjs b/src/data-pod-client.test-e2e.mjs index 568ab590fb4a3a504f29f66b351cdd42237a9b6a..807ea8279e09b6cf1d75a5324a7dc30ed09bc779 100644 --- a/src/data-pod-client.test-e2e.mjs +++ b/src/data-pod-client.test-e2e.mjs @@ -1,7 +1,7 @@ import test from 'ava'; import * as app from './data-pod-client.mjs'; -test('data-pod-client real server request', async t => { +test.skip('data-pod-client real server request', async t => { const hosts = ['https://g1.data.e-is.pro/']; const query = 'user/profile/2sZF6j2PkxBDNAqUde7Dgo5x3crkerZpQ4rBqqJGn8QT?&_source=title'; const expectedResult = JSON.parse(`{ @@ -15,4 +15,3 @@ test('data-pod-client real server request', async t => { t.is(result._source.title, expectedResult._source.title); }); - diff --git a/src/data-pod-client.test.mjs b/src/data-pod-client.test.mjs index e69de29bb2d1d6434b8b29ae775ad8c2e48c5391..aab9fed49c0fe1bbaf421e2171f637df3e325149 100644 --- a/src/data-pod-client.test.mjs +++ b/src/data-pod-client.test.mjs @@ -0,0 +1,7 @@ +import test from 'ava'; +import * as app from './data-pod-client.mjs'; + +test('dummy', async t => { + t.true(true); +}); + diff --git a/src/gva-client.mjs b/src/gva-client.mjs index e69de29bb2d1d6434b8b29ae775ad8c2e48c5391..cb0ff5c3b541f646105198ee23ac0fc3d805023e 100644 --- a/src/gva-client.mjs +++ b/src/gva-client.mjs @@ -0,0 +1 @@ +export {}; diff --git a/src/gva-client.test-e2e.mjs b/src/gva-client.test-e2e.mjs index e69de29bb2d1d6434b8b29ae775ad8c2e48c5391..75c7f6135f8de32b14da5e22a09566bc042f28d5 100644 --- a/src/gva-client.test-e2e.mjs +++ b/src/gva-client.test-e2e.mjs @@ -0,0 +1,6 @@ +import test from 'ava'; +import * as app from './gva-client.mjs'; + +test('dummy', async t => { + t.true(true); +}); diff --git a/src/gva-client.test.js b/src/gva-client.test.js deleted file mode 100644 index e69de29bb2d1d6434b8b29ae775ad8c2e48c5391..0000000000000000000000000000000000000000 diff --git a/src/gva-client.test.mjs b/src/gva-client.test.mjs new file mode 100644 index 0000000000000000000000000000000000000000..75c7f6135f8de32b14da5e22a09566bc042f28d5 --- /dev/null +++ b/src/gva-client.test.mjs @@ -0,0 +1,6 @@ +import test from 'ava'; +import * as app from './gva-client.mjs'; + +test('dummy', async t => { + t.true(true); +}); diff --git a/src/multi-node-layer.mjs b/src/multi-node-layer.mjs index e69de29bb2d1d6434b8b29ae775ad8c2e48c5391..cb0ff5c3b541f646105198ee23ac0fc3d805023e 100644 --- a/src/multi-node-layer.mjs +++ b/src/multi-node-layer.mjs @@ -0,0 +1 @@ +export {}; diff --git a/src/multi-node-layer.test.mjs b/src/multi-node-layer.test.mjs index e69de29bb2d1d6434b8b29ae775ad8c2e48c5391..5467eedef86da485f654efaa9de18a7c54c8966b 100644 --- a/src/multi-node-layer.test.mjs +++ b/src/multi-node-layer.test.mjs @@ -0,0 +1,6 @@ +import test from 'ava'; +import * as app from './multi-node-layer.mjs'; + +test('dummy', async t => { + t.true(true); +});