diff --git a/oydid-js/dist/basic.js b/oydid-js/dist/basic.js index 29eb908..ea406f9 100644 --- a/oydid-js/dist/basic.js +++ b/oydid-js/dist/basic.js @@ -12,34 +12,14 @@ Object.defineProperty(exports, "__esModule", { value: true }); exports.multi_hash = exports.multi_encode = exports.DEFAULT_ENCODING = exports.DEFAULT_DIGEST = void 0; exports.DEFAULT_DIGEST = "sha2-256"; exports.DEFAULT_ENCODING = "base58btc"; -const libsodium_wrappers_1 = require("libsodium-wrappers"); const multi_encode = (message, options) => __awaiter(void 0, void 0, void 0, function* () { const o = Object.assign({ encode: exports.DEFAULT_ENCODING, digest: exports.DEFAULT_DIGEST, simulate: false }, options); const method = o.encode; - return "asdf"; + return "string"; }); exports.multi_encode = multi_encode; const multi_hash = (message, options) => __awaiter(void 0, void 0, void 0, function* () { const opt = Object.assign({ encode: exports.DEFAULT_ENCODING, digest: exports.DEFAULT_DIGEST, simulate: false }, options); - yield libsodium_wrappers_1.ready; // Wait for libsodium to be ready - // Convert the string to Uint8Array - const data = new TextEncoder().encode(message); - const method = opt.digest; - var digest = ""; - switch (method) { - case "sha2-256": - case "blake2b-64": - // Make sure the desired hash length is valid - if (libsodium_wrappers_1.crypto_generichash_BYTES_MAX < 64) { - throw new Error('Hash length is too large for BLAKE2b with this version of libsodium.'); - } - const digest = (0, libsodium_wrappers_1.crypto_generichash)(64, data); - break; - default: - throw new Error("unsupported digest: '" + method.toString() + "'"); - break; - } - const encoded = yield (0, exports.multi_encode)(digest, opt); - return encoded; + return "string"; }); exports.multi_hash = multi_hash; diff --git a/oydid-js/dist/oydid.d.ts b/oydid-js/dist/oydid.d.ts index e697b64..965a524 100644 --- a/oydid-js/dist/oydid.d.ts +++ b/oydid-js/dist/oydid.d.ts @@ -94,6 +94,13 @@ export interface RegistrarResponse { */ keys: didKey[]; } +/** + * create a new DID + * @param content payload in the new DID Document + * @param options optional parameters + * @returns DID and private keys + */ +export declare const create: (content?: any, options?: Partial) => Promise; /** * resolve DID to DID Document * @param did DID string (in format did:oyd:123) @@ -102,14 +109,50 @@ export interface RegistrarResponse { */ export declare const read: (did: string, options?: Partial) => Promise; /** - * create a new DID - * @param content payload in the new DID Document + * update DID Document for existing DID + * @param did DID string (in format did:oyd:123) + * @param content payload of the updated DID Document * @param options optional parameters * @returns DID and private keys */ -export declare const create: (content?: any, options?: Partial) => Promise; +export declare const update: (did: string, content: any, options?: Partial) => Promise; +/** + * deactivate DID + * @param did DID string (in format did:oyd:123) + * @param options optional parameters + * @returns DID + */ +export declare const deactivate: (did: string, options?: Partial) => Promise; +/** + * encrypt a message using libsodium + * @param payload to encrypt + * @param option parameters with public key for encryption + * @returns cipher and nonce of encrypted message + */ +export declare const encrypt: (payload: string, options: Partial) => Promise; +/** + * decrypt a libsodium encrypted message + * @param message cipher and nonce of encrypted message + * @param key private key to decrypt message + * @param options optional parameters + * @returns decrypted message + */ +export declare const decrypt: (message: CipherMessage, key: string, options?: Partial) => Promise; +/** + * sign a message + * @param payload to sign + * @param option parameters with private key for signing + * @returns signature of payload + */ +export declare const sign: (payload: string, options: Partial) => Promise; +/** + * verify signature for a message + * @param hexKey hexadecimal encoded object + * @param options optional parameters to specify preferred target encoding + * @returns base58btc Multiformat encoded object + */ +export declare const verify: (message: string, signature: string, options?: Partial) => Promise; /** - * * @param did DID string (in format did:oyd:123) * @param key private key necessary for signing during authorization process * @param regapi_url RegAPI URL (only protocol and host, e.g. http://host.com) @@ -123,11 +166,3 @@ export declare const didAuth: (did: string, key: string, regapi_url: string) => * @returns base58btc Multiformat encoded object */ export declare const hexToMulti: (hexKey: string, options?: Partial) => Promise; -/** - * decrypt a libsodium encrypted message - * @param message cipher and nonce of encrypted message - * @param key private key to decrypt message - * @param options optional parameters - * @returns decrypted message - */ -export declare const decrypt: (message: CipherMessage, key: string, options?: Partial) => Promise; diff --git a/oydid-js/dist/oydid.js b/oydid-js/dist/oydid.js index 6ddcdb0..67a8b74 100644 --- a/oydid-js/dist/oydid.js +++ b/oydid-js/dist/oydid.js @@ -12,13 +12,28 @@ var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); -exports.decrypt = exports.hexToMulti = exports.didAuth = exports.create = exports.read = exports.DEFAULT_ENCODING = exports.DEFAULT_DIGEST = void 0; +exports.hexToMulti = exports.didAuth = exports.verify = exports.sign = exports.decrypt = exports.encrypt = exports.deactivate = exports.update = exports.read = exports.create = exports.DEFAULT_ENCODING = exports.DEFAULT_DIGEST = void 0; +const did_jwt_1 = __importDefault(require("did-jwt")); const axios_1 = __importDefault(require("axios")); -const libsodium_wrappers_sumo_1 = require("libsodium-wrappers-sumo"); const base58_1 = require("multiformats/bases/base58"); -// import bs58 from 'bs58'; exports.DEFAULT_DIGEST = "sha2-256"; exports.DEFAULT_ENCODING = "base58btc"; +/** + * create a new DID + * @param content payload in the new DID Document + * @param options optional parameters + * @returns DID and private keys + */ +const create = (content, options) => __awaiter(void 0, void 0, void 0, function* () { + const url = "https://oydid-registrar.data-container.net/1.0/createIdentifier"; + const result = yield axios_1.default.post(url, {}); + return { + id: result.data.did, + docKey: result.data.keys[0].privateKeyHex, + revKey: result.data.keys[1].privateKeyHex + }; +}); +exports.create = create; /** * resolve DID to DID Document * @param did DID string (in format did:oyd:123) @@ -28,36 +43,118 @@ exports.DEFAULT_ENCODING = "base58btc"; const read = (did, options) => __awaiter(void 0, void 0, void 0, function* () { const o = Object.assign({ encode: exports.DEFAULT_ENCODING, digest: exports.DEFAULT_DIGEST, simulate: false }, options); if (!did) { - throw new Error("missing DID1"); + throw new Error("missing DID"); } return { doc: { "hello": "world" }, key: "asdf:qwer", log: "asdf" }; }); exports.read = read; /** - * create a new DID - * @param content payload in the new DID Document + * update DID Document for existing DID + * @param did DID string (in format did:oyd:123) + * @param content payload of the updated DID Document * @param options optional parameters * @returns DID and private keys */ -const create = (content, options) => __awaiter(void 0, void 0, void 0, function* () { - const url = "https://oydid-registrar.data-container.net/1.0/createIdentifier"; - const result = yield axios_1.default.post(url, {}); +const update = (did, content, options) => __awaiter(void 0, void 0, void 0, function* () { + const o = Object.assign({ encode: exports.DEFAULT_ENCODING, digest: exports.DEFAULT_DIGEST, simulate: false }, options); + if (!did) { + throw new Error("missing DID"); + } return { - id: result.data.did, - docKey: result.data.keys[0].privateKeyHex, - revKey: result.data.keys[1].privateKeyHex + id: did, + docKey: "", + revKey: "" }; }); -exports.create = create; +exports.update = update; +/** + * deactivate DID + * @param did DID string (in format did:oyd:123) + * @param options optional parameters + * @returns DID + */ +const deactivate = (did, options) => __awaiter(void 0, void 0, void 0, function* () { + const o = Object.assign({ encode: exports.DEFAULT_ENCODING, digest: exports.DEFAULT_DIGEST, simulate: false }, options); + if (!did) { + throw new Error("missing DID"); + } + return { + id: did, + docKey: "", + revKey: "" + }; +}); +exports.deactivate = deactivate; +/** + * encrypt a message using libsodium + * @param payload to encrypt + * @param option parameters with public key for encryption + * @returns cipher and nonce of encrypted message + */ +const encrypt = (payload, options) => __awaiter(void 0, void 0, void 0, function* () { + if (!payload) { + throw new Error("missing payload"); + } + const url = "https://oydid.ownyourdata.eu/helper/encrypt"; + const body = { message: payload, key: "" }; + const result = yield axios_1.default.post(url, body); + return { + cipher: result.data.cipher, + nonce: result.data.nonce + }; +}); +exports.encrypt = encrypt; +/** + * decrypt a libsodium encrypted message + * @param message cipher and nonce of encrypted message + * @param key private key to decrypt message + * @param options optional parameters + * @returns decrypted message + */ +const decrypt = (message, key, options) => __awaiter(void 0, void 0, void 0, function* () { + const url = "https://oydid.ownyourdata.eu/helper/decrypt"; + const body = { message: message, key: key }; + const result = yield axios_1.default.post(url, body); + return JSON.stringify(result.data, null, 0); +}); +exports.decrypt = decrypt; +/** + * sign a message + * @param payload to sign + * @param option parameters with private key for signing + * @returns signature of payload + */ +const sign = (payload, options) => __awaiter(void 0, void 0, void 0, function* () { + if (!payload) { + throw new Error("missing payload"); + } + return "string"; +}); +exports.sign = sign; +/** + * verify signature for a message + * @param hexKey hexadecimal encoded object + * @param options optional parameters to specify preferred target encoding + * @returns base58btc Multiformat encoded object + */ +const verify = (message, signature, options) => __awaiter(void 0, void 0, void 0, function* () { + if (!message) { + throw new Error("missing message"); + } + if (!signature) { + throw new Error("missing signature"); + } + return true; +}); +exports.verify = verify; /** - * * @param did DID string (in format did:oyd:123) * @param key private key necessary for signing during authorization process * @param regapi_url RegAPI URL (only protocol and host, e.g. http://host.com) * @returns OAuth 2.0 Bearer Token */ const didAuth = (did, key, regapi_url) => __awaiter(void 0, void 0, void 0, function* () { - const url = regapi_url + "/did_auth"; + const url = regapi_url + (regapi_url.endsWith('/') ? "" : "/") + "did_auth"; const body = { did: did, key: key }; const result = yield axios_1.default.post(url, body); return result.data.access_token; @@ -70,26 +167,8 @@ exports.didAuth = didAuth; * @returns base58btc Multiformat encoded object */ const hexToMulti = (hexKey, options) => __awaiter(void 0, void 0, void 0, function* () { - yield libsodium_wrappers_sumo_1.ready; - const keyBytes = (0, libsodium_wrappers_sumo_1.from_hex)(hexKey); + const keyBytes = did_jwt_1.default.hexToBytes(hexKey); const multiformatKey = base58_1.base58btc.encode(keyBytes); return multiformatKey; }); exports.hexToMulti = hexToMulti; -/** - * decrypt a libsodium encrypted message - * @param message cipher and nonce of encrypted message - * @param key private key to decrypt message - * @param options optional parameters - * @returns decrypted message - */ -const decrypt = (message, key, options) => __awaiter(void 0, void 0, void 0, function* () { - yield libsodium_wrappers_sumo_1.ready; - const privateKeyBytes = base58_1.base58btc.decode(key); - const privateKey = privateKeyBytes.slice(privateKeyBytes.length - 32); - const authHash = (0, libsodium_wrappers_sumo_1.crypto_hash_sha256)((0, libsodium_wrappers_sumo_1.from_string)('auth')); - const authKey = (0, libsodium_wrappers_sumo_1.crypto_scalarmult_base)(authHash); - const decryptedMessageBytes = (0, libsodium_wrappers_sumo_1.crypto_box_open_easy)((0, libsodium_wrappers_sumo_1.from_hex)(message.value), (0, libsodium_wrappers_sumo_1.from_hex)(message.nonce), authKey, privateKey); - return (0, libsodium_wrappers_sumo_1.to_string)(decryptedMessageBytes); -}); -exports.decrypt = decrypt; diff --git a/oydid-js/package-lock.json b/oydid-js/package-lock.json index 6cf8cba..9e7bad7 100644 --- a/oydid-js/package-lock.json +++ b/oydid-js/package-lock.json @@ -1,15 +1,16 @@ { "name": "oydid", - "version": "0.0.6", + "version": "0.0.8", "lockfileVersion": 2, "requires": true, "packages": { "": { "name": "oydid", - "version": "0.0.6", + "version": "0.0.8", "license": "MIT", "dependencies": { "axios": "^1.5.0", + "did-jwt": "^8.0.0", "libsodium-wrappers-sumo": "^0.7.13", "multiformats": "^9.9.0" }, @@ -24,8 +25,45 @@ "node_modules/@multiformats/base-x": { "version": "4.0.1", "resolved": "https://registry.npmjs.org/@multiformats/base-x/-/base-x-4.0.1.tgz", - "integrity": "sha512-eMk0b9ReBbV23xXU693TAIrLyeO5iTgBZGSJfpqriG8UkYvr/hC9u9pyMlAakDNHWmbhMZCDs6KQO0jzKD8OTw==", - "dev": true + "integrity": "sha512-eMk0b9ReBbV23xXU693TAIrLyeO5iTgBZGSJfpqriG8UkYvr/hC9u9pyMlAakDNHWmbhMZCDs6KQO0jzKD8OTw==" + }, + "node_modules/@noble/ciphers": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/@noble/ciphers/-/ciphers-0.4.1.tgz", + "integrity": "sha512-QCOA9cgf3Rc33owG0AYBB9wszz+Ul2kramWN8tXG44Gyciud/tbkEqvxRF/IpqQaBpRBNi9f4jdNxqB2CQCIXg==", + "funding": { + "url": "https://paulmillr.com/funding/" + } + }, + "node_modules/@noble/curves": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/@noble/curves/-/curves-1.3.0.tgz", + "integrity": "sha512-t01iSXPuN+Eqzb4eBX0S5oubSqXbK/xXa1Ne18Hj8f9pStxztHCE2gfboSp/dZRLSqfuLpRK2nDXDK+W9puocA==", + "dependencies": { + "@noble/hashes": "1.3.3" + }, + "funding": { + "url": "https://paulmillr.com/funding/" + } + }, + "node_modules/@noble/hashes": { + "version": "1.3.3", + "resolved": "https://registry.npmjs.org/@noble/hashes/-/hashes-1.3.3.tgz", + "integrity": "sha512-V7/fPHgl+jsVPXqqeOzT8egNj2iBIVt+ECeMMG8TdcnTikP3oaBtUVqpT/gYCR68aEBJSF+XbYUxStjbFMqIIA==", + "engines": { + "node": ">= 16" + }, + "funding": { + "url": "https://paulmillr.com/funding/" + } + }, + "node_modules/@scure/base": { + "version": "1.1.5", + "resolved": "https://registry.npmjs.org/@scure/base/-/base-1.1.5.tgz", + "integrity": "sha512-Brj9FiG2W1MRQSTB212YVPRrcbjkv48FoZi/u4l/zds/ieRrqsh7aUf6CLwkAq61oKXr/ZlTzlY66gLIj3TFTQ==", + "funding": { + "url": "https://paulmillr.com/funding/" + } }, "node_modules/@types/libsodium-wrappers": { "version": "0.7.11", @@ -57,6 +95,11 @@ "proxy-from-env": "^1.1.0" } }, + "node_modules/canonicalize": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/canonicalize/-/canonicalize-2.0.0.tgz", + "integrity": "sha512-ulDEYPv7asdKvqahuAY35c1selLdzDwHqugK92hfkzvlDCwXRRelDkR+Er33md/PtnpqHemgkuDPanZ4fiYZ8w==" + }, "node_modules/combined-stream": { "version": "1.0.8", "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz", @@ -76,6 +119,27 @@ "node": ">=0.4.0" } }, + "node_modules/did-jwt": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/did-jwt/-/did-jwt-8.0.0.tgz", + "integrity": "sha512-lJSVC9Ckxl+U+jDPbdATDtXV7CwE0XGT0Js6KNfjRlaj0LTXvDF90IAyayFwLUzO6punA/q3ZHVfTZaYDhHrLw==", + "dependencies": { + "@noble/ciphers": "^0.4.0", + "@noble/curves": "^1.0.0", + "@noble/hashes": "^1.3.0", + "@scure/base": "^1.1.3", + "canonicalize": "^2.0.0", + "did-resolver": "^4.1.0", + "multibase": "^4.0.6", + "multiformats": "^9.6.2", + "uint8arrays": "3.1.1" + } + }, + "node_modules/did-resolver": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/did-resolver/-/did-resolver-4.1.0.tgz", + "integrity": "sha512-S6fWHvCXkZg2IhS4RcVHxwuyVejPR7c+a4Go0xbQ9ps5kILa8viiYQgrM4gfTyeTjJ0ekgJH9gk/BawTpmkbZA==" + }, "node_modules/follow-redirects": { "version": "1.15.3", "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.3.tgz", @@ -160,7 +224,6 @@ "resolved": "https://registry.npmjs.org/multibase/-/multibase-4.0.6.tgz", "integrity": "sha512-x23pDe5+svdLz/k5JPGCVdfn7Q5mZVMBETiC+ORfO+sor9Sgs0smJzAjfTbM5tckeCqnaUuMYoz+k3RXMmJClQ==", "deprecated": "This module has been superseded by the multiformats module", - "dev": true, "dependencies": { "@multiformats/base-x": "^4.0.1" }, @@ -191,14 +254,44 @@ "engines": { "node": ">=14.17" } + }, + "node_modules/uint8arrays": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/uint8arrays/-/uint8arrays-3.1.1.tgz", + "integrity": "sha512-+QJa8QRnbdXVpHYjLoTpJIdCTiw9Ir62nocClWuXIq2JIh4Uta0cQsTSpFL678p2CN8B+XSApwcU+pQEqVpKWg==", + "dependencies": { + "multiformats": "^9.4.2" + } } }, "dependencies": { "@multiformats/base-x": { "version": "4.0.1", "resolved": "https://registry.npmjs.org/@multiformats/base-x/-/base-x-4.0.1.tgz", - "integrity": "sha512-eMk0b9ReBbV23xXU693TAIrLyeO5iTgBZGSJfpqriG8UkYvr/hC9u9pyMlAakDNHWmbhMZCDs6KQO0jzKD8OTw==", - "dev": true + "integrity": "sha512-eMk0b9ReBbV23xXU693TAIrLyeO5iTgBZGSJfpqriG8UkYvr/hC9u9pyMlAakDNHWmbhMZCDs6KQO0jzKD8OTw==" + }, + "@noble/ciphers": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/@noble/ciphers/-/ciphers-0.4.1.tgz", + "integrity": "sha512-QCOA9cgf3Rc33owG0AYBB9wszz+Ul2kramWN8tXG44Gyciud/tbkEqvxRF/IpqQaBpRBNi9f4jdNxqB2CQCIXg==" + }, + "@noble/curves": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/@noble/curves/-/curves-1.3.0.tgz", + "integrity": "sha512-t01iSXPuN+Eqzb4eBX0S5oubSqXbK/xXa1Ne18Hj8f9pStxztHCE2gfboSp/dZRLSqfuLpRK2nDXDK+W9puocA==", + "requires": { + "@noble/hashes": "1.3.3" + } + }, + "@noble/hashes": { + "version": "1.3.3", + "resolved": "https://registry.npmjs.org/@noble/hashes/-/hashes-1.3.3.tgz", + "integrity": "sha512-V7/fPHgl+jsVPXqqeOzT8egNj2iBIVt+ECeMMG8TdcnTikP3oaBtUVqpT/gYCR68aEBJSF+XbYUxStjbFMqIIA==" + }, + "@scure/base": { + "version": "1.1.5", + "resolved": "https://registry.npmjs.org/@scure/base/-/base-1.1.5.tgz", + "integrity": "sha512-Brj9FiG2W1MRQSTB212YVPRrcbjkv48FoZi/u4l/zds/ieRrqsh7aUf6CLwkAq61oKXr/ZlTzlY66gLIj3TFTQ==" }, "@types/libsodium-wrappers": { "version": "0.7.11", @@ -230,6 +323,11 @@ "proxy-from-env": "^1.1.0" } }, + "canonicalize": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/canonicalize/-/canonicalize-2.0.0.tgz", + "integrity": "sha512-ulDEYPv7asdKvqahuAY35c1selLdzDwHqugK92hfkzvlDCwXRRelDkR+Er33md/PtnpqHemgkuDPanZ4fiYZ8w==" + }, "combined-stream": { "version": "1.0.8", "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz", @@ -243,6 +341,27 @@ "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", "integrity": "sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==" }, + "did-jwt": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/did-jwt/-/did-jwt-8.0.0.tgz", + "integrity": "sha512-lJSVC9Ckxl+U+jDPbdATDtXV7CwE0XGT0Js6KNfjRlaj0LTXvDF90IAyayFwLUzO6punA/q3ZHVfTZaYDhHrLw==", + "requires": { + "@noble/ciphers": "^0.4.0", + "@noble/curves": "^1.0.0", + "@noble/hashes": "^1.3.0", + "@scure/base": "^1.1.3", + "canonicalize": "^2.0.0", + "did-resolver": "^4.1.0", + "multibase": "^4.0.6", + "multiformats": "^9.6.2", + "uint8arrays": "3.1.1" + } + }, + "did-resolver": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/did-resolver/-/did-resolver-4.1.0.tgz", + "integrity": "sha512-S6fWHvCXkZg2IhS4RcVHxwuyVejPR7c+a4Go0xbQ9ps5kILa8viiYQgrM4gfTyeTjJ0ekgJH9gk/BawTpmkbZA==" + }, "follow-redirects": { "version": "1.15.3", "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.3.tgz", @@ -303,7 +422,6 @@ "version": "4.0.6", "resolved": "https://registry.npmjs.org/multibase/-/multibase-4.0.6.tgz", "integrity": "sha512-x23pDe5+svdLz/k5JPGCVdfn7Q5mZVMBETiC+ORfO+sor9Sgs0smJzAjfTbM5tckeCqnaUuMYoz+k3RXMmJClQ==", - "dev": true, "requires": { "@multiformats/base-x": "^4.0.1" } @@ -323,6 +441,14 @@ "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.2.2.tgz", "integrity": "sha512-mI4WrpHsbCIcwT9cF4FZvr80QUeKvsUsUvKDoR+X/7XHQH98xYD8YHZg7ANtz2GtZt/CBq2QJ0thkGJMHfqc1w==", "dev": true + }, + "uint8arrays": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/uint8arrays/-/uint8arrays-3.1.1.tgz", + "integrity": "sha512-+QJa8QRnbdXVpHYjLoTpJIdCTiw9Ir62nocClWuXIq2JIh4Uta0cQsTSpFL678p2CN8B+XSApwcU+pQEqVpKWg==", + "requires": { + "multiformats": "^9.4.2" + } } } } diff --git a/oydid-js/package.json b/oydid-js/package.json index 7e0a851..7959fd0 100644 --- a/oydid-js/package.json +++ b/oydid-js/package.json @@ -1,6 +1,6 @@ { "name": "oydid", - "version": "0.0.6", + "version": "0.0.8", "description": "", "main": "dist/index.js", "scripts": { @@ -13,15 +13,12 @@ "author": "", "license": "MIT", "devDependencies": { - "@types/libsodium-wrappers": "^0.7.11", - "@types/libsodium-wrappers-sumo": "^0.7.6", - "libsodium-wrappers": "^0.7.13", "multibase": "^4.0.6", "typescript": "^5.2.2" }, "dependencies": { "axios": "^1.5.0", - "libsodium-wrappers-sumo": "^0.7.13", + "did-jwt": "^8.0.0", "multiformats": "^9.9.0" } } diff --git a/oydid-js/src/basic.ts b/oydid-js/src/basic.ts index cf435d9..ccf3043 100644 --- a/oydid-js/src/basic.ts +++ b/oydid-js/src/basic.ts @@ -7,7 +7,6 @@ interface ReadOptions { simulate: boolean } -import { ready, crypto_generichash, crypto_generichash_BYTES_MAX } from 'libsodium-wrappers'; import multibase from 'multibase'; export const multi_encode = async (message: string, options?: Partial) : Promise => { @@ -20,7 +19,7 @@ export const multi_encode = async (message: string, options?: Partial) : Promise => { @@ -30,28 +29,6 @@ export const multi_hash = async (message: string, options?: Partial simulate: false, ...options, } - await ready; // Wait for libsodium to be ready - // Convert the string to Uint8Array - const data = new TextEncoder().encode(message); - - const method = opt.digest; - var digest = ""; - switch(method) { - case "sha2-256": - - case "blake2b-64": - // Make sure the desired hash length is valid - if (crypto_generichash_BYTES_MAX < 64) { - throw new Error('Hash length is too large for BLAKE2b with this version of libsodium.'); - } - const digest = crypto_generichash(64, data); - break; - default: - throw new Error("unsupported digest: '" + method.toString() + "'"); - break; - } - const encoded = await multi_encode(digest, opt); - - return encoded; + return "string"; } \ No newline at end of file diff --git a/oydid-js/src/oydid.ts b/oydid-js/src/oydid.ts index 9d120aa..9cc658a 100644 --- a/oydid-js/src/oydid.ts +++ b/oydid-js/src/oydid.ts @@ -1,7 +1,6 @@ +import didJWT from 'did-jwt'; import axios from 'axios'; -import { ready as sodiumReady, from_hex, from_string, to_string, crypto_box_open_easy, crypto_hash_sha256, crypto_scalarmult_base } from 'libsodium-wrappers-sumo'; import { base58btc } from 'multiformats/bases/base58'; -// import bs58 from 'bs58'; export const DEFAULT_DIGEST = "sha2-256"; export const DEFAULT_ENCODING = "base58btc"; @@ -149,7 +148,7 @@ export const read = async (did: string, options?: Partial) : Promis * @param options optional parameters * @returns DID and private keys */ -export const update = async (did: string, content: any, options?: Partial) : Promise => { +export const update = async (did: string, content: any, options?: Partial) : Promise => { const o: ReadOptions = { encode: DEFAULT_ENCODING, digest: DEFAULT_DIGEST, @@ -161,9 +160,9 @@ export const update = async (did: string, content: any, options?: Partial) : Promise => { +export const deactivate = async (did: string, options?: Partial) : Promise => { const o: ReadOptions = { encode: DEFAULT_ENCODING, digest: DEFAULT_DIGEST, @@ -185,7 +184,9 @@ export const deactivate = async (did: string, options?: Partial) : } return { - id: did + id: did, + docKey: "", + revKey: "" } } @@ -195,14 +196,16 @@ export const deactivate = async (did: string, options?: Partial) : * @param option parameters with public key for encryption * @returns cipher and nonce of encrypted message */ -export const encrypt = async(payload: string, options: Partial) : Promise => { +export const encrypt = async(payload: string, options: Partial) : Promise => { if (!payload) { throw new Error("missing payload") } - + const url = "https://oydid.ownyourdata.eu/helper/encrypt"; + const body = {message: payload, key: ""}; + const result = await axios.post(url, body); return { - cipher: "cipher", - nonce: "nonce" + cipher: result.data.cipher, + nonce: result.data.nonce } } @@ -214,20 +217,10 @@ export const encrypt = async(payload: string, options: Partial) : P * @returns decrypted message */ export const decrypt = async(message: CipherMessage, key: string, options?: Partial) : Promise => { - await sodiumReady; - const privateKeyBytes = base58btc.decode(key); - const privateKey = privateKeyBytes.slice(privateKeyBytes.length - 32); - const authHash = crypto_hash_sha256(from_string('auth')); - const authKey = crypto_scalarmult_base(authHash); - - const decryptedMessageBytes = crypto_box_open_easy( - from_hex(message.value), - from_hex(message.nonce), - authKey, - privateKey); - - return to_string(decryptedMessageBytes); - + const url = "https://oydid.ownyourdata.eu/helper/decrypt"; + const body = {message: message, key: key}; + const result = await axios.post(url, body); + return JSON.stringify(result.data, null, 0); } /** @@ -266,7 +259,7 @@ export const verify = async(message: string, signature: string, options?: Partia * @returns OAuth 2.0 Bearer Token */ export const didAuth = async(did: string, key: string, regapi_url: string) : Promise => { - const url = regapi_url + "/did_auth"; + const url = regapi_url + (regapi_url.endsWith('/') ? "" : "/") + "did_auth"; const body = {did: did, key: key}; const result = await axios.post(url, body); return result.data.access_token; @@ -279,8 +272,7 @@ export const didAuth = async(did: string, key: string, regapi_url: string) : Pro * @returns base58btc Multiformat encoded object */ export const hexToMulti = async(hexKey: string, options?: Partial) : Promise => { - await sodiumReady; - const keyBytes = from_hex(hexKey); + const keyBytes = didJWT.hexToBytes(hexKey); const multiformatKey = base58btc.encode(keyBytes); return multiformatKey; } diff --git a/repository/app/controllers/dids_controller.rb b/repository/app/controllers/dids_controller.rb index 9707ed1..f89a56f 100644 --- a/repository/app/controllers/dids_controller.rb +++ b/repository/app/controllers/dids_controller.rb @@ -685,4 +685,48 @@ def token status: 500 end end + + def encrypt + begin + msg, err = Oydid.encrypt(params[:message], params[:key]) + if err.to_s == "" + render json: msg, + status: 200 + else + render json: {error: err}, + status: 500 + end + rescue => error + render json: {error: error.message}, + status: 500 + end + end + + def decrypt + begin + msg, err = Oydid.decrypt(params[:message].to_json, params[:key]) + if err.to_s == "" + msg_parsed = JSON.parse(msg) rescue nil + if msg_parsed.nil? + if msg.is_a?(String) + render json: [msg], + status: 200 + else + render json: msg, + status: 200 + end + else + render json: msg_parsed, + status: 200 + end + else + render json: {error: err}, + status: 500 + end + rescue => error + render json: {error: error.message}, + status: 500 + end + end + end \ No newline at end of file diff --git a/repository/app/helpers/application_helper.rb b/repository/app/helpers/application_helper.rb index cf87590..ea8179e 100644 --- a/repository/app/helpers/application_helper.rb +++ b/repository/app/helpers/application_helper.rb @@ -264,7 +264,7 @@ def dag_update(currentDID, options) did_orig = "did:oyd:" + did_orig end case rotate_DID_method - when "did:ebsi" + when "did:ebsi", "did:cheqd" public_resolver = ENV["PUBLIC_RESOLVER"] || DEFAULT_PUBLIC_RESOLVER rotate_DID_Document = HTTParty.get(public_resolver + rotate_DID) rotate_ddoc = JSON.parse(rotate_DID_Document.parsed_response) diff --git a/repository/config/routes.rb b/repository/config/routes.rb index 83283c9..6b01626 100644 --- a/repository/config/routes.rb +++ b/repository/config/routes.rb @@ -31,6 +31,10 @@ match 'oydid/init', to: 'dids#init', via: 'post' match 'oydid/token', to: 'dids#token', via: 'post' + # helper functions + match 'helper/encrypt', to: 'dids#encrypt', via: 'post' + match 'helper/decrypt', to: 'dids#decrypt', via: 'post' + # administrative root 'application#home' match '/', to: 'application#home', via: 'get' diff --git a/repository/docker/local-gem/oydid-0.5.5.gem b/repository/docker/local-gem/oydid-0.5.5.gem deleted file mode 100644 index 83601e3..0000000 Binary files a/repository/docker/local-gem/oydid-0.5.5.gem and /dev/null differ diff --git a/repository/docker/local-gem/oydid-0.5.6.gem b/repository/docker/local-gem/oydid-0.5.6.gem new file mode 100644 index 0000000..dc64cfd Binary files /dev/null and b/repository/docker/local-gem/oydid-0.5.6.gem differ diff --git a/ruby-gem/lib/oydid/log.rb b/ruby-gem/lib/oydid/log.rb index da97957..d9dddf4 100644 --- a/ruby-gem/lib/oydid/log.rb +++ b/ruby-gem/lib/oydid/log.rb @@ -512,7 +512,7 @@ def self.dag_update(currentDID, options) did_orig = "did:oyd:" + did_orig end case rotate_DID_method - when "did:ebsi" + when "did:ebsi", "did:cheqd" public_resolver = DEFAULT_PUBLIC_RESOLVER rotate_DID_Document = HTTParty.get(public_resolver + rotate_DID) rotate_ddoc = JSON.parse(rotate_DID_Document.parsed_response) diff --git a/uniresolver-plugin/Gemfile b/uniresolver-plugin/Gemfile index beb339a..ad6743c 100644 --- a/uniresolver-plugin/Gemfile +++ b/uniresolver-plugin/Gemfile @@ -1,8 +1,8 @@ source 'https://rubygems.org' -ruby '2.6.9' +ruby '3.2.2' -gem 'rails', '~> 5.2.5' +gem 'rails' gem 'puma', '>= 3.12.2' gem 'rack-cors', ">= 1.0.4", require: 'rack/cors' gem 'rbnacl' @@ -15,7 +15,7 @@ gem 'multibases' gem 'multihashes' gem 'multicodecs' gem 'json-canonicalization', '~> 0.3.0' -gem 'oydid', '~> 0.5.3' +gem 'oydid' gem 'bootsnap' group :development, :test do @@ -28,7 +28,7 @@ group :development do # gem 'listen', '>= 3.0.5', '< 3.2' gem 'better_errors' # Spring speeds up development by keeping your application running in the background. Read more: https://github.com/rails/spring - gem 'spring' - gem 'spring-watcher-listen', '~> 2.0.0' + # gem 'spring' + # gem 'spring-watcher-listen', '~> 2.0.0' gem 'annotate' end diff --git a/uniresolver-plugin/config/application.rb b/uniresolver-plugin/config/application.rb index fc5d913..63b959c 100644 --- a/uniresolver-plugin/config/application.rb +++ b/uniresolver-plugin/config/application.rb @@ -20,7 +20,7 @@ module Resolver class Application < Rails::Application # Initialize configuration defaults for originally generated Rails version. - config.load_defaults 5.2 + config.load_defaults 7.0 # Don't generate system test files. config.generators.system_tests = nil diff --git a/uniresolver-plugin/docker/Dockerfile-local b/uniresolver-plugin/docker/Dockerfile-local index 76c7d74..7e887dc 100644 --- a/uniresolver-plugin/docker/Dockerfile-local +++ b/uniresolver-plugin/docker/Dockerfile-local @@ -1,4 +1,4 @@ -FROM ruby:2.6.9 +FROM ruby:3.2.2 MAINTAINER "Christoph Fabianek" christoph@ownyourdata.eu WORKDIR /usr/src/app @@ -18,8 +18,8 @@ RUN gem install /tmp/*.gem && \ COPY docker/local-gem/*.gem /tmp/ -RUN gem install bundler:1.17.3 && \ - gem update --system 3.2.3 && \ +RUN gem install bundler && \ + gem update --system && \ bundle install && \ bundle update diff --git a/uniresolver-plugin/docker/local-gem/oydid-0.5.5.gem b/uniresolver-plugin/docker/local-gem/oydid-0.5.5.gem deleted file mode 100644 index 83601e3..0000000 Binary files a/uniresolver-plugin/docker/local-gem/oydid-0.5.5.gem and /dev/null differ diff --git a/uniresolver-plugin/docker/local-gem/oydid-0.5.6.gem b/uniresolver-plugin/docker/local-gem/oydid-0.5.6.gem new file mode 100644 index 0000000..dc64cfd Binary files /dev/null and b/uniresolver-plugin/docker/local-gem/oydid-0.5.6.gem differ diff --git a/uniresolver-plugin/test/cmd.txt b/uniresolver-plugin/test/cmd.txt index d332757..72c9f7f 100644 --- a/uniresolver-plugin/test/cmd.txt +++ b/uniresolver-plugin/test/cmd.txt @@ -10,8 +10,6 @@ curl -s http://localhost:3000/1.0/identifiers/did:oyd:zQmaBZTghndXTgxNwfbdpVLWdF https://oydid-resolver.data-container.net/1.0/identifiers/did:oyd:zQmaBZTghndXTgxNwfbdpVLWdFf6faYE4oeuN2zzXdQt1kh - curl -s http://localhost:3000/1.0/identifiers/did:oyd:zQmdXNRiMWEYTiYF58a9BaiUkfB2xWUgL7G7ozyCCNPqjKV | jq - curl -s http://localhost:3000/1.0/identifiers/did:oyd:zQmeArtmfxJ1JB6CXvoFdcQCyxPcYii5DUTBR44g4xYpCLR | jq \ No newline at end of file