From 7e516e4065251ba7eaa2ab9c32fbfbda7e318bb1 Mon Sep 17 00:00:00 2001 From: Simonas Karuzas Date: Tue, 10 Dec 2019 13:20:21 +0200 Subject: [PATCH] feat: URL message validator --- examples/expressjs-ethr/package.json | 1 + examples/expressjs-ethr/src/setup.ts | 2 + examples/expressjs-ethr/tsconfig.json | 1 + packages/daf-cli/package.json | 1 + packages/daf-cli/src/msg.ts | 3 +- packages/daf-cli/src/setup.ts | 2 + packages/daf-cli/tsconfig.json | 1 + packages/daf-url/LICENSE | 201 ++++++++++++++++++ packages/daf-url/README.md | 1 + packages/daf-url/package.json | 31 +++ .../daf-url/src/__tests__/default.test.ts | 22 ++ packages/daf-url/src/index.ts | 1 + packages/daf-url/src/message-validator.ts | 24 +++ packages/daf-url/tsconfig.json | 8 + packages/tsconfig.json | 1 + yarn.lock | 23 ++ 16 files changed, 322 insertions(+), 1 deletion(-) create mode 100644 packages/daf-url/LICENSE create mode 100644 packages/daf-url/README.md create mode 100644 packages/daf-url/package.json create mode 100644 packages/daf-url/src/__tests__/default.test.ts create mode 100644 packages/daf-url/src/index.ts create mode 100644 packages/daf-url/src/message-validator.ts create mode 100644 packages/daf-url/tsconfig.json diff --git a/examples/expressjs-ethr/package.json b/examples/expressjs-ethr/package.json index 8567793ce..3b3f7963a 100644 --- a/examples/expressjs-ethr/package.json +++ b/examples/expressjs-ethr/package.json @@ -25,6 +25,7 @@ "daf-selective-disclosure": "../../packages/daf-selective-disclosure", "daf-sodium-fs": "../../packages/daf-sodium-fs", "daf-trust-graph": "../../packages/daf-trust-graph", + "daf-url": "../../packages/daf-url", "daf-w3c": "../../packages/daf-w3c", "debug": "^4.1.1", "express": "^4.17.1", diff --git a/examples/expressjs-ethr/src/setup.ts b/examples/expressjs-ethr/src/setup.ts index 12a14a78e..7c8120597 100644 --- a/examples/expressjs-ethr/src/setup.ts +++ b/examples/expressjs-ethr/src/setup.ts @@ -10,6 +10,7 @@ import * as SD from 'daf-selective-disclosure' import * as TG from 'daf-trust-graph' import * as DBG from 'daf-debug' import * as DIDComm from 'daf-did-comm' +import * as URL from 'daf-url' import { NodeSqlite3 } from 'daf-node-sqlite3' import { DataStore } from 'daf-data-store' @@ -43,6 +44,7 @@ const identityControllers = [new EthrDidFsController(identityStoreFilename)] const messageValidator = new DBG.MessageValidator() messageValidator + .setNext(new URL.MessageValidator()) .setNext(new DIDComm.MessageValidator()) .setNext(new DidJwt.MessageValidator()) .setNext(new W3c.MessageValidator()) diff --git a/examples/expressjs-ethr/tsconfig.json b/examples/expressjs-ethr/tsconfig.json index 861c423dc..b470b6bd9 100644 --- a/examples/expressjs-ethr/tsconfig.json +++ b/examples/expressjs-ethr/tsconfig.json @@ -28,6 +28,7 @@ { "path": "../../packages/daf-selective-disclosure" }, { "path": "../../packages/daf-sodium-fs" }, { "path": "../../packages/daf-trust-graph" }, + { "path": "../../packages/daf-url" }, { "path": "../../packages/daf-w3c" } ] } diff --git a/packages/daf-cli/package.json b/packages/daf-cli/package.json index 7902a44ea..fc844b77f 100644 --- a/packages/daf-cli/package.json +++ b/packages/daf-cli/package.json @@ -27,6 +27,7 @@ "daf-selective-disclosure": "^0.9.0", "daf-sodium-fs": "^0.9.0", "daf-trust-graph": "^0.9.0", + "daf-url": "^0.9.0", "daf-w3c": "^0.9.0", "date-fns": "^2.8.1", "debug": "^4.1.1", diff --git a/packages/daf-cli/src/msg.ts b/packages/daf-cli/src/msg.ts index 8e7990a66..ea15fd251 100644 --- a/packages/daf-cli/src/msg.ts +++ b/packages/daf-cli/src/msg.ts @@ -1,5 +1,5 @@ import * as Daf from 'daf-core' -import { core } from './setup' +import { core, dataStore } from './setup' import program from 'commander' program @@ -7,6 +7,7 @@ program .description('Handle raw message (JWT)') .action(async raw => { try { + await dataStore.initialize() const result = await core.validateMessage( new Daf.Message({ raw, diff --git a/packages/daf-cli/src/setup.ts b/packages/daf-cli/src/setup.ts index c4cc39cbf..5a7a3d907 100644 --- a/packages/daf-cli/src/setup.ts +++ b/packages/daf-cli/src/setup.ts @@ -10,6 +10,7 @@ import * as SD from 'daf-selective-disclosure' import * as TG from 'daf-trust-graph' import * as DBG from 'daf-debug' import * as DIDComm from 'daf-did-comm' +import * as URL from 'daf-url' import { NodeSqlite3 } from 'daf-node-sqlite3' import { DataStore } from 'daf-data-store' @@ -46,6 +47,7 @@ const identityControllers = [new EthrDidFsController(identityStoreFilename)] const messageValidator = new DBG.MessageValidator() messageValidator + .setNext(new URL.MessageValidator()) .setNext(new DIDComm.MessageValidator()) .setNext(new DidJwt.MessageValidator()) .setNext(new W3c.MessageValidator()) diff --git a/packages/daf-cli/tsconfig.json b/packages/daf-cli/tsconfig.json index c1ed0134b..6202bb7b5 100644 --- a/packages/daf-cli/tsconfig.json +++ b/packages/daf-cli/tsconfig.json @@ -17,6 +17,7 @@ { "path": "../daf-selective-disclosure" }, { "path": "../daf-sodium-fs" }, { "path": "../daf-trust-graph" }, + { "path": "../daf-url" }, { "path": "../daf-w3c" } ] } diff --git a/packages/daf-url/LICENSE b/packages/daf-url/LICENSE new file mode 100644 index 000000000..261eeb9e9 --- /dev/null +++ b/packages/daf-url/LICENSE @@ -0,0 +1,201 @@ + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. diff --git a/packages/daf-url/README.md b/packages/daf-url/README.md new file mode 100644 index 000000000..9f63b462f --- /dev/null +++ b/packages/daf-url/README.md @@ -0,0 +1 @@ +# DAF URL diff --git a/packages/daf-url/package.json b/packages/daf-url/package.json new file mode 100644 index 000000000..220f3db59 --- /dev/null +++ b/packages/daf-url/package.json @@ -0,0 +1,31 @@ +{ + "name": "daf-url", + "description": "DAF URL message validator", + "version": "0.9.0", + "main": "build/index.js", + "types": "build/index.d.ts", + "scripts": { + "build": "tsc" + }, + "dependencies": { + "daf-core": "^0.9.0", + "debug": "^4.1.1", + "url-parse": "^1.4.7" + }, + "devDependencies": { + "@types/debug": "^4.1.5", + "@types/url-parse": "^1.4.3", + "typescript": "^3.7.2" + }, + "files": [ + "build/**/*", + "src/**/*", + "README.md", + "LICENSE" + ], + "repository": "git@github.com:uport-project/daf.git", + "author": "Simonas Karuzas ", + "license": "Apache-2.0", + "keywords": [], + "gitHead": "ec317e0f10cffe731648a8c2d8f58def3d3c85ff" +} diff --git a/packages/daf-url/src/__tests__/default.test.ts b/packages/daf-url/src/__tests__/default.test.ts new file mode 100644 index 000000000..0f49fd249 --- /dev/null +++ b/packages/daf-url/src/__tests__/default.test.ts @@ -0,0 +1,22 @@ +import { Message } from 'daf-core' +import { MessageValidator } from '../message-validator' +describe('daf-url', () => { + const validator = new MessageValidator() + it('should reject unknown message type', async () => { + const message = new Message({ raw: 'test', meta: { type: 'test' } }) + expect(validator.validate(message, null)).rejects.toEqual('Unsupported message type') + }) + + it('should transform message after standard URL', async () => { + const JWT = + 'eyJ0eXAiOiJKV1QiLCJhbGciOiJFUzI1NkstUiJ9.eyJpYXQiOjE1NzU5Njc1MzEsInR5cGUiOiJzZHIiLCJ0YWciOiJzZXNzaW9uLTEyMyIsImNsYWltcyI6W3sicmVhc29uIjoiV2UgbmVlZCB5b3VyIG5hbWUiLCJjbGFpbVR5cGUiOiJuYW1lIn1dLCJpc3MiOiJkaWQ6ZXRocjoweDViMmIwMzM1Mzk4NDM2MDFmYjgxZGYxNzA0OTE4NzA0ZmQwMTQxZmEifQ.KoHbpJ5HkLLIw8iEqsu2Jql9m5dbydNy2zO53GKuIbwfPOW842_IPXw2zwVtj0FcEuHUkzhx-bhS28Zhmvkv2gE' + const message = new Message({ + raw: 'https://identity.foundation/ssi/?c_i=' + JWT, + meta: { + type: 'QRCode', + }, + }) + expect(validator.validate(message, null)).rejects.toEqual('Unsupported message type') + expect(message.raw).toEqual(JWT) + }) +}) diff --git a/packages/daf-url/src/index.ts b/packages/daf-url/src/index.ts new file mode 100644 index 000000000..b15f40ccd --- /dev/null +++ b/packages/daf-url/src/index.ts @@ -0,0 +1 @@ +export { MessageValidator } from './message-validator' diff --git a/packages/daf-url/src/message-validator.ts b/packages/daf-url/src/message-validator.ts new file mode 100644 index 000000000..83a16a757 --- /dev/null +++ b/packages/daf-url/src/message-validator.ts @@ -0,0 +1,24 @@ +import { Core, AbstractMessageValidator, Message } from 'daf-core' +import parse = require('url-parse') + +import Debug from 'debug' +const debug = Debug('daf:url:message-validator') + +export class MessageValidator extends AbstractMessageValidator { + async validate(message: Message, core: Core): Promise { + const parsed = parse(message.raw, true) + + if (parsed && parsed.query && parsed.query.c_i) { + debug('Detected standard URL') + message.transform({ + raw: parsed.query.c_i, + meta: { + type: 'URL', + id: parsed.origin + parsed.pathname, + }, + }) + } + + return super.validate(message, core) + } +} diff --git a/packages/daf-url/tsconfig.json b/packages/daf-url/tsconfig.json new file mode 100644 index 000000000..166b53ace --- /dev/null +++ b/packages/daf-url/tsconfig.json @@ -0,0 +1,8 @@ +{ + "extends": "../tsconfig.settings.json", + "compilerOptions": { + "rootDir": "src", + "outDir": "build" + }, + "references": [{ "path": "../daf-core" }] +} diff --git a/packages/tsconfig.json b/packages/tsconfig.json index 2ba00727c..de27313c8 100644 --- a/packages/tsconfig.json +++ b/packages/tsconfig.json @@ -17,6 +17,7 @@ { "path": "daf-selective-disclosure" }, { "path": "daf-sodium-fs" }, { "path": "daf-trust-graph" }, + { "path": "daf-url" }, { "path": "daf-w3c" } ] } diff --git a/yarn.lock b/yarn.lock index d24e676dd..bd8adaeba 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1730,6 +1730,11 @@ dependencies: "@types/node" "*" +"@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" + integrity sha512-4kHAkbV/OfW2kb5BLVUuUMoumB3CP8rHqlw48aHvFy5tf9ER0AfOonBlX29l/DD68G70DmyhRlSYfQPSYpC5Vw== + "@types/uuid@^3.4.6": version "3.4.6" resolved "https://registry.yarnpkg.com/@types/uuid/-/uuid-3.4.6.tgz#d2c4c48eb85a757bf2927f75f939942d521e3016" @@ -8242,6 +8247,11 @@ query-string@^6.8.2: split-on-first "^1.0.0" strict-uri-encode "^2.0.0" +querystringify@^2.1.1: + version "2.1.1" + resolved "https://registry.yarnpkg.com/querystringify/-/querystringify-2.1.1.tgz#60e5a5fd64a7f8bfa4d2ab2ed6fdf4c85bad154e" + integrity sha512-w7fLxIRCRT7U8Qu53jQnJyPkYZIaR4n5151KMfcJlO/A9397Wxb1amJvROTK6TOnp7PfoAmg/qXiNHI+08jRfA== + quick-lru@^1.0.0: version "1.1.0" resolved "https://registry.yarnpkg.com/quick-lru/-/quick-lru-1.1.0.tgz#4360b17c61136ad38078397ff11416e186dcfbb8" @@ -8602,6 +8612,11 @@ require-main-filename@^2.0.0: resolved "https://registry.yarnpkg.com/require-main-filename/-/require-main-filename-2.0.0.tgz#d0b329ecc7cc0f61649f62215be69af54aa8989b" integrity sha512-NKN5kMDylKuldxYLSUfrbo5Tuzh4hd+2E8NPPX02mZtn1VuREQToYe/ZdlJy+J3uCpfaiGF05e7B8W0iXbQHmg== +requires-port@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/requires-port/-/requires-port-1.0.0.tgz#925d2601d39ac485e091cf0da5c6e694dc3dcaff" + integrity sha1-kl0mAdOaxIXgkc8NpcbmlNw9yv8= + reselect@^3.0.1: version "3.0.1" resolved "https://registry.yarnpkg.com/reselect/-/reselect-3.0.1.tgz#efdaa98ea7451324d092b2b2163a6a1d7a9a2147" @@ -9918,6 +9933,14 @@ url-parse-lax@^1.0.0: dependencies: prepend-http "^1.0.1" +url-parse@^1.4.7: + version "1.4.7" + resolved "https://registry.yarnpkg.com/url-parse/-/url-parse-1.4.7.tgz#a8a83535e8c00a316e403a5db4ac1b9b853ae278" + integrity sha512-d3uaVyzDB9tQoSXFvuSUNFibTd9zxd2bkVrDRvF5TmvWWQwqE4lgYJ5m+x1DbecWkw+LK4RNl2CU1hHuOKPVlg== + dependencies: + querystringify "^2.1.1" + requires-port "^1.0.0" + use@^3.1.0: version "3.1.1" resolved "https://registry.yarnpkg.com/use/-/use-3.1.1.tgz#d50c8cac79a19fbc20f2911f56eb973f4e10070f"