From 56c464db7f6681931fa16928351e349344c36cec Mon Sep 17 00:00:00 2001 From: Simonas Karuzas Date: Tue, 15 Sep 2020 12:27:47 +0300 Subject: [PATCH] feat: Ngrok support in CLI --- packages/daf-cli/default/client.yml | 49 +++++++++++ packages/daf-cli/package.json | 2 + packages/daf-cli/src/server.ts | 128 ++++++++++++++++------------ yarn.lock | 109 ++++++++++++++++++++++- 4 files changed, 231 insertions(+), 57 deletions(-) create mode 100644 packages/daf-cli/default/client.yml diff --git a/packages/daf-cli/default/client.yml b/packages/daf-cli/default/client.yml new file mode 100644 index 000000000..01a2c6705 --- /dev/null +++ b/packages/daf-cli/default/client.yml @@ -0,0 +1,49 @@ +agent: + $require: daf-core#Agent + $args: + - plugins: + - $require: daf-rest#AgentRestClient + $args: + - url: http://localhost:3332 + enabledMethods: + - keyManagerGetKeyManagementSystems + - keyManagerCreateKey + - keyManagerGetKey + - keyManagerDeleteKey + - keyManagerImportKey + - keyManagerEncryptJWE + - keyManagerDecryptJWE + - keyManagerSignJWT + - keyManagerSignEthTX + - identityManagerGetProviders + - identityManagerGetIdentities + - identityManagerGetIdentity + - identityManagerCreateIdentity + - identityManagerGetOrCreateIdentity + - identityManagerImportIdentity + - identityManagerDeleteIdentity + - identityManagerAddKey + - identityManagerRemoveKey + - identityManagerAddService + - identityManagerRemoveService + - resolveDid + - dataStoreSaveMessage + - dataStoreSaveVerifiableCredential + - dataStoreSaveVerifiablePresentation + - dataStoreORMGetIdentities + - dataStoreORMGetIdentitiesCount + - dataStoreORMGetMessages + - dataStoreORMGetMessagesCount + - dataStoreORMGetVerifiableCredentialsByClaims + - dataStoreORMGetVerifiableCredentialsByClaimsCount + - dataStoreORMGetVerifiableCredentials + - dataStoreORMGetVerifiableCredentialsCount + - dataStoreORMGetVerifiablePresentations + - dataStoreORMGetVerifiablePresentationsCount + - handleMessage + - sendMessageDIDCommAlpha1 + - createVerifiablePresentation + - createVerifiableCredential + - createSelectiveDisclosureRequest + - getVerifiableCredentialsForSdr + - validatePresentationAgainstSdr diff --git a/packages/daf-cli/package.json b/packages/daf-cli/package.json index 3655f04be..6031c85a1 100644 --- a/packages/daf-cli/package.json +++ b/packages/daf-cli/package.json @@ -42,10 +42,12 @@ "inquirer": "^7.0.0", "jsonpointer": "^4.1.0", "lodash.merge": "^4.6.2", + "ngrok": "^3.3.0", "pg": "^8.2.0", "qrcode-terminal": "^0.12.0", "sqlite3": "^5.0.0", "typeorm": "0.2.24", + "url-parse": "^1.4.7", "ws": "^7.2.0", "yaml": "^1.10.0" }, diff --git a/packages/daf-cli/src/server.ts b/packages/daf-cli/src/server.ts index 686c12eb6..d6587a5bb 100644 --- a/packages/daf-cli/src/server.ts +++ b/packages/daf-cli/src/server.ts @@ -1,5 +1,7 @@ import express from 'express' import program from 'commander' +import ngrok from 'ngrok' +import parse from 'url-parse' import { AgentRouter } from 'daf-express' import { getAgent } from './setup' @@ -8,7 +10,9 @@ program .description('Launch OpenAPI server') .option('--port ', 'Port', '3332') .option('--hostname ', 'Server hostname', 'localhost') - .option('--https ', 'Use https instead of http', true) + .option('--ngrok', 'Open ngrok tunnel') + .option('--ngrokSubdomain ', 'ngrok subdomain') + .option('--ngrokRegion ', 'ngrok region') .option('--createDefaultIdentity ', 'Should the agent create default web did', true) .option('--messagingServiceEndpoint ', 'Path of the messaging service endpoint', '/messaging') .option( @@ -31,70 +35,86 @@ program app.use('/', agentRouter) - if (options.createDefaultIdentity) { - let serverIdentity = await agent.identityManagerGetOrCreateIdentity({ - provider: 'did:web', - alias: options.hostname, - }) - console.log('Created:', serverIdentity.did) + app.listen(options.port, async () => { + console.log(`🚀 Agent server ready at http://localhost:${options.port}`) + console.log('🧩 Available methods', JSON.stringify(agent.availableMethods())) + console.log('🛠 Exposed methods', JSON.stringify(exposedMethods)) - if (options.messagingServiceEndpoint) { - const serviceEndpoint = - (options.https ? 'https://' : 'http://') + options.hostname + options.messagingServiceEndpoint + let hostname = options.hostname - await agent.identityManagerAddService({ - did: serverIdentity.did, - service: { - id: 'msg', - type: 'Messaging', - serviceEndpoint, - }, - }) - console.log('Added endpoint', serviceEndpoint) + let baseUrl = 'http://' + hostname + ':' + options.port - app.post(serviceEndpoint, express.text({ type: '*/*' }), async (req, res) => { - try { - const message = await agent.handleMessage({ raw: req.body, save: true }) - res.json({ id: message.id }) - } catch (e) { - console.log(e) - res.send(e.message) - } + if (options.ngrok) { + baseUrl = await ngrok.connect({ + addr: options.port, + subdomain: options.ngrokSubdomain, + region: options.ngrokRegion, }) + hostname = parse(baseUrl).hostname } - app.get('/.well-known/did.json', async (req, res) => { - serverIdentity = await agent.identityManagerGetOrCreateIdentity({ + if (options.createDefaultIdentity) { + let serverIdentity = await agent.identityManagerGetOrCreateIdentity({ provider: 'did:web', - alias: options.hostname, + alias: hostname, }) + console.log('🆔', serverIdentity.did) + + if (options.messagingServiceEndpoint) { + const serviceEndpoint = 'https://' + hostname + options.messagingServiceEndpoint + + await agent.identityManagerAddService({ + did: serverIdentity.did, + service: { + id: serverIdentity.did + '#msg', + type: 'Messaging', + description: 'Handles incoming POST messages', + serviceEndpoint, + }, + }) + console.log('📨 Messaging endpoint', serviceEndpoint) - const didDoc = { - '@context': 'https://w3id.org/did/v1', - id: serverIdentity.did, - publicKey: serverIdentity.keys.map((key) => ({ - id: serverIdentity.did + '#' + key.kid, - type: key.type === 'Secp256k1' ? 'Secp256k1VerificationKey2018' : 'Ed25519VerificationKey2018', - owner: serverIdentity.did, - publicKeyHex: key.publicKeyHex, - })), - authentication: serverIdentity.keys.map((key) => ({ - type: - key.type === 'Secp256k1' - ? 'Secp256k1SignatureAuthentication2018' - : 'Ed25519SignatureAuthentication2018', - publicKey: serverIdentity.did + '#' + key.kid, - })), - service: serverIdentity.services, + app.post(options.messagingServiceEndpoint, express.text({ type: '*/*' }), async (req, res) => { + try { + const message = await agent.handleMessage({ raw: req.body, save: true }) + console.log('Received message', message.type, message.id) + res.json({ id: message.id }) + } catch (e) { + console.log(e) + res.send(e.message) + } + }) } - res.json(didDoc) - }) - } + const didDocEndpoint = '/.well-known/did.json' + app.get(didDocEndpoint, async (req, res) => { + serverIdentity = await agent.identityManagerGetOrCreateIdentity({ + provider: 'did:web', + alias: hostname, + }) - app.listen(options.port, () => { - console.log(`🚀 Server ready at http://${options.hostname}:${options.port}`) - console.log('Enabled agent methods', JSON.stringify(agent.availableMethods())) - console.log('Exposed methods', JSON.stringify(exposedMethods)) + const didDoc = { + '@context': 'https://w3id.org/did/v1', + id: serverIdentity.did, + publicKey: serverIdentity.keys.map((key) => ({ + id: serverIdentity.did + '#' + key.kid, + type: key.type === 'Secp256k1' ? 'Secp256k1VerificationKey2018' : 'Ed25519VerificationKey2018', + owner: serverIdentity.did, + publicKeyHex: key.publicKeyHex, + })), + authentication: serverIdentity.keys.map((key) => ({ + type: + key.type === 'Secp256k1' + ? 'Secp256k1SignatureAuthentication2018' + : 'Ed25519SignatureAuthentication2018', + publicKey: serverIdentity.did + '#' + key.kid, + })), + service: serverIdentity.services, + } + + res.json(didDoc) + }) + console.log('📋 DID Document ' + baseUrl + didDocEndpoint) + } }) }) diff --git a/yarn.lock b/yarn.lock index cb1257cd1..52d0427f2 100644 --- a/yarn.lock +++ b/yarn.lock @@ -2409,6 +2409,11 @@ "@types/connect" "*" "@types/node" "*" +"@types/caseless@*": + version "0.12.2" + resolved "https://registry.yarnpkg.com/@types/caseless/-/caseless-0.12.2.tgz#f65d3d6389e01eeb458bd54dc8f52b95a9463bc8" + integrity sha512-6ckxMjBBD8URvjB6J3NcnuAn5Pkl7t3TizAg+xdlzzQGSPSmBcXf8KoIH0ua/i+tio+ZRUHEXp0HEmvaR4kt0w== + "@types/color-name@^1.1.1": version "1.1.1" resolved "https://registry.yarnpkg.com/@types/color-name/-/color-name-1.1.1.tgz#1c1261bbeaa10a8055bbc5d8ab84b7b2afc846a0" @@ -2653,6 +2658,11 @@ resolved "https://registry.yarnpkg.com/@types/node/-/node-10.17.29.tgz#263b7013f9f4afa53585b199f9a4255d9613b178" integrity sha512-zLo9rjUeQ5+QVhOufDwrb3XKyso31fJBJnk9wUUQIBDExF/O4LryvpOfozfUaxgqifTnlt7FyqsAPXUq5yFZSA== +"@types/node@^8.10.50": + version "8.10.63" + resolved "https://registry.yarnpkg.com/@types/node/-/node-8.10.63.tgz#f86775d576bc07a2992da244f41c23d3ba66d402" + integrity sha512-g+nSkeHFDd2WOQChfmy9SAXLywT47WZBrGS/NC5ym5PJ8c8RC6l4pbGaUW/X0+eZJnXw6/AVNEouXWhV4iz72Q== + "@types/normalize-package-data@^2.4.0": version "2.4.0" resolved "https://registry.yarnpkg.com/@types/normalize-package-data/-/normalize-package-data-2.4.0.tgz#e486d0d97396d79beedd0a6e33f4534ff6b4973e" @@ -2678,6 +2688,16 @@ resolved "https://registry.yarnpkg.com/@types/range-parser/-/range-parser-1.2.3.tgz#7ee330ba7caafb98090bece86a5ee44115904c2c" integrity sha512-ewFXqrQHlFsgc09MK5jP5iR7vumV/BYayNC6PgJO2LPe8vrnNFyjQjSppfEngITi0qvfKtzFvgKymGheFM9UOA== +"@types/request@^2.48.2": + version "2.48.5" + resolved "https://registry.yarnpkg.com/@types/request/-/request-2.48.5.tgz#019b8536b402069f6d11bee1b2c03e7f232937a0" + integrity sha512-/LO7xRVnL3DxJ1WkPGDQrp4VTV1reX9RkC85mJ+Qzykj2Bdw+mG15aAfDahc76HtknjzE16SX/Yddn6MxVbmGQ== + dependencies: + "@types/caseless" "*" + "@types/node" "*" + "@types/tough-cookie" "*" + form-data "^2.5.0" + "@types/retry@^0.12.0": version "0.12.0" resolved "https://registry.yarnpkg.com/@types/retry/-/retry-0.12.0.tgz#2b35eccfcee7d38cd72ad99232fbd58bffb3c84d" @@ -2703,6 +2723,11 @@ dependencies: "@types/node" "*" +"@types/tough-cookie@*": + version "4.0.0" + resolved "https://registry.yarnpkg.com/@types/tough-cookie/-/tough-cookie-4.0.0.tgz#fef1904e4668b6e5ecee60c52cc6a078ffa6697d" + integrity sha512-I99sngh224D0M7XgW1s120zxCt3VYQ3IQsuw3P3jbq5GG4yc79+ZjyKznyOGIQrflfylLgcfekeZW/vk0yng6A== + "@types/url-parse@^1.4.3": version "1.4.3" resolved "https://registry.yarnpkg.com/@types/url-parse/-/url-parse-1.4.3.tgz#fba49d90f834951cb000a674efee3d6f20968329" @@ -3553,6 +3578,14 @@ bin-links@^1.1.2, bin-links@^1.1.8: npm-normalize-package-bin "^1.0.0" write-file-atomic "^2.3.0" +binary@^0.3.0: + version "0.3.0" + resolved "https://registry.yarnpkg.com/binary/-/binary-0.3.0.tgz#9f60553bc5ce8c3386f3b553cff47462adecaa79" + integrity sha1-n2BVO8XOjDOG87VTz/R0Yq3sqnk= + dependencies: + buffers "~0.1.1" + chainsaw "~0.1.0" + blakejs@^1.1.0: version "1.1.0" resolved "https://registry.yarnpkg.com/blakejs/-/blakejs-1.1.0.tgz#69df92ef953aa88ca51a32df6ab1c54a155fc7a5" @@ -3699,6 +3732,11 @@ buffer@^5.1.0, buffer@^5.2.1, buffer@^5.6.0: base64-js "^1.0.2" ieee754 "^1.1.4" +buffers@~0.1.1: + version "0.1.1" + resolved "https://registry.yarnpkg.com/buffers/-/buffers-0.1.1.tgz#b24579c3bed4d6d396aeee6d9a8ae7f5482ab7bb" + integrity sha1-skV5w77U1tOWru5tmorn9Ugqt7s= + bufferutil@^4.0.1: version "4.0.1" resolved "https://registry.yarnpkg.com/bufferutil/-/bufferutil-4.0.1.tgz#3a177e8e5819a1243fe16b63a199951a7ad8d4a7" @@ -3902,6 +3940,13 @@ caseless@~0.12.0: resolved "https://registry.yarnpkg.com/caseless/-/caseless-0.12.0.tgz#1b681c21ff84033c826543090689420d187151dc" integrity sha1-G2gcIf+EAzyCZUMJBolCDRhxUdw= +chainsaw@~0.1.0: + version "0.1.0" + resolved "https://registry.yarnpkg.com/chainsaw/-/chainsaw-0.1.0.tgz#5eab50b28afe58074d0d58291388828b5e5fbc98" + integrity sha1-XqtQsor+WAdNDVgpE4iCi15fvJg= + dependencies: + traverse ">=0.3.0 <0.4" + chalk@2.4.2, chalk@^2.0.0, chalk@^2.0.1, chalk@^2.3.1, chalk@^2.3.2, chalk@^2.4.1, chalk@^2.4.2: version "2.4.2" resolved "https://registry.yarnpkg.com/chalk/-/chalk-2.4.2.tgz#cd42541677a54333cf541a49108c1432b44c9424" @@ -4686,6 +4731,19 @@ decode-uri-component@^0.2.0: resolved "https://registry.yarnpkg.com/decode-uri-component/-/decode-uri-component-0.2.0.tgz#eb3913333458775cb84cd1a1fae062106bb87545" integrity sha1-6zkTMzRYd1y4TNGh+uBiEGu4dUU= +decompress-zip@^0.3.2: + version "0.3.2" + resolved "https://registry.yarnpkg.com/decompress-zip/-/decompress-zip-0.3.2.tgz#f3fa2841666abce394604f4a9e8a7085c202d464" + integrity sha512-Ab1QY4LrWMrUuo53lLnmGOby7v8ryqxJ+bKibKSiPisx+25mhut1dScVBXAYx14i/PqSrFZvR2FRRazhLbvL+g== + dependencies: + binary "^0.3.0" + graceful-fs "^4.1.3" + mkpath "^0.1.0" + nopt "^3.0.1" + q "^1.1.2" + readable-stream "^1.1.8" + touch "0.0.3" + dedent@^0.7.0: version "0.7.0" resolved "https://registry.yarnpkg.com/dedent/-/dedent-0.7.0.tgz#2495ddbaf6eb874abb0e1be9df22d2e5a544326c" @@ -5799,6 +5857,15 @@ form-data@3.0.0, form-data@^3.0.0: combined-stream "^1.0.8" mime-types "^2.1.12" +form-data@^2.5.0: + version "2.5.1" + resolved "https://registry.yarnpkg.com/form-data/-/form-data-2.5.1.tgz#f2cbec57b5e59e23716e128fe44d4e5dd23895f4" + integrity sha512-m21N3WOmEEURgk6B9GLOE4RuWOFf28Lhh9qGYeNlGq4VDXUlJy2th2slBNU8Gp8EzloYZOibZJ7t5ecIrFSjVA== + dependencies: + asynckit "^0.4.0" + combined-stream "^1.0.6" + mime-types "^2.1.12" + form-data@~2.3.2: version "2.3.3" resolved "https://registry.yarnpkg.com/form-data/-/form-data-2.3.3.tgz#dcce52c05f644f298c6a7ab936bd724ceffbf3a6" @@ -8729,6 +8796,11 @@ mkdirp@0.x, "mkdirp@>=0.5 0", mkdirp@^0.5.0, mkdirp@^0.5.1, mkdirp@^0.5.5, mkdir dependencies: minimist "^1.2.5" +mkpath@^0.1.0: + version "0.1.0" + resolved "https://registry.yarnpkg.com/mkpath/-/mkpath-0.1.0.tgz#7554a6f8d871834cc97b5462b122c4c124d6de91" + integrity sha1-dVSm+Nhxg0zJe1RisSLEwSTW3pE= + modify-values@^1.0.0: version "1.0.1" resolved "https://registry.yarnpkg.com/modify-values/-/modify-values-1.0.1.tgz#b3939fa605546474e3e3e3c63d64bd43b4ee6022" @@ -8872,6 +8944,18 @@ next-tick@~1.0.0: resolved "https://registry.yarnpkg.com/next-tick/-/next-tick-1.0.0.tgz#ca86d1fe8828169b0120208e3dc8424b9db8342c" integrity sha1-yobR/ogoFpsBICCOPchCS524NCw= +ngrok@^3.3.0: + version "3.3.0" + resolved "https://registry.yarnpkg.com/ngrok/-/ngrok-3.3.0.tgz#85e5ff72de38de1a416f0fe559ff439169d24c60" + integrity sha512-NuTfuxttodW6o9cPEKiJgjmjNzolKHoUPaK7I4SbaJVkHd4cuUTlv9YsXNzBFrcNFSsDLuCyCpjsaqe1OvIPSQ== + dependencies: + "@types/node" "^8.10.50" + "@types/request" "^2.48.2" + decompress-zip "^0.3.2" + request "^2.88.0" + request-promise-native "^1.0.7" + uuid "^3.3.2" + nice-try@^1.0.4: version "1.0.5" resolved "https://registry.yarnpkg.com/nice-try/-/nice-try-1.0.5.tgz#a3378a7696ce7d223e88fc9b764bd7ef1089e366" @@ -9001,7 +9085,7 @@ node-pre-gyp@^0.11.0: semver "^5.3.0" tar "^4" -"nopt@2 || 3": +"nopt@2 || 3", nopt@^3.0.1: version "3.0.6" resolved "https://registry.yarnpkg.com/nopt/-/nopt-3.0.6.tgz#c6465dbf08abcd4db359317f79ac68a646b28ff9" integrity sha1-xkZdvwirzU2zWTF/eaxopkayj/k= @@ -9016,6 +9100,13 @@ nopt@^4.0.1, nopt@^4.0.3: abbrev "1" osenv "^0.1.4" +nopt@~1.0.10: + version "1.0.10" + resolved "https://registry.yarnpkg.com/nopt/-/nopt-1.0.10.tgz#6ddd21bd2a31417b92727dd585f8a6f37608ebee" + integrity sha1-bd0hvSoxQXuScn3Vhfim83YI6+4= + dependencies: + abbrev "1" + normalize-git-url@^3.0.2: version "3.0.2" resolved "https://registry.yarnpkg.com/normalize-git-url/-/normalize-git-url-3.0.2.tgz#8e5f14be0bdaedb73e07200310aa416c27350fc4" @@ -10219,7 +10310,7 @@ punycode@^2.1.0, punycode@^2.1.1: resolved "https://registry.yarnpkg.com/punycode/-/punycode-2.1.1.tgz#b58b010ac40c22c5657616c8d2c2c02c7bf479ec" integrity sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A== -q@^1.5.1: +q@^1.1.2, q@^1.5.1: version "1.5.1" resolved "https://registry.yarnpkg.com/q/-/q-1.5.1.tgz#7e32f75b41381291d04611f1bf14109ac00651d7" integrity sha1-fjL3W0E4EpHQRhHxvxQQmsAGUdc= @@ -10437,7 +10528,7 @@ read@1, read@~1.0.1, read@~1.0.7: string_decoder "^1.1.1" util-deprecate "^1.0.1" -readable-stream@~1.1.10: +readable-stream@^1.1.8, readable-stream@~1.1.10: version "1.1.14" resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-1.1.14.tgz#7cf4c54ef648e3813084c636dd2079e166c081d9" integrity sha1-fPTFTvZI44EwhMY23SB54WbAgdk= @@ -11846,6 +11937,13 @@ toidentifier@1.0.0: resolved "https://registry.yarnpkg.com/toidentifier/-/toidentifier-1.0.0.tgz#7e1be3470f1e77948bc43d94a3c8f4d7752ba553" integrity sha512-yaOH/Pk/VEhBWWTlhI+qXxDFXlejDGcQipMlyxda9nthulaxLZUNcUqFxokp0vcYnvteJln5FNQDRrxj3YcbVw== +touch@0.0.3: + version "0.0.3" + resolved "https://registry.yarnpkg.com/touch/-/touch-0.0.3.tgz#51aef3d449571d4f287a5d87c9c8b49181a0db1d" + integrity sha1-Ua7z1ElXHU8oel2Hyci0kYGg2x0= + dependencies: + nopt "~1.0.10" + tough-cookie@^2.3.3, tough-cookie@~2.5.0: version "2.5.0" resolved "https://registry.yarnpkg.com/tough-cookie/-/tough-cookie-2.5.0.tgz#cd9fb2a0aa1d5a12b473bd9fb96fa3dcff65ade2" @@ -11870,6 +11968,11 @@ tr46@^1.0.1: dependencies: punycode "^2.1.0" +"traverse@>=0.3.0 <0.4": + version "0.3.9" + resolved "https://registry.yarnpkg.com/traverse/-/traverse-0.3.9.tgz#717b8f220cc0bb7b44e40514c22b2e8bbc70d8b9" + integrity sha1-cXuPIgzAu3tE5AUUwisui7xw2Lk= + traverse@~0.6.6: version "0.6.6" resolved "https://registry.yarnpkg.com/traverse/-/traverse-0.6.6.tgz#cbdf560fd7b9af632502fed40f918c157ea97137"