diff --git a/.gitignore b/.gitignore index 07545ca..6d832e7 100644 --- a/.gitignore +++ b/.gitignore @@ -8,6 +8,8 @@ db/*.db start.sh config/integrations/*_development.yaml config/integrations/*_production.yaml +build/ +dimension.db # Logs logs diff --git a/.travis.yml b/.travis.yml index 49b9257..297b85c 100644 --- a/.travis.yml +++ b/.travis.yml @@ -9,3 +9,4 @@ install: - npm install script: - npm run build + - npm run lint:app diff --git a/config/database.json b/config/database.json deleted file mode 100644 index f2abade..0000000 --- a/config/database.json +++ /dev/null @@ -1,13 +0,0 @@ -{ - "defaultEnv": { - "ENV": "NODE_ENV" - }, - "development": { - "driver": "sqlite", - "filename": "db/development.db" - }, - "production": { - "driver": "sqlite", - "filename": "db/production.db" - } -} \ No newline at end of file diff --git a/config/default.yaml b/config/default.yaml index 7824d86..200af3d 100644 --- a/config/default.yaml +++ b/config/default.yaml @@ -3,6 +3,28 @@ web: port: 8184 address: '0.0.0.0' +# Homeserver configuration (used to proxy some requests to the homeserver for processing) +homeserver: + name: "t2bot.io" + accessToken: "something" + +# These users can modify the integrations this Dimension supports. +# To access the admin interface, open Dimension in Riot and click the settings icon. +admins: + - "@someone:domain.com" + +# IPs and CIDR ranges listed here will be blocked from being widgets. +# Note: Widgets may still be embedded with restricted content, although not through Dimension directly. +widgetBlacklist: +- 10.0.0.0/8 +- 172.16.0.0/12 +- 192.168.0.0/16 +- 127.0.0.0/8 + +# Where the database for Dimension is +database: + file: "dimension.db" + # Settings for controlling how logging works logging: file: logs/dimension.log @@ -11,29 +33,4 @@ logging: fileLevel: verbose rotate: size: 52428800 # bytes, default is 50mb - count: 5 - -# Demo bot configuration. Used purely to show how to configure a self-hosted bot in Dimension -demobot: - enabled: false - userId: "@dimension:t2bot.io" - homeserverUrl: "https://t2bot.io" - accessToken: "something" - -# Upstream configuration. This should almost never change. -upstreams: -- name: vector - url: "https://scalar.vector.im/api" - -# Homeserver configuration (used to proxy some requests to the homeserver for processing) -homeserver: - name: "t2bot.io" - accessToken: "something" - -# IPs and CIDR ranges listed here will be blocked from being widgets. -# Note: Widgets may still be embedded with restricted content, although not through Dimension directly. -widgetBlacklist: -- 10.0.0.0/8 -- 172.16.0.0/12 -- 192.168.0.0/16 -- 127.0.0.0/8 \ No newline at end of file + count: 5 \ No newline at end of file diff --git a/db/.gitkeep b/db/.gitkeep deleted file mode 100644 index e69de29..0000000 diff --git a/migrations/20170527035704-add-tokens-table.js b/migrations/20170527035704-add-tokens-table.js deleted file mode 100644 index 34ad73e..0000000 --- a/migrations/20170527035704-add-tokens-table.js +++ /dev/null @@ -1,34 +0,0 @@ -'use strict'; - -var dbm; -var type; -var seed; - -/** - * We receive the dbmigrate dependency from dbmigrate initially. - * This enables us to not have to rely on NODE_PATH. - */ -exports.setup = function (options, seedLink) { - dbm = options.dbmigrate; - type = dbm.dataType; - seed = seedLink; -}; - -exports.up = function (db) { - return db.createTable("tokens", { - id: {type: 'int', primaryKey: true, autoIncrement: true, notNull: true}, - matrixUserId: {type: 'string', notNull: true}, - matrixServerName: {type: 'string', notNull: true}, - matrixAccessToken: {type: 'string', notNull: true}, - scalarToken: {type: 'string', notNull: true}, - expires: {type: 'timestamp', notNull: true} - }); -}; - -exports.down = function (db) { - return db.dropTable("tokens"); -}; - -exports._meta = { - "version": 1 -}; diff --git a/migrations/20170527221910-add-upstream-scalar-token-to-tokens.js b/migrations/20170527221910-add-upstream-scalar-token-to-tokens.js deleted file mode 100644 index 7d025aa..0000000 --- a/migrations/20170527221910-add-upstream-scalar-token-to-tokens.js +++ /dev/null @@ -1,27 +0,0 @@ -'use strict'; - -var dbm; -var type; -var seed; - -/** - * We receive the dbmigrate dependency from dbmigrate initially. - * This enables us to not have to rely on NODE_PATH. - */ -exports.setup = function (options, seedLink) { - dbm = options.dbmigrate; - type = dbm.dataType; - seed = seedLink; -}; - -exports.up = function (db) { - return db.addColumn('tokens', 'upstreamToken', {type: 'string', notNull: false}); // has to be nullable, despite our best intentions -}; - -exports.down = function (db) { - return db.removeColumn('tokens', 'upstreamToken'); -}; - -exports._meta = { - "version": 1 -}; diff --git a/package-lock.json b/package-lock.json index e0cdec6..494863d 100644 --- a/package-lock.json +++ b/package-lock.json @@ -106,6 +106,54 @@ "integrity": "sha1-WLyB9hACj0BSZSnOQEg6lQKBY7A=", "dev": true }, + "@types/bluebird": { + "version": "3.5.18", + "resolved": "https://registry.npmjs.org/@types/bluebird/-/bluebird-3.5.18.tgz", + "integrity": "sha512-OTPWHmsyW18BhrnG5x8F7PzeZ2nFxmHGb42bZn79P9hl+GI5cMzyPgQTwNjbem0lJhoru/8vtjAFCUOu3+gE2w==" + }, + "@types/body-parser": { + "version": "1.16.8", + "resolved": "https://registry.npmjs.org/@types/body-parser/-/body-parser-1.16.8.tgz", + "integrity": "sha512-BdN2PXxOFnTXFcyONPW6t0fHjz2fvRZHVMFpaS0wYr+Y8fWEaNOs4V8LEu/fpzQlMx+ahdndgTaGTwPC+J/EeA==", + "requires": { + "@types/express": "4.0.39", + "@types/node": "8.5.1" + } + }, + "@types/continuation-local-storage": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/@types/continuation-local-storage/-/continuation-local-storage-3.2.1.tgz", + "integrity": "sha1-oz4N+dzptCTRyY/E/evYV43O7H4=", + "requires": { + "@types/node": "8.5.1" + } + }, + "@types/cookie-parser": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/@types/cookie-parser/-/cookie-parser-1.4.1.tgz", + "integrity": "sha512-iJY6B3ZGufLiDf2OCAgiAAQuj1sMKC/wz/7XCEjZ+/MDuultfFJuSwrBKcLSmJ5iYApLzCCYBYJZs0Ws8GPmwA==", + "requires": { + "@types/express": "4.0.39" + } + }, + "@types/express": { + "version": "4.0.39", + "resolved": "https://registry.npmjs.org/@types/express/-/express-4.0.39.tgz", + "integrity": "sha512-dBUam7jEjyuEofigUXCtublUHknRZvcRgITlGsTbFgPvnTwtQUt2NgLakbsf+PsGo/Nupqr3IXCYsOpBpofyrA==", + "requires": { + "@types/body-parser": "1.16.8", + "@types/express-serve-static-core": "4.0.57", + "@types/serve-static": "1.13.1" + } + }, + "@types/express-serve-static-core": { + "version": "4.0.57", + "resolved": "https://registry.npmjs.org/@types/express-serve-static-core/-/express-serve-static-core-4.0.57.tgz", + "integrity": "sha512-QLAHjdLwEICm3thVbXSKRoisjfgMVI4xJH/HU8F385BR2HI7PmM6ax4ELXf8Du6sLmSpySXMYaI+xc//oQ/IFw==", + "requires": { + "@types/node": "8.5.1" + } + }, "@types/geojson": { "version": "1.0.6", "resolved": "https://registry.npmjs.org/@types/geojson/-/geojson-1.0.6.tgz", @@ -117,10 +165,58 @@ "integrity": "sha512-q2WC02YxQoX2nY1HRKlYGHpGP1saPmD7GN0pwCDlTz35a4eOtJG+aHRlXyjCuXokUukSrR2aXyBhSW3j+jPc0A==", "dev": true }, + "@types/lodash": { + "version": "4.14.91", + "resolved": "https://registry.npmjs.org/@types/lodash/-/lodash-4.14.91.tgz", + "integrity": "sha512-k+nc3moSlAaXacyvz4/c6D9lnUeI6AKsLvkXFuNzUEEqMw7sjDnLW2GqlJ4nyFgMX/p+QzvVG6zRoDo4lJIV5g==" + }, + "@types/mime": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/@types/mime/-/mime-2.0.0.tgz", + "integrity": "sha512-A2TAGbTFdBw9azHbpVd+/FkdW2T6msN1uct1O9bH3vTerEHKZhTXJUQXy+hNq1B0RagfU8U+KBdqiZpxjhOUQA==" + }, + "@types/multer": { + "version": "0.0.32", + "resolved": "https://registry.npmjs.org/@types/multer/-/multer-0.0.32.tgz", + "integrity": "sha1-+Jx1EifcILfJM8MJo+dGfEmfzew=", + "requires": { + "@types/express": "4.0.39" + } + }, "@types/node": { - "version": "6.0.92", - "resolved": "https://registry.npmjs.org/@types/node/-/node-6.0.92.tgz", - "integrity": "sha512-awEYSSTn7dauwVCYSx2CJaPTu0Z1Ht2oR1b2AD3CYao6ZRb+opb6EL43fzmD7eMFgMHzTBWSUzlWSD+S8xN0Nw==" + "version": "8.5.1", + "resolved": "https://registry.npmjs.org/@types/node/-/node-8.5.1.tgz", + "integrity": "sha512-SrmAO+NhnsuG/6TychSl2VdxBZiw/d6V+8j+DFo8O3PwFi+QeYXWHhAw+b170aSc6zYab6/PjEWRZHIDN9mNUw==" + }, + "@types/reflect-metadata": { + "version": "0.0.4", + "resolved": "https://registry.npmjs.org/@types/reflect-metadata/-/reflect-metadata-0.0.4.tgz", + "integrity": "sha1-tkd8qal+UmXyrGf56nBOrl4Or00=" + }, + "@types/sequelize": { + "version": "4.0.79", + "resolved": "https://registry.npmjs.org/@types/sequelize/-/sequelize-4.0.79.tgz", + "integrity": "sha512-rtBBoxXNrSyEaBJm1duQy8C6AeZ4EoSI2MzI/twAVZShKa9y4tAhMiFWwACkrp1VInbJ1aSB+IaCtL+B9btpNA==", + "requires": { + "@types/bluebird": "3.5.18", + "@types/continuation-local-storage": "3.2.1", + "@types/lodash": "4.14.91", + "@types/validator": "6.3.0" + } + }, + "@types/serve-static": { + "version": "1.13.1", + "resolved": "https://registry.npmjs.org/@types/serve-static/-/serve-static-1.13.1.tgz", + "integrity": "sha512-jDMH+3BQPtvqZVIcsH700Dfi8Q3MIcEx16g/VdxjoqiGR/NntekB10xdBpirMKnPe9z2C5cBmL0vte0YttOr3Q==", + "requires": { + "@types/express-serve-static-core": "4.0.57", + "@types/mime": "2.0.0" + } + }, + "@types/validator": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/@types/validator/-/validator-6.3.0.tgz", + "integrity": "sha512-fUc+9BEr1WWW8wVRl5I/pyRDGZNe9nH06kOzlGH3eN7N8VVPW/zSrE0Vdca6G2sRCVmIN/XuOenbmldAAyTYaw==" }, "abbrev": { "version": "1.1.1", @@ -384,6 +480,11 @@ "integrity": "sha1-zWLc+OT9WkF+/GZNLlsQZTxlG0Y=", "dev": true }, + "append-field": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/append-field/-/append-field-0.1.0.tgz", + "integrity": "sha1-bdxY+gg8e8VF08WZWygwzCNm1Eo=" + }, "aproba": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/aproba/-/aproba-1.2.0.tgz", @@ -451,7 +552,6 @@ "version": "1.0.2", "resolved": "https://registry.npmjs.org/array-union/-/array-union-1.0.2.tgz", "integrity": "sha1-mjRBDk9OPaI96jdb5b5w8kd47Dk=", - "dev": true, "requires": { "array-uniq": "1.0.3" } @@ -459,8 +559,7 @@ "array-uniq": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/array-uniq/-/array-uniq-1.0.3.tgz", - "integrity": "sha1-r2rId6Jcx/dOBYiUdThY39sk/bY=", - "dev": true + "integrity": "sha1-r2rId6Jcx/dOBYiUdThY39sk/bY=" }, "array-unique": { "version": "0.3.2", @@ -504,11 +603,6 @@ "integrity": "sha1-ECyenpAF0+fjgpvwxPok7oYu6bk=", "dev": true }, - "async": { - "version": "0.9.2", - "resolved": "https://registry.npmjs.org/async/-/async-0.9.2.tgz", - "integrity": "sha1-rqdNXmHB+JlhO/ZL2mbUx48v0X0=" - }, "async-each": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/async-each/-/async-each-1.0.1.tgz", @@ -614,7 +708,6 @@ "version": "6.26.0", "resolved": "https://registry.npmjs.org/babel-runtime/-/babel-runtime-6.26.0.tgz", "integrity": "sha1-llxwWGaOgrVde/4E/yM3vItWR/4=", - "dev": true, "requires": { "core-js": "2.5.2", "regenerator-runtime": "0.11.0" @@ -623,7 +716,8 @@ "balanced-match": { "version": "0.4.2", "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-0.4.2.tgz", - "integrity": "sha1-yz8+PHMtwPAe5wtAPzAuYddwmDg=" + "integrity": "sha1-yz8+PHMtwPAe5wtAPzAuYddwmDg=", + "dev": true }, "base": { "version": "0.11.2", @@ -920,6 +1014,38 @@ "integrity": "sha1-hZgoeOIbmOHGZCXgPQF0eI9Wnug=", "dev": true }, + "busboy": { + "version": "0.2.14", + "resolved": "https://registry.npmjs.org/busboy/-/busboy-0.2.14.tgz", + "integrity": "sha1-bCpiLvz0fFe7vh4qnDetNseSVFM=", + "requires": { + "dicer": "0.2.5", + "readable-stream": "1.1.14" + }, + "dependencies": { + "isarray": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz", + "integrity": "sha1-ihis/Kmo9Bd+Cav8YDiTmwXR7t8=" + }, + "readable-stream": { + "version": "1.1.14", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-1.1.14.tgz", + "integrity": "sha1-fPTFTvZI44EwhMY23SB54WbAgdk=", + "requires": { + "core-util-is": "1.0.2", + "inherits": "2.0.3", + "isarray": "0.0.1", + "string_decoder": "0.10.31" + } + }, + "string_decoder": { + "version": "0.10.31", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-0.10.31.tgz", + "integrity": "sha1-YuIDvEF2bGwoyfyEMB2rHFMQ+pQ=" + } + } + }, "bytes": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.0.0.tgz", @@ -942,6 +1068,11 @@ "unset-value": "1.0.0" } }, + "callsites": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/callsites/-/callsites-1.0.1.tgz", + "integrity": "sha1-wUwkGIzo4dagMLTDyULmuolbaho=" + }, "camel-case": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/camel-case/-/camel-case-3.0.0.tgz", @@ -1224,9 +1355,9 @@ "dev": true }, "codelyzer": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/codelyzer/-/codelyzer-3.2.2.tgz", - "integrity": "sha512-VNvW9gRThsqRarEnLioiILd0Pdk0yCq/7cVgYvqHpC+3CHqfnrJfmXjoana7vzWfSis+9pODXofjCWX+nlU9Gw==", + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/codelyzer/-/codelyzer-4.0.2.tgz", + "integrity": "sha512-nYwOr49+IV09e7C4aXkVALRz0+XpHqZiUUcxHuDZH4xP1FBcHINyr3qvVhv5Gfm7XRmoLx32tsIhrQhW/gBcog==", "dev": true, "requires": { "app-root-path": "2.0.1", @@ -1294,7 +1425,8 @@ "colors": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/colors/-/colors-1.1.2.tgz", - "integrity": "sha1-FopHAXVran9RoSzgyXv6KMCE7WM=" + "integrity": "sha1-FopHAXVran9RoSzgyXv6KMCE7WM=", + "dev": true }, "combined-stream": { "version": "1.0.5", @@ -1345,6 +1477,16 @@ "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=" }, + "concat-stream": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/concat-stream/-/concat-stream-1.6.0.tgz", + "integrity": "sha1-CqxmL9Ur54lk1VMvaUeE5wEQrPc=", + "requires": { + "inherits": "2.0.3", + "readable-stream": "2.3.3", + "typedarray": "0.0.6" + } + }, "config": { "version": "1.28.1", "resolved": "https://registry.npmjs.org/config/-/config-1.28.1.tgz", @@ -1396,6 +1538,15 @@ "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.3.1.tgz", "integrity": "sha1-5+Ch+e9DtMi6klxcWpboBtFoc7s=" }, + "cookie-parser": { + "version": "1.4.3", + "resolved": "https://registry.npmjs.org/cookie-parser/-/cookie-parser-1.4.3.tgz", + "integrity": "sha1-D+MfoZ0AC5X0qt8fU/3CuKIDuqU=", + "requires": { + "cookie": "0.3.1", + "cookie-signature": "1.0.6" + } + }, "cookie-signature": { "version": "1.0.6", "resolved": "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.0.6.tgz", @@ -1444,14 +1595,22 @@ "core-js": { "version": "2.5.2", "resolved": "https://registry.npmjs.org/core-js/-/core-js-2.5.2.tgz", - "integrity": "sha1-vEZIZW59ydyA19PHu8Fy2W50TmM=", - "dev": true + "integrity": "sha1-vEZIZW59ydyA19PHu8Fy2W50TmM=" }, "core-util-is": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz", "integrity": "sha1-tf1UIgqivFq1eqtxQMlAdUUDwac=" }, + "cors": { + "version": "2.8.4", + "resolved": "https://registry.npmjs.org/cors/-/cors-2.8.4.tgz", + "integrity": "sha1-K9OB8usgECAQXNUOpZ2mMJBpRoY=", + "requires": { + "object-assign": "4.1.1", + "vary": "1.1.2" + } + }, "cosmiconfig": { "version": "2.2.2", "resolved": "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-2.2.2.tgz", @@ -1749,53 +1908,6 @@ "integrity": "sha1-6vQ5/U1ISK105cx9vvIAZyueNFs=", "dev": true }, - "db-migrate": { - "version": "0.10.2", - "resolved": "https://registry.npmjs.org/db-migrate/-/db-migrate-0.10.2.tgz", - "integrity": "sha512-uU3AXQ89DPKAePCHHoZSJRnLam6/zgOBhgSXVXB9Z3JeHms5OMTQuCdj1leUwYvI6ygHdQ3Z9CS6S9yOuELdcw==", - "requires": { - "balanced-match": "0.4.2", - "bluebird": "3.5.1", - "db-migrate-shared": "1.1.3", - "deep-extend": "0.4.2", - "dotenv": "2.0.0", - "final-fs": "1.6.1", - "inflection": "1.12.0", - "mkdirp": "0.5.1", - "moment": "2.19.3", - "optimist": "0.6.1", - "parse-database-url": "0.3.0", - "pkginfo": "0.4.1", - "prompt": "1.0.0", - "rc": "1.2.2", - "resolve": "1.4.0", - "semver": "5.4.1", - "tunnel-ssh": "4.1.3" - } - }, - "db-migrate-base": { - "version": "1.5.3", - "resolved": "https://registry.npmjs.org/db-migrate-base/-/db-migrate-base-1.5.3.tgz", - "integrity": "sha512-dbJHFVYIY75vSOL3MD4qbpjilcwrYn7ZnTqsdA2AGs6w1mYugspfWEBea+uMgJVH/YsUFxw2AYPKRHCHUjhirw==", - "requires": { - "bluebird": "3.5.1" - } - }, - "db-migrate-shared": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/db-migrate-shared/-/db-migrate-shared-1.1.3.tgz", - "integrity": "sha1-7bPIF7KVAixhmEwYcmdBm7NqLVg=" - }, - "db-migrate-sqlite3": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/db-migrate-sqlite3/-/db-migrate-sqlite3-0.2.1.tgz", - "integrity": "sha1-ox1nudNtz5lWSymLz9C5hx+2bmc=", - "requires": { - "bluebird": "3.5.1", - "db-migrate-base": "1.5.3", - "sqlite3": "3.1.13" - } - }, "debug": { "version": "2.6.9", "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", @@ -1816,16 +1928,6 @@ "integrity": "sha1-6zkTMzRYd1y4TNGh+uBiEGu4dUU=", "dev": true }, - "deep-equal": { - "version": "0.2.2", - "resolved": "https://registry.npmjs.org/deep-equal/-/deep-equal-0.2.2.tgz", - "integrity": "sha1-hLdFiW80xoTpjyzg5Cq69Du6AX0=" - }, - "deep-extend": { - "version": "0.4.2", - "resolved": "https://registry.npmjs.org/deep-extend/-/deep-extend-0.4.2.tgz", - "integrity": "sha1-SLaZwn4zS/ifEIkr5DL25MfTSn8=" - }, "define-properties": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.1.2.tgz", @@ -1910,6 +2012,38 @@ "integrity": "sha1-ogM8CcyOFY03dI+951B4Mr1s4Sc=", "dev": true }, + "dicer": { + "version": "0.2.5", + "resolved": "https://registry.npmjs.org/dicer/-/dicer-0.2.5.tgz", + "integrity": "sha1-WZbAhrszIYyBLAkL3cCc0S+stw8=", + "requires": { + "readable-stream": "1.1.14", + "streamsearch": "0.1.2" + }, + "dependencies": { + "isarray": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz", + "integrity": "sha1-ihis/Kmo9Bd+Cav8YDiTmwXR7t8=" + }, + "readable-stream": { + "version": "1.1.14", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-1.1.14.tgz", + "integrity": "sha1-fPTFTvZI44EwhMY23SB54WbAgdk=", + "requires": { + "core-util-is": "1.0.2", + "inherits": "2.0.3", + "isarray": "0.0.1", + "string_decoder": "0.10.31" + } + }, + "string_decoder": { + "version": "0.10.31", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-0.10.31.tgz", + "integrity": "sha1-YuIDvEF2bGwoyfyEMB2rHFMQ+pQ=" + } + } + }, "diff": { "version": "3.4.0", "resolved": "https://registry.npmjs.org/diff/-/diff-3.4.0.tgz", @@ -2026,11 +2160,6 @@ "domelementtype": "1.3.0" } }, - "dotenv": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/dotenv/-/dotenv-2.0.0.tgz", - "integrity": "sha1-vXWcNXqqcDZeAclrewvsCKbg2Uk=" - }, "dottie": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/dottie/-/dottie-2.0.0.tgz", @@ -2075,6 +2204,7 @@ "version": "2.0.0", "resolved": "https://registry.npmjs.org/embed-video/-/embed-video-2.0.0.tgz", "integrity": "sha1-1/JouzRkIg9pXbM6YCHhpgjI4fk=", + "dev": true, "requires": { "fetch-ponyfill": "4.1.0", "lodash.escape": "4.0.1", @@ -2096,6 +2226,7 @@ "version": "0.1.12", "resolved": "https://registry.npmjs.org/encoding/-/encoding-0.1.12.tgz", "integrity": "sha1-U4tm8+5izRq1HsMjgp0flIDHS+s=", + "dev": true, "requires": { "iconv-lite": "0.4.15" } @@ -2216,6 +2347,11 @@ "event-emitter": "0.3.5" } }, + "es6-shim": { + "version": "0.35.3", + "resolved": "https://registry.npmjs.org/es6-shim/-/es6-shim-0.35.3.tgz", + "integrity": "sha1-m/tzY/7//4emzbbNk+QF7DxLbyY=" + }, "es6-symbol": { "version": "3.1.1", "resolved": "https://registry.npmjs.org/es6-symbol/-/es6-symbol-3.1.1.tgz", @@ -2606,6 +2742,7 @@ "version": "4.1.0", "resolved": "https://registry.npmjs.org/fetch-ponyfill/-/fetch-ponyfill-4.1.0.tgz", "integrity": "sha1-rjzl9zLGReq4fkroeTQUcJsjmJM=", + "dev": true, "requires": { "node-fetch": "1.7.3" } @@ -2638,15 +2775,6 @@ "to-regex-range": "2.1.1" } }, - "final-fs": { - "version": "1.6.1", - "resolved": "https://registry.npmjs.org/final-fs/-/final-fs-1.6.1.tgz", - "integrity": "sha1-1tzZLvb+T+jAer1WjHE1YQ7eMjY=", - "requires": { - "node-fs": "0.1.7", - "when": "2.0.1" - } - }, "finalhandler": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.1.0.tgz", @@ -2739,6 +2867,15 @@ "resolved": "https://registry.npmjs.org/fresh/-/fresh-0.5.2.tgz", "integrity": "sha1-PYyt2Q2XZWn6g1qx+OSyOhBWBac=" }, + "fs-extra": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-2.1.2.tgz", + "integrity": "sha1-BGxwFjzvmq1GsOSn+kZ/si1x3jU=", + "requires": { + "graceful-fs": "4.1.11", + "jsonfile": "2.4.0" + } + }, "fs.realpath": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", @@ -2909,7 +3046,6 @@ "version": "6.1.0", "resolved": "https://registry.npmjs.org/globby/-/globby-6.1.0.tgz", "integrity": "sha1-9abXDoOV4hyFj7BInWTfAkJNUGw=", - "dev": true, "requires": { "array-union": "1.0.2", "glob": "7.1.2", @@ -2941,8 +3077,7 @@ "graceful-fs": { "version": "4.1.11", "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.1.11.tgz", - "integrity": "sha1-Dovf5NHduIVNZOBOp8AOKgJuVlg=", - "dev": true + "integrity": "sha1-Dovf5NHduIVNZOBOp8AOKgJuVlg=" }, "handle-thing": { "version": "1.2.5", @@ -3388,15 +3523,11 @@ "integrity": "sha1-7AbBDgo0wPL68Zn3/X/Hj//QPHM=", "dev": true }, - "i": { - "version": "0.3.6", - "resolved": "https://registry.npmjs.org/i/-/i-0.3.6.tgz", - "integrity": "sha1-2WyScyB28HJxG2sQ/X1PZa2O4j0=" - }, "iconv-lite": { "version": "0.4.15", "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.15.tgz", - "integrity": "sha1-/iZaIYrGpXz+hUkn6dBMGYJe3es=" + "integrity": "sha1-/iZaIYrGpXz+hUkn6dBMGYJe3es=", + "dev": true }, "icss-replace-symbols": { "version": "1.1.0", @@ -3503,11 +3634,6 @@ "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz", "integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=" }, - "ini": { - "version": "1.3.5", - "resolved": "https://registry.npmjs.org/ini/-/ini-1.3.5.tgz", - "integrity": "sha512-RZY5huIKCMRWDUqZlEi72f/lmXKMvuszcMBduliQ3nnWbx9X/ZBQO7DijMEYS9EhHBb2qacRUMtC7svLwe0lcw==" - }, "internal-ip": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/internal-ip/-/internal-ip-1.2.0.tgz", @@ -3682,8 +3808,7 @@ "is-extglob": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", - "integrity": "sha1-qIwCU1eR8C7TfHahueqXc8gz+MI=", - "dev": true + "integrity": "sha1-qIwCU1eR8C7TfHahueqXc8gz+MI=" }, "is-finite": { "version": "1.0.2", @@ -3822,7 +3947,8 @@ "is-stream": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-1.1.0.tgz", - "integrity": "sha1-EtSj3U5o4Lec6428hBc66A2RykQ=" + "integrity": "sha1-EtSj3U5o4Lec6428hBc66A2RykQ=", + "dev": true }, "is-svg": { "version": "2.1.0", @@ -3859,8 +3985,7 @@ "isarray": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", - "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=", - "dev": true + "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=" }, "isexe": { "version": "2.0.0", @@ -3965,6 +4090,14 @@ "resolved": "https://registry.npmjs.org/json5/-/json5-0.4.0.tgz", "integrity": "sha1-BUNS5MTIDIbAkjh31EneF2pzLI0=" }, + "jsonfile": { + "version": "2.4.0", + "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-2.4.0.tgz", + "integrity": "sha1-NzaitCi4e72gzIO1P6PWM6NcKug=", + "requires": { + "graceful-fs": "4.1.11" + } + }, "jsonify": { "version": "0.0.0", "resolved": "https://registry.npmjs.org/jsonify/-/jsonify-0.0.0.tgz", @@ -4103,15 +4236,11 @@ "integrity": "sha1-4j8/nE+Pvd6HJSnBBxhXoIblzO8=", "dev": true }, - "lodash.defaults": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/lodash.defaults/-/lodash.defaults-4.2.0.tgz", - "integrity": "sha1-0JF4cW/+pN3p5ft7N/bwgCJ0WAw=" - }, "lodash.escape": { "version": "4.0.1", "resolved": "https://registry.npmjs.org/lodash.escape/-/lodash.escape-4.0.1.tgz", - "integrity": "sha1-yQRGkMIeBClL6qUXcS/e0fqI3pg=" + "integrity": "sha1-yQRGkMIeBClL6qUXcS/e0fqI3pg=", + "dev": true }, "lodash.memoize": { "version": "4.1.2", @@ -4228,17 +4357,36 @@ "dev": true }, "matrix-js-sdk": { - "version": "0.8.5", - "resolved": "https://registry.npmjs.org/matrix-js-sdk/-/matrix-js-sdk-0.8.5.tgz", - "integrity": "sha1-1ZAVTx53ADVyZw+p28rH5APnbk8=", + "version": "0.9.2", + "resolved": "https://registry.npmjs.org/matrix-js-sdk/-/matrix-js-sdk-0.9.2.tgz", + "integrity": "sha1-KlIb3c9jfL796ROHhOYn6kNkW3c=", "requires": { "another-json": "0.2.0", + "babel-runtime": "6.26.0", "bluebird": "3.5.1", "browser-request": "0.3.3", "content-type": "1.0.4", "request": "2.83.0" } }, + "matrix-js-snippets": { + "version": "0.2.5", + "resolved": "https://registry.npmjs.org/matrix-js-snippets/-/matrix-js-snippets-0.2.5.tgz", + "integrity": "sha512-Q/asN11Bd9giHnQ5kWRPixkAErUJKwprUSLPM5n2ju2W7JgqkSdXhSWBZ7YM9Yc9pc/W8Sb6t1CHAbdbyK3ArA==", + "requires": { + "chalk": "2.3.0", + "moment": "2.20.0", + "typescript": "2.6.2", + "winston": "2.4.0" + }, + "dependencies": { + "moment": { + "version": "2.20.0", + "resolved": "https://registry.npmjs.org/moment/-/moment-2.20.0.tgz", + "integrity": "sha512-r7aEpLB/mhMUiC5ksahDajF/Jr3wS/qLzUnwOJCZyKWF34ibdvW8saujBKfR7aQlov//JgFA38HXOoIt7lXzcA==" + } + } + }, "md5.js": { "version": "1.3.4", "resolved": "https://registry.npmjs.org/md5.js/-/md5.js-1.3.4.tgz", @@ -4275,6 +4423,11 @@ "mimic-fn": "1.1.0" } }, + "memory-cache": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/memory-cache/-/memory-cache-0.2.0.tgz", + "integrity": "sha1-eJCwHVLADI68nVM+H46xfjA0hxo=" + }, "memory-fs": { "version": "0.4.1", "resolved": "https://registry.npmjs.org/memory-fs/-/memory-fs-0.4.1.tgz", @@ -4353,10 +4506,9 @@ } }, "mime": { - "version": "1.3.4", - "resolved": "https://registry.npmjs.org/mime/-/mime-1.3.4.tgz", - "integrity": "sha1-EV+eO2s9rylZmDyzjxSaLUDrXVM=", - "dev": true + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/mime/-/mime-2.0.3.tgz", + "integrity": "sha512-TrpAd/vX3xaLPDgVRm6JkZwLR0KHfukMdU2wTEbqMDdCnY6Yo3mE+mjs9YE6oMNw2QRfXVeBEYpmpO94BIqiug==" }, "mime-db": { "version": "1.30.0", @@ -4377,6 +4529,11 @@ "integrity": "sha1-5md4PZLonb00KBi1IwudYqZyrRg=", "dev": true }, + "mini-deep-assign": { + "version": "0.0.8", + "resolved": "https://registry.npmjs.org/mini-deep-assign/-/mini-deep-assign-0.0.8.tgz", + "integrity": "sha1-FPpMrZPUfPu0OSeWqLABXn9gy80=" + }, "minimalistic-assert": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/minimalistic-assert/-/minimalistic-assert-1.0.0.tgz", @@ -4449,6 +4606,11 @@ "minimist": "0.0.8" } }, + "module-parent": { + "version": "0.0.2", + "resolved": "https://registry.npmjs.org/module-parent/-/module-parent-0.0.2.tgz", + "integrity": "sha1-vhy7PLalUGD8hkZ9Ly0s0KYA4Zk=" + }, "moment": { "version": "2.19.3", "resolved": "https://registry.npmjs.org/moment/-/moment-2.19.3.tgz", @@ -4462,16 +4624,33 @@ "moment": "2.19.3" } }, - "mongodb-uri": { - "version": "0.9.7", - "resolved": "https://registry.npmjs.org/mongodb-uri/-/mongodb-uri-0.9.7.tgz", - "integrity": "sha1-D3ca0W9IOuZfQoeWlCjp+8SqYYE=" - }, "ms": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=" }, + "multer": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/multer/-/multer-1.3.0.tgz", + "integrity": "sha1-CSsmcPaEb6SRSWXvyM+Uwg/sbNI=", + "requires": { + "append-field": "0.1.0", + "busboy": "0.2.14", + "concat-stream": "1.6.0", + "mkdirp": "0.5.1", + "object-assign": "3.0.0", + "on-finished": "2.3.0", + "type-is": "1.6.15", + "xtend": "4.0.1" + }, + "dependencies": { + "object-assign": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-3.0.0.tgz", + "integrity": "sha1-m+3VygiXlJvKR+f/QIBi1Un1h/I=" + } + } + }, "multicast-dns": { "version": "6.2.1", "resolved": "https://registry.npmjs.org/multicast-dns/-/multicast-dns-6.2.1.tgz", @@ -4488,11 +4667,6 @@ "integrity": "sha1-iZ8R2WhuXgXLkbNdXw5jt3PPyQE=", "dev": true }, - "mute-stream": { - "version": "0.0.7", - "resolved": "https://registry.npmjs.org/mute-stream/-/mute-stream-0.0.7.tgz", - "integrity": "sha1-MHXOk7whuPq0PhvE2n6BFe0ee6s=" - }, "nan": { "version": "2.8.0", "resolved": "https://registry.npmjs.org/nan/-/nan-2.8.0.tgz", @@ -4535,11 +4709,6 @@ "xml-char-classes": "1.0.0" } }, - "ncp": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/ncp/-/ncp-1.0.1.tgz", - "integrity": "sha1-0VNn5cuHQyuhF9K/gP30Wuz7QkY=" - }, "negotiator": { "version": "0.6.1", "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.1.tgz", @@ -4557,9 +4726,9 @@ "dev": true }, "ngx-modialog": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/ngx-modialog/-/ngx-modialog-3.0.4.tgz", - "integrity": "sha512-rkjLI2GPsikdEKqDxooBdTl8BXh4ndGnLg8iLk4xGNSq+ltRzm7QH4C62V8XcKdG7Kk7VSVc7tGKMtooxLcORQ==", + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/ngx-modialog/-/ngx-modialog-5.0.0.tgz", + "integrity": "sha512-EYqlwoHHMzKBhQegIVIAKGqAk23riah485tEFFdiPHeNbtgBfpSUJ8L7fW3YtHQGuV2tUc+mU8Ty728VwPP1mQ==", "dev": true }, "no-case": { @@ -4575,6 +4744,7 @@ "version": "1.7.3", "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-1.7.3.tgz", "integrity": "sha512-NhZ4CsKx7cYm2vSrBAr2PvFOe6sWDf0UYLRqA6svUYg7+/TSfVAu49jYC4BvQ4Sms9SZgdqGBgroqfDhJdTyKQ==", + "dev": true, "requires": { "encoding": "0.1.12", "is-stream": "1.1.0" @@ -4586,11 +4756,6 @@ "integrity": "sha1-RjgRh59XPUUVWtap9D3ClujoXrw=", "dev": true }, - "node-fs": { - "version": "0.1.7", - "resolved": "https://registry.npmjs.org/node-fs/-/node-fs-0.1.7.tgz", - "integrity": "sha1-MjI8zLRsn78PwRgS1FAhzDHTJbs=" - }, "node-gyp": { "version": "3.6.2", "resolved": "https://registry.npmjs.org/node-gyp/-/node-gyp-3.6.2.tgz", @@ -4955,8 +5120,7 @@ "object-assign": { "version": "4.1.1", "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", - "integrity": "sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM=", - "dev": true + "integrity": "sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM=" }, "object-copy": { "version": "0.1.0", @@ -5096,15 +5260,6 @@ "is-wsl": "1.1.0" } }, - "optimist": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/optimist/-/optimist-0.6.1.tgz", - "integrity": "sha1-2j6nRob6IaGaERwybpDrFaAZZoY=", - "requires": { - "minimist": "0.0.8", - "wordwrap": "0.0.3" - } - }, "original": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/original/-/original-1.0.0.tgz", @@ -5204,6 +5359,14 @@ "no-case": "2.3.1" } }, + "parent-module": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/parent-module/-/parent-module-0.1.0.tgz", + "integrity": "sha1-tSkoY6HoxHbs+Ffn11yYkgskuKY=", + "requires": { + "callsites": "1.0.1" + } + }, "parse-asn1": { "version": "5.1.0", "resolved": "https://registry.npmjs.org/parse-asn1/-/parse-asn1-5.1.0.tgz", @@ -5217,14 +5380,6 @@ "pbkdf2": "3.0.14" } }, - "parse-database-url": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/parse-database-url/-/parse-database-url-0.3.0.tgz", - "integrity": "sha1-NpZmMh6SfJreY838Gqr2+zdFPQ0=", - "requires": { - "mongodb-uri": "0.9.7" - } - }, "parse-glob": { "version": "3.0.4", "resolved": "https://registry.npmjs.org/parse-glob/-/parse-glob-3.0.4.tgz", @@ -5274,12 +5429,26 @@ "integrity": "sha1-s2PlXoAGym/iF4TS2yK9FdeRfxQ=", "dev": true }, + "path": { + "version": "0.12.7", + "resolved": "https://registry.npmjs.org/path/-/path-0.12.7.tgz", + "integrity": "sha1-1NwqUGxM4hl+tIHr/NWzbAFAsQ8=", + "requires": { + "process": "0.11.10", + "util": "0.10.3" + } + }, "path-browserify": { "version": "0.0.0", "resolved": "https://registry.npmjs.org/path-browserify/-/path-browserify-0.0.0.tgz", "integrity": "sha1-oLhwcpquIUAFt9UDLsLLuw+0RRo=", "dev": true }, + "path-dirname": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/path-dirname/-/path-dirname-1.0.2.tgz", + "integrity": "sha1-zDPSTVJeCZpTiMAzbG4yuRYGCeA=" + }, "path-exists": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-2.1.0.tgz", @@ -5309,7 +5478,8 @@ "path-parse": { "version": "1.0.5", "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.5.tgz", - "integrity": "sha1-PBrfhx6pzWyUMbbqK9dKD/BVxME=" + "integrity": "sha1-PBrfhx6pzWyUMbbqK9dKD/BVxME=", + "dev": true }, "path-to-regexp": { "version": "0.1.7", @@ -5348,20 +5518,17 @@ "pify": { "version": "2.3.0", "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz", - "integrity": "sha1-7RQaasBDqEnqWISY59yosVMw6Qw=", - "dev": true + "integrity": "sha1-7RQaasBDqEnqWISY59yosVMw6Qw=" }, "pinkie": { "version": "2.0.4", "resolved": "https://registry.npmjs.org/pinkie/-/pinkie-2.0.4.tgz", - "integrity": "sha1-clVrgM+g1IqXToDnckjoDtT3+HA=", - "dev": true + "integrity": "sha1-clVrgM+g1IqXToDnckjoDtT3+HA=" }, "pinkie-promise": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/pinkie-promise/-/pinkie-promise-2.0.1.tgz", "integrity": "sha1-ITXW36ejWMBprJsXh3YogihFD/o=", - "dev": true, "requires": { "pinkie": "2.0.4" } @@ -5420,11 +5587,6 @@ } } }, - "pkginfo": { - "version": "0.4.1", - "resolved": "https://registry.npmjs.org/pkginfo/-/pkginfo-0.4.1.tgz", - "integrity": "sha1-tUGO8EOd5UJfxJlQQtztFPsqhP8=" - }, "pleeease-filters": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/pleeease-filters/-/pleeease-filters-4.0.0.tgz", @@ -6171,27 +6333,41 @@ } }, "postcss-import": { - "version": "10.0.0", - "resolved": "https://registry.npmjs.org/postcss-import/-/postcss-import-10.0.0.tgz", - "integrity": "sha1-TIXJewmRNsxeoCQNwd/b/eTi674=", + "version": "11.0.0", + "resolved": "https://registry.npmjs.org/postcss-import/-/postcss-import-11.0.0.tgz", + "integrity": "sha1-qWLi34LTvFptpqOGhBdHIE9B71s=", "dev": true, "requires": { - "object-assign": "4.1.1", - "postcss": "6.0.9", + "postcss": "6.0.14", "postcss-value-parser": "3.3.0", "read-cache": "1.0.0", "resolve": "1.4.0" }, "dependencies": { "postcss": { - "version": "6.0.9", - "resolved": "https://registry.npmjs.org/postcss/-/postcss-6.0.9.tgz", - "integrity": "sha512-bBE2AHNEBhF23TfET6AA/lFP8ah+qHOZoFJEflFG+HgvVLdTmMOrocx/4LVVDIn3w6jUssw1q2Exk1cc9UOI8w==", + "version": "6.0.14", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-6.0.14.tgz", + "integrity": "sha512-NJ1z0f+1offCgadPhz+DvGm5Mkci+mmV5BqD13S992o0Xk9eElxUfPPF+t2ksH5R/17gz4xVK8KWocUQ5o3Rog==", "dev": true, "requires": { "chalk": "2.3.0", - "source-map": "0.5.7", - "supports-color": "4.2.1" + "source-map": "0.6.1", + "supports-color": "4.5.0" + } + }, + "source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "dev": true + }, + "supports-color": { + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-4.5.0.tgz", + "integrity": "sha1-vnoN5ITexcXN34s9WRJQRJEvY1s=", + "dev": true, + "requires": { + "has-flag": "2.0.0" } } } @@ -6854,65 +7030,18 @@ "process": { "version": "0.11.10", "resolved": "https://registry.npmjs.org/process/-/process-0.11.10.tgz", - "integrity": "sha1-czIwDoQBYb2j5podHZGn1LwW8YI=", - "dev": true + "integrity": "sha1-czIwDoQBYb2j5podHZGn1LwW8YI=" }, "process-nextick-args": { "version": "1.0.7", "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-1.0.7.tgz", - "integrity": "sha1-FQ4gt1ZZCtP5EJPyWk8q2L/zC6M=", - "dev": true + "integrity": "sha1-FQ4gt1ZZCtP5EJPyWk8q2L/zC6M=" }, "promise-polyfill": { "version": "6.0.2", "resolved": "https://registry.npmjs.org/promise-polyfill/-/promise-polyfill-6.0.2.tgz", - "integrity": "sha1-2chtPcTcLfkBboiUbe/Wm0m0EWI=" - }, - "prompt": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/prompt/-/prompt-1.0.0.tgz", - "integrity": "sha1-jlcSPDlquYiJf7Mn/Trtw+c15P4=", - "requires": { - "colors": "1.1.2", - "pkginfo": "0.4.1", - "read": "1.0.7", - "revalidator": "0.1.8", - "utile": "0.3.0", - "winston": "2.1.1" - }, - "dependencies": { - "async": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/async/-/async-1.0.0.tgz", - "integrity": "sha1-+PwEyjoTeErenhZBr5hXjPvWR6k=" - }, - "winston": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/winston/-/winston-2.1.1.tgz", - "integrity": "sha1-PJNJ0ZYgf9G9/51LxD73JRDjoS4=", - "requires": { - "async": "1.0.0", - "colors": "1.0.3", - "cycle": "1.0.3", - "eyes": "0.1.8", - "isstream": "0.1.2", - "pkginfo": "0.3.1", - "stack-trace": "0.0.10" - }, - "dependencies": { - "colors": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/colors/-/colors-1.0.3.tgz", - "integrity": "sha1-BDP0TYCWgP3rYO0mDxsMJi6CpAs=" - }, - "pkginfo": { - "version": "0.3.1", - "resolved": "https://registry.npmjs.org/pkginfo/-/pkginfo-0.3.1.tgz", - "integrity": "sha1-Wyn2qB9wcXFC4J52W76rl7T4HiE=" - } - } - } - } + "integrity": "sha1-2chtPcTcLfkBboiUbe/Wm0m0EWI=", + "dev": true }, "proxy-addr": { "version": "2.0.2", @@ -7071,32 +7200,6 @@ "integrity": "sha1-DD0L6u2KAclm2Xh793goElKpeao=", "dev": true }, - "rc": { - "version": "1.2.2", - "resolved": "https://registry.npmjs.org/rc/-/rc-1.2.2.tgz", - "integrity": "sha1-2M6ctX6NZNnHut2YdsfDTL48cHc=", - "requires": { - "deep-extend": "0.4.2", - "ini": "1.3.5", - "minimist": "1.2.0", - "strip-json-comments": "2.0.1" - }, - "dependencies": { - "minimist": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz", - "integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ=" - } - } - }, - "read": { - "version": "1.0.7", - "resolved": "https://registry.npmjs.org/read/-/read-1.0.7.tgz", - "integrity": "sha1-s9oZvQUkMal2cdRKQmNK33ELQMQ=", - "requires": { - "mute-stream": "0.0.7" - } - }, "read-cache": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/read-cache/-/read-cache-1.0.0.tgz", @@ -7131,7 +7234,6 @@ "version": "2.3.3", "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.3.tgz", "integrity": "sha512-m+qzzcn7KUxEmd1gMbchF+Y2eIUbieUaxkWtptyHywrX0rE8QEYqPC07Vuy4Wm32/xE16NcdBctb8S0Xe/5IeQ==", - "dev": true, "requires": { "core-util-is": "1.0.2", "inherits": "2.0.3", @@ -7216,8 +7318,7 @@ "reflect-metadata": { "version": "0.1.10", "resolved": "https://registry.npmjs.org/reflect-metadata/-/reflect-metadata-0.1.10.tgz", - "integrity": "sha1-tPg3BEFqytiZiMmxVjXUfgO5NEo=", - "dev": true + "integrity": "sha1-tPg3BEFqytiZiMmxVjXUfgO5NEo=" }, "regenerate": { "version": "1.3.3", @@ -7228,8 +7329,7 @@ "regenerator-runtime": { "version": "0.11.0", "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.11.0.tgz", - "integrity": "sha512-/aA0kLeRb5N9K0d4fw7ooEbI+xDe+DKD499EQqygGqeS8N3xto15p09uY2xj7ixP81sNPXvRLnAQIqdVStgb1A==", - "dev": true + "integrity": "sha512-/aA0kLeRb5N9K0d4fw7ooEbI+xDe+DKD499EQqygGqeS8N3xto15p09uY2xj7ixP81sNPXvRLnAQIqdVStgb1A==" }, "regex-cache": { "version": "0.4.4", @@ -7358,6 +7458,15 @@ "uuid": "3.1.0" } }, + "require-dir-all": { + "version": "0.4.12", + "resolved": "https://registry.npmjs.org/require-dir-all/-/require-dir-all-0.4.12.tgz", + "integrity": "sha1-7HxyFadukiB5IMlx8VR3aZ6vY6c=", + "requires": { + "mini-deep-assign": "0.0.8", + "module-parent": "0.0.2" + } + }, "require-directory": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", @@ -7370,6 +7479,35 @@ "integrity": "sha1-UpyczvJzgK3+yaL5ZbZJu+5jZBg=", "dev": true }, + "require-glob": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/require-glob/-/require-glob-3.2.0.tgz", + "integrity": "sha1-kL/iyO+0ufly65o/XlgIMuBPZNM=", + "requires": { + "glob-parent": "3.1.0", + "globby": "6.1.0", + "parent-module": "0.1.0" + }, + "dependencies": { + "glob-parent": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-3.1.0.tgz", + "integrity": "sha1-nmr2KZ2NO9K9QEMIMr0RPfkGxa4=", + "requires": { + "is-glob": "3.1.0", + "path-dirname": "1.0.2" + } + }, + "is-glob": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-3.1.0.tgz", + "integrity": "sha1-e6WuJCF4BKxwcHuWkiVnSGzD6Eo=", + "requires": { + "is-extglob": "2.1.1" + } + } + } + }, "require-main-filename": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/require-main-filename/-/require-main-filename-1.0.1.tgz", @@ -7386,6 +7524,7 @@ "version": "1.4.0", "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.4.0.tgz", "integrity": "sha512-aW7sVKPufyHqOmyyLzg/J+8606v5nevBgaliIlV7nUpVMsDnoBGV/cbSLNjZAg9q0Cfd/+easKVKQ8vOu8fn1Q==", + "dev": true, "requires": { "path-parse": "1.0.5" } @@ -7420,11 +7559,6 @@ "debug": "2.6.9" } }, - "revalidator": { - "version": "0.1.8", - "resolved": "https://registry.npmjs.org/revalidator/-/revalidator-0.1.8.tgz", - "integrity": "sha1-/s5hv6DBtSoga9axgZgYS91SOjs=" - }, "rgb": { "version": "0.1.0", "resolved": "https://registry.npmjs.org/rgb/-/rgb-0.1.0.tgz", @@ -7450,6 +7584,7 @@ "version": "2.6.2", "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.6.2.tgz", "integrity": "sha512-lreewLK/BlghmxtfH36YYVg1i8IAce4TI7oao75I1g245+6BctqTVQiBP3YUJ9C6DQOXJmkYR9X9fCLtCOJc5w==", + "dev": true, "requires": { "glob": "7.1.2" } @@ -7552,7 +7687,8 @@ "screenfull": { "version": "3.3.2", "resolved": "https://registry.npmjs.org/screenfull/-/screenfull-3.3.2.tgz", - "integrity": "sha512-zrnT8EidEWGFkmXEa1d/YUYNvvJaMX05g4O82K+Oiy9jR6Fh3ZTsovsccJOjRJyhS0KPV7AQpDFQRAYXBl9a5A==" + "integrity": "sha512-zrnT8EidEWGFkmXEa1d/YUYNvvJaMX05g4O82K+Oiy9jR6Fh3ZTsovsccJOjRJyhS0KPV7AQpDFQRAYXBl9a5A==", + "dev": true }, "scss-tokenizer": { "version": "0.2.3", @@ -7670,6 +7806,26 @@ } } }, + "sequelize-typescript": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/sequelize-typescript/-/sequelize-typescript-0.6.1.tgz", + "integrity": "sha512-DbKayDlqzg13qMGvhDg7/wvoaNYO1dIhHdyt12Nbf6Kr12yFS/apqe9MecniEXYFt0nsqQFa/6RZXVM0IJt3/g==", + "requires": { + "@types/bluebird": "3.5.18", + "@types/node": "6.0.41", + "@types/reflect-metadata": "0.0.4", + "@types/sequelize": "4.0.79", + "es6-shim": "0.35.3", + "glob": "7.1.2" + }, + "dependencies": { + "@types/node": { + "version": "6.0.41", + "resolved": "https://registry.npmjs.org/@types/node/-/node-6.0.41.tgz", + "integrity": "sha1-V4z1Oq7GWIe8rxZ5L4ciky6P+Oo=" + } + } + }, "serve-index": { "version": "1.9.1", "resolved": "https://registry.npmjs.org/serve-index/-/serve-index-1.9.1.tgz", @@ -8815,24 +8971,6 @@ } } }, - "ssh2": { - "version": "0.5.4", - "resolved": "https://registry.npmjs.org/ssh2/-/ssh2-0.5.4.tgz", - "integrity": "sha1-G/a2soyW6u8mf01sRqWiUXpZnic=", - "requires": { - "ssh2-streams": "0.1.20" - } - }, - "ssh2-streams": { - "version": "0.1.20", - "resolved": "https://registry.npmjs.org/ssh2-streams/-/ssh2-streams-0.1.20.tgz", - "integrity": "sha1-URGNFUVV31Rp7h9n4M8efoosDjo=", - "requires": { - "asn1": "0.2.3", - "semver": "5.4.1", - "streamsearch": "0.1.2" - } - }, "sshpk": { "version": "1.13.1", "resolved": "https://registry.npmjs.org/sshpk/-/sshpk-1.13.1.tgz", @@ -8943,7 +9081,6 @@ "version": "1.0.3", "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.0.3.tgz", "integrity": "sha512-4AH6Z5fzNNBcH+6XDMfA/BTt87skxqJlO0lAh3Dker5zThcAxG6mKz+iGu308UKoPPQ8Dcqx/4JhujzltRa+hQ==", - "dev": true, "requires": { "safe-buffer": "5.1.1" } @@ -8997,15 +9134,10 @@ "get-stdin": "4.0.1" } }, - "strip-json-comments": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-2.0.1.tgz", - "integrity": "sha1-PFMZQukIwml8DsNEhYwobHygpgo=" - }, "style-loader": { - "version": "0.18.2", - "resolved": "https://registry.npmjs.org/style-loader/-/style-loader-0.18.2.tgz", - "integrity": "sha512-WPpJPZGUxWYHWIUMNNOYqql7zh85zGmr84FdTVWq52WTIkqlW9xSxD3QYWi/T31cqn9UNSsietVEgGn2aaSCzw==", + "version": "0.19.1", + "resolved": "https://registry.npmjs.org/style-loader/-/style-loader-0.19.1.tgz", + "integrity": "sha512-IRE+ijgojrygQi3rsqT0U4dd+UcPCqcVvauZpCnQrGAlEe+FUIyrK93bUDScamesjP08JlQNsFJU+KmPedP5Og==", "dev": true, "requires": { "loader-utils": "1.1.0", @@ -9053,6 +9185,11 @@ } } }, + "swagger-ui-express": { + "version": "2.0.13", + "resolved": "https://registry.npmjs.org/swagger-ui-express/-/swagger-ui-express-2.0.13.tgz", + "integrity": "sha1-IDQ1GPIxPHiVps3/ZHjg7xPLn2Q=" + }, "symbol-observable": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/symbol-observable/-/symbol-observable-1.0.1.tgz", @@ -9310,31 +9447,6 @@ "safe-buffer": "5.1.1" } }, - "tunnel-ssh": { - "version": "4.1.3", - "resolved": "https://registry.npmjs.org/tunnel-ssh/-/tunnel-ssh-4.1.3.tgz", - "integrity": "sha1-kRIWrXnfEAkILFcT/tJkdu0jm60=", - "requires": { - "debug": "2.6.0", - "lodash.defaults": "4.2.0", - "ssh2": "0.5.4" - }, - "dependencies": { - "debug": { - "version": "2.6.0", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.0.tgz", - "integrity": "sha1-vFlryr52F/Edn6FTYe3tVgi4SZs=", - "requires": { - "ms": "0.7.2" - } - }, - "ms": { - "version": "0.7.2", - "resolved": "https://registry.npmjs.org/ms/-/ms-0.7.2.tgz", - "integrity": "sha1-riXPJRKziFodldfwN4aNhDESR2U=" - } - } - }, "tweetnacl": { "version": "0.14.5", "resolved": "https://registry.npmjs.org/tweetnacl/-/tweetnacl-0.14.5.tgz", @@ -9350,11 +9462,50 @@ "mime-types": "2.1.17" } }, + "typedarray": { + "version": "0.0.6", + "resolved": "https://registry.npmjs.org/typedarray/-/typedarray-0.0.6.tgz", + "integrity": "sha1-hnrHTjhkGHsdPUfZlqeOxciDB3c=" + }, "typescript": { "version": "2.6.2", "resolved": "https://registry.npmjs.org/typescript/-/typescript-2.6.2.tgz", - "integrity": "sha1-PFtv1/beCRQmkCfwPAlGdY92c6Q=", - "dev": true + "integrity": "sha1-PFtv1/beCRQmkCfwPAlGdY92c6Q=" + }, + "typescript-rest": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/typescript-rest/-/typescript-rest-1.2.0.tgz", + "integrity": "sha1-4B+oM2VU/tYt6qmQuq7VK2gISQ8=", + "requires": { + "@types/body-parser": "0.0.33", + "@types/cookie-parser": "1.4.1", + "@types/express": "4.0.39", + "@types/express-serve-static-core": "4.0.57", + "@types/multer": "0.0.32", + "@types/serve-static": "1.13.1", + "body-parser": "1.18.2", + "cookie-parser": "1.4.3", + "cors": "2.8.4", + "express": "4.16.2", + "fs-extra": "2.1.2", + "lodash": "4.17.4", + "multer": "1.3.0", + "path": "0.12.7", + "reflect-metadata": "0.1.10", + "require-glob": "3.2.0", + "swagger-ui-express": "2.0.13", + "yamljs": "0.2.10" + }, + "dependencies": { + "@types/body-parser": { + "version": "0.0.33", + "resolved": "https://registry.npmjs.org/@types/body-parser/-/body-parser-0.0.33.tgz", + "integrity": "sha1-M8oUmPw35Rxd8MgcrjRWnnBB4CU=", + "requires": { + "@types/express": "4.0.39" + } + } + } }, "uglify-js": { "version": "3.0.28", @@ -9563,13 +9714,22 @@ } }, "url-loader": { - "version": "0.5.9", - "resolved": "https://registry.npmjs.org/url-loader/-/url-loader-0.5.9.tgz", - "integrity": "sha512-B7QYFyvv+fOBqBVeefsxv6koWWtjmHaMFT6KZWti4KRw8YUD/hOU+3AECvXuzyVawIBx3z7zQRejXCDSO5kk1Q==", + "version": "0.6.2", + "resolved": "https://registry.npmjs.org/url-loader/-/url-loader-0.6.2.tgz", + "integrity": "sha512-h3qf9TNn53BpuXTTcpC+UehiRrl0Cv45Yr/xWayApjw6G8Bg2dGke7rIwDQ39piciWCWrC+WiqLjOh3SUp9n0Q==", "dev": true, "requires": { "loader-utils": "1.1.0", - "mime": "1.3.4" + "mime": "1.6.0", + "schema-utils": "0.3.0" + }, + "dependencies": { + "mime": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/mime/-/mime-1.6.0.tgz", + "integrity": "sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg==", + "dev": true + } } }, "url-parse": { @@ -9633,7 +9793,6 @@ "version": "0.10.3", "resolved": "https://registry.npmjs.org/util/-/util-0.10.3.tgz", "integrity": "sha1-evsa/lCAUkZInj23/g7TeTNqwPk=", - "dev": true, "requires": { "inherits": "2.0.1" }, @@ -9641,16 +9800,14 @@ "inherits": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.1.tgz", - "integrity": "sha1-sX0I0ya0Qj5Wjv9xn5GwscvfafE=", - "dev": true + "integrity": "sha1-sX0I0ya0Qj5Wjv9xn5GwscvfafE=" } } }, "util-deprecate": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", - "integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=", - "dev": true + "integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=" }, "utila": { "version": "0.4.0", @@ -9658,19 +9815,6 @@ "integrity": "sha1-ihagXURWV6Oupe7MWxKk+lN5dyw=", "dev": true }, - "utile": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/utile/-/utile-0.3.0.tgz", - "integrity": "sha1-E1LDQOuCDk2N26A5pPv6oy7U7zo=", - "requires": { - "async": "0.9.2", - "deep-equal": "0.2.2", - "i": "0.3.6", - "mkdirp": "0.5.1", - "ncp": "1.0.1", - "rimraf": "2.6.2" - } - }, "utils-merge": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/utils-merge/-/utils-merge-1.0.1.tgz", @@ -10100,11 +10244,6 @@ "integrity": "sha512-nqHUnMXmBzT0w570r2JpJxfiSD1IzoI+HGVdd3aZ0yNi3ngvQ4jv1dtHt5VGxfI2yj5yqImPhOK4vmIh2xMbGg==", "dev": true }, - "when": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/when/-/when-2.0.1.tgz", - "integrity": "sha1-jYcv4V5oQkyRtLck6EjggH2rZkI=" - }, "whet.extend": { "version": "0.9.9", "resolved": "https://registry.npmjs.org/whet.extend/-/whet.extend-0.9.9.tgz", @@ -10171,14 +10310,9 @@ "resolved": "https://registry.npmjs.org/wkx/-/wkx-0.4.2.tgz", "integrity": "sha1-d201pjSlwi5lbkdEvetU+D/Szo0=", "requires": { - "@types/node": "6.0.92" + "@types/node": "8.5.1" } }, - "wordwrap": { - "version": "0.0.3", - "resolved": "https://registry.npmjs.org/wordwrap/-/wordwrap-0.0.3.tgz", - "integrity": "sha1-o9XabNXAvAAI03I0u68b7WMFkQc=" - }, "wrap-ansi": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-2.1.0.tgz", @@ -10203,8 +10337,7 @@ "xtend": { "version": "4.0.1", "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.1.tgz", - "integrity": "sha1-pcbVMr5lbiPbgg77lDofBJmNY68=", - "dev": true + "integrity": "sha1-pcbVMr5lbiPbgg77lDofBJmNY68=" }, "y18n": { "version": "3.2.1", @@ -10218,6 +10351,15 @@ "integrity": "sha1-HBH5IY8HYImkfdUS+TxmmaaoHVI=", "dev": true }, + "yamljs": { + "version": "0.2.10", + "resolved": "https://registry.npmjs.org/yamljs/-/yamljs-0.2.10.tgz", + "integrity": "sha1-SBzHwlynOvWfWR8MluPOVsdXpA8=", + "requires": { + "argparse": "1.0.9", + "glob": "7.1.2" + } + }, "yargs": { "version": "7.1.0", "resolved": "https://registry.npmjs.org/yargs/-/yargs-7.1.0.tgz", diff --git a/package.json b/package.json index fe4885b..e4c57d3 100644 --- a/package.json +++ b/package.json @@ -2,46 +2,49 @@ "name": "matrix-dimension", "version": "1.0.0", "description": "An alternative integrations manager for Riot", - "main": "app.js", + "main": "build/app/index.js", "license": "GPL-3.0", "scripts": { - "dev": "webpack-dev-server --inline --progress --port 8080 --host 0.0.0.0", - "build": "rimraf web-dist && webpack --progress --profile --bail" + "start:dev": "webpack-dev-server --inline --progress --port 8080 --host 0.0.0.0", + "start:app": "npm run-script build && node build/app/index.js", + "build": "rimraf build && npm run-script build:web && npm run-script build:app", + "build:web": "webpack --progress --profile --bail", + "build:app": "tsc -p tsconfig-app.json", + "lint:app": "tslint --project ./tsconfig-app.json -t stylish" }, "repository": { "type": "git", "url": "git+https://github.com/turt2live/matrix-dimension.git" }, - "greenkeeper": { - "ignore": [ - "@types/node" - ] - }, "author": "Travis Ralston", "dependencies": { + "@types/body-parser": "^1.16.8", + "@types/node": "^8.5.1", "bluebird": "^3.5.1", "body-parser": "^1.18.2", - "chalk": "^2.3.0", "config": "^1.28.1", - "db-migrate": "^0.10.2", - "db-migrate-sqlite3": "^0.2.1", "dns-then": "^0.1.0", - "embed-video": "^2.0.0", "express": "^4.16.2", "js-yaml": "^3.10.0", "lodash": "^4.17.4", - "matrix-js-sdk": "^0.8.5", + "matrix-js-sdk": "^0.9.2", + "matrix-js-snippets": "^0.2.5", + "memory-cache": "^0.2.0", + "mime": "^2.0.3", "moment": "^2.19.3", "netmask": "^1.0.6", "random-string": "^0.2.0", "request": "^2.83.0", - "screenfull": "^3.3.2", + "require-dir-all": "^0.4.12", "sequelize": "^4.27.0", + "sequelize-typescript": "^0.6.1", "sqlite3": "^3.1.13", - "url": "^0.11.0", - "winston": "^2.4.0" + "typescript-rest": "^1.2.0", + "url": "^0.11.0" }, "devDependencies": { + "embed-video": "^2.0.0", + "screenfull": "^3.3.2", "@angular/animations": "^5.0.0", "@angular/common": "^5.0.0", "@angular/compiler": "^5.0.0", @@ -55,12 +58,11 @@ "@angularclass/hmr-loader": "^3.0.2", "@ng-bootstrap/ng-bootstrap": "^1.0.0-beta.7", "@types/jquery": "^3.2.16", - "@types/node": "^6.0.92", "angular2-template-loader": "^0.6.2", "angular2-toaster": "^4.0.0", "angular2-ui-switch": "^1.2.0", "awesome-typescript-loader": "^3.4.1", - "codelyzer": "^3.2.2", + "codelyzer": "^4.0.2", "copy-webpack-plugin": "^4.2.3", "core-js": "^2.5.2", "css-loader": "^0.28.7", @@ -73,10 +75,10 @@ "jquery": "^3.2.1", "json-loader": "^0.5.4", "ng2-breadcrumbs": "^0.1.281", - "ngx-modialog": "^3.0.4", + "ngx-modialog": "^5.0.0", "node-sass": "^4.7.2", "postcss-cssnext": "^3.0.0", - "postcss-import": "^10.0.0", + "postcss-import": "^11.0.0", "postcss-loader": "^2.0.9", "postcss-scss": "^1.0.0", "raw-loader": "^0.5.1", @@ -86,12 +88,12 @@ "sass-loader": "^6.0.3", "shelljs": "^0.7.8", "spinkit": "^1.2.5", - "style-loader": "^0.18.2", + "style-loader": "^0.19.1", "ts-helpers": "^1.1.2", "tslint": "^5.8.0", "tslint-loader": "^3.4.3", "typescript": "^2.6.2", - "url-loader": "^0.5.8", + "url-loader": "^0.6.2", "webpack": "^3.10.0", "webpack-dev-server": "^2.9.7", "zone.js": "^0.8.18" diff --git a/src-ts/MemoryCache.ts b/src-ts/MemoryCache.ts new file mode 100644 index 0000000..6934d32 --- /dev/null +++ b/src-ts/MemoryCache.ts @@ -0,0 +1,25 @@ +import * as cache from "memory-cache"; + +export class MemoryCache { + + private internalCache = new cache.Cache(); + + constructor() { + } + + public put(key: string, value: any, timeoutMs?: number): void { + this.internalCache.put(key, value, timeoutMs); + } + + public get(key: string): any { + return this.internalCache.get(key); + } + + public del(key: string): void { + this.internalCache.del(key); + } + + public clear(): void { + this.internalCache.clear(); + } +} \ No newline at end of file diff --git a/src-ts/api/ApiError.ts b/src-ts/api/ApiError.ts new file mode 100644 index 0000000..6e99257 --- /dev/null +++ b/src-ts/api/ApiError.ts @@ -0,0 +1,14 @@ +export class ApiError { + + public statusCode: number; + public jsonResponse: any; + + constructor(statusCode: number, json: any) { + // Because typescript is just plain dumb + // https://stackoverflow.com/questions/31626231/custom-error-class-in-typescript + Error.apply(this, ["ApiError"]); + + this.jsonResponse = json; + this.statusCode = statusCode; + } +} \ No newline at end of file diff --git a/src-ts/api/Webserver.ts b/src-ts/api/Webserver.ts new file mode 100644 index 0000000..7e7296a --- /dev/null +++ b/src-ts/api/Webserver.ts @@ -0,0 +1,76 @@ +import * as express from "express"; +import * as path from "path"; +import * as bodyParser from "body-parser"; +import * as URL from "url"; +import { LogService } from "matrix-js-snippets"; +import { Server } from "typescript-rest"; +import * as _ from "lodash"; +import config from "../config"; +import { ApiError } from "./ApiError"; + +export default class Webserver { + + private app: express.Application; + + constructor() { + this.app = express(); + + this.configure(); + this.loadRoutes(); + } + + private loadRoutes() { + const apis = ["scalar", "dimension"].map(a => path.join(__dirname, a, "*.js")); + const router = express.Router(); + Server.loadServices(router, apis); + const routes = _.uniq(router.stack.map(r => r.route.path)); + for (const route of routes) { + this.app.options(route, (_req, res) => res.sendStatus(200)); + LogService.info("Webserver", "Registered route: " + route); + } + this.app.use(router); + + // We register the default route last to make sure we don't override anything by accident. + // We'll pass off all other requests to the web app + this.app.get("*", (_req, res) => { + res.sendFile(path.join(__dirname, "..", "..", "web", "index.html")); + }); + + // Set up the error handler + this.app.use((err: any, _req, res, next) => { + if (err instanceof ApiError) { + // Don't do anything for 'connection reset' + if (res.headersSent) return next(err); + + LogService.warn("Webserver", "Handling ApiError " + err.statusCode + " " + JSON.stringify(err.jsonResponse)); + res.setHeader("Content-Type", "application/json"); + res.status(err.statusCode); + res.json(err.jsonResponse); + } else next(err); + }); + } + + private configure() { + this.app.use(express.static(path.join(__dirname, "..", "..", "web"))); + this.app.use(bodyParser.json()); + this.app.use((req, _res, next) => { + const parsedUrl = URL.parse(req.url, true); + if (parsedUrl.query && parsedUrl.query["scalar_token"]) { + parsedUrl.query["scalar_token"] = "redacted"; + parsedUrl.search = undefined; // to force URL.format to use `query` + } + LogService.verbose("Webserver", "Incoming request: " + req.method + " " + URL.format(parsedUrl)); + next(); + }); + this.app.use((_req, res, next) => { + res.setHeader("Access-Control-Allow-Origin", "*"); + res.setHeader("Access-Control-Allow-Headers", "Origin, X-Requested-With, Content-Type, Accept"); + next(); + }); + } + + start() { + this.app.listen(config.web.port, config.web.address); + LogService.info("Webserver", "API and UI listening on " + config.web.address + ":" + config.web.port); + } +} \ No newline at end of file diff --git a/src-ts/api/scalar/ScalarService.ts b/src-ts/api/scalar/ScalarService.ts new file mode 100644 index 0000000..71e5d4f --- /dev/null +++ b/src-ts/api/scalar/ScalarService.ts @@ -0,0 +1,106 @@ +import { GET, Path, POST, QueryParam } from "typescript-rest"; +import * as Promise from "bluebird"; +import { MatrixOpenIdClient } from "../../matrix/MatrixOpenIdClient"; +import Upstream from "../../db/models/Upstream"; +import { ScalarClient } from "../../scalar/ScalarClient"; +import User from "../../db/models/User"; +import UserScalarToken from "../../db/models/UserScalarToken"; +import { LogService } from "matrix-js-snippets"; +import { ApiError } from "../ApiError"; +import * as randomString from "random-string"; +import { OpenId } from "../../models/OpenId"; +import { ScalarAccountResponse, ScalarRegisterResponse } from "../../models/ScalarResponses"; +import { DimensionStore } from "../../db/DimensionStore"; +import { MemoryCache } from "../../MemoryCache"; + +interface RegisterRequest { + access_token: string; + token_type: string; + matrix_server_name: string; + expires_in: number; +} + +@Path("/api/v1/scalar") +export class ScalarService { + + private static accountCache = new MemoryCache(); + + public static clearAccountCache(): void { + ScalarService.accountCache.clear(); + } + + public static getTokenOwner(scalarToken: string): Promise { + const cachedUserId = ScalarService.accountCache.get(scalarToken); + if (cachedUserId) return Promise.resolve(cachedUserId); + + return DimensionStore.getTokenOwner(scalarToken).then(user => { + if (!user) return Promise.reject("Invalid token"); + ScalarService.accountCache.put(scalarToken, user.userId, 30 * 60 * 1000); // 30 minutes + return Promise.resolve(user.userId); + }); + } + + @POST + @Path("register") + public register(request: RegisterRequest): Promise { + let userId = null; + const mxClient = new MatrixOpenIdClient(request); + return mxClient.getUserId().then(mxUserId => { + userId = mxUserId; + return User.findByPrimary(userId).then(user => { + if (!user) { + // There's a small chance we'll get a validation error because of: + // https://github.com/vector-im/riot-web/issues/5846 + LogService.verbose("ScalarService", "User " + userId + " never seen before - creating"); + return User.create({userId: userId}); + } + }); + }).then(() => { + return Upstream.findAll(); + }).then(upstreams => { + return Promise.all(upstreams.map(u => { + return UserScalarToken.findAll({where: {userId: userId, upstreamId: u.id}}).then(tokens => { + if (!tokens || tokens.length === 0) { + LogService.info("ScalarService", "Registering " + userId + " for token at upstream " + u.id + " (" + u.name + ")"); + const client = new ScalarClient(u); + return client.register(request).then(registerResponse => { + return UserScalarToken.create({ + userId: userId, + scalarToken: registerResponse.scalar_token, + isDimensionToken: false, + upstreamId: u.id, + }); + }); + } + }); + })); + }).then(() => { + const dimensionToken = randomString({length: 25}); + return UserScalarToken.create({ + userId: userId, + scalarToken: dimensionToken, + isDimensionToken: true, + }); + }).then(userToken => { + return {scalar_token: userToken.scalarToken}; + }).catch(err => { + LogService.error("ScalarService", err); + throw new ApiError(401, {message: "Failed to authenticate user"}); + }); + } + + @GET + @Path("account") + public getAccount(@QueryParam("scalar_token") scalarToken: string): Promise { + return ScalarService.getTokenOwner(scalarToken).then(userId => { + return {user_id: userId}; + }, err => { + if (err !== "Invalid token") { + LogService.error("ScalarService", "Error getting account information for user"); + LogService.error("ScalarService", err); + } + throw new ApiError(401, {message: "Invalid token"}); + }); + } + +} \ No newline at end of file diff --git a/src-ts/api/scalar/ScalarWidgetService.ts b/src-ts/api/scalar/ScalarWidgetService.ts new file mode 100644 index 0000000..cba14bf --- /dev/null +++ b/src-ts/api/scalar/ScalarWidgetService.ts @@ -0,0 +1,81 @@ +import { GET, Path, QueryParam } from "typescript-rest"; +import * as Promise from "bluebird"; +import { LogService } from "matrix-js-snippets"; +import { ApiError } from "../ApiError"; +import { MemoryCache } from "../../MemoryCache"; +import { MatrixLiteClient } from "../../matrix/MatrixLiteClient"; +import config from "../../config"; +import { ScalarService } from "./ScalarService"; +import moment = require("moment"); + +interface UrlPreviewResponse { + cached_response: boolean; + page_title_cache_item: { + expires: string; // "2017-12-18T04:20:04.001806738Z" + cached_response_err: string; + cached_title: string; // the actual thing riot uses + }; + error: { + message: string; + }; +} + +@Path("/api/v1/scalar/widgets") +export class ScalarWidgetService { + + private static urlCache = new MemoryCache(); + + private static getUrlTitle(url: string): Promise { + const cachedResult = ScalarWidgetService.urlCache.get(url); + if (cachedResult) { + cachedResult.cached_response = true; + return Promise.resolve(cachedResult); + } + + const client = new MatrixLiteClient(config.homeserver.name, config.homeserver.accessToken); + return client.getUrlPreview(url).then(preview => { + const expirationTime = 60 * 80 * 1000; // 1 hour + const expirationAsString = moment().add(expirationTime, "milliseconds").toISOString(); + const cachedItem = { + cached_response: false, // we're not cached yet + page_title_cache_item: { + expires: expirationAsString, + cached_response_err: null, + cached_title: preview["og:title"], + }, + error: {message: null}, + }; + ScalarWidgetService.urlCache.put(url, cachedItem, expirationTime); + return cachedItem; + }).catch(err => { + LogService.error("ScalarWidgetService", "Error getting URL preview"); + LogService.error("ScalarWidgetService", err); + return { + // All of this is to match scalar's response :/ + cached_response: false, + page_title_cache_item: { + expires: null, + cached_response_err: "Failed to get URL preview", + cached_title: null + }, + error: { + message: "Failed to get URL preview", + }, + }; + }) + } + + @GET + @Path("title_lookup") + public register(@QueryParam("scalar_token") scalarToken: string, @QueryParam("curl") url: string): Promise { + return ScalarService.getTokenOwner(scalarToken).then(_userId => { + return ScalarWidgetService.getUrlTitle(url); + }, err => { + if (err !== "Invalid token") { + LogService.error("ScalarWidgetService", "Error getting account information for user"); + LogService.error("ScalarWidgetService", err); + } + throw new ApiError(401, {message: "Invalid token"}); + }) + } +} \ No newline at end of file diff --git a/src-ts/config.ts b/src-ts/config.ts new file mode 100644 index 0000000..7149e0a --- /dev/null +++ b/src-ts/config.ts @@ -0,0 +1,21 @@ +import * as config from "config"; +import { LogConfig } from "matrix-js-snippets"; + +export interface DimensionConfig { + web: { + port: number; + address: string; + }; + homeserver: { + name: string; + accessToken: string; + }; + widgetBlacklist: string[]; + database: { + file: string; + }; + admins: string[]; + logging: LogConfig; +} + +export default config; \ No newline at end of file diff --git a/src-ts/db/DimensionStore.ts b/src-ts/db/DimensionStore.ts new file mode 100644 index 0000000..a044270 --- /dev/null +++ b/src-ts/db/DimensionStore.ts @@ -0,0 +1,75 @@ +import { Model, Sequelize } from "sequelize-typescript"; +import config from "../config"; +import { LogService } from "matrix-js-snippets"; +import User from "./models/User"; +import UserScalarToken from "./models/UserScalarToken"; +import Upstream from "./models/Upstream"; +import * as Promise from "bluebird"; + +class _DimensionStore { + private sequelize: Sequelize; + + constructor() { + this.sequelize = new Sequelize({ + dialect: 'sqlite', + database: "dimension", + storage: config.database.file, + username: "", + password: "", + logging: i => LogService.verbose("DimensionStore [SQL]", i) + }); + this.sequelize.addModels(>[ + User, + UserScalarToken, + Upstream, + ]); + } + + public updateSchema(): Promise { + LogService.info("DimensionStore", "Updating schema..."); + return this.sequelize.sync(); + } + + public doesUserHaveTokensForAllUpstreams(userId: string): Promise { + let upstreamTokenIds: number[] = []; + let hasDimensionToken = false; + return UserScalarToken.findAll({where: {userId: userId}}).then(results => { + upstreamTokenIds = results.filter(t => !t.isDimensionToken).map(t => t.upstreamId); + hasDimensionToken = results.filter(t => t.isDimensionToken).length >= 1; + return Upstream.findAll(); + }).then(upstreams => { + if (!hasDimensionToken) { + LogService.warn("DimensionStore", "User " + userId + " is missing a Dimension scalar token"); + return false; + } + + for (const upstream of upstreams) { + if (upstreamTokenIds.indexOf(upstream.id) === -1) { + LogService.warn("DimensionStore", "User " + userId + " is missing a scalar token for upstream " + upstream.id + " (" + upstream.name + ")"); + return false; + } + } + + return true; + }); + } + + public getTokenOwner(scalarToken: string): Promise { + let user: User = null; + return UserScalarToken.findAll({where: {isDimensionToken: true, scalarToken: scalarToken}, include: [User]}).then(tokens => { + if (!tokens || tokens.length === 0) { + return Promise.reject("Invalid token"); + } + + user = tokens[0].user; + return this.doesUserHaveTokensForAllUpstreams(user.userId); + }).then(hasUpstreams => { + if (!hasUpstreams) { + return Promise.reject("Invalid token"); // missing one or more upstreams == no validation + } + return Promise.resolve(user); + }); + } +} + +export const DimensionStore = new _DimensionStore(); \ No newline at end of file diff --git a/src-ts/db/models/Upstream.ts b/src-ts/db/models/Upstream.ts new file mode 100644 index 0000000..908a1bc --- /dev/null +++ b/src-ts/db/models/Upstream.ts @@ -0,0 +1,25 @@ +import { AutoIncrement, Column, Model, PrimaryKey, Table } from "sequelize-typescript"; + +@Table({ + tableName: "dimension_upstreams", + underscoredAll: false, + timestamps: false, +}) +export default class Upstream extends Model { + @PrimaryKey + @AutoIncrement + @Column + id: number; + + @Column + name: string; + + @Column + type: string; + + @Column + scalarUrl: string; + + @Column + apiUrl: string; +} \ No newline at end of file diff --git a/src-ts/db/models/User.ts b/src-ts/db/models/User.ts new file mode 100644 index 0000000..36a28f4 --- /dev/null +++ b/src-ts/db/models/User.ts @@ -0,0 +1,14 @@ +import { Column, Model, PrimaryKey, Table } from "sequelize-typescript"; + +@Table({ + tableName: "dimension_users", + underscoredAll: false, + timestamps: false, +}) +export default class User extends Model { + // This is really just a holding class to keep foreign keys alive + + @PrimaryKey + @Column + userId: string; +} \ No newline at end of file diff --git a/src-ts/db/models/UserScalarToken.ts b/src-ts/db/models/UserScalarToken.ts new file mode 100644 index 0000000..522d573 --- /dev/null +++ b/src-ts/db/models/UserScalarToken.ts @@ -0,0 +1,39 @@ +import { + AllowNull, AutoIncrement, BelongsTo, Column, ForeignKey, Model, PrimaryKey, + Table +} from "sequelize-typescript"; +import User from "./User"; +import Upstream from "./Upstream"; + +@Table({ + tableName: "dimension_scalar_tokens", + underscoredAll: false, + timestamps: false, +}) +export default class UserScalarToken extends Model { + @PrimaryKey + @AutoIncrement + @Column + id: number; + + @Column + @ForeignKey(() => User) + userId: string; + + @BelongsTo(() => User) + user: User; + + @Column + scalarToken: string; + + @Column + isDimensionToken: boolean; + + @AllowNull + @Column + @ForeignKey(() => Upstream) + upstreamId?: number; + + @BelongsTo(() => Upstream) + upstream: Upstream; +} \ No newline at end of file diff --git a/src-ts/index.ts b/src-ts/index.ts new file mode 100644 index 0000000..ac720b8 --- /dev/null +++ b/src-ts/index.ts @@ -0,0 +1,15 @@ +import { LogService } from "matrix-js-snippets"; +import config from "./config"; +import { DimensionStore } from "./db/DimensionStore"; +import Webserver from "./api/Webserver"; + +LogService.configure(config.logging); +LogService.info("index", "Starting voyager..."); + +const webserver = new Webserver(); + +DimensionStore.updateSchema() + .then(() => webserver.start()) + .then(() => { + LogService.info("index", "Dimension is ready!"); + }); \ No newline at end of file diff --git a/src-ts/matrix/MatrixLiteClient.ts b/src-ts/matrix/MatrixLiteClient.ts new file mode 100644 index 0000000..ccde92e --- /dev/null +++ b/src-ts/matrix/MatrixLiteClient.ts @@ -0,0 +1,24 @@ +import * as Promise from "bluebird"; +import { doFederatedApiCall } from "./helpers"; + +export interface MatrixUrlPreview { + // This is really the only parameter we care about + "og:title"?: string; +} + +export class MatrixLiteClient { + + constructor(private homeserverName: string, private accessToken: string) { + } + + public getUrlPreview(url: string): Promise { + return doFederatedApiCall( + "GET", + this.homeserverName, + "/_matrix/media/r0/preview_url", + {access_token: this.accessToken, url: url} + ).then(response => { + return response; + }); + } +} diff --git a/src-ts/matrix/MatrixOpenIdClient.ts b/src-ts/matrix/MatrixOpenIdClient.ts new file mode 100644 index 0000000..beec738 --- /dev/null +++ b/src-ts/matrix/MatrixOpenIdClient.ts @@ -0,0 +1,20 @@ +import * as Promise from "bluebird"; +import { doFederatedApiCall } from "./helpers"; +import { OpenId } from "../models/OpenId"; + +export class MatrixOpenIdClient { + + constructor(private openId: OpenId) { + } + + public getUserId(): Promise { + return doFederatedApiCall( + "GET", + this.openId.matrix_server_name, + "/_matrix/federation/v1/openid/userinfo", + {access_token: this.openId.access_token} + ).then(response => { + return response['sub']; + }); + } +} diff --git a/src-ts/matrix/helpers.ts b/src-ts/matrix/helpers.ts new file mode 100644 index 0000000..28a7be6 --- /dev/null +++ b/src-ts/matrix/helpers.ts @@ -0,0 +1,61 @@ +import * as dns from "dns-then"; +import * as Promise from "bluebird"; +import { LogService } from "matrix-js-snippets"; +import { MemoryCache } from "../MemoryCache"; +import * as request from "request"; + +const federationUrlCache = new MemoryCache(); + +export function getFederationUrl(serverName: string): Promise { + const cachedUrl = federationUrlCache.get(serverName); + if (cachedUrl) { + LogService.verbose("matrix", "Cached federation URL for " + serverName + " is " + cachedUrl); + return Promise.resolve(cachedUrl); + } + + let serverUrl = null; + let expirationMs = 4 * 60 * 60 * 1000; // default is 4 hours + const dnsPromise = dns.resolveSrv("_matrix._tcp." + serverName); + return Promise.resolve(dnsPromise).then(records => { + if (records && records.length > 0) { + serverUrl = "https://" + records[0].name + ":" + records[0].port; + expirationMs = records[0].ttl * 1000; + } + }, _err => { + // Not having the SRV record isn't bad, it just means that the server operator decided to not use SRV records. + // When there's no SRV record we default to port 8448 (as per the federation rules) in the lower .then() + // People tend to think that the lack of an SRV record is bad, but in reality it's only a problem if one was set and + // it's not being found. Most people don't set up the SRV record, but some do. + LogService.warn("matrix", "Could not find _matrix._tcp." + serverName + " DNS record. This is normal for most servers."); + }).then(() => { + if (!serverUrl) serverUrl = "https://" + serverName + ":8448"; + LogService.verbose("matrix", "Federation URL for " + serverName + " is " + serverUrl + " - caching for " + expirationMs + " ms"); + federationUrlCache.put(serverName, serverUrl, expirationMs); + return serverUrl; + }); +} + +export function doFederatedApiCall(method: string, serverName: string, endpoint: string, query?: object, body?:object):Promise { + return getFederationUrl(serverName).then(federationUrl => { + return new Promise((resolve, reject) => { + request({ + method: method, + url: federationUrl + endpoint, + qs: query, + json: body, + rejectUnauthorized: false, // allow self signed certs (for federation) + }, (err, res, _body) => { + if (err) { + LogService.error("matrix", "Error calling " + endpoint); + LogService.error("matrix", err); + reject(err); + } else if (res.statusCode !== 200) { + LogService.error("matrix", "Got status code " + res.statusCode + " while calling " + endpoint); + reject(new Error("Error in request: invalid status code")); + } else { + resolve(res.body); + } + }); + }); + }); +} \ No newline at end of file diff --git a/src-ts/models/OpenId.ts b/src-ts/models/OpenId.ts new file mode 100644 index 0000000..6f61827 --- /dev/null +++ b/src-ts/models/OpenId.ts @@ -0,0 +1,6 @@ +export interface OpenId { + access_token: string; + matrix_server_name: string; + expires_in: number; + token_type: 'Bearer'; +} \ No newline at end of file diff --git a/src-ts/models/ScalarResponses.ts b/src-ts/models/ScalarResponses.ts new file mode 100644 index 0000000..5039c61 --- /dev/null +++ b/src-ts/models/ScalarResponses.ts @@ -0,0 +1,8 @@ +export interface ScalarRegisterResponse { + scalar_token: string; +} + +export interface ScalarAccountResponse { + user_id: string; + //credit: number; // present on scalar-web +} \ No newline at end of file diff --git a/src-ts/scalar/ScalarClient.ts b/src-ts/scalar/ScalarClient.ts new file mode 100644 index 0000000..f064ab7 --- /dev/null +++ b/src-ts/scalar/ScalarClient.ts @@ -0,0 +1,32 @@ +import { OpenId } from "../models/OpenId"; +import { ScalarRegisterResponse } from "../models/ScalarResponses"; +import * as Promise from "bluebird"; +import * as request from "request"; +import { LogService } from "matrix-js-snippets"; +import Upstream from "../db/models/Upstream"; + +export class ScalarClient { + constructor(private upstream: Upstream) { + } + + public register(openId: OpenId): Promise { + return new Promise((resolve, reject) => { + request({ + method: "POST", + url: this.upstream.scalarUrl + "/register", + json: openId, + }, (err, res, _body) => { + if (err) { + LogService.error("ScalarClient", "Error registering for token"); + LogService.error("ScalarClient", err); + reject(err); + } else if (res.statusCode !== 200) { + LogService.error("ScalarClient", "Got status code " + res.statusCode + " while registering for token"); + reject(new Error("Could not get token")); + } else { + resolve(res.body); + } + }); + }); + } +} \ No newline at end of file diff --git a/src-ts/temp_todo.txt b/src-ts/temp_todo.txt new file mode 100644 index 0000000..796bc2f --- /dev/null +++ b/src-ts/temp_todo.txt @@ -0,0 +1,5 @@ +* dimension apis +* integration management +* admin ui +* delete old src +* import from old db/config (script) \ No newline at end of file diff --git a/tsconfig-app.json b/tsconfig-app.json new file mode 100644 index 0000000..e58ba89 --- /dev/null +++ b/tsconfig-app.json @@ -0,0 +1,18 @@ +{ + "compilerOptions": { + "experimentalDecorators": true, + "emitDecoratorMetadata": true, + "module": "commonjs", + "moduleResolution": "node", + "target": "es2015", + "noImplicitAny": false, + "sourceMap": true, + "outDir": "./build/app", + "types": [ + "node" + ] + }, + "include": [ + "./src-ts/**/*" + ] +} \ No newline at end of file diff --git a/tslint.json b/tslint.json index 697a78d..25c7919 100644 --- a/tslint.json +++ b/tslint.json @@ -9,7 +9,7 @@ "check-space" ], "curly": false, - "eofline": true, + "eofline": false, "forin": false, "indent": [ true, @@ -107,9 +107,6 @@ ], "no-attribute-parameter-decorator": true, "no-forward-ref": true, - "import-destructuring-spacing": true, - "no-access-missing-member": true, - "templates-use-public": true, - "invoke-injectable": true + "import-destructuring-spacing": true } } \ No newline at end of file diff --git a/web/app/integration-bag/integration-bag.component.scss b/web/app/integration-bag/integration-bag.component.scss index 757f71e..063ff49 100644 --- a/web/app/integration-bag/integration-bag.component.scss +++ b/web/app/integration-bag/integration-bag.component.scss @@ -11,7 +11,7 @@ border: 1px solid #eee; border-radius: 5px; margin: 7px; - padding: 5px; + padding: 6px; width: calc(325px - 14px); position: relative; cursor: pointer; @@ -21,7 +21,7 @@ display: none; position: absolute; top: calc(50% - 12px); // icon happens to be 24px tall - right: 0; + right: 1px; color: #bbb; } diff --git a/webpack.config.js b/webpack.config.js index 4ac4b0b..85eb0f4 100644 --- a/webpack.config.js +++ b/webpack.config.js @@ -6,7 +6,7 @@ var HtmlWebpackPlugin = require('html-webpack-plugin'); var ExtractTextPlugin = require('extract-text-webpack-plugin'); var CopyWebpackPlugin = require('copy-webpack-plugin'); -var isProd = process.env.npm_lifecycle_event == 'build'; +var isProd = process.env.npm_lifecycle_event === 'build'; module.exports = function () { var config = {}; @@ -21,7 +21,7 @@ module.exports = function () { }; config.output = { - path: root('web-dist'), + path: path.join(root('build'), 'web'), publicPath: isProd ? '/' : '/', //http://0.0.0.0:8080', filename: isProd ? 'js/[name].[hash].js' : 'js/[name].js', chunkFilename: isProd ? '[id].[hash].chunk.js' : '[id].chunk.js'