diff --git a/CHANGELOG.md b/CHANGELOG.md index 853b70188..e3491656a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,8 @@ +## 1.3.13 (September 29, 2020) + +- add did auth storage tingo +- [skip travis] update readme + ## 1.3.12 (August 31, 2020) - [skip travis] update readme diff --git a/did/did-auth-storage-tingo/LICENSE b/did/did-auth-storage-tingo/LICENSE new file mode 100644 index 000000000..973582a17 --- /dev/null +++ b/did/did-auth-storage-tingo/LICENSE @@ -0,0 +1,13 @@ +Copyright 2018-2019 ArcBlock + +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/did/did-auth-storage-tingo/README.md b/did/did-auth-storage-tingo/README.md new file mode 100644 index 000000000..a56236e8f --- /dev/null +++ b/did/did-auth-storage-tingo/README.md @@ -0,0 +1,51 @@ +![did-auth-storage-tingo](https://www.arcblock.io/.netlify/functions/badge/?text=did-auth-storage-tingo) + +[![styled with prettier](https://img.shields.io/badge/styled_with-prettier-ff69b4.svg)](https://github.com/prettier/prettier) + +> Storage engine that uses tingo to store data, implements interfaces defined in `@arcblock/did-auth-storage`. + + +## Table of Contents + +* [Install](#install) +* [Usage](#usage) +* [Contributors](#contributors) + + +## Install + +```sh +npm install @arcblock/did-auth-storage-tingo +// or +yarn add @arcblock/did-auth-storage-tingo +``` + + +## Usage + +```js +const tingoStorage = require('@arcblock/did-auth-storage-tingo'); + +const storage = new tingoStorage({ + dbPath: '/some/local/path', + collection: 'did_auth_tokens', +}); + +// Listen on events of the storage +storage.on('create', d => console.log('create', d)); +storage.on('update', d => console.log('update', d)); +storage.on('destroy', d => console.log('destroy', d)); + +(async () => { + const token = '123456'; + const item = await storage.create(token); +})(); +``` + + +## Contributors + +| Name | Website | +| ---------------- | -------------------------- | +| **wangshijun** | | +| **NateRobinson** | | diff --git a/did/did-auth-storage-tingo/docs/README.md b/did/did-auth-storage-tingo/docs/README.md new file mode 100644 index 000000000..c070de191 --- /dev/null +++ b/did/did-auth-storage-tingo/docs/README.md @@ -0,0 +1,7 @@ + +## Contributors + +| Name | Website | +| ---------------- | -------------------------- | +| **wangshijun** | | +| **NateRobinson** | | diff --git a/did/did-auth-storage-tingo/jest.config.js b/did/did-auth-storage-tingo/jest.config.js new file mode 100644 index 000000000..00a430c3d --- /dev/null +++ b/did/did-auth-storage-tingo/jest.config.js @@ -0,0 +1,9 @@ +// For a detailed explanation regarding each configuration property, visit: +// https://jestjs.io/docs/en/configuration.html +module.exports = { + browser: false, + clearMocks: true, + coverageDirectory: 'coverage', + testEnvironment: 'node', + testMatch: ['**/__tests__/**/*.js?(x)', '**/?(*.)+(spec).js?(x)'], +}; diff --git a/did/did-auth-storage-tingo/lib/index.d.ts b/did/did-auth-storage-tingo/lib/index.d.ts new file mode 100644 index 000000000..d47ec6b58 --- /dev/null +++ b/did/did-auth-storage-tingo/lib/index.d.ts @@ -0,0 +1,59 @@ +// Generate by [js2dts@0.3.3](https://github.com/whxaxes/js2dts#readme) + +import { EventEmitter } from 'events'; +/** + * Defines the interface of DID-Auth Token Storage + * Which is used to persist state during the DID-Auth process in a dApp + * + * @class AuthStorage + * @see @arcblock/did-auth-storage-firebase + * @see @arcblock/did-auth-storage-mongo + * @see @arcblock/did-auth-storage-keystone + * @extends {EventEmitter} + */ +declare class AuthStorage extends EventEmitter { + /** + * Creates an instance of AuthStorage. + * + * @class + * @param {object} options + */ + constructor(options: any); + create(token: any, status?: string): void; + read(token: any): void; + update(token: any, updates: any): void; + delete(token: any): void; + exist(token: any, did: any): void; +} +declare class TingoAuthStorage extends AuthStorage { + collectionName: string; + options: _Lib.T100; + db: any; + /** + * Creates an instance of TingoAuthStorage. + * + * @class + * @param {Object} options { collection, url } + * @param {string} options.dbPath - tingodb connection string + * @param {string} [options.collection='did_auth_tokens'] - which collection to store did auth tokens + */ + constructor(options: _Lib.T100); + connectionFailed(err: any): void; + setCollection(collection: any): void; + collectionReady(): any; + read(token: any): any; + create(token: any, status?: string): any; + update(token: any, updates: any, upsert?: boolean): any; + delete(token: any): any; + exist(token: any, did: any): any; + clear(): any; + close(): void; +} +declare const _Lib: typeof TingoAuthStorage; +declare namespace _Lib { + export interface T100 { + dbPath: string; + collection?: string; + } +} +export = _Lib; diff --git a/did/did-auth-storage-tingo/lib/index.js b/did/did-auth-storage-tingo/lib/index.js new file mode 100644 index 000000000..a6d949406 --- /dev/null +++ b/did/did-auth-storage-tingo/lib/index.js @@ -0,0 +1,137 @@ +/* eslint-disable max-len */ +/* eslint-disable compat/compat */ +/* eslint-disable prefer-destructuring */ +/* eslint-disable no-param-reassign */ +/* eslint-disable no-underscore-dangle */ +const Db = require('tingodb')().Db; +const StorageInterface = require('@arcblock/did-auth-storage'); + +const debug = require('debug')(require('../package.json').name); + +const promiseUpdateOrInsert = (collection, token, updates, upsert = false) => + new Promise((resolve, reject) => { + collection.update({ token }, { $set: updates }, { upsert }, (err, result) => { + if (err) { + return reject(err); + } + return resolve(result); + }); + }); + +const promiseFindOne = (collection, condition) => + new Promise((resolve, reject) => { + collection.findOne(condition, (err, result) => { + if (err) { + return reject(err); + } + return resolve(result); + }); + }); + +const promiseDelete = (collection, condition) => + new Promise((resolve, reject) => { + collection.remove(condition, (err, result) => { + if (err) { + return reject(err); + } + return resolve(result); + }); + }); + +module.exports = class TingoAuthStorage extends StorageInterface { + /** + * Creates an instance of TingoAuthStorage. + * + * @class + * @param {Object} options { collection, url } + * @param {string} options.dbPath - tingodb connection string + * @param {string} [options.collection='did_auth_tokens'] - which collection to store did auth tokens + */ + constructor(options) { + options = options || {}; + + super(options); + + this.collectionName = options.collection || 'did_auth_tokens'; + this.options = options; + + if (options.dbPath) { + this.db = new Db(options.dbPath, {}); + this.setCollection(this.db.collection(this.collectionName)); + } else { + throw new Error('Connection strategy not found'); + } + } + + connectionFailed(err) { + throw err; + } + + setCollection(collection) { + this.collectionReadyPromise = undefined; + this.collection = collection; + } + + collectionReady() { + let promise = this.collectionReadyPromise; + if (!promise) { + // eslint-disable-next-line no-unused-vars + promise = new Promise((resolve, reject) => resolve(this.collection)); + this.collectionReadyPromise = promise; + } + return promise; + } + + read(token) { + return this.collectionReady().then(collection => promiseFindOne(collection, { token })); + } + + create(token, status = 'created') { + return this.update(token, { status }, true); + } + + update(token, updates, upsert = false) { + if (!updates.updatedAt) { + updates.updatedAt = new Date(); + } + debug('update', { token, updates }); + return this.collectionReady() + .then(collection => promiseUpdateOrInsert(collection, token, updates, upsert)) + .then(rawResponse => { + if (rawResponse.result) { + rawResponse = rawResponse.result; + } + const data = Object.assign({ token }, updates); + + if (rawResponse && rawResponse.upserted) { + this.emit('create', data); + debug('emit.create', { token, updates }); + } else { + this.emit('update', data); + debug('emit.update', { token, updates }); + } + + return data; + }); + } + + delete(token) { + return this.collectionReady() + .then(collection => promiseDelete(collection, { token })) + .then(() => this.emit('destroy', token)); + } + + exist(token, did) { + return this.collectionReady().then(collection => promiseFindOne(collection, { token, did })); + } + + clear() { + return this.collectionReady().then(collection => collection.drop()); + } + + close() { + if (this.db) { + this.db.close(); + } + } +}; diff --git a/did/did-auth-storage-tingo/package.json b/did/did-auth-storage-tingo/package.json new file mode 100644 index 000000000..7b761f7df --- /dev/null +++ b/did/did-auth-storage-tingo/package.json @@ -0,0 +1,70 @@ +{ + "name": "@arcblock/did-auth-storage-tingo", + "description": "Storage engine that uses tingodb for did-auth", + "version": "1.2.7", + "author": "wangshijun (https://ocap.arcblock.io)", + "bugs": { + "url": "https://github.com/ArcBlock/forge-js/issues", + "email": "shijun@arcblock.io" + }, + "publishConfig": { + "access": "public" + }, + "contributors": [ + "wangshijun (https://ocap.arcblock.io)", + "NateRobinson (https://ocap.arcblock.io)" + ], + "devDependencies": { + "j2d": "^1.0.3-dev", + "jest": "^23.5.0", + "remark-cli": "^5.0.0", + "remark-preset-github": "^0.0.9" + }, + "remarkConfig": { + "plugins": [ + "preset-github", + [ + "validate-links", + { + "repository": "ArcBlock/forge-js" + } + ] + ] + }, + "homepage": "https://github.com/ArcBlock/forge-js/tree/master/did/did-auth-storage-tingo", + "keywords": [ + "forge", + "blockchain", + "arcblock", + "sdk", + "nodejs" + ], + "license": "Apache-2.0", + "main": "./lib/index.js", + "files": [ + "lib" + ], + "repository": { + "type": "git", + "url": "https://github.com/ArcBlock/forge-js/tree/master/did/did-auth-storage-tingo" + }, + "scripts": { + "lint": "eslint lib tests", + "docs": "yarn generate-dts && yarn generate-docs && yarn cleanup-docs && yarn format-docs", + "cleanup-docs": "node ../../tools/cleanup-docs.js docs/README.md $npm_package_name", + "generate-docs": "jsdoc2md lib/index.js > docs/README.md", + "generate-dts": "j2d lib/index.js", + "format-docs": "remark . -o", + "precommit": "CI=1 yarn test", + "prepush": "CI=1 yarn test", + "test": "npm run lint && node tools/jest.js", + "coverage": "npm run lint && yarn test -- --coverage" + }, + "gitHead": "87990c8b5e215107fc587c1ced0d6b3e2cd2483e", + "dependencies": { + "@arcblock/did-auth-storage": "^1.2.7", + "debug": "^4.1.1", + "mongodb": "1.4.x", + "tingodb": "^0.6.1" + } +} diff --git a/did/did-auth-storage-tingo/tests/index.spec.js b/did/did-auth-storage-tingo/tests/index.spec.js new file mode 100644 index 000000000..2d3850c40 --- /dev/null +++ b/did/did-auth-storage-tingo/tests/index.spec.js @@ -0,0 +1,5 @@ +describe('#Storage', () => { + test('should have test', () => { + expect(true).toBeTruthy(); + }); +}); diff --git a/did/did-auth-storage-tingo/tools/jest.js b/did/did-auth-storage-tingo/tools/jest.js new file mode 100644 index 000000000..81e624838 --- /dev/null +++ b/did/did-auth-storage-tingo/tools/jest.js @@ -0,0 +1,25 @@ +/* eslint no-console: "off" */ +// Do this as the first thing so that any code reading it knows the right env. +process.env.BABEL_ENV = 'test'; +process.env.NODE_ENV = 'test'; +process.env.PUBLIC_URL = ''; +process.env.DEBUG = '@arcblock/*,-@arcblock/forge-proto'; + +// Makes the script crash on unhandled rejections instead of silently +// ignoring them. In the future, promise rejections that are not handled will +// terminate the Node.js process with a non-zero exit code. +process.on('unhandledRejection', err => { + console.trace(err); + process.exit(1); +}); + +const jest = require('jest'); +let argv = process.argv.slice(2); +argv.push('--forceExit'); + +// Watch unless on CI or in coverage mode +if (!process.env.CI && argv.indexOf('--coverage') < 0) { + argv.push('--watch'); +} + +jest.run(argv); diff --git a/version b/version index 90a7f6029..7962dcfdb 100644 --- a/version +++ b/version @@ -1 +1 @@ -1.3.12 +1.3.13 diff --git a/yarn.lock b/yarn.lock index b8aa557ab..1d8918bb3 100644 --- a/yarn.lock +++ b/yarn.lock @@ -2987,11 +2987,23 @@ bser@2.1.1: dependencies: node-int64 "^0.4.0" +bson@^1.0.4: + version "1.1.5" + resolved "https://registry.yarnpkg.com/bson/-/bson-1.1.5.tgz#2aaae98fcdf6750c0848b0cba1ddec3c73060a34" + integrity sha512-kDuEzldR21lHciPQAIulLs1LZlCXdLziXI6Mb/TDkwXhb//UORJNPXgcRs2CuO4H0DcMkpfT3/ySsP3unoZjBg== + bson@^1.1.0: version "1.1.4" resolved "https://registry.yarnpkg.com/bson/-/bson-1.1.4.tgz#f76870d799f15b854dffb7ee32f0a874797f7e89" integrity sha512-S/yKGU1syOMzO86+dGpg2qGoDL0zvzcb262G+gqEy6TgP6rt6z6qxSFX/8X6vLC91P7G7C3nLs0+bvDzmvBA3Q== +bson@~0.2: + version "0.2.22" + resolved "https://registry.yarnpkg.com/bson/-/bson-0.2.22.tgz#fcda103f26d0c074d5a52d50927db80fd02b4b39" + integrity sha1-/NoQPybQwHTVpS1Qkn24D9ArSzk= + dependencies: + nan "~1.8" + btoa-lite@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/btoa-lite/-/btoa-lite-1.0.0.tgz#337766da15801210fdd956c22e9c6891ab9d0337" @@ -7894,6 +7906,13 @@ jws@^4.0.0: jwa "^2.0.0" safe-buffer "^5.0.1" +kerberos@0.0.11: + version "0.0.11" + resolved "https://registry.yarnpkg.com/kerberos/-/kerberos-0.0.11.tgz#cb29891c21c22ac195f3140b97dd12204fea7dc2" + integrity sha1-yymJHCHCKsGV8xQLl90SIE/qfcI= + dependencies: + nan "~1.8" + kind-of@^3.0.2, kind-of@^3.0.3, kind-of@^3.2.0: version "3.2.2" resolved "https://registry.yarnpkg.com/kind-of/-/kind-of-3.2.2.tgz#31ea21a734bab9bbb0f32466d893aea51e4a3c64" @@ -8862,6 +8881,16 @@ mongodb-core@3.1.11: optionalDependencies: saslprep "^1.0.0" +mongodb@1.4.x: + version "1.4.40" + resolved "https://registry.yarnpkg.com/mongodb/-/mongodb-1.4.40.tgz#cfd80b74fdf0fa053f2ccfb5f49c47ca32a38efb" + integrity sha1-z9gLdP3w+gU/LM+19JxHyjKjjvs= + dependencies: + bson "~0.2" + optionalDependencies: + kerberos "0.0.11" + readable-stream latest + mongodb@3.1.13: version "3.1.13" resolved "https://registry.yarnpkg.com/mongodb/-/mongodb-3.1.13.tgz#f8cdcbb36ad7a08b570bd1271c8525753f75f9f4" @@ -8939,6 +8968,11 @@ nan@^2.12.1, nan@^2.14.0: resolved "https://registry.yarnpkg.com/nan/-/nan-2.14.1.tgz#d7be34dfa3105b91494c3147089315eff8874b01" integrity sha512-isWHgVjnFjh2x2yuJ/tj3JbwoHu3UC2dX5G/88Cm24yB6YopVgxvBObDY7n5xW6ExmFhJpSEQqFPvq9zaXc8Jw== +nan@~1.8: + version "1.8.4" + resolved "https://registry.yarnpkg.com/nan/-/nan-1.8.4.tgz#3c76b5382eab33e44b758d2813ca9d92e9342f34" + integrity sha1-PHa1OC6rM+RLdY0oE8qdkuk0LzQ= + nanomatch@^1.2.9: version "1.2.13" resolved "https://registry.yarnpkg.com/nanomatch/-/nanomatch-1.2.13.tgz#b87a8aa4fc0de8fe6be88895b38983ff265bd119" @@ -10393,7 +10427,7 @@ read@1, read@~1.0.1: string_decoder "~1.1.1" util-deprecate "~1.0.1" -"readable-stream@2 || 3", readable-stream@^3.0.2, readable-stream@^3.1.1, readable-stream@^3.6.0: +"readable-stream@2 || 3", readable-stream@^3.0.2, readable-stream@^3.1.1, readable-stream@^3.6.0, readable-stream@latest: version "3.6.0" resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-3.6.0.tgz#337bbda3adc0706bd3e024426a286d4b4b2c9198" integrity sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA== @@ -11646,6 +11680,11 @@ safe-regex@^1.1.0: dependencies: ret "~0.1.10" +safe@^0.4.5: + version "0.4.6" + resolved "https://registry.yarnpkg.com/safe/-/safe-0.4.6.tgz#1d5580cf2635c5cb940ea48fb5081ae3c25b1be1" + integrity sha1-HVWAzyY1xcuUDqSPtQga48JbG+E= + safefs@^4.1.0: version "4.2.0" resolved "https://registry.yarnpkg.com/safefs/-/safefs-4.2.0.tgz#6d60d3aecc47c3d02b0ecf39ee0a3798cb363218" @@ -12651,6 +12690,17 @@ timers-browserify@^2.0.4: dependencies: setimmediate "^1.0.4" +tingodb@^0.6.1: + version "0.6.1" + resolved "https://registry.yarnpkg.com/tingodb/-/tingodb-0.6.1.tgz#f63336259af7dfa6c90dfe2556a0dfb0d4eede59" + integrity sha1-9jM2JZr336bJDf4lVqDfsNTu3lk= + dependencies: + lodash "^4.17.5" + safe "^0.4.5" + safe-buffer "^5.1.1" + optionalDependencies: + bson "^1.0.4" + tmp@^0.0.33: version "0.0.33" resolved "https://registry.yarnpkg.com/tmp/-/tmp-0.0.33.tgz#6d34335889768d21b2bcda0aa277ced3b1bfadf9"